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;
192
                try
814 mhunt 193
                {
886 mhunt 194
                  if ( reportingFullyPublished != null && reportingFullyPublished.compareTo("yes") == 0 )
814 mhunt 195
                  {
886 mhunt 196
                    buildErrorOccurred = false;
868 mhunt 197
 
886 mhunt 198
                    if ( reportingNewLabel.length() > 0 )
852 mhunt 199
                    {
886 mhunt 200
                      Integer rtagId = new Integer(mRtagId);
201
 
202
                      if ( mGbeGatherMetricsOnly == null )
868 mhunt 203
                      {
886 mhunt 204
                        if ( mReportingDoesNotRequireSourceControlInteraction.compareTo("false") == 0 )
205
                        {
206
                          // requires source control interaction ie labelled in ClearCase
207
                          // publish to release manager
208
                          mReleaseManager.autoMakeRelease(rtagId.toString(), mReportingPackageName, mReportingPackageExtension, mReportingPackageVersion, reportingNewLabel, mReportingPackageDepends, mReportingIsRipple);
209
                        }
210
                        else
211
                        {
212
                          // trigger release note generation and on_make_official.wsf, which changes ownership and write access in the archive
213
                          // this should not be through autoMakeRelease (sledgehammer, the package is already official in release manager in this scenario)
214
                          // at the time of writing, calling autoMakeRelease does not help if the package was 'released' more than 24 hours ago
215
                          // this seems to be a business rule in the generate_release_notes package
216
                          // the buildtool has no option but to call autoMakeRelease at present
217
                          mReleaseManager.autoMakeRelease(rtagId.toString(), mReportingPackageName, mReportingPackageExtension, mReportingPackageVersion, reportingNewLabel, mReportingPackageDepends, mReportingIsRipple);
218
                        }
868 mhunt 219
                      }
886 mhunt 220
 
221
                      FileInputStream abtmetrics = new FileInputStream( rtagId.toString() + "abtmetrics.txt" );
222
                      DataInputStream din = new DataInputStream( abtmetrics );
223
                      InputStreamReader isr = new InputStreamReader( din );
224
                      BufferedReader br = new BufferedReader( isr );
225
                      String metrics = br.readLine();
226
                      mLogger.warn( "execute read metrics string " + metrics );
227
                      br.close();
228
                      isr.close();
229
                      din.close();
230
 
231
                      mReleaseManager.insertPackageMetrics(rtagId.toString(), mReportingPackageName, mReportingPackageExtension, metrics );
852 mhunt 232
                    }
886 mhunt 233
                    else
234
                    {
235
                      mLogger.info("run package not labelled in ClearCase on " + mReportingPackageName + mReportingPackageVersion);
236
                      throw new Exception();
237
                    }
814 mhunt 238
                  }
239
                  else
240
                  {
886 mhunt 241
                    mLogger.info("run build error occurred on " + mReportingPackageName + mReportingPackageVersion);
814 mhunt 242
                    throw new Exception();
243
                  }
886 mhunt 244
 
814 mhunt 245
                }
886 mhunt 246
                catch( Exception e)
814 mhunt 247
                {
886 mhunt 248
                  // an error occurred publishing to ClearCase or Release Manager
249
                  // take out the archive entry first
250
                  String fs = System.getProperty( "file.separator" );
251
                  String dpkgArchiveEntry = new String(Package.mGbeDpkg + fs + mReportingPackageName + fs + mReportingPackageVersion);
252
                  File dpkgArchiveEntryFile = new File(dpkgArchiveEntry);
253
                  mLogger.info("run checking existence of " + dpkgArchiveEntry);
254
 
255
                  if ( dpkgArchiveEntryFile.exists() )
814 mhunt 256
                  {
886 mhunt 257
                    if ( dpkgArchiveEntryFile.isDirectory() )
258
                    {
259
                      mLogger.warn("run deleting " + dpkgArchiveEntryFile.getName());
260
                      deleteDirectory(dpkgArchiveEntryFile);
261
                    }
814 mhunt 262
                  }
886 mhunt 263
                  else
814 mhunt 264
                  {
886 mhunt 265
                    String dplyArchiveEntry = new String(Package.mGbeDply + fs + mReportingPackageName + fs + mReportingPackageVersion);
266
                    File dplyArchiveEntryFile = new File(dplyArchiveEntry);
267
                    mLogger.info("run checking existence of " + dplyArchiveEntry);
268
 
269
                    if ( dplyArchiveEntryFile.exists() )
814 mhunt 270
                    {
886 mhunt 271
                      if ( dplyArchiveEntryFile.isDirectory() )
272
                      {
273
                        mLogger.warn("run deleting " + dplyArchiveEntryFile.getName());
274
                        deleteDirectory(dplyArchiveEntryFile);
275
                      }
814 mhunt 276
                    }
277
                  }
886 mhunt 278
 
279
                  Integer rtagId = new Integer(mRtagId);
280
                  // pass root file
281
                  mReleaseManager.excludeFromBuild(mReportingPackageVersionId, mReportingPackageVersion, rtagId.toString(), null, null, mReportingBuildFailureLogFile);
282
 
283
                  if ( !buildErrorOccurred )
284
                  {
285
                    mLogger.fatal("an error occurred publishing to ClearCase or Release Manager");
286
                    throw new Exception("an error occurred publishing to ClearCase or Release Manager");
287
                  }
814 mhunt 288
                }
289
              }
886 mhunt 290
 
896 mhunt 291
              if ( mUnitTest.compareTo("unit test coordinate slave threads") == 0 )            
886 mhunt 292
              {
293
                throw new ExitException();
294
              }
295
              mLogger.info("run coordinate slave threads returned");
814 mhunt 296
            }
297
 
886 mhunt 298
            // DEVI 51366 allowed to proceed after coordinate slave threads
299
            mLogger.warn("run checking allowedToProceed");
300
            allowedToProceed(true);
301
            mLogger.info("run allowedToProceed returned");
302
 
896 mhunt 303
            if ( mUnitTest.compareTo("unit test allowed to proceed") == 0 )            
886 mhunt 304
            {
305
              throw new ExitException();
306
            }
814 mhunt 307
 
308
            // generate build files
309
            mLogger.warn("run generating build files");
310
            rippleEngine.planRelease();
311
 
312
            // get the build file from the ripple engine
313
            rippleEngine.getFirstBuildFileContent(buildFileContent, addendum);
314
 
315
            if ( addendum.value.compareTo("non generic") == 0 )
316
            {
317
              // publish the build file
318
              mLogger.warn("run publishing build file");
319
              mReleaseManager.publishBuildFile(mRtagId, buildFileContent.value);
320
            }
321
            else
322
            {
323
              // publish a dummy build file for either generic or dummy cases
324
              // this results in the slave not running ant
325
              mLogger.warn("run publishing dummy build file");
326
              mReleaseManager.publishBuildFile(mRtagId, mDummyBuildFileContent);
327
            }
328
          }
329
          mLogger.info("run generated build files");
330
 
868 mhunt 331
          if ( mGbeGatherMetricsOnly != null )
332
          {
333
            // set view up early for metrics gathering to ensure build file is fully written before letting the slave loose
334
            setViewUp(buildFileContent.value, true);            
335
          }
336
 
814 mhunt 337
          // change the run level for all threads in associated with the baseline
338
          mLogger.warn("run change the run level for all threads in associated with the baseline");
339
          mReleaseManager.queryReleaseConfig(mRtagId);
340
          rconId.value = -1;
341
          boolean moreBuildThreadsConfigured = mReleaseManager.getFirstReleaseConfig(rconId);
342
          mRunLevel = RunLevel.ACTIVE;
343
 
344
          do
345
          {
346
            if (moreBuildThreadsConfigured)
347
            {
816 mhunt 348
                mLogger.warn("run changing run level to ACTIVE for rcon_id " + rconId.value);
814 mhunt 349
                mRunLevel.persist(mReleaseManager, rconId.value);
350
                moreBuildThreadsConfigured = mReleaseManager.getNextReleaseConfig(rconId);
351
            }
352
          }
353
          while (moreBuildThreadsConfigured);
354
 
896 mhunt 355
          if ( mUnitTest.compareTo("unit test generate build files") == 0 )
814 mhunt 356
          {
357
            throw new ExitException();
358
          }
359
        }
360
 
361
        mLogger.info("run changed run levels");
362
 
363
        // check environment
364
        mLogger.warn("run checkEnvironment");
365
        checkEnvironment();
366
        mLogger.info("run checkEnvironment returned");
367
 
896 mhunt 368
        if ( mUnitTest.compareTo("unit test check environment") == 0 )
814 mhunt 369
        {
370
          throw new ExitException();
371
        }
372
 
373
        // deliver change to product baseline
374
        mLogger.warn("run deliverChange");
868 mhunt 375
 
376
        if ( mGbeGatherMetricsOnly == null )
377
        {
378
          setViewUp(buildFileContent.value, true);
379
        }
380
 
814 mhunt 381
        deliverChange(null, null, false);
382
        mLogger.info("run deliverChange returned");
886 mhunt 383
 
384
        mSleep = false;
385
        if ( addendum.value.compareTo("dummy") == 0 )
386
        {
387
          // no build requirement, so let things settle
388
          mLogger.warn("run no build requirement, so let things settle");
389
          mSleep = true;
390
        }        
391
 
814 mhunt 392
      }
393
      catch( SQLException e )
394
      {
395
        // oracle connection issues        
396
        mLogger.warn("run oracle connection issues");
886 mhunt 397
        mException = true;
814 mhunt 398
      }
399
      catch( ExitException e )
400
      {
858 mhunt 401
        mLogger.warn("run ExitException");
814 mhunt 402
        exit = true;
403
      }
404
      catch( InterruptedException e )
405
      {
406
        mLogger.warn("run InterruptedException");
407
      }
408
      catch( Exception e )
409
      {
410
        mLogger.error("run indefinitePause");
868 mhunt 411
        String cause = e.getMessage();
412
 
413
        if ( cause != null )
814 mhunt 414
        {
868 mhunt 415
          try
416
          {
417
            // notify first
418
            // many reasons for indefinite pause, including database related, so do database last
896 mhunt 419
            mRecoverable = false;
420
 
421
            if ( cause.compareTo(Package.mRecoverable) == 0 )
422
            {
423
              mRecoverable = true;
424
            }
425
 
868 mhunt 426
            indefinitePause(rippleEngine, cause);
427
            mReleaseManager.indefinitePause();
886 mhunt 428
            // DEVI 51366 force sleep at beginning of while loop
429
            mException = true;
868 mhunt 430
          }
431
          catch( Exception f )
432
          {
433
            mLogger.error("run indefinitePause failed");
434
          }
814 mhunt 435
        }
436
      }
437
    }
438
  }
439
 
440
  /**returns 'M'
441
   */
442
  protected char getMode()
443
  {
444
    mLogger.debug("getMode");
445
    return 'M';
446
  }
447
}