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