Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
814 mhunt 1
package com.erggroup.buildtool.daemon;
2
 
3
import com.erggroup.buildtool.daemon.BuildThread;
4
import com.erggroup.buildtool.ripple.MutableInt;
5
import com.erggroup.buildtool.ripple.MutableString;
6
import com.erggroup.buildtool.ripple.Package;
7
import com.erggroup.buildtool.ripple.ReleaseManager;
8
import com.erggroup.buildtool.ripple.RippleEngine;
9
 
10
import java.io.BufferedReader;
834 mhunt 11
import java.io.DataInputStream;
814 mhunt 12
import java.io.File;
834 mhunt 13
import java.io.FileInputStream;
14
import java.io.InputStreamReader;
814 mhunt 15
import java.sql.SQLException;
16
 
17
import org.apache.log4j.Logger;
18
 
19
/**Master Thread sub component
20
 */
21
public class MasterThread
22
  extends BuildThread
23
{
24
 
25
  /**Logger
26
   * @attribute
27
   */
28
  private static final Logger mLogger = Logger.getLogger(MasterThread.class);
29
 
864 mhunt 30
   /**constructor
814 mhunt 31
   */
896 mhunt 32
  public MasterThread(int rtag_id, int rcon_id, String unitTest)
814 mhunt 33
  {
818 mhunt 34
    mLogger.warn("MasterThread rtag_id " + rtag_id + " rcon_id " + rcon_id);
814 mhunt 35
    mRtagId = rtag_id;
36
    mRconId = rcon_id;
896 mhunt 37
    if ( unitTest == null )
38
    {
39
      unitTest = new String();
40
    }
41
    mUnitTest = unitTest;
814 mhunt 42
  }
43
 
44
  /**implements the sequence diagrams coordinate slave threads, generate build files, allowed to proceed, check environment
45
   */
46
  public void run()
47
  {
48
    Integer id = new Integer(mRtagId);
49
    setName(id.toString());
50
    mLogger.debug("run");
51
    boolean exit = false;
52
    RippleEngine rippleEngine = new RippleEngine(mReleaseManager, mRtagId, true);
53
    MutableInt rconId = new MutableInt();
54
    MutableInt current_run_level = new MutableInt();
55
    MutableString addendum = new MutableString();
56
 
57
    while(!exit)
58
    {
59
      try
60
      {
916 mhunt 61
        mLogger.fatal("run calling sleepCheck");
886 mhunt 62
        sleepCheck();
916 mhunt 63
        mLogger.fatal("run calling rippleEngine.collectMetaData");
868 mhunt 64
        rippleEngine.collectMetaData();
65
 
814 mhunt 66
        if ( Thread.currentThread().isInterrupted() )
67
        {
68
          mLogger.warn("run is interrupted");
69
          // unit test technique
70
          throw new ExitException();
71
        }
72
 
896 mhunt 73
        if ( mUnitTest.compareTo("unit test spawn thread") == 0)
814 mhunt 74
        {
75
          throw new Exception();
76
        }
77
 
78
        MutableString buildFileContent = new MutableString();
79
 
896 mhunt 80
        if ( mUnitTest.compareTo("unit test check environment") != 0)
814 mhunt 81
        {
896 mhunt 82
          if ( mUnitTest.compareTo("unit test generate build files") != 0)
814 mhunt 83
          {
896 mhunt 84
            if ((mUnitTest.compareTo("unit test allowed to proceed") != 0) &&
85
                (mUnitTest.compareTo("unit test not allowed to proceed") != 0) &&
86
                (mUnitTest.compareTo("unit test exit") != 0))
814 mhunt 87
            {
886 mhunt 88
              // coordinate slave threads
89
              mLogger.warn("run coordinate slave threads");
90
 
91
              mRunLevel = RunLevel.WAITING;
92
              mLogger.warn("run changing run level to WAITING for rcon_id " + mRconId);
916 mhunt 93
              mLogger.fatal("run calling mRunLevel.persistNew to set WAITING");
890 mhunt 94
              mRunLevel.persistNew(mReleaseManager, mRconId);
886 mhunt 95
 
96
              boolean allSlaveThreadsWaiting = false;
97
              boolean logWarning = true;
98
              boolean logWarning2 = true;
99
 
100
              while ( !allSlaveThreadsWaiting )
882 mhunt 101
              {
916 mhunt 102
                mLogger.fatal("run calling mReleaseManager.queryRunLevel");
886 mhunt 103
                mReleaseManager.queryRunLevel(mRtagId);
104
 
892 mhunt 105
                // anything but WAITING or PAUSED
886 mhunt 106
                current_run_level.value = ReleaseManager.DB_IDLE;
916 mhunt 107
                mLogger.fatal("run calling mReleaseManager.getFirstRunLevel");
886 mhunt 108
                boolean moreRunLevelsConfigured = mReleaseManager.getFirstRunLevel(rconId, current_run_level);
109
 
110
                // attempt to exit loop
111
                allSlaveThreadsWaiting = true;
814 mhunt 112
 
886 mhunt 113
                do
814 mhunt 114
                {
886 mhunt 115
                  if (moreRunLevelsConfigured)
814 mhunt 116
                  {
892 mhunt 117
                    // DEVI 53065 Slave indication that they are done with a package includes
118
                    // having a paused run level
119
                    if ((current_run_level.value != ReleaseManager.DB_WAITING) &&
120
                        (current_run_level.value != ReleaseManager.DB_PAUSED))
816 mhunt 121
                    {
886 mhunt 122
                      if ( logWarning )
123
                      {
124
                        mLogger.warn("run waiting for rcon id " + rconId.value);
125
                        logWarning = false;
126
                      }
127
                      else
128
                      {
129
                        mLogger.info("run waiting for rcon id " + rconId.value);                      
130
                      }
131
                      allSlaveThreadsWaiting = false;
816 mhunt 132
                    }
133
                    else
134
                    {
916 mhunt 135
                      mLogger.fatal("run calling mReleaseManager.getNextRunLevel");
886 mhunt 136
                      moreRunLevelsConfigured = mReleaseManager.getNextRunLevel(rconId, current_run_level);
816 mhunt 137
                    }
814 mhunt 138
                  }
139
                }
886 mhunt 140
                while (moreRunLevelsConfigured && allSlaveThreadsWaiting);
141
 
142
                if ( !allSlaveThreadsWaiting )
814 mhunt 143
                {
886 mhunt 144
                  // to do, sleep for periodicMs
896 mhunt 145
                  if ( mUnitTest.compareTo("unit test coordinate slave threads") == 0 )
820 mhunt 146
                  {
886 mhunt 147
                    Thread.currentThread().interrupt();
820 mhunt 148
                  }
149
                  else
150
                  {
886 mhunt 151
                    if ( logWarning2 )
152
                    {
153
                      mLogger.warn("run sleeping 3 secs waiting for slave threads");
154
                      logWarning2 = false;
155
                    }
156
                    else
157
                    {
158
                      mLogger.info("run sleeping 3 secs waiting for slave threads");
159
                    }
916 mhunt 160
                    mLogger.fatal("run calling Thread.sleep for 3 secs");
886 mhunt 161
                    Thread.sleep(3000);
162
                    mLogger.info("run sleep returned");
820 mhunt 163
                  }
814 mhunt 164
                }
165
              }
886 mhunt 166
 
896 mhunt 167
              if ( mUnitTest.compareTo("unit test coordinate slave threads") == 0 )
814 mhunt 168
              {
886 mhunt 169
                throw new ExitException();
170
              }
171
 
172
              // DEVI 50527
173
              mRunLevel = RunLevel.PUBLISHING;
174
              mLogger.warn("run changing run level to PUBLISHING for rcon_id " + mRconId);
916 mhunt 175
              mLogger.fatal("run calling mRunLevel.persist to set PUBLISHING");
886 mhunt 176
              mRunLevel.persist(mReleaseManager, mRconId);
177
 
916 mhunt 178
              mLogger.fatal("run calling deliverChange on AbtPublish");
886 mhunt 179
              deliverChange(null, "AbtPublish", false);
180
              // preserve 
181
              String reportingFullyPublished = mReportingFullyPublished;
182
              String reportingNewLabel = mReportingNewLabel;
916 mhunt 183
              mLogger.fatal("run calling deliverChange on AbtTearDown");
886 mhunt 184
              deliverChange(null, "AbtTearDown", false);
185
 
186
              // DEVI 47395 delete the build file now
187
              // this will prevent any chance of multiply publishing a package version
188
              File buildFile = new File(mRtagId + "build.xml");
189
 
190
              if ( buildFile.exists() )
191
              {
192
                buildFile.delete();
193
              }
194
 
195
              if ( mReportingPackageName != null )
196
              {
197
                // a dummy build file did not apply
198
                // Publishing is done outside ant by design
199
                // The preference is to do all release manager work outside ant
200
 
201
                boolean buildErrorOccurred = true;
898 mhunt 202
                // max 50 characters
203
                String rootCause = "Error publishing to Release Manager";
886 mhunt 204
                try
814 mhunt 205
                {
908 mhunt 206
                  if ( mReportingTestBuild.compareTo("0") != 0 )
207
                  {
208
                    mLogger.info("run completing test build on " + mReportingPackageName + mReportingPackageExtension);
209
                    // build failure emails will have been sent
210
                    // just left to notify the user of the test build completion
211
                    Package p = rippleEngine.findPackage(mReportingPackageName + mReportingPackageExtension);
212
 
213
                    if (p != ReleaseManager.NULL_PACKAGE)
214
                    {
215
                      boolean success = false;
216
 
217
                      if ( reportingFullyPublished != null && reportingFullyPublished.compareTo("yes") == 0 )
218
                      {
219
                        success = true;
220
                      }
221
 
916 mhunt 222
                      mLogger.fatal("run calling p.completeTestBuild");                      
908 mhunt 223
                      p.completeTestBuild(rippleEngine.mMailServer, rippleEngine.mMailSender, mReleaseManager, rippleEngine.mBaselineName, success);
224
                    }
225
 
226
                    // ... and clean up the mess in the archive
227
                    throw new Exception();                    
228
                  }
229
 
886 mhunt 230
                  if ( reportingFullyPublished != null && reportingFullyPublished.compareTo("yes") == 0 )
814 mhunt 231
                  {
886 mhunt 232
                    buildErrorOccurred = false;
868 mhunt 233
 
886 mhunt 234
                    if ( reportingNewLabel.length() > 0 )
852 mhunt 235
                    {
886 mhunt 236
                      Integer rtagId = new Integer(mRtagId);
237
 
238
                      if ( mGbeGatherMetricsOnly == null )
868 mhunt 239
                      {
906 mhunt 240
                        // publish to release manager
916 mhunt 241
                        mLogger.fatal("run calling mReleaseManager.autoMakeRelease");                      
906 mhunt 242
                        mReleaseManager.autoMakeRelease(rtagId.toString(), mReportingPackageName, mReportingPackageExtension, mReportingPackageVersion, reportingNewLabel, mReportingPackageDepends, mReportingIsRipple);
868 mhunt 243
                      }
886 mhunt 244
 
245
                      FileInputStream abtmetrics = new FileInputStream( rtagId.toString() + "abtmetrics.txt" );
246
                      DataInputStream din = new DataInputStream( abtmetrics );
247
                      InputStreamReader isr = new InputStreamReader( din );
248
                      BufferedReader br = new BufferedReader( isr );
249
                      String metrics = br.readLine();
250
                      mLogger.warn( "execute read metrics string " + metrics );
251
                      br.close();
252
                      isr.close();
253
                      din.close();
254
 
916 mhunt 255
                      mLogger.fatal("run calling mReleaseManager.insertPackageMetrics");                      
886 mhunt 256
                      mReleaseManager.insertPackageMetrics(rtagId.toString(), mReportingPackageName, mReportingPackageExtension, metrics );
852 mhunt 257
                    }
886 mhunt 258
                    else
259
                    {
260
                      mLogger.info("run package not labelled in ClearCase on " + mReportingPackageName + mReportingPackageVersion);
898 mhunt 261
                      // max 50 characters
262
                      rootCause = "Error publishing to ClearCase";
886 mhunt 263
                      throw new Exception();
264
                    }
814 mhunt 265
                  }
266
                  else
267
                  {
886 mhunt 268
                    mLogger.info("run build error occurred on " + mReportingPackageName + mReportingPackageVersion);
814 mhunt 269
                    throw new Exception();
270
                  }
886 mhunt 271
 
814 mhunt 272
                }
886 mhunt 273
                catch( Exception e)
814 mhunt 274
                {
898 mhunt 275
                  // a build error occurred or
886 mhunt 276
                  // an error occurred publishing to ClearCase or Release Manager
277
                  // take out the archive entry first
278
                  String fs = System.getProperty( "file.separator" );
279
                  String dpkgArchiveEntry = new String(Package.mGbeDpkg + fs + mReportingPackageName + fs + mReportingPackageVersion);
280
                  File dpkgArchiveEntryFile = new File(dpkgArchiveEntry);
281
                  mLogger.info("run checking existence of " + dpkgArchiveEntry);
282
 
283
                  if ( dpkgArchiveEntryFile.exists() )
814 mhunt 284
                  {
886 mhunt 285
                    if ( dpkgArchiveEntryFile.isDirectory() )
286
                    {
287
                      mLogger.warn("run deleting " + dpkgArchiveEntryFile.getName());
916 mhunt 288
                      mLogger.fatal("run calling deleteDirectory on " + dpkgArchiveEntryFile);                      
886 mhunt 289
                      deleteDirectory(dpkgArchiveEntryFile);
290
                    }
814 mhunt 291
                  }
886 mhunt 292
                  else
814 mhunt 293
                  {
886 mhunt 294
                    String dplyArchiveEntry = new String(Package.mGbeDply + fs + mReportingPackageName + fs + mReportingPackageVersion);
295
                    File dplyArchiveEntryFile = new File(dplyArchiveEntry);
296
                    mLogger.info("run checking existence of " + dplyArchiveEntry);
297
 
298
                    if ( dplyArchiveEntryFile.exists() )
814 mhunt 299
                    {
886 mhunt 300
                      if ( dplyArchiveEntryFile.isDirectory() )
301
                      {
302
                        mLogger.warn("run deleting " + dplyArchiveEntryFile.getName());
916 mhunt 303
                        mLogger.fatal("run calling deleteDirectory on " + dplyArchiveEntryFile);                      
886 mhunt 304
                        deleteDirectory(dplyArchiveEntryFile);
305
                      }
814 mhunt 306
                    }
307
                  }
886 mhunt 308
 
309
                  Integer rtagId = new Integer(mRtagId);
310
 
311
                  if ( !buildErrorOccurred )
312
                  {
313
                    mLogger.fatal("an error occurred publishing to ClearCase or Release Manager");
908 mhunt 314
                    // force exclusion by default
315
                    int testBuildInstruction = 0;
316
                    try
317
                    {
318
                      testBuildInstruction = Integer.parseInt( mReportingTestBuild );
319
                    }
320
                    catch( NumberFormatException nfe )
321
                    {
322
                    }
916 mhunt 323
                    mLogger.fatal("run calling excludeFromBuild");                      
908 mhunt 324
                    mReleaseManager.excludeFromBuild(mReportingPackageVersionId, null, rtagId.toString(), null, rootCause, null, false, testBuildInstruction);
886 mhunt 325
                    throw new Exception("an error occurred publishing to ClearCase or Release Manager");
326
                  }
898 mhunt 327
 
902 mhunt 328
                  // DEVI 55364
329
                  // Package has not been built on all configured platforms
330
                  // Under normal circumstances, this root cause will be masked by a previously reported error
331
                  // Under abnormal circumstances amidst build activity such as:
332
                  // - slave build machine reboots
333
                  // - slave build machines with a read only file system
334
                  // this root cause is required to keep the end user informed
335
                  // max 50 chars
336
                  String cause = "Buildtool env error occurred. Attempt build again";
908 mhunt 337
                  // force exclusion by default
338
                  int testBuildInstruction = 0;
339
                  try
340
                  {
341
                    testBuildInstruction = Integer.parseInt( mReportingTestBuild );
342
                  }
343
                  catch( NumberFormatException nfe )
344
                  {
345
                  }
916 mhunt 346
                  mLogger.fatal("run calling excludeFromBuild");                      
908 mhunt 347
                  mReleaseManager.excludeFromBuild(mReportingPackageVersionId, mReportingPackageVersion, rtagId.toString(), null, mReportingBuildFailureLogFile == null ? cause : null, mReportingBuildFailureLogFile, false, testBuildInstruction);
814 mhunt 348
                }
349
              }
886 mhunt 350
 
896 mhunt 351
              if ( mUnitTest.compareTo("unit test coordinate slave threads") == 0 )            
886 mhunt 352
              {
353
                throw new ExitException();
354
              }
355
              mLogger.info("run coordinate slave threads returned");
814 mhunt 356
            }
357
 
886 mhunt 358
            // DEVI 51366 allowed to proceed after coordinate slave threads
359
            mLogger.warn("run checking allowedToProceed");
916 mhunt 360
            mLogger.fatal("run calling allowedToProceed");                      
886 mhunt 361
            allowedToProceed(true);
362
            mLogger.info("run allowedToProceed returned");
363
 
896 mhunt 364
            if ( mUnitTest.compareTo("unit test allowed to proceed") == 0 )            
886 mhunt 365
            {
366
              throw new ExitException();
367
            }
814 mhunt 368
 
369
            // generate build files
370
            mLogger.warn("run generating build files");
916 mhunt 371
            mLogger.fatal("run calling planRelease");                      
814 mhunt 372
            rippleEngine.planRelease();
916 mhunt 373
            mLogger.fatal("run calling reportChange");                      
908 mhunt 374
            rippleEngine.reportChange();
814 mhunt 375
 
376
            // get the build file from the ripple engine
377
            rippleEngine.getFirstBuildFileContent(buildFileContent, addendum);
378
 
379
            if ( addendum.value.compareTo("non generic") == 0 )
380
            {
381
              // publish the build file
382
              mLogger.warn("run publishing build file");
916 mhunt 383
              mLogger.fatal("run calling publishBuildFile");                      
814 mhunt 384
              mReleaseManager.publishBuildFile(mRtagId, buildFileContent.value);
385
            }
386
            else
387
            {
388
              // publish a dummy build file for either generic or dummy cases
389
              // this results in the slave not running ant
390
              mLogger.warn("run publishing dummy build file");
916 mhunt 391
              mLogger.fatal("run calling publishBuildFile on dummy");                      
814 mhunt 392
              mReleaseManager.publishBuildFile(mRtagId, mDummyBuildFileContent);
393
            }
394
          }
395
          mLogger.info("run generated build files");
396
 
868 mhunt 397
          if ( mGbeGatherMetricsOnly != null )
398
          {
399
            // set view up early for metrics gathering to ensure build file is fully written before letting the slave loose
916 mhunt 400
            mLogger.fatal("run calling setViewUp");                      
868 mhunt 401
            setViewUp(buildFileContent.value, true);            
402
          }
403
 
814 mhunt 404
          // change the run level for all threads in associated with the baseline
405
          mLogger.warn("run change the run level for all threads in associated with the baseline");
916 mhunt 406
          mLogger.fatal("run calling queryReleaseConfig");                      
814 mhunt 407
          mReleaseManager.queryReleaseConfig(mRtagId);
408
          rconId.value = -1;
409
          boolean moreBuildThreadsConfigured = mReleaseManager.getFirstReleaseConfig(rconId);
410
          mRunLevel = RunLevel.ACTIVE;
411
 
412
          do
413
          {
414
            if (moreBuildThreadsConfigured)
415
            {
816 mhunt 416
                mLogger.warn("run changing run level to ACTIVE for rcon_id " + rconId.value);
916 mhunt 417
                mLogger.fatal("run calling mRunLevel.persist to set ACTIVE");                      
814 mhunt 418
                mRunLevel.persist(mReleaseManager, rconId.value);
419
                moreBuildThreadsConfigured = mReleaseManager.getNextReleaseConfig(rconId);
420
            }
421
          }
422
          while (moreBuildThreadsConfigured);
423
 
896 mhunt 424
          if ( mUnitTest.compareTo("unit test generate build files") == 0 )
814 mhunt 425
          {
426
            throw new ExitException();
427
          }
428
        }
429
 
430
        mLogger.info("run changed run levels");
431
 
432
        // check environment
433
        mLogger.warn("run checkEnvironment");
916 mhunt 434
        mLogger.fatal("run calling checkEnvironment");                      
814 mhunt 435
        checkEnvironment();
436
        mLogger.info("run checkEnvironment returned");
437
 
896 mhunt 438
        if ( mUnitTest.compareTo("unit test check environment") == 0 )
814 mhunt 439
        {
440
          throw new ExitException();
441
        }
442
 
443
        // deliver change to product baseline
444
        mLogger.warn("run deliverChange");
868 mhunt 445
 
446
        if ( mGbeGatherMetricsOnly == null )
447
        {
916 mhunt 448
          mLogger.fatal("run calling setViewUp metrics only");                      
868 mhunt 449
          setViewUp(buildFileContent.value, true);
450
        }
451
 
916 mhunt 452
        mLogger.fatal("run calling deliverChange - the actual build");                      
814 mhunt 453
        deliverChange(null, null, false);
454
        mLogger.info("run deliverChange returned");
886 mhunt 455
 
456
        mSleep = false;
457
        if ( addendum.value.compareTo("dummy") == 0 )
458
        {
459
          // no build requirement, so let things settle
460
          mLogger.warn("run no build requirement, so let things settle");
461
          mSleep = true;
462
        }        
463
 
814 mhunt 464
      }
465
      catch( SQLException e )
466
      {
467
        // oracle connection issues        
468
        mLogger.warn("run oracle connection issues");
886 mhunt 469
        mException = true;
814 mhunt 470
      }
471
      catch( ExitException e )
472
      {
858 mhunt 473
        mLogger.warn("run ExitException");
814 mhunt 474
        exit = true;
475
      }
476
      catch( InterruptedException e )
477
      {
478
        mLogger.warn("run InterruptedException");
479
      }
480
      catch( Exception e )
481
      {
482
        mLogger.error("run indefinitePause");
868 mhunt 483
        String cause = e.getMessage();
484
 
485
        if ( cause != null )
814 mhunt 486
        {
868 mhunt 487
          try
488
          {
489
            // notify first
490
            // many reasons for indefinite pause, including database related, so do database last
896 mhunt 491
            mRecoverable = false;
492
 
493
            if ( cause.compareTo(Package.mRecoverable) == 0 )
494
            {
495
              mRecoverable = true;
496
            }
497
 
868 mhunt 498
            indefinitePause(rippleEngine, cause);
499
            mReleaseManager.indefinitePause();
886 mhunt 500
            // DEVI 51366 force sleep at beginning of while loop
501
            mException = true;
868 mhunt 502
          }
503
          catch( Exception f )
504
          {
505
            mLogger.error("run indefinitePause failed");
506
          }
814 mhunt 507
        }
508
      }
509
    }
510
  }
511
 
512
  /**returns 'M'
513
   */
514
  protected char getMode()
515
  {
516
    mLogger.debug("getMode");
517
    return 'M';
518
  }
519
}