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
      {
886 mhunt 61
        sleepCheck();
868 mhunt 62
        rippleEngine.collectMetaData();
63
 
814 mhunt 64
        if ( Thread.currentThread().isInterrupted() )
65
        {
66
          mLogger.warn("run is interrupted");
67
          // unit test technique
68
          throw new ExitException();
69
        }
70
 
896 mhunt 71
        if ( mUnitTest.compareTo("unit test spawn thread") == 0)
814 mhunt 72
        {
73
          throw new Exception();
74
        }
75
 
76
        MutableString buildFileContent = new MutableString();
77
 
896 mhunt 78
        if ( mUnitTest.compareTo("unit test check environment") != 0)
814 mhunt 79
        {
896 mhunt 80
          if ( mUnitTest.compareTo("unit test generate build files") != 0)
814 mhunt 81
          {
896 mhunt 82
            if ((mUnitTest.compareTo("unit test allowed to proceed") != 0) &&
83
                (mUnitTest.compareTo("unit test not allowed to proceed") != 0) &&
84
                (mUnitTest.compareTo("unit test exit") != 0))
814 mhunt 85
            {
886 mhunt 86
              // coordinate slave threads
87
              mLogger.warn("run coordinate slave threads");
88
 
89
              mRunLevel = RunLevel.WAITING;
90
              mLogger.warn("run changing run level to WAITING for rcon_id " + mRconId);
890 mhunt 91
              mRunLevel.persistNew(mReleaseManager, mRconId);
886 mhunt 92
 
93
              boolean allSlaveThreadsWaiting = false;
94
              boolean logWarning = true;
95
              boolean logWarning2 = true;
96
 
97
              while ( !allSlaveThreadsWaiting )
882 mhunt 98
              {
886 mhunt 99
                mReleaseManager.queryRunLevel(mRtagId);
100
 
892 mhunt 101
                // anything but WAITING or PAUSED
886 mhunt 102
                current_run_level.value = ReleaseManager.DB_IDLE;
103
                boolean moreRunLevelsConfigured = mReleaseManager.getFirstRunLevel(rconId, current_run_level);
104
 
105
                // attempt to exit loop
106
                allSlaveThreadsWaiting = true;
814 mhunt 107
 
886 mhunt 108
                do
814 mhunt 109
                {
886 mhunt 110
                  if (moreRunLevelsConfigured)
814 mhunt 111
                  {
892 mhunt 112
                    // DEVI 53065 Slave indication that they are done with a package includes
113
                    // having a paused run level
114
                    if ((current_run_level.value != ReleaseManager.DB_WAITING) &&
115
                        (current_run_level.value != ReleaseManager.DB_PAUSED))
816 mhunt 116
                    {
886 mhunt 117
                      if ( logWarning )
118
                      {
119
                        mLogger.warn("run waiting for rcon id " + rconId.value);
120
                        logWarning = false;
121
                      }
122
                      else
123
                      {
124
                        mLogger.info("run waiting for rcon id " + rconId.value);                      
125
                      }
126
                      allSlaveThreadsWaiting = false;
816 mhunt 127
                    }
128
                    else
129
                    {
886 mhunt 130
                      moreRunLevelsConfigured = mReleaseManager.getNextRunLevel(rconId, current_run_level);
816 mhunt 131
                    }
814 mhunt 132
                  }
133
                }
886 mhunt 134
                while (moreRunLevelsConfigured && allSlaveThreadsWaiting);
135
 
136
                if ( !allSlaveThreadsWaiting )
814 mhunt 137
                {
886 mhunt 138
                  // to do, sleep for periodicMs
896 mhunt 139
                  if ( mUnitTest.compareTo("unit test coordinate slave threads") == 0 )
820 mhunt 140
                  {
886 mhunt 141
                    Thread.currentThread().interrupt();
820 mhunt 142
                  }
143
                  else
144
                  {
886 mhunt 145
                    if ( logWarning2 )
146
                    {
147
                      mLogger.warn("run sleeping 3 secs waiting for slave threads");
148
                      logWarning2 = false;
149
                    }
150
                    else
151
                    {
152
                      mLogger.info("run sleeping 3 secs waiting for slave threads");
153
                    }
154
                    Thread.sleep(3000);
155
                    mLogger.info("run sleep returned");
820 mhunt 156
                  }
814 mhunt 157
                }
158
              }
886 mhunt 159
 
896 mhunt 160
              if ( mUnitTest.compareTo("unit test coordinate slave threads") == 0 )
814 mhunt 161
              {
886 mhunt 162
                throw new ExitException();
163
              }
164
 
165
              // DEVI 50527
166
              mRunLevel = RunLevel.PUBLISHING;
167
              mLogger.warn("run changing run level to PUBLISHING for rcon_id " + mRconId);
168
              mRunLevel.persist(mReleaseManager, mRconId);
169
 
170
              deliverChange(null, "AbtPublish", false);
171
              // preserve 
172
              String reportingFullyPublished = mReportingFullyPublished;
173
              String reportingNewLabel = mReportingNewLabel;
174
              deliverChange(null, "AbtTearDown", false);
175
 
176
              // DEVI 47395 delete the build file now
177
              // this will prevent any chance of multiply publishing a package version
178
              File buildFile = new File(mRtagId + "build.xml");
179
 
180
              if ( buildFile.exists() )
181
              {
182
                buildFile.delete();
183
              }
184
 
185
              if ( mReportingPackageName != null )
186
              {
187
                // a dummy build file did not apply
188
                // Publishing is done outside ant by design
189
                // The preference is to do all release manager work outside ant
190
 
191
                boolean buildErrorOccurred = true;
898 mhunt 192
                // max 50 characters
193
                String rootCause = "Error publishing to Release Manager";
886 mhunt 194
                try
814 mhunt 195
                {
886 mhunt 196
                  if ( reportingFullyPublished != null && reportingFullyPublished.compareTo("yes") == 0 )
814 mhunt 197
                  {
886 mhunt 198
                    buildErrorOccurred = false;
868 mhunt 199
 
886 mhunt 200
                    if ( reportingNewLabel.length() > 0 )
852 mhunt 201
                    {
886 mhunt 202
                      Integer rtagId = new Integer(mRtagId);
203
 
204
                      if ( mGbeGatherMetricsOnly == null )
868 mhunt 205
                      {
906 mhunt 206
                        // publish to release manager
207
                        mReleaseManager.autoMakeRelease(rtagId.toString(), mReportingPackageName, mReportingPackageExtension, mReportingPackageVersion, reportingNewLabel, mReportingPackageDepends, mReportingIsRipple);
868 mhunt 208
                      }
886 mhunt 209
 
210
                      FileInputStream abtmetrics = new FileInputStream( rtagId.toString() + "abtmetrics.txt" );
211
                      DataInputStream din = new DataInputStream( abtmetrics );
212
                      InputStreamReader isr = new InputStreamReader( din );
213
                      BufferedReader br = new BufferedReader( isr );
214
                      String metrics = br.readLine();
215
                      mLogger.warn( "execute read metrics string " + metrics );
216
                      br.close();
217
                      isr.close();
218
                      din.close();
219
 
220
                      mReleaseManager.insertPackageMetrics(rtagId.toString(), mReportingPackageName, mReportingPackageExtension, metrics );
852 mhunt 221
                    }
886 mhunt 222
                    else
223
                    {
224
                      mLogger.info("run package not labelled in ClearCase on " + mReportingPackageName + mReportingPackageVersion);
898 mhunt 225
                      // max 50 characters
226
                      rootCause = "Error publishing to ClearCase";
886 mhunt 227
                      throw new Exception();
228
                    }
814 mhunt 229
                  }
230
                  else
231
                  {
886 mhunt 232
                    mLogger.info("run build error occurred on " + mReportingPackageName + mReportingPackageVersion);
814 mhunt 233
                    throw new Exception();
234
                  }
886 mhunt 235
 
814 mhunt 236
                }
886 mhunt 237
                catch( Exception e)
814 mhunt 238
                {
898 mhunt 239
                  // a build error occurred or
886 mhunt 240
                  // an error occurred publishing to ClearCase or Release Manager
241
                  // take out the archive entry first
242
                  String fs = System.getProperty( "file.separator" );
243
                  String dpkgArchiveEntry = new String(Package.mGbeDpkg + fs + mReportingPackageName + fs + mReportingPackageVersion);
244
                  File dpkgArchiveEntryFile = new File(dpkgArchiveEntry);
245
                  mLogger.info("run checking existence of " + dpkgArchiveEntry);
246
 
247
                  if ( dpkgArchiveEntryFile.exists() )
814 mhunt 248
                  {
886 mhunt 249
                    if ( dpkgArchiveEntryFile.isDirectory() )
250
                    {
251
                      mLogger.warn("run deleting " + dpkgArchiveEntryFile.getName());
252
                      deleteDirectory(dpkgArchiveEntryFile);
253
                    }
814 mhunt 254
                  }
886 mhunt 255
                  else
814 mhunt 256
                  {
886 mhunt 257
                    String dplyArchiveEntry = new String(Package.mGbeDply + fs + mReportingPackageName + fs + mReportingPackageVersion);
258
                    File dplyArchiveEntryFile = new File(dplyArchiveEntry);
259
                    mLogger.info("run checking existence of " + dplyArchiveEntry);
260
 
261
                    if ( dplyArchiveEntryFile.exists() )
814 mhunt 262
                    {
886 mhunt 263
                      if ( dplyArchiveEntryFile.isDirectory() )
264
                      {
265
                        mLogger.warn("run deleting " + dplyArchiveEntryFile.getName());
266
                        deleteDirectory(dplyArchiveEntryFile);
267
                      }
814 mhunt 268
                    }
269
                  }
886 mhunt 270
 
271
                  Integer rtagId = new Integer(mRtagId);
272
 
273
                  if ( !buildErrorOccurred )
274
                  {
275
                    mLogger.fatal("an error occurred publishing to ClearCase or Release Manager");
900 mhunt 276
                    mReleaseManager.excludeFromBuild(mReportingPackageVersionId, null, rtagId.toString(), null, rootCause, null, true, false);
886 mhunt 277
                    throw new Exception("an error occurred publishing to ClearCase or Release Manager");
278
                  }
898 mhunt 279
 
902 mhunt 280
                  // DEVI 55364
281
                  // Package has not been built on all configured platforms
282
                  // Under normal circumstances, this root cause will be masked by a previously reported error
283
                  // Under abnormal circumstances amidst build activity such as:
284
                  // - slave build machine reboots
285
                  // - slave build machines with a read only file system
286
                  // this root cause is required to keep the end user informed
287
                  // max 50 chars
288
                  String cause = "Buildtool env error occurred. Attempt build again";
289
                  mReleaseManager.excludeFromBuild(mReportingPackageVersionId, mReportingPackageVersion, rtagId.toString(), null, mReportingBuildFailureLogFile == null ? cause : null, mReportingBuildFailureLogFile, true, false);
814 mhunt 290
                }
291
              }
886 mhunt 292
 
896 mhunt 293
              if ( mUnitTest.compareTo("unit test coordinate slave threads") == 0 )            
886 mhunt 294
              {
295
                throw new ExitException();
296
              }
297
              mLogger.info("run coordinate slave threads returned");
814 mhunt 298
            }
299
 
886 mhunt 300
            // DEVI 51366 allowed to proceed after coordinate slave threads
301
            mLogger.warn("run checking allowedToProceed");
302
            allowedToProceed(true);
303
            mLogger.info("run allowedToProceed returned");
304
 
896 mhunt 305
            if ( mUnitTest.compareTo("unit test allowed to proceed") == 0 )            
886 mhunt 306
            {
307
              throw new ExitException();
308
            }
814 mhunt 309
 
310
            // generate build files
311
            mLogger.warn("run generating build files");
312
            rippleEngine.planRelease();
313
 
314
            // get the build file from the ripple engine
315
            rippleEngine.getFirstBuildFileContent(buildFileContent, addendum);
316
 
317
            if ( addendum.value.compareTo("non generic") == 0 )
318
            {
319
              // publish the build file
320
              mLogger.warn("run publishing build file");
321
              mReleaseManager.publishBuildFile(mRtagId, buildFileContent.value);
322
            }
323
            else
324
            {
325
              // publish a dummy build file for either generic or dummy cases
326
              // this results in the slave not running ant
327
              mLogger.warn("run publishing dummy build file");
328
              mReleaseManager.publishBuildFile(mRtagId, mDummyBuildFileContent);
329
            }
330
          }
331
          mLogger.info("run generated build files");
332
 
868 mhunt 333
          if ( mGbeGatherMetricsOnly != null )
334
          {
335
            // set view up early for metrics gathering to ensure build file is fully written before letting the slave loose
336
            setViewUp(buildFileContent.value, true);            
337
          }
338
 
814 mhunt 339
          // change the run level for all threads in associated with the baseline
340
          mLogger.warn("run change the run level for all threads in associated with the baseline");
341
          mReleaseManager.queryReleaseConfig(mRtagId);
342
          rconId.value = -1;
343
          boolean moreBuildThreadsConfigured = mReleaseManager.getFirstReleaseConfig(rconId);
344
          mRunLevel = RunLevel.ACTIVE;
345
 
346
          do
347
          {
348
            if (moreBuildThreadsConfigured)
349
            {
816 mhunt 350
                mLogger.warn("run changing run level to ACTIVE for rcon_id " + rconId.value);
814 mhunt 351
                mRunLevel.persist(mReleaseManager, rconId.value);
352
                moreBuildThreadsConfigured = mReleaseManager.getNextReleaseConfig(rconId);
353
            }
354
          }
355
          while (moreBuildThreadsConfigured);
356
 
896 mhunt 357
          if ( mUnitTest.compareTo("unit test generate build files") == 0 )
814 mhunt 358
          {
359
            throw new ExitException();
360
          }
361
        }
362
 
363
        mLogger.info("run changed run levels");
364
 
365
        // check environment
366
        mLogger.warn("run checkEnvironment");
367
        checkEnvironment();
368
        mLogger.info("run checkEnvironment returned");
369
 
896 mhunt 370
        if ( mUnitTest.compareTo("unit test check environment") == 0 )
814 mhunt 371
        {
372
          throw new ExitException();
373
        }
374
 
375
        // deliver change to product baseline
376
        mLogger.warn("run deliverChange");
868 mhunt 377
 
378
        if ( mGbeGatherMetricsOnly == null )
379
        {
380
          setViewUp(buildFileContent.value, true);
381
        }
382
 
814 mhunt 383
        deliverChange(null, null, false);
384
        mLogger.info("run deliverChange returned");
886 mhunt 385
 
386
        mSleep = false;
387
        if ( addendum.value.compareTo("dummy") == 0 )
388
        {
389
          // no build requirement, so let things settle
390
          mLogger.warn("run no build requirement, so let things settle");
391
          mSleep = true;
392
        }        
393
 
814 mhunt 394
      }
395
      catch( SQLException e )
396
      {
397
        // oracle connection issues        
398
        mLogger.warn("run oracle connection issues");
886 mhunt 399
        mException = true;
814 mhunt 400
      }
401
      catch( ExitException e )
402
      {
858 mhunt 403
        mLogger.warn("run ExitException");
814 mhunt 404
        exit = true;
405
      }
406
      catch( InterruptedException e )
407
      {
408
        mLogger.warn("run InterruptedException");
409
      }
410
      catch( Exception e )
411
      {
412
        mLogger.error("run indefinitePause");
868 mhunt 413
        String cause = e.getMessage();
414
 
415
        if ( cause != null )
814 mhunt 416
        {
868 mhunt 417
          try
418
          {
419
            // notify first
420
            // many reasons for indefinite pause, including database related, so do database last
896 mhunt 421
            mRecoverable = false;
422
 
423
            if ( cause.compareTo(Package.mRecoverable) == 0 )
424
            {
425
              mRecoverable = true;
426
            }
427
 
868 mhunt 428
            indefinitePause(rippleEngine, cause);
429
            mReleaseManager.indefinitePause();
886 mhunt 430
            // DEVI 51366 force sleep at beginning of while loop
431
            mException = true;
868 mhunt 432
          }
433
          catch( Exception f )
434
          {
435
            mLogger.error("run indefinitePause failed");
436
          }
814 mhunt 437
        }
438
      }
439
    }
440
  }
441
 
442
  /**returns 'M'
443
   */
444
  protected char getMode()
445
  {
446
    mLogger.debug("getMode");
447
    return 'M';
448
  }
449
}