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
 
16
import java.io.FileReader;
17
 
18
import java.io.IOException;
19
 
20
import java.sql.SQLException;
21
 
22
import org.apache.log4j.Logger;
23
 
24
/**Master Thread sub component
25
 */
26
public class MasterThread
27
  extends BuildThread
28
{
29
 
30
  /**Logger
31
   * @attribute
32
   */
33
  private static final Logger mLogger = Logger.getLogger(MasterThread.class);
34
 
864 mhunt 35
   /**constructor
814 mhunt 36
   */
37
  public MasterThread(int rtag_id, int rcon_id, String gbebuildfilter)
38
  {
818 mhunt 39
    mLogger.warn("MasterThread rtag_id " + rtag_id + " rcon_id " + rcon_id);
814 mhunt 40
    mRtagId = rtag_id;
41
    mRconId = rcon_id;
42
    mGbebuildfilter = gbebuildfilter;
43
  }
44
 
45
  /**implements the sequence diagrams coordinate slave threads, generate build files, allowed to proceed, check environment
46
   */
47
  public void run()
48
  {
49
    Integer id = new Integer(mRtagId);
50
    setName(id.toString());
51
    mLogger.debug("run");
52
    boolean exit = false;
53
    RippleEngine rippleEngine = new RippleEngine(mReleaseManager, mRtagId, true);
54
    MutableInt rconId = new MutableInt();
55
    MutableInt current_run_level = new MutableInt();
56
    MutableString addendum = new MutableString();
57
 
58
    while(!exit)
59
    {
60
      try
61
      {
62
        if ( Thread.currentThread().isInterrupted() )
63
        {
64
          mLogger.warn("run is interrupted");
65
          // unit test technique
66
          throw new ExitException();
67
        }
68
 
69
        if ( mGbebuildfilter.compareTo("unit test spawn thread") == 0)
70
        {
71
          throw new Exception();
72
        }
73
 
74
        // allowed to proceed
75
        MutableString buildFileContent = new MutableString();
76
 
77
        if ( mGbebuildfilter.compareTo("unit test check environment") != 0)
78
        {
79
          if ( mGbebuildfilter.compareTo("unit test generate build files") != 0)
80
          {
81
            if ( mGbebuildfilter.compareTo("unit test coordinate slave threads") != 0 )
82
            {
83
              mLogger.warn("run checking allowedToProceed");
84
              allowedToProceed();
85
              mLogger.info("run allowedToProceed returned");
86
 
87
              if ( mGbebuildfilter.compareTo("unit test allowed to proceed") == 0 )            
88
              {
89
                throw new ExitException();
90
              }
91
            }
92
 
93
            // coordinate slave threads
94
            mLogger.warn("run coordinate slave threads");
95
            boolean allSlaveThreadsWaiting = false;
816 mhunt 96
            boolean logWarning = true;
820 mhunt 97
            boolean logWarning2 = true;
814 mhunt 98
 
99
            while ( !allSlaveThreadsWaiting )
100
            {
101
              mReleaseManager.queryRunLevel(mRtagId);
102
 
103
              // anything but WAITING
104
              current_run_level.value = ReleaseManager.DB_IDLE;
105
              boolean moreRunLevelsConfigured = mReleaseManager.getFirstRunLevel(rconId, current_run_level);
106
 
107
              // attempt to exit loop
108
              allSlaveThreadsWaiting = true;
109
 
110
              do
111
              {
112
                if (moreRunLevelsConfigured)
113
                {
114
                  if (current_run_level.value != ReleaseManager.DB_WAITING)
115
                  {
816 mhunt 116
                    if ( logWarning )
117
                    {
118
                      mLogger.warn("run waiting for rcon id " + rconId.value);
119
                      logWarning = false;
120
                    }
121
                    else
122
                    {
123
                      mLogger.info("run waiting for rcon id " + rconId.value);                      
124
                    }
814 mhunt 125
                    allSlaveThreadsWaiting = false;
126
                  }
127
                  else
128
                  {
129
                    moreRunLevelsConfigured = mReleaseManager.getNextRunLevel(rconId, current_run_level);
130
                  }
131
                }
132
              }
133
              while (moreRunLevelsConfigured && allSlaveThreadsWaiting);
134
 
135
              if ( !allSlaveThreadsWaiting )
136
              {
137
                // to do, sleep for periodicMs
138
                if ( mGbebuildfilter.compareTo("unit test coordinate slave threads") == 0 )
139
                {
140
                  Thread.currentThread().interrupt();
141
                }
142
                else
143
                {
820 mhunt 144
                  if ( logWarning2 )
145
                  {
146
                    mLogger.warn("run sleeping 3 secs waiting for slave threads");
147
                    logWarning2 = false;
148
                  }
149
                  else
150
                  {
151
                    mLogger.info("run sleeping 3 secs waiting for slave threads");
152
                  }
814 mhunt 153
                  Thread.sleep(3000);
154
                  mLogger.info("run sleep returned");
155
                }
156
              }
157
            }
158
 
159
            if ( mGbebuildfilter.compareTo("unit test coordinate slave threads") == 0 )
160
            {
161
              throw new ExitException();
162
            }
163
 
164
            deliverChange(null, "AbtPublish", false);
165
 
166
            // Publishing is done outside ant by design
167
            // The preference is to do all release manager work outside ant
168
            MutableString packageName = new MutableString();
169
            MutableString packageExtension = new MutableString();
170
            MutableString packageVersion = new MutableString();
171
            MutableString packageDepends = new MutableString();
172
            MutableString isRipple = new MutableString();
173
            MutableString packageVersionId = new MutableString();
174
            MutableString fullyPublished = new MutableString();
175
            MutableString newLabel = new MutableString();
852 mhunt 176
            MutableString doesNotRequireSourceControlInteraction = new MutableString();
854 mhunt 177
            boolean buildOccurred = false;
178
 
179
            try
180
            {
181
              buildOccurred = retrieveLastPackage(mRtagId,
182
                                                  packageName, 
183
                                                  packageExtension, 
184
                                                  packageVersion, 
185
                                                  packageDepends, 
186
                                                  isRipple,
187
                                                  packageVersionId, 
188
                                                  fullyPublished,
189
                                                  newLabel,
190
                                                  doesNotRequireSourceControlInteraction);
191
            }
192
            catch( IOException e )
193
            {
194
              // this is caught here to ensure an exception cannot circumvent the deletion of the build file below
195
              mLogger.warn("run IOException");
196
            }
197
 
814 mhunt 198
            if ( buildOccurred )
199
            {
816 mhunt 200
              // buildOccurred simply means a dummy build file did not apply ie the build file had attempted a build
201
              // by now it has been labelled
202
              tearViewDown();
203
 
854 mhunt 204
              // DEVI 47395 delete the build file now
205
              // this will prevent any chance of multiply publishing a package version
206
              File buildFile = new File(mRtagId + "build.xml");
207
 
208
              if ( buildFile.exists() )
209
              {
210
                buildFile.delete();
211
              }
212
 
814 mhunt 213
              boolean buildErrorOccurred = true;
214
              try
215
              {
216
 
217
                if ( fullyPublished.value.compareTo("yes") == 0 )
218
                {
219
                  buildErrorOccurred = false;
220
 
221
                  if ( newLabel.value.length() > 0 )
222
                  {
223
                    Integer rtagId = new Integer(mRtagId);
852 mhunt 224
 
225
                    if ( doesNotRequireSourceControlInteraction.value.length() == 0 )
226
                    {
227
                      // requires source control interaction ie labelled in ClearCase
228
                      // publish to release manager
229
                      mReleaseManager.autoMakeRelease(rtagId.toString(), packageName.value, packageExtension.value, packageVersion.value, newLabel.value, packageDepends.value, isRipple.value);
230
                    }
231
                    else
232
                    {
233
                      // trigger release note generation and on_make_official.wsf, which changes ownership and write access in the archive
234
                      // this should not be through autoMakeRelease (sledgehammer, the package is already official in release manager in this scenario)
235
                      // at the time of writing, calling autoMakeRelease does not help if the package was 'released' more than 24 hours ago
236
                      // this seems to be a business rule in the generate_release_notes package
237
                      // the buildtool has no option but to call autoMakeRelease at present
238
                      mReleaseManager.autoMakeRelease(rtagId.toString(), packageName.value, packageExtension.value, packageVersion.value, newLabel.value, packageDepends.value, isRipple.value);
239
                    }
834 mhunt 240
 
241
                    FileInputStream abtmetrics = new FileInputStream( rtagId.toString() + "abtmetrics.txt" );
242
                    DataInputStream din = new DataInputStream( abtmetrics );
243
                    InputStreamReader isr = new InputStreamReader( din );
244
                    BufferedReader br = new BufferedReader( isr );
245
                    String metrics = br.readLine();
246
                    mLogger.warn( "execute read metrics string " + metrics );
247
                    br.close();
248
                    isr.close();
249
                    din.close();
250
 
251
                    mReleaseManager.insertPackageMetrics(rtagId.toString(), packageName.value, packageExtension.value, metrics );
814 mhunt 252
                  }
253
                  else
254
                  {
255
                    mLogger.info("run package not labelled in ClearCase on " + packageName.value + packageVersion.value);
256
                    throw new Exception();
257
                  }
258
                }
816 mhunt 259
                else
814 mhunt 260
                {
261
                  mLogger.info("run build error occurred on " + packageName.value + packageVersion.value);
262
                  throw new Exception();
263
                }
264
 
265
              }
266
              catch( Exception e)
267
              {
268
                // an error occurred publishing to ClearCase or Release Manager
269
                // take out the archive entry first
270
                String fs = System.getProperty( "file.separator" );
271
                String dpkgArchiveEntry = new String(Package.mGbeDpkg + fs + packageName.value + fs + packageVersion.value);
272
                File dpkgArchiveEntryFile = new File(dpkgArchiveEntry);
273
                mLogger.info("run checking existence of " + dpkgArchiveEntry);
274
 
275
                if ( dpkgArchiveEntryFile.exists() )
276
                {
277
                  if ( dpkgArchiveEntryFile.isDirectory() )
278
                  {
279
                    mLogger.warn("run deleting " + dpkgArchiveEntryFile.getName());
280
                    deleteDirectory(dpkgArchiveEntryFile);
281
                  }
282
                }
283
                else
284
                {
285
                  String dplyArchiveEntry = new String(Package.mGbeDply + fs + packageName.value + fs + packageVersion.value);
286
                  File dplyArchiveEntryFile = new File(dplyArchiveEntry);
287
                  mLogger.info("run checking existence of " + dplyArchiveEntry);
288
 
289
                  if ( dplyArchiveEntryFile.exists() )
290
                  {
291
                    if ( dplyArchiveEntryFile.isDirectory() )
292
                    {
293
                      mLogger.warn("run deleting " + dplyArchiveEntryFile.getName());
294
                      deleteDirectory(dplyArchiveEntryFile);
295
                    }
296
                  }
297
                }
298
 
820 mhunt 299
                Integer rtagId = new Integer(mRtagId);
300
                mReleaseManager.excludeFromBuild(packageVersionId.value, packageVersion.value, rtagId.toString());
301
 
302
                if ( !buildErrorOccurred )
814 mhunt 303
                {
304
                  mLogger.fatal("an error occurred publishing to ClearCase or Release Manager");
305
                  throw new Exception();
306
                }
307
              }
308
            }
309
 
310
            mLogger.info("run coordinate slave threads returned");
311
 
312
            // generate build files
313
            mLogger.warn("run generating build files");
314
            rippleEngine.planRelease();
315
 
316
            // get the build file from the ripple engine
317
            rippleEngine.getFirstBuildFileContent(buildFileContent, addendum);
318
 
319
            if ( addendum.value.compareTo("non generic") == 0 )
320
            {
321
              // publish the build file
322
              mLogger.warn("run publishing build file");
323
              mReleaseManager.publishBuildFile(mRtagId, buildFileContent.value);
324
            }
325
            else
326
            {
327
              // publish a dummy build file for either generic or dummy cases
328
              // this results in the slave not running ant
329
              mLogger.warn("run publishing dummy build file");
330
              mReleaseManager.publishBuildFile(mRtagId, mDummyBuildFileContent);
331
            }
332
          }
333
          mLogger.info("run generated build files");
334
 
335
          // change the run level for all threads in associated with the baseline
336
          mLogger.warn("run change the run level for all threads in associated with the baseline");
337
          mReleaseManager.queryReleaseConfig(mRtagId);
338
          rconId.value = -1;
339
          boolean moreBuildThreadsConfigured = mReleaseManager.getFirstReleaseConfig(rconId);
340
          mRunLevel = RunLevel.ACTIVE;
341
 
342
          do
343
          {
344
            if (moreBuildThreadsConfigured)
345
            {
816 mhunt 346
                mLogger.warn("run changing run level to ACTIVE for rcon_id " + rconId.value);
814 mhunt 347
                mRunLevel.persist(mReleaseManager, rconId.value);
348
                moreBuildThreadsConfigured = mReleaseManager.getNextReleaseConfig(rconId);
349
            }
350
          }
351
          while (moreBuildThreadsConfigured);
352
 
353
          if ( mGbebuildfilter.compareTo("unit test generate build files") == 0 )
354
          {
355
            throw new ExitException();
356
          }
357
        }
358
 
359
        mLogger.info("run changed run levels");
360
 
361
        // check environment
362
        mLogger.warn("run checkEnvironment");
363
        checkEnvironment();
364
        mLogger.info("run checkEnvironment returned");
365
 
366
        if ( mGbebuildfilter.compareTo("unit test check environment") == 0 )
367
        {
368
          throw new ExitException();
369
        }
370
 
371
        // deliver change to product baseline
372
        mLogger.warn("run deliverChange");
373
        setViewUp(buildFileContent.value, true);
374
        deliverChange(null, null, false);
375
        mLogger.info("run deliverChange returned");
376
      }
377
      catch( SQLException e )
378
      {
379
        // oracle connection issues        
380
        mLogger.warn("run oracle connection issues");
820 mhunt 381
        mSleep = true;
814 mhunt 382
      }
383
      catch( ExitException e )
384
      {
858 mhunt 385
        mLogger.warn("run ExitException");
814 mhunt 386
        exit = true;
387
      }
388
      catch( InterruptedException e )
389
      {
390
        mLogger.warn("run InterruptedException");
391
      }
392
      catch( Exception e )
393
      {
394
        mLogger.error("run indefinitePause");
395
        try
396
        {
397
          mReleaseManager.indefinitePause();
398
        }
399
        catch( Exception f )
400
        {
401
          mLogger.error("run indefinitePause failed");
402
        }
403
      }
404
 
405
      mSleep = false;
406
      if ( addendum.value.compareTo("dummy") == 0 )
407
      {
408
        // no build requirement, so let things settle
409
        mLogger.warn("run no build requirement, so let things settle");
410
        mSleep = true;
411
      }
412
    }
413
  }
414
 
415
  /**returns 'M'
416
   */
417
  protected char getMode()
418
  {
419
    mLogger.debug("getMode");
420
    return 'M';
421
  }
422
 
423
  /**retrieves details concerning the last package built for an rtag_id
424
   * isRipple = "0" (a WIP or direct change) or "1"
425
   * generic = "generic" or not
426
   * buildStandard = "JATS" or "ANT"
427
   */
428
  boolean retrieveLastPackage(int rtagId, MutableString packageName, 
429
                              MutableString packageExtension, 
430
                              MutableString packageVersion, 
431
                              MutableString packageDepends, 
432
                              MutableString isRipple, 
433
                              MutableString packageVersionId, 
434
                              MutableString fullyPublished,
852 mhunt 435
                              MutableString newLabel,
436
                              MutableString doesNotRequireSourceControlInteraction) throws IOException
814 mhunt 437
  {
438
    mLogger.debug("retrieveLastPackage");
439
    boolean retVal = false;
440
    Integer rtag = new Integer(rtagId);
441
    File rtagIdOfficial = new File(rtag + "official");
442
 
443
    if ( rtagIdOfficial.exists() )
444
    {
445
      // read <rtagId>offical
446
      FileReader rtagIdOfficialFileReader = new FileReader(rtagIdOfficial);
447
      BufferedReader rtagIdOfficialBufferedReader = new BufferedReader(rtagIdOfficialFileReader);
448
      String line;
449
 
450
      while( ( line = rtagIdOfficialBufferedReader.readLine() ) != null)
451
      {
452
        String []keyVal = line.split("=", 2);
852 mhunt 453
 
454
        if ( keyVal.length == 2 )
814 mhunt 455
        {
852 mhunt 456
          if (keyVal[0].compareTo("packageName") == 0)
457
          {
458
            packageName.value = keyVal[1];
459
            mLogger.info("retrieveLastPackage packageName " + packageName.value);
460
          }
461
          else
462
          if (keyVal[0].compareTo("packageExtension") == 0)
463
          {
464
            packageExtension.value = keyVal[1];
465
            mLogger.info("retrieveLastPackage packageExtension " + packageExtension.value);
466
          }
467
          else
468
          if (keyVal[0].compareTo("packageVersion") == 0)
469
          {
470
            packageVersion.value = keyVal[1];
471
            mLogger.info("retrieveLastPackage packageVersion " + packageVersion.value);
472
          }
473
          else
474
          if (keyVal[0].compareTo("packageDepends") == 0)
475
          {
476
            packageDepends.value = keyVal[1];
477
            mLogger.info("retrieveLastPackage packageDepends " + packageDepends.value);
478
          }
479
          else
480
          if (keyVal[0].compareTo("packageRipple") == 0)
481
          {
482
            isRipple.value = keyVal[1];
483
            mLogger.info("retrieveLastPackage packageRipple " + isRipple.value);
484
          }
485
          else
486
          if (keyVal[0].compareTo("packageVersionID") == 0)
487
          {
488
            packageVersionId.value = keyVal[1];
489
            mLogger.info("retrieveLastPackage packageVersionID " + packageVersionId.value);
490
          }
491
          else
492
          if (keyVal[0].compareTo("fullyPublished") == 0)
493
          {
494
            fullyPublished.value = keyVal[1];
495
            mLogger.info("retrieveLastPackage fullyPublished " + fullyPublished.value);
496
          }
497
          else
498
          if (keyVal[0].compareTo("newLabel") == 0)
499
          {
500
            newLabel.value = keyVal[1];
501
            mLogger.info("retrieveLastPackage newLabel " + newLabel.value);
502
          }
503
          else
504
          if (keyVal[0].compareTo("doesNotRequireSourceControlInteraction") == 0)
505
          {
506
            doesNotRequireSourceControlInteraction.value = keyVal[1];
507
            mLogger.info("retrieveLastPackage doesNotRequireSourceControlInteraction " + doesNotRequireSourceControlInteraction.value);
508
          }
814 mhunt 509
        }
510
      }
511
      rtagIdOfficialBufferedReader.close();
826 mhunt 512
      rtagIdOfficialFileReader.close();
513
 
514
      boolean del = rtagIdOfficial.delete();
515
 
516
      if ( !del )
517
      {
518
        // the delete failed
519
        // some literature suggests a forced garbage collection may free up resources associated with file handles
520
        // nothing to lose since the file "must" be deleted
521
        System.gc();
522
        del = rtagIdOfficial.delete();
523
 
524
        if ( !del )
525
        {
526
          mLogger.fatal("rtagIdOfficial.delete() returned " + del);
527
        }
528
      }
814 mhunt 529
      retVal = true;
530
    }
531
 
532
 
533
    mLogger.info("retrieveLastPackage returned " + retVal);
534
    return retVal;
535
  }
536
}