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.ripple.MutableChar;
4
import com.erggroup.buildtool.ripple.MutableInt;
5
import com.erggroup.buildtool.ripple.Package;
6
import com.erggroup.buildtool.ripple.ReleaseManager;
1350 dpurdie 7
import com.erggroup.buildtool.daemon.NagiosThread;
814 mhunt 8
 
854 mhunt 9
import java.io.File;
1352 dpurdie 10
import java.io.IOException;
1350 dpurdie 11
 
814 mhunt 12
import java.net.InetAddress;
13
import java.net.UnknownHostException;
1350 dpurdie 14
import java.net.ServerSocket;
814 mhunt 15
 
16
import java.sql.SQLException;
17
 
18
import java.util.Iterator;
19
import java.util.Vector;
20
 
21
import org.apache.log4j.Logger;
22
import org.apache.log4j.xml.DOMConfigurator;
23
 
24
/**BuildDaemon sub component and entry point (main BuildDaemon thread)
25
 */
26
public class BuildDaemon
27
{
28
 
29
  /**hostname
30
   * @attribute
31
   */
32
  static String mHostname = new String();
33
 
854 mhunt 34
  /**GBE_LOG
35
   * @attribute
36
   */
37
  static String mGbeLog = new String();
38
 
814 mhunt 39
  /**Logger
40
   * @attribute
41
   */
42
  private static final Logger mLogger = Logger.getLogger(BuildDaemon.class);
43
 
44
  /**Collection of ThreadIdentifier objects.
45
   * @attribute
46
   */
864 mhunt 47
  private Vector<ThreadIdentifier> mThreadCollection = new Vector<ThreadIdentifier>();
814 mhunt 48
 
1350 dpurdie 49
  /**Nagios
50
   * @attribute
51
   */
52
  ServerSocket nagiosSrv;
53
  NagiosThread nagiosChecker;
54
 
814 mhunt 55
  /**mThreadCollection items
56
   */
57
  private class ThreadIdentifier
58
  {
59
    /**rcon_id associated with the thread
60
     * @attribute
61
     */
62
    private final int mRcon_id;
63
 
64
    /**thread identifier
65
     * @attribute
66
     */
1361 dpurdie 67
    private final BuildThread mThread;
814 mhunt 68
 
69
    /**constructor
70
     */
1361 dpurdie 71
    ThreadIdentifier(int rcon_id, BuildThread thread)
814 mhunt 72
    {
73
      mLogger.debug("ThreadIdentifier " + rcon_id);
74
      mRcon_id = rcon_id;
75
      mThread = thread;
76
    }
77
 
78
    /**accessor
79
     */
80
    int get_rcon_id()
81
    {
82
      mLogger.debug("get_rcon_id");
83
      mLogger.info("get_rcon_id returned " + mRcon_id);
84
      return mRcon_id;
85
    }
86
 
87
    /**accessor
88
     */
1361 dpurdie 89
    BuildThread get_thread()
814 mhunt 90
    {
91
      mLogger.debug("get_thread");
92
      return mThread;
93
    }
94
  }
95
 
96
  /**main method for the Build Daemon program
97
   * instantiates a BuildDaemon object
98
   */
99
  public static void main(String[] args)
100
  {
858 mhunt 101
    String abtdXml = System.getenv("ABT_HOME");
102
 
103
    if ( abtdXml != null )
104
    {
105
      abtdXml += System.getProperty( "file.separator" ) + "abtd.xml";
106
    }
107
    else
108
    {
109
      abtdXml = new String("abtd.xml");
110
    }
111
    DOMConfigurator.configure(abtdXml);
112
    mLogger.debug("main");
854 mhunt 113
    String antHome = System.getenv("ANT_HOME");
114
 
115
    if ( antHome == null )
116
    {
117
      mLogger.fatal("main ANT_HOME not set");
118
      System.exit(1);
119
    }
120
 
121
    mGbeLog = System.getenv("GBE_LOG");
122
 
123
    if ( mGbeLog == null )
124
    {
125
      mLogger.fatal("main GBE_LOG not set");
126
      System.exit(1);
127
    }
128
 
129
    File gl = new File( mGbeLog );
130
 
131
    if ( !gl.isDirectory() )
132
    {
133
      mLogger.fatal("main GBE_LOG is not a directory");
134
    }
135
 
136
    String gbeUNC = System.getenv("GBE_UNC");
137
 
138
    if ( gbeUNC == null )
139
    {
140
      mLogger.fatal("main GBE_UNC not set");
141
      System.exit(1);
142
    }
143
 
814 mhunt 144
    String connectionString = System.getenv("GBE_RM_LOCATION");
145
    String username = System.getenv("GBE_RM_USERNAME");
146
    String password = System.getenv("GBE_RM_PASSWORD");
147
 
148
    for (int optind = 0; optind < args.length; optind++)
149
    {
150
      if (args[optind].equals("-c") && optind < (args.length - 1))
151
      {
152
        connectionString = args[++optind];
153
      }
154
      else if (args[optind].equals("-u") && optind < (args.length - 1))
155
      {
156
        username = args[++optind];
157
      }
158
      else if (args[optind].equals("-p") && optind < (args.length - 1))
159
      {
160
        password = args[++optind];
161
      }
162
    }
163
 
854 mhunt 164
    if (connectionString == null ||
165
        connectionString.length() == 0 ||
166
        username == null ||
167
        username.length() == 0 ||
168
        password == null ||
169
        password.length() == 0)
814 mhunt 170
    {
854 mhunt 171
      mLogger.fatal("Usage: java -jar abtdD.jar -c connectionString -u username -p password");
814 mhunt 172
      System.exit(1);
173
    }
1350 dpurdie 174
 
814 mhunt 175
    BuildDaemon buildDaemon = new BuildDaemon(connectionString, username, password);
176
    buildDaemon.cleanUp();
177
 
178
  }
179
 
180
  /**constructor, implements the sequence diagram spawn thread
181
   */
182
  public BuildDaemon(String connectionString, String username, 
183
                     String password)
184
  {
4123 dpurdie 185
    mLogger.warn("BuildDaemon");
814 mhunt 186
    ReleaseManager releaseManager = 
906 mhunt 187
      new ReleaseManager(connectionString, username + "[release_manager]", password);
814 mhunt 188
    boolean run = true;
189
    MutableInt rtag_id = new MutableInt();
190
    MutableInt rcon_id = new MutableInt();
191
    MutableChar daemon_mode = new MutableChar();
192
    String hostname = new String("");
193
 
194
    try
195
    {
196
      InetAddress local = InetAddress.getLocalHost();
197
      hostname = local.getHostName();
198
      mHostname = hostname;
199
      mLogger.info("BuildDaemon set hostname " + mHostname);
200
 
924 dpurdie 201
      if ( Package.mGenericMachtype == null )
814 mhunt 202
      {
924 dpurdie 203
        mLogger.fatal("run GBE_MACHTYPE not set");
204
        throw new Exception("run GBE_MACHTYPE not set");
814 mhunt 205
      }
924 dpurdie 206
 
207
      if ( Package.mGbeDpkg == null )
208
      {
209
        mLogger.fatal("run GBE_DPKG not set");
210
        throw new Exception("run GBE_DPKG not set");
211
      }
212
 
4123 dpurdie 213
      //Set the default handler invoked when a thread abruptly terminates due to an
214
      //uncaught exception, and no other handler has been defined for that thread.
215
      Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler());
216
 
1350 dpurdie 217
      //
218
      //  Start the Nagios Interface Thread
219
      //
1365 dpurdie 220
      if ( connectionString.compareTo("unit test spawn thread") != 0 )
221
      {
222
        try {
223
          nagiosSrv = new ServerSocket(1111);
224
          nagiosChecker = new NagiosThread(nagiosSrv, this);
225
          nagiosChecker.start();
226
        } catch ( IOException e ) {
227
              mLogger.fatal("Failed to start Nagios Service. Port already in use");
228
              throw new Exception("Nagios port in use");
229
        }
1352 dpurdie 230
      }
1350 dpurdie 231
 
820 mhunt 232
      boolean firstTime = true;
233
 
814 mhunt 234
      while (run)
235
      {
236
        try
237
        {
820 mhunt 238
          if ( !firstTime )
239
          {
240
            mLogger.warn("BuildDaemon sleep for 10 mins");
241
            Thread.sleep(600000);
242
            mLogger.info("BuildDaemon sleep returned");
243
          }
244
          else
245
          {
246
            firstTime = false;    
247
          }
248
 
814 mhunt 249
          releaseManager.queryReleaseConfig(hostname);
250
 
251
          rtag_id.value = 0;
252
          rcon_id.value = 0;
253
          daemon_mode.value = 'X';
254
 
255
          boolean moreReleasesConfigured = 
256
            releaseManager.getFirstReleaseConfig(rtag_id, rcon_id, 
896 mhunt 257
                                                 daemon_mode);
814 mhunt 258
 
259
          do
260
          {
261
            if (moreReleasesConfigured)
262
            {
263
              if (!isActive(rcon_id.value))
264
              {
896 mhunt 265
                mLogger.warn("BuildDaemon activating " + rtag_id.value + " " + rcon_id.value + " " + daemon_mode.value);
814 mhunt 266
 
896 mhunt 267
                String utf = null;
268
 
269
                if ( connectionString.compareTo("unit test spawn thread") == 0 )
270
                {
271
                  utf = connectionString;
272
                }
273
 
814 mhunt 274
                // spawn and run the BuildThread
275
                if (daemon_mode.value == 'M')
276
                {
896 mhunt 277
                  MasterThread thread = new MasterThread(rtag_id.value, rcon_id.value, utf);
814 mhunt 278
                  ThreadIdentifier threadIdentifier = 
279
                    new ThreadIdentifier(rcon_id.value, thread);
280
                  mThreadCollection.add(threadIdentifier);
281
                  // begin thread execution and invoke thread.run();
282
                  thread.start();
283
                }
284
                else if (daemon_mode.value == 'S')
285
                {
896 mhunt 286
                  SlaveThread thread = new SlaveThread(rtag_id.value, rcon_id.value, utf);
814 mhunt 287
                  ThreadIdentifier threadIdentifier = 
288
                    new ThreadIdentifier(rcon_id.value, thread);
289
                  mThreadCollection.add(threadIdentifier);
290
                  // begin thread execution and invoke thread.run();
291
                  thread.start();
292
                }
293
              }
294
 
295
              moreReleasesConfigured = 
296
                  releaseManager.getNextReleaseConfig(rtag_id, rcon_id, 
896 mhunt 297
                                                      daemon_mode);
814 mhunt 298
            }
299
          }
300
          while (moreReleasesConfigured);
301
 
302
          if ( connectionString.compareTo("unit test spawn thread") == 0)
303
          {
820 mhunt 304
            run = false;
814 mhunt 305
          }
306
 
307
        }
308
        catch (SQLException e)
309
        {
310
          mLogger.warn("BuildDaemon caught SQLException");
311
        }
312
        catch (InterruptedException e)
313
        {
314
          mLogger.warn("BuildDaemon caught InterruptedException");
315
        }
316
        catch (Exception e)
317
        {
820 mhunt 318
          mLogger.warn("BuildDaemon caught Exception");
814 mhunt 319
        }
320
      }
321
    }
322
    catch( UnknownHostException e )
323
    {
324
      mLogger.fatal("BuildDaemon caught UnknownHostException");
325
    }
326
    catch( Exception e )
327
    {
328
      mLogger.fatal("BuildDaemon caught Exception");
329
    }
330
  }
331
 
332
  /**calls isAlive on the Thread object associated with the rcon_id
333
   */
334
  public boolean isActive(final int rcon_id)
335
  {
336
    mLogger.debug("isActive " + rcon_id);
337
    boolean retVal = false;
4123 dpurdie 338
    boolean found = false;
814 mhunt 339
 
864 mhunt 340
    for (Iterator<ThreadIdentifier> it = mThreadCollection.iterator(); it.hasNext(); )
814 mhunt 341
    {
864 mhunt 342
      ThreadIdentifier threadIdentifier = it.next();
814 mhunt 343
 
344
      if (threadIdentifier.get_rcon_id() == rcon_id)
345
      {
4123 dpurdie 346
        found = true;
814 mhunt 347
        if (threadIdentifier.get_thread().isAlive())
348
        {
349
          retVal = true;
844 dpurdie 350
          break;
814 mhunt 351
        }
844 dpurdie 352
        else
353
        {
354
            mLogger.warn("isActive found dead thread " + rcon_id );
355
        }
814 mhunt 356
      }
357
    }
4123 dpurdie 358
 
359
    if ( !found )
360
    {
361
        mLogger.warn("isActive thread not found " + rcon_id);
362
    }
363
 
364
    mLogger.warn("isActive returned " + retVal);
814 mhunt 365
    return retVal;
366
  }
367
 
1361 dpurdie 368
    /**
369
     *  Nagios interface
370
     *      Returns true if ALL the thread looks OK
371
     *      Must have one active thread
372
    */
373
    boolean checkThreads()
374
    {
375
      boolean retVal = false;
376
        mLogger.info("checkThreads called");
377
      for (Iterator<ThreadIdentifier> it = mThreadCollection.iterator(); it.hasNext(); )
378
      {
379
        ThreadIdentifier threadIdentifier = it.next();
380
 
381
        if (threadIdentifier.get_thread().checkThread())
382
        {
383
          retVal = true;
384
        }
385
        else
386
        {
387
          retVal = false;
388
          break;
389
        }
390
      }
391
 
392
      mLogger.info("checkThreads returned " + retVal);
393
      return retVal;
394
    }
395
 
396
 
814 mhunt 397
  /**terminates all BuildThreads
398
   */
399
  public void cleanUp()
400
  {
4123 dpurdie 401
    mLogger.warn("cleanUp");
1354 dpurdie 402
    if ( nagiosChecker != null )
403
    {
404
        nagiosChecker.terminate();
405
    }
1350 dpurdie 406
 
864 mhunt 407
    for (Iterator<ThreadIdentifier> it = mThreadCollection.iterator(); it.hasNext(); )
814 mhunt 408
    {
864 mhunt 409
      ThreadIdentifier threadIdentifier = it.next();
814 mhunt 410
 
411
      if (threadIdentifier.get_thread().isAlive())
412
      {
413
        try
414
        {
415
          threadIdentifier.get_thread().interrupt();
416
          threadIdentifier.get_thread().join();
417
        }
418
        catch( InterruptedException e )
419
        {
420
        }
421
      }
422
    }
423
  }
424
}
1361 dpurdie 425
 
4123 dpurdie 426
class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler
427
{
428
    private static final Logger mLogger = Logger.getLogger(UncaughtExceptionHandler.class);
429
 
430
    //Implements Thread.UncaughtExceptionHandler.uncaughtException()
431
    public void uncaughtException(Thread th, Throwable ex)
432
    {
433
        System.out.println("You crashed thread " + th.getName());
434
        System.out.println("Exception was: " + ex.toString());
435
 
436
        mLogger.fatal("UncaughtException ThreadName: " + th.getName());
437
        mLogger.fatal("UncaughtException was: " + ex.toString());
438
    }
439
}