Subversion Repositories DevTools

Rev

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