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