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