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 }