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;
11
import java.io.File;
12
 
13
import java.io.FileReader;
14
 
15
import java.io.IOException;
16
 
17
import java.sql.SQLException;
18
 
19
import java.util.Iterator;
20
 
21
import java.util.Vector;
22
 
23
import org.apache.log4j.Logger;
24
import org.apache.tools.ant.taskdefs.Execute;
25
 
26
/**Master Thread sub component
27
 */
28
public class MasterThread
29
  extends BuildThread
30
{
31
 
32
  /**Logger
33
   * @attribute
34
   */
35
  private static final Logger mLogger = Logger.getLogger(MasterThread.class);
36
 
37
  /**
38
   * @attribute
39
   */
40
  private String[] command = new String[100];
41
 
42
  /**
43
   * @attribute
44
   */
45
  private int commandIndex = 0;
46
 
47
  /**
48
   * @attribute
49
   */
50
  private Execute thread = new Execute();
51
 
52
  /**constructor
53
   */
54
  public MasterThread(int rtag_id, int rcon_id, String gbebuildfilter)
55
  {
56
    mLogger.debug("MasterThread " + rtag_id);
57
    mRtagId = rtag_id;
58
    mRconId = rcon_id;
59
    mGbebuildfilter = gbebuildfilter;
60
  }
61
 
62
  /**implements the sequence diagrams coordinate slave threads, generate build files, allowed to proceed, check environment
63
   */
64
  public void run()
65
  {
66
    Integer id = new Integer(mRtagId);
67
    setName(id.toString());
68
    mLogger.debug("run");
69
    boolean exit = false;
70
    RippleEngine rippleEngine = new RippleEngine(mReleaseManager, mRtagId, true);
71
    MutableInt rconId = new MutableInt();
72
    MutableInt current_run_level = new MutableInt();
73
    MutableString addendum = new MutableString();
74
    boolean runLevelSet = false;
75
 
76
    while(!exit)
77
    {
78
      try
79
      {
80
        if ( Thread.currentThread().isInterrupted() )
81
        {
82
          mLogger.warn("run is interrupted");
83
          // unit test technique
84
          throw new ExitException();
85
        }
86
 
87
        if ( mGbebuildfilter.compareTo("unit test spawn thread") == 0)
88
        {
89
          throw new Exception();
90
        }
91
 
92
        // allowed to proceed
93
        MutableString buildFileContent = new MutableString();
94
 
95
        if ( mGbebuildfilter.compareTo("unit test check environment") != 0)
96
        {
97
          if ( mGbebuildfilter.compareTo("unit test generate build files") != 0)
98
          {
99
            if ( mGbebuildfilter.compareTo("unit test coordinate slave threads") != 0 )
100
            {
101
 
102
              if ( !runLevelSet )
103
              {
104
                // IMPORTANT - this is done once before a Thread.sleep by design
105
                // In the case of an SQLException (signifying a database access issue)
106
                // avoid accessing the database immediately
107
                mRunLevel = RunLevel.IDLE;
108
                mRunLevel.persist(mReleaseManager, mRconId);
109
                runLevelSet = true;
110
              }
111
 
112
              mLogger.warn("run checking allowedToProceed");
113
              allowedToProceed();
114
              mLogger.info("run allowedToProceed returned");
115
 
116
              if ( mGbebuildfilter.compareTo("unit test allowed to proceed") == 0 )            
117
              {
118
                throw new ExitException();
119
              }
120
            }
121
 
122
            // coordinate slave threads
123
            mLogger.warn("run coordinate slave threads");
124
            boolean allSlaveThreadsWaiting = false;
125
 
126
            while ( !allSlaveThreadsWaiting )
127
            {
128
              mReleaseManager.queryRunLevel(mRtagId);
129
 
130
              // anything but WAITING
131
              current_run_level.value = ReleaseManager.DB_IDLE;
132
              boolean moreRunLevelsConfigured = mReleaseManager.getFirstRunLevel(rconId, current_run_level);
133
 
134
              // attempt to exit loop
135
              allSlaveThreadsWaiting = true;
136
 
137
              do
138
              {
139
                if (moreRunLevelsConfigured)
140
                {
141
                  if (current_run_level.value != ReleaseManager.DB_WAITING)
142
                  {
143
                    mLogger.warn("run waiting for rcon id " + rconId.value);
144
                    allSlaveThreadsWaiting = false;
145
                  }
146
                  else
147
                  {
148
                    moreRunLevelsConfigured = mReleaseManager.getNextRunLevel(rconId, current_run_level);
149
                  }
150
                }
151
              }
152
              while (moreRunLevelsConfigured && allSlaveThreadsWaiting);
153
 
154
              if ( !allSlaveThreadsWaiting )
155
              {
156
                // to do, sleep for periodicMs
157
                if ( mGbebuildfilter.compareTo("unit test coordinate slave threads") == 0 )
158
                {
159
                  Thread.currentThread().interrupt();
160
                }
161
                else
162
                {
163
                  mLogger.warn("run sleeping 3 secs waiting for slave threads");
164
                  Thread.sleep(3000);
165
                  mLogger.info("run sleep returned");
166
                }
167
              }
168
            }
169
 
170
            if ( mGbebuildfilter.compareTo("unit test coordinate slave threads") == 0 )
171
            {
172
              throw new ExitException();
173
            }
174
 
175
            deliverChange(null, "AbtPublish", false);
176
 
177
            // Publishing is done outside ant by design
178
            // The preference is to do all release manager work outside ant
179
            MutableString packageName = new MutableString();
180
            MutableString packageExtension = new MutableString();
181
            MutableString packageVersion = new MutableString();
182
            MutableString packageDepends = new MutableString();
183
            MutableString isRipple = new MutableString();
184
            MutableString packageVersionId = new MutableString();
185
            MutableString fullyPublished = new MutableString();
186
            MutableString newLabel = new MutableString();
187
            boolean buildOccurred = retrieveLastPackage(mRtagId,
188
                                                        packageName, 
189
                                                        packageExtension, 
190
                                                        packageVersion, 
191
                                                        packageDepends, 
192
                                                        isRipple,
193
                                                        packageVersionId, 
194
                                                        fullyPublished,
195
                                                        newLabel);
196
            if ( buildOccurred )
197
            {
198
              boolean buildErrorOccurred = true;
199
              try
200
              {
201
 
202
                if ( fullyPublished.value.compareTo("yes") == 0 )
203
                {
204
                  buildErrorOccurred = false;
205
 
206
                  if ( newLabel.value.length() > 0 )
207
                  {
208
                    // labelled in ClearCase                
209
                    Integer rtagId = new Integer(mRtagId);
210
                    mReleaseManager.autoMakeRelease(rtagId.toString(), packageName.value, packageExtension.value, packageVersion.value, newLabel.value, packageDepends.value, isRipple.value);
211
                  }
212
                  else
213
                  {
214
                    mLogger.info("run package not labelled in ClearCase on " + packageName.value + packageVersion.value);
215
                    throw new Exception();
216
                  }
217
                }
218
 
219
                if ( buildErrorOccurred )
220
                {
221
                  mLogger.info("run build error occurred on " + packageName.value + packageVersion.value);
222
                  throw new Exception();
223
                }
224
 
225
                tearViewDown();
226
              }
227
              catch( Exception e)
228
              {
229
                // an error occurred publishing to ClearCase or Release Manager
230
                // take out the archive entry first
231
                String fs = System.getProperty( "file.separator" );
232
                String dpkgArchiveEntry = new String(Package.mGbeDpkg + fs + packageName.value + fs + packageVersion.value);
233
                File dpkgArchiveEntryFile = new File(dpkgArchiveEntry);
234
                mLogger.info("run checking existence of " + dpkgArchiveEntry);
235
 
236
                if ( dpkgArchiveEntryFile.exists() )
237
                {
238
                  if ( dpkgArchiveEntryFile.isDirectory() )
239
                  {
240
                    mLogger.warn("run deleting " + dpkgArchiveEntryFile.getName());
241
                    deleteDirectory(dpkgArchiveEntryFile);
242
                  }
243
                }
244
                else
245
                {
246
                  String dplyArchiveEntry = new String(Package.mGbeDply + fs + packageName.value + fs + packageVersion.value);
247
                  File dplyArchiveEntryFile = new File(dplyArchiveEntry);
248
                  mLogger.info("run checking existence of " + dplyArchiveEntry);
249
 
250
                  if ( dplyArchiveEntryFile.exists() )
251
                  {
252
                    if ( dplyArchiveEntryFile.isDirectory() )
253
                    {
254
                      mLogger.warn("run deleting " + dplyArchiveEntryFile.getName());
255
                      deleteDirectory(dplyArchiveEntryFile);
256
                    }
257
                  }
258
                }
259
 
260
                if ( buildErrorOccurred )
261
                {
262
                  Integer rtagId = new Integer(mRtagId);
263
                  mReleaseManager.excludeFromBuild(packageVersionId.value, packageVersion.value, rtagId.toString());
264
                }
265
                else
266
                {
267
                  mLogger.fatal("an error occurred publishing to ClearCase or Release Manager");
268
                  tearViewDown();
269
                  throw new Exception();
270
                }
271
              }
272
            }
273
 
274
            mLogger.info("run coordinate slave threads returned");
275
 
276
            // generate build files
277
            mLogger.warn("run generating build files");
278
            rippleEngine.planRelease();
279
 
280
            // get the build file from the ripple engine
281
            rippleEngine.getFirstBuildFileContent(buildFileContent, addendum);
282
 
283
            if ( addendum.value.compareTo("non generic") == 0 )
284
            {
285
              // publish the build file
286
              mLogger.warn("run publishing build file");
287
              mReleaseManager.publishBuildFile(mRtagId, buildFileContent.value);
288
            }
289
            else
290
            {
291
              // publish a dummy build file for either generic or dummy cases
292
              // this results in the slave not running ant
293
              mLogger.warn("run publishing dummy build file");
294
              mReleaseManager.publishBuildFile(mRtagId, mDummyBuildFileContent);
295
            }
296
          }
297
          mLogger.info("run generated build files");
298
 
299
          // change the run level for all threads in associated with the baseline
300
          mLogger.warn("run change the run level for all threads in associated with the baseline");
301
          mReleaseManager.queryReleaseConfig(mRtagId);
302
          rconId.value = -1;
303
          boolean moreBuildThreadsConfigured = mReleaseManager.getFirstReleaseConfig(rconId);
304
          mRunLevel = RunLevel.ACTIVE;
305
 
306
          do
307
          {
308
            if (moreBuildThreadsConfigured)
309
            {
310
                mRunLevel.persist(mReleaseManager, rconId.value);
311
                moreBuildThreadsConfigured = mReleaseManager.getNextReleaseConfig(rconId);
312
            }
313
          }
314
          while (moreBuildThreadsConfigured);
315
 
316
          if ( mGbebuildfilter.compareTo("unit test generate build files") == 0 )
317
          {
318
            throw new ExitException();
319
          }
320
        }
321
 
322
        mLogger.info("run changed run levels");
323
 
324
        // check environment
325
        mLogger.warn("run checkEnvironment");
326
        checkEnvironment();
327
        mLogger.info("run checkEnvironment returned");
328
 
329
        if ( mGbebuildfilter.compareTo("unit test check environment") == 0 )
330
        {
331
          throw new ExitException();
332
        }
333
 
334
        // deliver change to product baseline
335
        mLogger.warn("run deliverChange");
336
        setViewUp(buildFileContent.value, true);
337
        deliverChange(null, null, false);
338
        mLogger.info("run deliverChange returned");
339
      }
340
      catch( SQLException e )
341
      {
342
        // oracle connection issues        
343
        mLogger.warn("run oracle connection issues");
344
      }
345
      catch( ExitException e )
346
      {
347
        mLogger.fatal("run ExitException");
348
        exit = true;
349
      }
350
      catch( InterruptedException e )
351
      {
352
        mLogger.warn("run InterruptedException");
353
      }
354
      catch( Exception e )
355
      {
356
        mLogger.error("run indefinitePause");
357
        try
358
        {
359
          mReleaseManager.indefinitePause();
360
        }
361
        catch( Exception f )
362
        {
363
          mLogger.error("run indefinitePause failed");
364
        }
365
      }
366
 
367
      mSleep = false;
368
      if ( addendum.value.compareTo("dummy") == 0 )
369
      {
370
        // no build requirement, so let things settle
371
        mLogger.warn("run no build requirement, so let things settle");
372
        mSleep = true;
373
      }
374
    }
375
  }
376
 
377
  /**returns 'M'
378
   */
379
  protected char getMode()
380
  {
381
    mLogger.debug("getMode");
382
    return 'M';
383
  }
384
 
385
  /**retrieves details concerning the last package built for an rtag_id
386
   * isRipple = "0" (a WIP or direct change) or "1"
387
   * generic = "generic" or not
388
   * buildStandard = "JATS" or "ANT"
389
   */
390
  boolean retrieveLastPackage(int rtagId, MutableString packageName, 
391
                              MutableString packageExtension, 
392
                              MutableString packageVersion, 
393
                              MutableString packageDepends, 
394
                              MutableString isRipple, 
395
                              MutableString packageVersionId, 
396
                              MutableString fullyPublished,
397
                              MutableString newLabel) throws IOException
398
  {
399
    mLogger.debug("retrieveLastPackage");
400
    boolean retVal = false;
401
    Integer rtag = new Integer(rtagId);
402
    File rtagIdOfficial = new File(rtag + "official");
403
 
404
    if ( rtagIdOfficial.exists() )
405
    {
406
      // read <rtagId>offical
407
      FileReader rtagIdOfficialFileReader = new FileReader(rtagIdOfficial);
408
      BufferedReader rtagIdOfficialBufferedReader = new BufferedReader(rtagIdOfficialFileReader);
409
      String line;
410
 
411
      while( ( line = rtagIdOfficialBufferedReader.readLine() ) != null)
412
      {
413
        String []keyVal = line.split("=", 2);
414
        if (keyVal[0].compareTo("packageName") == 0)
415
        {
416
          packageName.value = keyVal[1];
417
          mLogger.info("retrieveLastPackage packageName " + packageName.value);
418
        }
419
        else
420
        if (keyVal[0].compareTo("packageExtension") == 0)
421
        {
422
          packageExtension.value = keyVal[1];
423
          mLogger.info("retrieveLastPackage packageExtension " + packageExtension.value);
424
        }
425
        else
426
        if (keyVal[0].compareTo("packageVersion") == 0)
427
        {
428
          packageVersion.value = keyVal[1];
429
          mLogger.info("retrieveLastPackage packageVersion " + packageVersion.value);
430
        }
431
        else
432
        if (keyVal[0].compareTo("packageDepends") == 0)
433
        {
434
          packageDepends.value = keyVal[1];
435
          mLogger.info("retrieveLastPackage packageDepends " + packageDepends.value);
436
        }
437
        else
438
        if (keyVal[0].compareTo("packageRipple") == 0)
439
        {
440
          isRipple.value = keyVal[1];
441
          mLogger.info("retrieveLastPackage packageRipple " + isRipple.value);
442
        }
443
        else
444
        if (keyVal[0].compareTo("packageVersionID") == 0)
445
        {
446
          packageVersionId.value = keyVal[1];
447
          mLogger.info("retrieveLastPackage packageVersionID " + packageVersionId.value);
448
        }
449
        else
450
        if (keyVal[0].compareTo("fullyPublished") == 0)
451
        {
452
          fullyPublished.value = keyVal[1];
453
          mLogger.info("retrieveLastPackage fullyPublished " + fullyPublished.value);
454
        }
455
        else
456
        if (keyVal[0].compareTo("newLabel") == 0)
457
        {
458
          newLabel.value = keyVal[1];
459
          mLogger.info("retrieveLastPackage newLabel " + newLabel.value);
460
        }
461
      }
462
      rtagIdOfficialBufferedReader.close();
463
      retVal = true;
464
    }
465
 
466
    rtagIdOfficial.delete();
467
 
468
    mLogger.info("retrieveLastPackage returned " + retVal);
469
    return retVal;
470
  }
471
}