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 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();
196
            boolean buildOccurred = retrieveLastPackage(mRtagId,
197
                                                        packageName, 
198
                                                        packageExtension, 
199
                                                        packageVersion, 
200
                                                        packageDepends, 
201
                                                        isRipple,
202
                                                        packageVersionId, 
203
                                                        fullyPublished,
204
                                                        newLabel);
205
            if ( buildOccurred )
206
            {
816 mhunt 207
              // buildOccurred simply means a dummy build file did not apply ie the build file had attempted a build
208
              // by now it has been labelled
209
              tearViewDown();
210
 
814 mhunt 211
              boolean buildErrorOccurred = true;
212
              try
213
              {
214
 
215
                if ( fullyPublished.value.compareTo("yes") == 0 )
216
                {
217
                  buildErrorOccurred = false;
218
 
219
                  if ( newLabel.value.length() > 0 )
220
                  {
221
                    // labelled in ClearCase                
222
                    Integer rtagId = new Integer(mRtagId);
223
                    mReleaseManager.autoMakeRelease(rtagId.toString(), packageName.value, packageExtension.value, packageVersion.value, newLabel.value, packageDepends.value, isRipple.value);
834 mhunt 224
 
225
                    FileInputStream abtmetrics = new FileInputStream( rtagId.toString() + "abtmetrics.txt" );
226
                    DataInputStream din = new DataInputStream( abtmetrics );
227
                    InputStreamReader isr = new InputStreamReader( din );
228
                    BufferedReader br = new BufferedReader( isr );
229
                    String metrics = br.readLine();
230
                    mLogger.warn( "execute read metrics string " + metrics );
231
                    br.close();
232
                    isr.close();
233
                    din.close();
234
 
235
                    mReleaseManager.insertPackageMetrics(rtagId.toString(), packageName.value, packageExtension.value, metrics );
814 mhunt 236
                  }
237
                  else
238
                  {
239
                    mLogger.info("run package not labelled in ClearCase on " + packageName.value + packageVersion.value);
240
                    throw new Exception();
241
                  }
242
                }
816 mhunt 243
                else
814 mhunt 244
                {
245
                  mLogger.info("run build error occurred on " + packageName.value + packageVersion.value);
246
                  throw new Exception();
247
                }
248
 
249
              }
250
              catch( Exception e)
251
              {
252
                // an error occurred publishing to ClearCase or Release Manager
253
                // take out the archive entry first
254
                String fs = System.getProperty( "file.separator" );
255
                String dpkgArchiveEntry = new String(Package.mGbeDpkg + fs + packageName.value + fs + packageVersion.value);
256
                File dpkgArchiveEntryFile = new File(dpkgArchiveEntry);
257
                mLogger.info("run checking existence of " + dpkgArchiveEntry);
258
 
259
                if ( dpkgArchiveEntryFile.exists() )
260
                {
261
                  if ( dpkgArchiveEntryFile.isDirectory() )
262
                  {
263
                    mLogger.warn("run deleting " + dpkgArchiveEntryFile.getName());
264
                    deleteDirectory(dpkgArchiveEntryFile);
265
                  }
266
                }
267
                else
268
                {
269
                  String dplyArchiveEntry = new String(Package.mGbeDply + fs + packageName.value + fs + packageVersion.value);
270
                  File dplyArchiveEntryFile = new File(dplyArchiveEntry);
271
                  mLogger.info("run checking existence of " + dplyArchiveEntry);
272
 
273
                  if ( dplyArchiveEntryFile.exists() )
274
                  {
275
                    if ( dplyArchiveEntryFile.isDirectory() )
276
                    {
277
                      mLogger.warn("run deleting " + dplyArchiveEntryFile.getName());
278
                      deleteDirectory(dplyArchiveEntryFile);
279
                    }
280
                  }
281
                }
282
 
820 mhunt 283
                Integer rtagId = new Integer(mRtagId);
284
                mReleaseManager.excludeFromBuild(packageVersionId.value, packageVersion.value, rtagId.toString());
285
 
286
                if ( !buildErrorOccurred )
814 mhunt 287
                {
288
                  mLogger.fatal("an error occurred publishing to ClearCase or Release Manager");
289
                  throw new Exception();
290
                }
291
              }
292
            }
293
 
294
            mLogger.info("run coordinate slave threads returned");
295
 
296
            // generate build files
297
            mLogger.warn("run generating build files");
298
            rippleEngine.planRelease();
299
 
300
            // get the build file from the ripple engine
301
            rippleEngine.getFirstBuildFileContent(buildFileContent, addendum);
302
 
303
            if ( addendum.value.compareTo("non generic") == 0 )
304
            {
305
              // publish the build file
306
              mLogger.warn("run publishing build file");
307
              mReleaseManager.publishBuildFile(mRtagId, buildFileContent.value);
308
            }
309
            else
310
            {
311
              // publish a dummy build file for either generic or dummy cases
312
              // this results in the slave not running ant
313
              mLogger.warn("run publishing dummy build file");
314
              mReleaseManager.publishBuildFile(mRtagId, mDummyBuildFileContent);
315
            }
316
          }
317
          mLogger.info("run generated build files");
318
 
319
          // change the run level for all threads in associated with the baseline
320
          mLogger.warn("run change the run level for all threads in associated with the baseline");
321
          mReleaseManager.queryReleaseConfig(mRtagId);
322
          rconId.value = -1;
323
          boolean moreBuildThreadsConfigured = mReleaseManager.getFirstReleaseConfig(rconId);
324
          mRunLevel = RunLevel.ACTIVE;
325
 
326
          do
327
          {
328
            if (moreBuildThreadsConfigured)
329
            {
816 mhunt 330
                mLogger.warn("run changing run level to ACTIVE for rcon_id " + rconId.value);
814 mhunt 331
                mRunLevel.persist(mReleaseManager, rconId.value);
332
                moreBuildThreadsConfigured = mReleaseManager.getNextReleaseConfig(rconId);
333
            }
334
          }
335
          while (moreBuildThreadsConfigured);
336
 
337
          if ( mGbebuildfilter.compareTo("unit test generate build files") == 0 )
338
          {
339
            throw new ExitException();
340
          }
341
        }
342
 
343
        mLogger.info("run changed run levels");
344
 
345
        // check environment
346
        mLogger.warn("run checkEnvironment");
347
        checkEnvironment();
348
        mLogger.info("run checkEnvironment returned");
349
 
350
        if ( mGbebuildfilter.compareTo("unit test check environment") == 0 )
351
        {
352
          throw new ExitException();
353
        }
354
 
355
        // deliver change to product baseline
356
        mLogger.warn("run deliverChange");
357
        setViewUp(buildFileContent.value, true);
358
        deliverChange(null, null, false);
359
        mLogger.info("run deliverChange returned");
360
      }
361
      catch( SQLException e )
362
      {
363
        // oracle connection issues        
364
        mLogger.warn("run oracle connection issues");
820 mhunt 365
        mSleep = true;
814 mhunt 366
      }
367
      catch( ExitException e )
368
      {
369
        mLogger.fatal("run ExitException");
370
        exit = true;
371
      }
372
      catch( InterruptedException e )
373
      {
374
        mLogger.warn("run InterruptedException");
375
      }
376
      catch( Exception e )
377
      {
378
        mLogger.error("run indefinitePause");
379
        try
380
        {
381
          mReleaseManager.indefinitePause();
382
        }
383
        catch( Exception f )
384
        {
385
          mLogger.error("run indefinitePause failed");
386
        }
387
      }
388
 
389
      mSleep = false;
390
      if ( addendum.value.compareTo("dummy") == 0 )
391
      {
392
        // no build requirement, so let things settle
393
        mLogger.warn("run no build requirement, so let things settle");
394
        mSleep = true;
395
      }
396
    }
397
  }
398
 
399
  /**returns 'M'
400
   */
401
  protected char getMode()
402
  {
403
    mLogger.debug("getMode");
404
    return 'M';
405
  }
406
 
407
  /**retrieves details concerning the last package built for an rtag_id
408
   * isRipple = "0" (a WIP or direct change) or "1"
409
   * generic = "generic" or not
410
   * buildStandard = "JATS" or "ANT"
411
   */
412
  boolean retrieveLastPackage(int rtagId, MutableString packageName, 
413
                              MutableString packageExtension, 
414
                              MutableString packageVersion, 
415
                              MutableString packageDepends, 
416
                              MutableString isRipple, 
417
                              MutableString packageVersionId, 
418
                              MutableString fullyPublished,
419
                              MutableString newLabel) throws IOException
420
  {
421
    mLogger.debug("retrieveLastPackage");
422
    boolean retVal = false;
423
    Integer rtag = new Integer(rtagId);
424
    File rtagIdOfficial = new File(rtag + "official");
425
 
426
    if ( rtagIdOfficial.exists() )
427
    {
428
      // read <rtagId>offical
429
      FileReader rtagIdOfficialFileReader = new FileReader(rtagIdOfficial);
430
      BufferedReader rtagIdOfficialBufferedReader = new BufferedReader(rtagIdOfficialFileReader);
431
      String line;
432
 
433
      while( ( line = rtagIdOfficialBufferedReader.readLine() ) != null)
434
      {
435
        String []keyVal = line.split("=", 2);
436
        if (keyVal[0].compareTo("packageName") == 0)
437
        {
438
          packageName.value = keyVal[1];
439
          mLogger.info("retrieveLastPackage packageName " + packageName.value);
440
        }
441
        else
442
        if (keyVal[0].compareTo("packageExtension") == 0)
443
        {
444
          packageExtension.value = keyVal[1];
445
          mLogger.info("retrieveLastPackage packageExtension " + packageExtension.value);
446
        }
447
        else
448
        if (keyVal[0].compareTo("packageVersion") == 0)
449
        {
450
          packageVersion.value = keyVal[1];
451
          mLogger.info("retrieveLastPackage packageVersion " + packageVersion.value);
452
        }
453
        else
454
        if (keyVal[0].compareTo("packageDepends") == 0)
455
        {
456
          packageDepends.value = keyVal[1];
457
          mLogger.info("retrieveLastPackage packageDepends " + packageDepends.value);
458
        }
459
        else
460
        if (keyVal[0].compareTo("packageRipple") == 0)
461
        {
462
          isRipple.value = keyVal[1];
463
          mLogger.info("retrieveLastPackage packageRipple " + isRipple.value);
464
        }
465
        else
466
        if (keyVal[0].compareTo("packageVersionID") == 0)
467
        {
468
          packageVersionId.value = keyVal[1];
469
          mLogger.info("retrieveLastPackage packageVersionID " + packageVersionId.value);
470
        }
471
        else
472
        if (keyVal[0].compareTo("fullyPublished") == 0)
473
        {
474
          fullyPublished.value = keyVal[1];
475
          mLogger.info("retrieveLastPackage fullyPublished " + fullyPublished.value);
476
        }
477
        else
478
        if (keyVal[0].compareTo("newLabel") == 0)
479
        {
480
          newLabel.value = keyVal[1];
481
          mLogger.info("retrieveLastPackage newLabel " + newLabel.value);
482
        }
483
      }
484
      rtagIdOfficialBufferedReader.close();
826 mhunt 485
      rtagIdOfficialFileReader.close();
486
 
487
      boolean del = rtagIdOfficial.delete();
488
 
489
      if ( !del )
490
      {
491
        // the delete failed
492
        // some literature suggests a forced garbage collection may free up resources associated with file handles
493
        // nothing to lose since the file "must" be deleted
494
        System.gc();
495
        del = rtagIdOfficial.delete();
496
 
497
        if ( !del )
498
        {
499
          mLogger.fatal("rtagIdOfficial.delete() returned " + del);
500
        }
501
      }
814 mhunt 502
      retVal = true;
503
    }
504
 
505
 
506
    mLogger.info("retrieveLastPackage returned " + retVal);
507
    return retVal;
508
  }
509
}