Rev 4285 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package com.erggroup.buildtool.daemon;import com.erggroup.buildtool.ripple.Package;import com.erggroup.buildtool.ripple.ReleaseConfig;import com.erggroup.buildtool.ripple.ReleaseManager;import com.erggroup.buildtool.daemon.NagiosThread;import java.io.File;import java.io.IOException;import java.net.InetAddress;import java.net.UnknownHostException;import java.net.ServerSocket;import java.sql.SQLException;import java.util.Iterator;import java.util.Vector;import org.apache.log4j.Logger;import org.apache.log4j.xml.DOMConfigurator;/**BuildDaemon sub component and entry point (main BuildDaemon thread)*/public class BuildDaemon{/**hostname* @attribute*/static String mHostname = new String();/**GBE_LOG* @attribute*/static String mGbeLog = new String();/**Logger* @attribute*/private static final Logger mLogger = Logger.getLogger(BuildDaemon.class);/**Collection of ThreadIdentifier objects.* @attribute*/private Vector<ThreadIdentifier> mThreadCollection = new Vector<ThreadIdentifier>();/**Nagios* @attribute*/ServerSocket nagiosSrv;NagiosThread nagiosChecker;/**mThreadCollection items*/private class ThreadIdentifier{/**rcon_id associated with the thread* @attribute*/private final int mRcon_id;/**thread identifier* @attribute*/private final BuildThread mThread;/**constructor*/ThreadIdentifier(int rcon_id, BuildThread thread){mLogger.debug("ThreadIdentifier " + rcon_id);mRcon_id = rcon_id;mThread = thread;}/**accessor*/int get_rcon_id(){mLogger.debug("get_rcon_id");mLogger.info("get_rcon_id returned " + mRcon_id);return mRcon_id;}/**accessor*/BuildThread get_thread(){mLogger.debug("get_thread");return mThread;}}/**main method for the Build Daemon program* instantiates a BuildDaemon object*/public static void main(String[] args){String abtdXml = System.getenv("ABT_HOME");if ( abtdXml != null ){abtdXml += System.getProperty( "file.separator" ) + "abtd.xml";}else{abtdXml = new String("abtd.xml");}DOMConfigurator.configure(abtdXml);mLogger.debug("main");String antHome = System.getenv("ANT_HOME");if ( antHome == null ){mLogger.fatal("main ANT_HOME not set");System.exit(1);}mGbeLog = System.getenv("GBE_LOG");if ( mGbeLog == null ){mLogger.fatal("main GBE_LOG not set");System.exit(1);}File gl = new File( mGbeLog );if ( !gl.isDirectory() ){mLogger.fatal("main GBE_LOG is not a directory");}String gbeUNC = System.getenv("GBE_UNC");if ( gbeUNC == null ){mLogger.fatal("main GBE_UNC not set");System.exit(1);}String connectionString = System.getenv("GBE_RM_LOCATION");String username = System.getenv("GBE_RM_USERNAME");String password = System.getenv("GBE_RM_PASSWORD");for (int optind = 0; optind < args.length; optind++){if (args[optind].equals("-c") && optind < (args.length - 1)){connectionString = args[++optind];}else if (args[optind].equals("-u") && optind < (args.length - 1)){username = args[++optind];}else if (args[optind].equals("-p") && optind < (args.length - 1)){password = args[++optind];}}if (connectionString == null ||connectionString.length() == 0 ||username == null ||username.length() == 0 ||password == null ||password.length() == 0){mLogger.fatal("Usage: java -jar abtdD.jar -c connectionString -u username -p password");System.exit(1);}BuildDaemon buildDaemon = new BuildDaemon(connectionString, username, password);buildDaemon.cleanUp();}/**constructor, implements the sequence diagram spawn thread*/public BuildDaemon(String connectionString, String username,String password){mLogger.warn("BuildDaemon");ReleaseManager releaseManager = new ReleaseManager(connectionString, username + "[release_manager]", password);boolean run = true;String utf = null;try{InetAddress local = InetAddress.getLocalHost();mHostname = local.getHostName();mLogger.info("BuildDaemon set hostname " + mHostname);// Flag UTF in progressif ( connectionString.compareTo("unit test spawn thread") == 0 ){utf = connectionString;}if ( Package.mGenericMachtype == null ){mLogger.fatal("run GBE_MACHTYPE not set");throw new Exception("run GBE_MACHTYPE not set");}if ( Package.mGbeDpkg == null ){mLogger.fatal("run GBE_DPKG not set");throw new Exception("run GBE_DPKG not set");}// Set the default handler invoked when a thread abruptly terminates due to an// uncaught exception, and no other handler has been defined for that thread.//Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler());//// Start the Nagios Interface Thread//if ( connectionString.compareTo("unit test spawn thread") != 0 ){try {nagiosSrv = new ServerSocket(1111);nagiosChecker = new NagiosThread(nagiosSrv, this);nagiosChecker.start();} catch ( IOException e ) {mLogger.fatal("Failed to start Nagios Service. Port already in use");throw new Exception("Nagios port in use");}}// Discover new build daemons to be started on the current host//while (run){try{// Create a list of all machines that are configured to run on this machine//releaseManager.queryReleaseConfig(mHostname);//// Iterate over all the configured machines// Start up new build threads for new machines//for (Iterator<ReleaseConfig> it = releaseManager.mReleaseConfigCollection.iterator(); it.hasNext(); ){ReleaseConfig rc = it.next();if (!isActive(rc.get_rcon_id())){mLogger.warn("BuildDaemon activating " + rc.get_rtag_id() + " " + rc.get_rcon_id() + " " + rc.get_daemon_mode());// spawn and run the BuildThreadif (rc.get_daemon_mode() == 'M'){MasterThread thread = new MasterThread(rc.get_rtag_id(), rc.get_rcon_id(), utf);ThreadIdentifier threadIdentifier = new ThreadIdentifier(rc.get_rcon_id(), thread);mThreadCollection.add(threadIdentifier);// begin thread execution and invoke thread.run();thread.start();}else if (rc.get_daemon_mode() == 'S'){SlaveThread thread = new SlaveThread(rc.get_rtag_id(), rc.get_rcon_id(), utf);ThreadIdentifier threadIdentifier = new ThreadIdentifier(rc.get_rcon_id(), thread);mThreadCollection.add(threadIdentifier);// begin thread execution and invoke thread.run();thread.start();}}}// In UTF mode we only execute the loop onceif ( utf != null ){run = false;continue;}// Wait 10 minutes before we try to discover new machinesmLogger.warn("BuildDaemon sleep for 10 mins");Thread.sleep(600000);mLogger.info("BuildDaemon sleep returned");}catch (SQLException e){mLogger.warn("BuildDaemon caught SQLException");}catch (InterruptedException e){mLogger.warn("BuildDaemon caught InterruptedException");}catch (Exception e){mLogger.warn("BuildDaemon caught Exception");}}}catch( UnknownHostException e ){mLogger.fatal("BuildDaemon caught UnknownHostException");}catch( Exception e ){mLogger.fatal("BuildDaemon caught Exception");}}/**calls isAlive on the Thread object associated with the rcon_id*/public boolean isActive(final int rcon_id){mLogger.debug("isActive " + rcon_id);boolean retVal = false;boolean found = false;for (Iterator<ThreadIdentifier> it = mThreadCollection.iterator(); it.hasNext(); ){ThreadIdentifier threadIdentifier = it.next();if (threadIdentifier.get_rcon_id() == rcon_id){found = true;if (threadIdentifier.get_thread().isAlive()){retVal = true;break;}else{mLogger.warn("isActive found dead thread " + rcon_id );}}}if ( !found ){mLogger.warn("isActive thread not found " + rcon_id);}mLogger.warn("isActive returned " + retVal);return retVal;}/*** Nagios interface* Returns true if ALL the thread looks OK* Must have one active thread*/boolean checkThreads(){boolean retVal = false;mLogger.info("checkThreads called");for (Iterator<ThreadIdentifier> it = mThreadCollection.iterator(); it.hasNext(); ){ThreadIdentifier threadIdentifier = it.next();if (threadIdentifier.get_thread().checkThread()){retVal = true;}else{retVal = false;break;}}mLogger.info("checkThreads returned " + retVal);return retVal;}/**terminates all BuildThreads*/public void cleanUp(){mLogger.warn("cleanUp");if ( nagiosChecker != null ){nagiosChecker.terminate();}for (Iterator<ThreadIdentifier> it = mThreadCollection.iterator(); it.hasNext(); ){ThreadIdentifier threadIdentifier = it.next();if (threadIdentifier.get_thread().isAlive()){try{threadIdentifier.get_thread().interrupt();threadIdentifier.get_thread().join();}catch( InterruptedException e ){}}}}}class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{private static final Logger mLogger = Logger.getLogger(UncaughtExceptionHandler.class);//Implements Thread.UncaughtExceptionHandler.uncaughtException()public void uncaughtException(Thread th, Throwable ex){System.out.println("You crashed thread " + th.getName());System.out.println("Exception was: " + ex.toString());mLogger.fatal("UncaughtException ThreadName: " + th.getName());mLogger.fatal("UncaughtException was: " + ex.toString());}}