001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.sys.context;
017    
018    import java.io.File;
019    import java.io.IOException;
020    import java.util.Arrays;
021    import java.util.Date;
022    
023    import org.apache.commons.lang.StringUtils;
024    import org.apache.log4j.Appender;
025    import org.apache.log4j.FileAppender;
026    import org.apache.log4j.Logger;
027    import org.apache.log4j.NDC;
028    import org.kuali.kfs.sys.KFSConstants;
029    import org.kuali.kfs.sys.batch.BatchSpringContext;
030    import org.kuali.kfs.sys.batch.Job;
031    import org.kuali.kfs.sys.batch.Step;
032    import org.kuali.rice.kns.service.DateTimeService;
033    import org.kuali.rice.kns.service.KualiConfigurationService;
034    import org.kuali.rice.kns.service.KualiModuleService;
035    import org.kuali.rice.kns.service.ModuleService;
036    import org.kuali.rice.kns.service.ParameterService;
037    import org.springframework.aop.framework.Advised;
038    import org.springframework.aop.support.AopUtils;
039    
040    public class BatchStepRunner {
041        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BatchStepRunner.class);
042    
043        public static void main(String[] args) {
044            if (args.length < 1) {
045                System.err.println("ERROR: You must pass the name of the step to run on the command line.");
046                System.exit(8);
047            }
048            try {
049                Log4jConfigurer.configureLogging(false);
050                SpringContext.initializeBatchApplicationContext();
051                String[] stepNames;
052                if (args[0].indexOf(",") > 0) {
053                    stepNames = StringUtils.split(args[0], ",");
054                }
055                else {
056                    stepNames = new String[] { args[0] };
057                }
058                ParameterService parameterService = SpringContext.getBean(ParameterService.class);
059                DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
060                
061                String jobName = args.length >= 2 ? args[1] : KFSConstants.BATCH_STEP_RUNNER_JOB_NAME;
062                Date jobRunDate = dateTimeService.getCurrentDate();
063                LOG.info("Executing job: " + jobName + " steps: " + Arrays.toString(stepNames));
064                for (int i = 0; i < stepNames.length; ++i) {
065                    Step step = BatchSpringContext.getStep(stepNames[i]);
066                    if ( step != null ) {
067                        Step unProxiedStep = (Step) ProxyUtils.getTargetIfProxied(step);
068                        Class stepClass = unProxiedStep.getClass();
069                        
070                        ModuleService module = SpringContext.getBean(KualiModuleService.class).getResponsibleModuleService( stepClass );                    
071                        Appender ndcAppender = null; 
072                        String nestedDiagnosticContext = 
073                                StringUtils.substringAfter( module.getModuleConfiguration().getNamespaceCode(), "-").toLowerCase()
074                                + File.separator + step.getName()
075                                + "-" + dateTimeService.toDateTimeStringForFilename(dateTimeService.getCurrentDate());
076                        boolean ndcSet = false;;
077                        try {
078                            ndcAppender = new FileAppender(Logger.getRootLogger().getAppender("LogFile").getLayout(), getLogFileName(nestedDiagnosticContext));
079                            ndcAppender.addFilter(new NDCFilter(nestedDiagnosticContext));
080                            Logger.getRootLogger().addAppender(ndcAppender);
081                            NDC.push(nestedDiagnosticContext);
082                            ndcSet = true;
083                        } catch (Exception ex) {
084                            LOG.warn("Could not initialize custom logging for step: " + step.getName(), ex);
085                        }
086                        try {
087                            if (!Job.runStep(parameterService, jobName, i, step, jobRunDate) ) {
088                                System.exit(4);
089                            }
090                        } catch ( RuntimeException ex ) {                        
091                            throw ex;
092                        } finally {
093                            if ( ndcSet ) {
094                                ndcAppender.close();
095                                Logger.getRootLogger().removeAppender(ndcAppender);
096                                NDC.pop();
097                            }
098                        }
099                    } else {
100                        throw new IllegalArgumentException( "Unable to find step: " + stepNames[i] );
101                    }
102                }
103                LOG.info("Finished executing job: " + jobName + " steps: " + Arrays.toString(stepNames));
104                System.exit(0);
105            }
106            catch (Throwable t) {
107                System.err.println("ERROR: Exception caught: ");
108                t.printStackTrace(System.err);
109                System.exit(8);
110            }
111        }
112        
113        protected static String getLogFileName(String nestedDiagnosticContext) {
114            return SpringContext.getBean( KualiConfigurationService.class ).getPropertyString(KFSConstants.REPORTS_DIRECTORY_KEY) 
115                    + File.separator 
116                    + nestedDiagnosticContext + ".log";
117        }
118    
119    }