Rev 858 | Blame | Last modification | View Log | RSS feed
package com.erggroup.buildtool.daemon;import com.erggroup.buildtool.daemon.BuildThread;import com.erggroup.buildtool.ripple.MutableInt;import com.erggroup.buildtool.ripple.MutableString;import com.erggroup.buildtool.ripple.Package;import com.erggroup.buildtool.ripple.ReleaseManager;import com.erggroup.buildtool.ripple.RippleEngine;import java.io.BufferedReader;import java.io.DataInputStream;import java.io.File;import java.io.FileInputStream;import java.io.InputStreamReader;import java.io.FileReader;import java.io.IOException;import java.sql.SQLException;import org.apache.log4j.Logger;/**Master Thread sub component*/public class MasterThreadextends BuildThread{/**Logger* @attribute*/private static final Logger mLogger = Logger.getLogger(MasterThread.class);/**constructor*/public MasterThread(int rtag_id, int rcon_id, String gbebuildfilter){mLogger.warn("MasterThread rtag_id " + rtag_id + " rcon_id " + rcon_id);mRtagId = rtag_id;mRconId = rcon_id;mGbebuildfilter = gbebuildfilter;}/**implements the sequence diagrams coordinate slave threads, generate build files, allowed to proceed, check environment*/public void run(){Integer id = new Integer(mRtagId);setName(id.toString());mLogger.debug("run");boolean exit = false;RippleEngine rippleEngine = new RippleEngine(mReleaseManager, mRtagId, true);MutableInt rconId = new MutableInt();MutableInt current_run_level = new MutableInt();MutableString addendum = new MutableString();while(!exit){try{if ( Thread.currentThread().isInterrupted() ){mLogger.warn("run is interrupted");// unit test techniquethrow new ExitException();}if ( mGbebuildfilter.compareTo("unit test spawn thread") == 0){throw new Exception();}// allowed to proceedMutableString buildFileContent = new MutableString();if ( mGbebuildfilter.compareTo("unit test check environment") != 0){if ( mGbebuildfilter.compareTo("unit test generate build files") != 0){if ( mGbebuildfilter.compareTo("unit test coordinate slave threads") != 0 ){mLogger.warn("run checking allowedToProceed");allowedToProceed();mLogger.info("run allowedToProceed returned");if ( mGbebuildfilter.compareTo("unit test allowed to proceed") == 0 ){throw new ExitException();}}// coordinate slave threadsmLogger.warn("run coordinate slave threads");boolean allSlaveThreadsWaiting = false;boolean logWarning = true;boolean logWarning2 = true;while ( !allSlaveThreadsWaiting ){mReleaseManager.queryRunLevel(mRtagId);// anything but WAITINGcurrent_run_level.value = ReleaseManager.DB_IDLE;boolean moreRunLevelsConfigured = mReleaseManager.getFirstRunLevel(rconId, current_run_level);// attempt to exit loopallSlaveThreadsWaiting = true;do{if (moreRunLevelsConfigured){if (current_run_level.value != ReleaseManager.DB_WAITING){if ( logWarning ){mLogger.warn("run waiting for rcon id " + rconId.value);logWarning = false;}else{mLogger.info("run waiting for rcon id " + rconId.value);}allSlaveThreadsWaiting = false;}else{moreRunLevelsConfigured = mReleaseManager.getNextRunLevel(rconId, current_run_level);}}}while (moreRunLevelsConfigured && allSlaveThreadsWaiting);if ( !allSlaveThreadsWaiting ){// to do, sleep for periodicMsif ( mGbebuildfilter.compareTo("unit test coordinate slave threads") == 0 ){Thread.currentThread().interrupt();}else{if ( logWarning2 ){mLogger.warn("run sleeping 3 secs waiting for slave threads");logWarning2 = false;}else{mLogger.info("run sleeping 3 secs waiting for slave threads");}Thread.sleep(3000);mLogger.info("run sleep returned");}}}if ( mGbebuildfilter.compareTo("unit test coordinate slave threads") == 0 ){throw new ExitException();}deliverChange(null, "AbtPublish", false);// Publishing is done outside ant by design// The preference is to do all release manager work outside antMutableString packageName = new MutableString();MutableString packageExtension = new MutableString();MutableString packageVersion = new MutableString();MutableString packageDepends = new MutableString();MutableString isRipple = new MutableString();MutableString packageVersionId = new MutableString();MutableString fullyPublished = new MutableString();MutableString newLabel = new MutableString();MutableString doesNotRequireSourceControlInteraction = new MutableString();boolean buildOccurred = false;try{buildOccurred = retrieveLastPackage(mRtagId,packageName,packageExtension,packageVersion,packageDepends,isRipple,packageVersionId,fullyPublished,newLabel,doesNotRequireSourceControlInteraction);}catch( IOException e ){// this is caught here to ensure an exception cannot circumvent the deletion of the build file belowmLogger.warn("run IOException");}if ( buildOccurred ){// buildOccurred simply means a dummy build file did not apply ie the build file had attempted a build// by now it has been labelledtearViewDown();// DEVI 47395 delete the build file now// this will prevent any chance of multiply publishing a package versionFile buildFile = new File(mRtagId + "build.xml");if ( buildFile.exists() ){buildFile.delete();}boolean buildErrorOccurred = true;try{if ( fullyPublished.value.compareTo("yes") == 0 ){buildErrorOccurred = false;if ( newLabel.value.length() > 0 ){Integer rtagId = new Integer(mRtagId);if ( doesNotRequireSourceControlInteraction.value.length() == 0 ){// requires source control interaction ie labelled in ClearCase// publish to release managermReleaseManager.autoMakeRelease(rtagId.toString(), packageName.value, packageExtension.value, packageVersion.value, newLabel.value, packageDepends.value, isRipple.value);}else{// trigger release note generation and on_make_official.wsf, which changes ownership and write access in the archive// this should not be through autoMakeRelease (sledgehammer, the package is already official in release manager in this scenario)// at the time of writing, calling autoMakeRelease does not help if the package was 'released' more than 24 hours ago// this seems to be a business rule in the generate_release_notes package// the buildtool has no option but to call autoMakeRelease at presentmReleaseManager.autoMakeRelease(rtagId.toString(), packageName.value, packageExtension.value, packageVersion.value, newLabel.value, packageDepends.value, isRipple.value);}FileInputStream abtmetrics = new FileInputStream( rtagId.toString() + "abtmetrics.txt" );DataInputStream din = new DataInputStream( abtmetrics );InputStreamReader isr = new InputStreamReader( din );BufferedReader br = new BufferedReader( isr );String metrics = br.readLine();mLogger.warn( "execute read metrics string " + metrics );br.close();isr.close();din.close();mReleaseManager.insertPackageMetrics(rtagId.toString(), packageName.value, packageExtension.value, metrics );}else{mLogger.info("run package not labelled in ClearCase on " + packageName.value + packageVersion.value);throw new Exception();}}else{mLogger.info("run build error occurred on " + packageName.value + packageVersion.value);throw new Exception();}}catch( Exception e){// an error occurred publishing to ClearCase or Release Manager// take out the archive entry firstString fs = System.getProperty( "file.separator" );String dpkgArchiveEntry = new String(Package.mGbeDpkg + fs + packageName.value + fs + packageVersion.value);File dpkgArchiveEntryFile = new File(dpkgArchiveEntry);mLogger.info("run checking existence of " + dpkgArchiveEntry);if ( dpkgArchiveEntryFile.exists() ){if ( dpkgArchiveEntryFile.isDirectory() ){mLogger.warn("run deleting " + dpkgArchiveEntryFile.getName());deleteDirectory(dpkgArchiveEntryFile);}}else{String dplyArchiveEntry = new String(Package.mGbeDply + fs + packageName.value + fs + packageVersion.value);File dplyArchiveEntryFile = new File(dplyArchiveEntry);mLogger.info("run checking existence of " + dplyArchiveEntry);if ( dplyArchiveEntryFile.exists() ){if ( dplyArchiveEntryFile.isDirectory() ){mLogger.warn("run deleting " + dplyArchiveEntryFile.getName());deleteDirectory(dplyArchiveEntryFile);}}}Integer rtagId = new Integer(mRtagId);mReleaseManager.excludeFromBuild(packageVersionId.value, packageVersion.value, rtagId.toString());if ( !buildErrorOccurred ){mLogger.fatal("an error occurred publishing to ClearCase or Release Manager");throw new Exception();}}}mLogger.info("run coordinate slave threads returned");// generate build filesmLogger.warn("run generating build files");rippleEngine.planRelease();// get the build file from the ripple enginerippleEngine.getFirstBuildFileContent(buildFileContent, addendum);if ( addendum.value.compareTo("non generic") == 0 ){// publish the build filemLogger.warn("run publishing build file");mReleaseManager.publishBuildFile(mRtagId, buildFileContent.value);}else{// publish a dummy build file for either generic or dummy cases// this results in the slave not running antmLogger.warn("run publishing dummy build file");mReleaseManager.publishBuildFile(mRtagId, mDummyBuildFileContent);}}mLogger.info("run generated build files");// change the run level for all threads in associated with the baselinemLogger.warn("run change the run level for all threads in associated with the baseline");mReleaseManager.queryReleaseConfig(mRtagId);rconId.value = -1;boolean moreBuildThreadsConfigured = mReleaseManager.getFirstReleaseConfig(rconId);mRunLevel = RunLevel.ACTIVE;do{if (moreBuildThreadsConfigured){mLogger.warn("run changing run level to ACTIVE for rcon_id " + rconId.value);mRunLevel.persist(mReleaseManager, rconId.value);moreBuildThreadsConfigured = mReleaseManager.getNextReleaseConfig(rconId);}}while (moreBuildThreadsConfigured);if ( mGbebuildfilter.compareTo("unit test generate build files") == 0 ){throw new ExitException();}}mLogger.info("run changed run levels");// check environmentmLogger.warn("run checkEnvironment");checkEnvironment();mLogger.info("run checkEnvironment returned");if ( mGbebuildfilter.compareTo("unit test check environment") == 0 ){throw new ExitException();}// deliver change to product baselinemLogger.warn("run deliverChange");setViewUp(buildFileContent.value, true);deliverChange(null, null, false);mLogger.info("run deliverChange returned");}catch( SQLException e ){// oracle connection issuesmLogger.warn("run oracle connection issues");mSleep = true;}catch( ExitException e ){mLogger.warn("run ExitException");exit = true;}catch( InterruptedException e ){mLogger.warn("run InterruptedException");}catch( Exception e ){mLogger.error("run indefinitePause");try{mReleaseManager.indefinitePause();}catch( Exception f ){mLogger.error("run indefinitePause failed");}}mSleep = false;if ( addendum.value.compareTo("dummy") == 0 ){// no build requirement, so let things settlemLogger.warn("run no build requirement, so let things settle");mSleep = true;}}}/**returns 'M'*/protected char getMode(){mLogger.debug("getMode");return 'M';}/**retrieves details concerning the last package built for an rtag_id* isRipple = "0" (a WIP or direct change) or "1"* generic = "generic" or not* buildStandard = "JATS" or "ANT"*/boolean retrieveLastPackage(int rtagId, MutableString packageName,MutableString packageExtension,MutableString packageVersion,MutableString packageDepends,MutableString isRipple,MutableString packageVersionId,MutableString fullyPublished,MutableString newLabel,MutableString doesNotRequireSourceControlInteraction) throws IOException{mLogger.debug("retrieveLastPackage");boolean retVal = false;Integer rtag = new Integer(rtagId);File rtagIdOfficial = new File(rtag + "official");if ( rtagIdOfficial.exists() ){// read <rtagId>officalFileReader rtagIdOfficialFileReader = new FileReader(rtagIdOfficial);BufferedReader rtagIdOfficialBufferedReader = new BufferedReader(rtagIdOfficialFileReader);String line;while( ( line = rtagIdOfficialBufferedReader.readLine() ) != null){String []keyVal = line.split("=", 2);if ( keyVal.length == 2 ){if (keyVal[0].compareTo("packageName") == 0){packageName.value = keyVal[1];mLogger.info("retrieveLastPackage packageName " + packageName.value);}elseif (keyVal[0].compareTo("packageExtension") == 0){packageExtension.value = keyVal[1];mLogger.info("retrieveLastPackage packageExtension " + packageExtension.value);}elseif (keyVal[0].compareTo("packageVersion") == 0){packageVersion.value = keyVal[1];mLogger.info("retrieveLastPackage packageVersion " + packageVersion.value);}elseif (keyVal[0].compareTo("packageDepends") == 0){packageDepends.value = keyVal[1];mLogger.info("retrieveLastPackage packageDepends " + packageDepends.value);}elseif (keyVal[0].compareTo("packageRipple") == 0){isRipple.value = keyVal[1];mLogger.info("retrieveLastPackage packageRipple " + isRipple.value);}elseif (keyVal[0].compareTo("packageVersionID") == 0){packageVersionId.value = keyVal[1];mLogger.info("retrieveLastPackage packageVersionID " + packageVersionId.value);}elseif (keyVal[0].compareTo("fullyPublished") == 0){fullyPublished.value = keyVal[1];mLogger.info("retrieveLastPackage fullyPublished " + fullyPublished.value);}elseif (keyVal[0].compareTo("newLabel") == 0){newLabel.value = keyVal[1];mLogger.info("retrieveLastPackage newLabel " + newLabel.value);}elseif (keyVal[0].compareTo("doesNotRequireSourceControlInteraction") == 0){doesNotRequireSourceControlInteraction.value = keyVal[1];mLogger.info("retrieveLastPackage doesNotRequireSourceControlInteraction " + doesNotRequireSourceControlInteraction.value);}}}rtagIdOfficialBufferedReader.close();rtagIdOfficialFileReader.close();boolean del = rtagIdOfficial.delete();if ( !del ){// the delete failed// some literature suggests a forced garbage collection may free up resources associated with file handles// nothing to lose since the file "must" be deletedSystem.gc();del = rtagIdOfficial.delete();if ( !del ){mLogger.fatal("rtagIdOfficial.delete() returned " + del);}}retVal = true;}mLogger.info("retrieveLastPackage returned " + retVal);return retVal;}}