View Javadoc
1   package org.kuali.ole.sys.context;
2   
3   
4   import java.util.concurrent.Executor;
5   import java.util.concurrent.Executors;
6   
7   import org.kuali.ole.sys.batch.BatchSpringContext;
8   
9   import org.kuali.ole.sys.batch.BatchContainerStep;
10  
11  /**
12   * This class should be used in the development environment to run the batch container, execute one or more steps, then shut down the batch container.
13   */
14  public class BatchStepLauncher implements Runnable {
15      private static final String LOG_PREFIX = BatchStepLauncher.class.getName() +": ";
16      private static final String batchContainerStep = "batchContainerStep";
17      
18      private static BatchStepTriggerParameters batchStepTriggerParms;
19  
20      /**
21       * This class validates the arguments, adds a shutdown hook to Runtime to clean up BatchContainer's semaphore, starts the batch container,
22       * and executes steps using the BatchStepTrigger.  
23       * 
24       * The BatchStepTrigger will exit the system using calls to System.exit(). This will cause this Launcher class to exit immediately without executing any further
25       * methods. Therefore the batch container cannot be shut down using the iu.stopBatchContainerStep which nicely cleans up its own semaphore. The shutdown hook has been
26       * added in order for this cleanup to occur. 
27       * 
28       * @param args the String[] arguments normally passed to BatchStepTrigger
29       */
30      public static void main(String[] args) {                
31          
32          //check arguments for the trigger
33          checkArguments(args);
34          
35          //run the Batch Container in its own thread
36          startBatchContainer();
37          
38          //confirm that the container started up before executing the steps 
39          //-uses batch container directory specified in args
40          confirmStartUp();
41              
42          //execute one or more steps
43          executeSteps(args);
44          
45          //the batch container will be shut down by the thread hook added to the Runtime in setUp()
46      }
47  
48      /**
49       * Run the Batch Container in its own thread
50       */
51      public void run() {        
52          String[] args = new String[2];
53          args[0] = batchContainerStep;
54          args[1] = (batchStepTriggerParms != null ? batchStepTriggerParms.getJobName(): "unknown");
55          
56          BatchStepRunner.main(args);
57      }    
58      
59      /**
60       * Uses the BatchStepTriggerParameters class to validate the arguments passed to the launcher.
61       * 
62       * @param args String[] of arguments that would normally passed to BatchStepTrigger
63       */
64      private static void checkArguments(String[] args) {
65          logToOut("checking arguments");
66          
67          batchStepTriggerParms = new BatchStepTriggerParameters(args);
68          
69          logToOut("received valid arguments");
70      }
71      
72      /**
73       * Start the batch container in its own Thread
74       */
75      private static void startBatchContainer() {
76          logToOut("starting the batch container");
77          Executor executor = Executors.newCachedThreadPool();        
78          
79          BatchStepLauncher batchStepLauncher = new BatchStepLauncher();
80          executor.execute(batchStepLauncher);        
81      }
82      
83      /**
84       * Loops and polls for the batch container start up (looks for the .runlock) 
85       */
86      private static void confirmStartUp() {
87          logToOut("confirming batch container start up");
88          
89          while (!batchStepTriggerParms.getBatchContainerDirectory().isBatchContainerRunning()) {
90              logToOut("waiting for the batch container to start up");
91              try {                
92                  Thread.sleep(batchStepTriggerParms.getSleepInterval());
93              }
94              catch (InterruptedException e) {
95                  throw new RuntimeException("BatchStepLauncher encountered interrupt exception while trying to wait for the batch container to start up", e);
96              }
97          }
98          
99          logToOut("batch container is running");
100     }
101     
102     /**
103      * Calls BatchStepTrigger to execute steps
104      * 
105      * @param args String[] arguments normally passed to the BatchStepTrigger
106      */
107     private static void executeSteps(String[] args) {
108         logToOut("executing step(s)");
109         
110         BatchStepTrigger.main(args);
111         
112         logToOut("finished executing step(s)");
113     }
114     
115     /**
116      * Removes the batch container semaphore (used by the shutdown hook added to Runtime)
117      * This is necessary because the Launcher exits immediately when the Trigger exits. Shutdown hook cleans up the semaphore.
118      */
119     private static void removeBatchContainerSemaphore() {
120         logToOut("removing batch container semaphore file");
121         
122         if (batchStepTriggerParms.getBatchContainerDirectory().isBatchContainerRunning()) {
123             batchStepTriggerParms.getBatchContainerDirectory().removeBatchContainerSemaphore();
124         }
125         
126         logToOut("batch container semaphore file has been removed");
127     }
128     
129     /**
130      * Logs statement to System.out with a prefix.
131      * 
132      * @param statement the statement to log
133      */
134     private static void logToOut(String statement) {
135         System.out.println(LOG_PREFIX + statement);
136     }    
137 }