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
 
16
import java.io.FileReader;
17
 
18
import java.io.IOException;
19
 
20
import java.sql.SQLException;
21
 
22
import java.util.Iterator;
23
 
24
import java.util.Vector;
25
 
26
import org.apache.log4j.Logger;
27
import org.apache.tools.ant.taskdefs.Execute;
28
 
29
/**Master Thread sub component
30
 */
31
public class MasterThread
32
  extends BuildThread
33
{
34
 
35
  /**Logger
36
   * @attribute
37
   */
38
  private static final Logger mLogger = Logger.getLogger(MasterThread.class);
39
 
40
  /**
41
   * @attribute
42
   */
43
  private String[] command = new String[100];
44
 
45
  /**
46
   * @attribute
47
   */
48
  private int commandIndex = 0;
49
 
50
  /**
51
   * @attribute
52
   */
53
  private Execute thread = new Execute();
54
 
55
  /**constructor
56
   */
57
  public MasterThread(int rtag_id, int rcon_id, String gbebuildfilter)
58
  {
818 mhunt 59
    mLogger.warn("MasterThread rtag_id " + rtag_id + " rcon_id " + rcon_id);
814 mhunt 60
    mRtagId = rtag_id;
61
    mRconId = rcon_id;
62
    mGbebuildfilter = gbebuildfilter;
63
  }
64
 
65
  /**implements the sequence diagrams coordinate slave threads, generate build files, allowed to proceed, check environment
66
   */
67
  public void run()
68
  {
69
    Integer id = new Integer(mRtagId);
70
    setName(id.toString());
71
    mLogger.debug("run");
72
    boolean exit = false;
73
    RippleEngine rippleEngine = new RippleEngine(mReleaseManager, mRtagId, true);
74
    MutableInt rconId = new MutableInt();
75
    MutableInt current_run_level = new MutableInt();
76
    MutableString addendum = new MutableString();
77
 
78
    while(!exit)
79
    {
80
      try
81
      {
82
        if ( Thread.currentThread().isInterrupted() )
83
        {
84
          mLogger.warn("run is interrupted");
85
          // unit test technique
86
          throw new ExitException();
87
        }
88
 
89
        if ( mGbebuildfilter.compareTo("unit test spawn thread") == 0)
90
        {
91
          throw new Exception();
92
        }
93
 
94
        // allowed to proceed
95
        MutableString buildFileContent = new MutableString();
96
 
97
        if ( mGbebuildfilter.compareTo("unit test check environment") != 0)
98
        {
99
          if ( mGbebuildfilter.compareTo("unit test generate build files") != 0)
100
          {
101
            if ( mGbebuildfilter.compareTo("unit test coordinate slave threads") != 0 )
102
            {
103
              mLogger.warn("run checking allowedToProceed");
104
              allowedToProceed();
105
              mLogger.info("run allowedToProceed returned");
106
 
107
              if ( mGbebuildfilter.compareTo("unit test allowed to proceed") == 0 )            
108
              {
109
                throw new ExitException();
110
              }
111
            }
112
 
113
            // coordinate slave threads
114
            mLogger.warn("run coordinate slave threads");
115
            boolean allSlaveThreadsWaiting = false;
816 mhunt 116
            boolean logWarning = true;
820 mhunt 117
            boolean logWarning2 = true;
814 mhunt 118
 
119
            while ( !allSlaveThreadsWaiting )
120
            {
121
              mReleaseManager.queryRunLevel(mRtagId);
122
 
123
              // anything but WAITING
124
              current_run_level.value = ReleaseManager.DB_IDLE;
125
              boolean moreRunLevelsConfigured = mReleaseManager.getFirstRunLevel(rconId, current_run_level);
126
 
127
              // attempt to exit loop
128
              allSlaveThreadsWaiting = true;
129
 
130
              do
131
              {
132
                if (moreRunLevelsConfigured)
133
                {
134
                  if (current_run_level.value != ReleaseManager.DB_WAITING)
135
                  {
816 mhunt 136
                    if ( logWarning )
137
                    {
138
                      mLogger.warn("run waiting for rcon id " + rconId.value);
139
                      logWarning = false;
140
                    }
141
                    else
142
                    {
143
                      mLogger.info("run waiting for rcon id " + rconId.value);                      
144
                    }
814 mhunt 145
                    allSlaveThreadsWaiting = false;
146
                  }
147
                  else
148
                  {
149
                    moreRunLevelsConfigured = mReleaseManager.getNextRunLevel(rconId, current_run_level);
150
                  }
151
                }
152
              }
153
              while (moreRunLevelsConfigured && allSlaveThreadsWaiting);
154
 
155
              if ( !allSlaveThreadsWaiting )
156
              {
157
                // to do, sleep for periodicMs
158
                if ( mGbebuildfilter.compareTo("unit test coordinate slave threads") == 0 )
159
                {
160
                  Thread.currentThread().interrupt();
161
                }
162
                else
163
                {
820 mhunt 164
                  if ( logWarning2 )
165
                  {
166
                    mLogger.warn("run sleeping 3 secs waiting for slave threads");
167
                    logWarning2 = false;
168
                  }
169
                  else
170
                  {
171
                    mLogger.info("run sleeping 3 secs waiting for slave threads");
172
                  }
814 mhunt 173
                  Thread.sleep(3000);
174
                  mLogger.info("run sleep returned");
175
                }
176
              }
177
            }
178
 
179
            if ( mGbebuildfilter.compareTo("unit test coordinate slave threads") == 0 )
180
            {
181
              throw new ExitException();
182
            }
183
 
184
            deliverChange(null, "AbtPublish", false);
185
 
186
            // Publishing is done outside ant by design
187
            // The preference is to do all release manager work outside ant
188
            MutableString packageName = new MutableString();
189
            MutableString packageExtension = new MutableString();
190
            MutableString packageVersion = new MutableString();
191
            MutableString packageDepends = new MutableString();
192
            MutableString isRipple = new MutableString();
193
            MutableString packageVersionId = new MutableString();
194
            MutableString fullyPublished = new MutableString();
195
            MutableString newLabel = new MutableString();
852 mhunt 196
            MutableString doesNotRequireSourceControlInteraction = new MutableString();
814 mhunt 197
            boolean buildOccurred = retrieveLastPackage(mRtagId,
198
                                                        packageName, 
199
                                                        packageExtension, 
200
                                                        packageVersion, 
201
                                                        packageDepends, 
202
                                                        isRipple,
203
                                                        packageVersionId, 
204
                                                        fullyPublished,
852 mhunt 205
                                                        newLabel,
206
                                                        doesNotRequireSourceControlInteraction);
814 mhunt 207
            if ( buildOccurred )
208
            {
816 mhunt 209
              // buildOccurred simply means a dummy build file did not apply ie the build file had attempted a build
210
              // by now it has been labelled
211
              tearViewDown();
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
      {
385
        mLogger.fatal("run ExitException");
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
}