1 19 package net.sf.jbatchengine.batch; 20 21 import java.io.IOException ; 22 import java.io.PrintWriter ; 23 import java.io.StringWriter ; 24 import java.net.InetAddress ; 25 import java.util.Date ; 26 import java.util.Properties ; 27 28 import net.sf.jbatchengine.batch.adapter.Adapter; 29 import net.sf.jbatchengine.batch.util.CommandFileParser; 30 import net.sf.jbatchengine.batch.util.LogRedirectionThread; 31 import net.sf.jbatchengine.model.Job; 32 33 import org.apache.commons.cli.CommandLine; 34 import org.apache.commons.cli.CommandLineParser; 35 import org.apache.commons.cli.HelpFormatter; 36 import org.apache.commons.cli.Option; 37 import org.apache.commons.cli.Options; 38 import org.apache.commons.cli.ParseException; 39 import org.apache.commons.cli.PosixParser; 40 import org.apache.log4j.Logger; 41 import org.springframework.context.ApplicationContext; 42 import org.springframework.context.support.ClassPathXmlApplicationContext; 43 import org.springframework.util.Log4jConfigurer; 44 45 51 public class BatchEngine extends Thread { 52 53 54 private static transient Logger log = Logger.getLogger(BatchEngine.class); 55 56 57 private static boolean shouldNotRedirect; 58 59 60 private static Properties prop; 61 62 63 private Adapter adapter; 64 65 66 private Process process; 67 68 69 private static final int EXIT_VALUE_DEFAULT = Integer.MIN_VALUE; 70 71 74 private BatchEngine() { 75 String [] paths = { "applicationContext.xml" }; 76 77 ApplicationContext ap = new ClassPathXmlApplicationContext(paths); 78 79 adapter = (Adapter) ap.getBean("adapter"); 80 81 Runtime.getRuntime().addShutdownHook(new Thread () { 83 84 public void run() { 85 terminate(); 86 } 87 }); 88 } 89 90 96 public static void main(String [] args) throws Exception { 97 init(args); 98 } 99 100 105 108 public void run() { 109 110 while (true) { 111 try { 112 log.info("Get next Job to process"); 114 115 Job job = this.adapter.getNextJob(0); 116 String batch = prop.getProperty(job.getTyp()); 118 119 if (batch == null) { 120 log.fatal("Batchtyp not configured"); 121 throw new RuntimeException ("BatchTyp not configured"); 122 } 123 124 if (batch.indexOf(".jcmd") > -1) { 126 batch = CommandFileParser.parse(batch); 127 } 128 129 if (job.getParameters() != null && !job.getParameters().equals("")) { 131 batch += " " + job.getParameters(); 132 } 133 134 log.info("Executing Job: " + batch); 136 process = Runtime.getRuntime().exec(batch); 137 138 job.setStatus(Job.STATUS_RUNNING); 139 job.setStarted_at(new Date ()); 140 job.setQueue(InetAddress.getLocalHost().getHostName()); 141 adapter.updateJob(job); 142 143 if (!shouldNotRedirect) { 144 new LogRedirectionThread(process, LogRedirectionThread.OUT).start(); 146 new LogRedirectionThread(process, LogRedirectionThread.ERR).start(); 147 } 148 149 int exitValue = EXIT_VALUE_DEFAULT; 150 long startMillis = System.currentTimeMillis(); 151 152 while (true) { 153 try { 155 Thread.sleep(10000); 156 exitValue = process.exitValue(); 157 } 158 catch (IllegalThreadStateException e) { 159 } 161 catch (InterruptedException ie) { 162 } 164 if (exitValue != EXIT_VALUE_DEFAULT) { 166 break; 167 } 168 String timeoutString = prop.getProperty("timeout", "180000"); 169 long timeout = Long.parseLong(timeoutString); 170 if ((System.currentTimeMillis() - startMillis) > timeout) { 171 process.destroy(); 173 job.setStatus(Job.STATUS_FINISHED_WITH_TIMEOUT); 174 job.setEnded_at(new Date ()); 175 job.setReturncode("" + exitValue); 176 adapter.updateJob(job); 177 exitValue = EXIT_VALUE_DEFAULT; 178 break; 179 } 180 job = adapter.getJob(job.getId()); 181 if (job.getStatus().equals(Job.STATUS_WAITING_FOR_CANCEL)) { 182 process.destroy(); 184 job.setStatus(Job.STATUS_CANCELED); 185 job.setEnded_at(new Date ()); 186 job.setReturncode("" + exitValue); 187 adapter.updateJob(job); 188 exitValue = EXIT_VALUE_DEFAULT; 189 break; 190 } 191 } 192 193 if (exitValue == 0) { 195 log.info("Job finished without errors"); 197 job.setEnded_at(new Date ()); 198 job.setStatus(Job.STATUS_FINISHED); 199 job.setReturncode("" + exitValue); 200 adapter.updateJob(job); 201 } 202 else if (exitValue == EXIT_VALUE_DEFAULT) { 203 } 205 else { 206 log.info("Job terminated error code: " + exitValue); 207 job.setEnded_at(new Date ()); 208 job.setStatus(Job.STATUS_FINISHED_WITH_ERRORS); 209 job.setReturncode("" + exitValue); 210 adapter.updateJob(job); 211 } 212 process = null; 213 } 214 catch (Exception e) { 215 log.fatal(e); 216 } 217 } 218 } 219 220 228 private static void init(String [] args) throws ParseException, IOException , InterruptedException { 229 230 Log4jConfigurer.initLogging("classpath:log4j.xml"); 231 232 log.info("BatchEngine initalize started"); 233 234 CommandLine cl = parseCommandLineArgs(args); 235 if (cl != null) { 236 shouldNotRedirect = cl.hasOption('n'); 237 } 238 239 prop = new Properties (); 240 prop.load(ClassLoader.getSystemResourceAsStream("jbatchengine.properties")); 241 242 int numberOfThreads = Integer.parseInt(prop.getProperty("numberOfThreads", "1")); 243 244 for (int i = 0; i < numberOfThreads; i++) { 245 BatchEngine batchEngine = new BatchEngine(); 246 log.info("BatchEngine starting thread."); 247 batchEngine.start(); 248 Thread.sleep(5000); 249 } 250 251 log.info("BatchEngine initalize ended"); 252 } 253 254 261 private static CommandLine parseCommandLineArgs(String [] args) throws ParseException { 262 263 Options options = new Options(); 264 Option op1 = new Option("n", "noredirect", true, 265 "no redirection of the system out and the system err from the child processes to this process"); 266 op1.setRequired(false); 267 op1.setArgName("switch"); 268 op1.setOptionalArg(true); 269 options.addOption(op1); 270 271 Option op2 = new Option("c", "check", true, "check"); 272 op2.setRequired(false); 273 op2.setArgName("switch"); 274 op2.setOptionalArg(true); 275 options.addOption(op2); 276 277 if ((args != null) && (args.length != 0)) { 278 CommandLineParser parser = new PosixParser(); 279 try { 280 return parser.parse(options, args); 281 } 282 catch (ParseException e) { 283 logUsage(options); 284 throw e; 285 } 286 } 287 return null; 288 } 289 290 295 private static void logUsage(Options options) { 296 HelpFormatter formatter = new HelpFormatter(); 297 StringWriter sw = new StringWriter (); 298 formatter.printHelp(new PrintWriter (sw), 100, "<commandfile_name>", "", options, 20, 10, ""); 299 sw.flush(); 300 log.fatal("\n" + sw); 301 } 302 303 306 private void terminate() { 307 log.info("BatchEngine about to stop"); 308 309 if (process != null) { 310 process.destroy(); 311 log.info("Child process forced to stop"); 312 } 313 log.info("BatchEngine stopped"); 314 } 315 } | Popular Tags |