001    /**
002     * Copyright 2004-2013 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.hr.time.batch;
017    
018    import java.sql.Timestamp;
019    
020    import org.apache.commons.lang.StringUtils;
021    import org.apache.commons.lang3.ArrayUtils;
022    import org.apache.log4j.Logger;
023    import org.kuali.hr.time.service.base.TkServiceLocator;
024    import org.kuali.hr.time.util.TkConstants;
025    import org.kuali.rice.core.api.config.property.ConfigContext;
026    import org.springframework.transaction.TransactionStatus;
027    import org.springframework.transaction.support.TransactionCallbackWithoutResult;
028    
029    public class BatchJob {
030        private Logger LOG = Logger.getLogger(BatchJob.class);
031        int lastPlace = 0;
032    
033        private Long tkBatchJobId;
034        private String batchJobName;
035        private String batchJobStatus;
036        private String hrPyCalendarEntryId;
037        private Long timeElapsed = 0L;
038        private Timestamp timestamp;
039        long startTime;
040        long endTime;
041    
042        public BatchJob() {
043            this.setBatchJobStatus(TkConstants.BATCH_JOB_ENTRY_STATUS.SCHEDULED);
044            this.setTimestamp(new Timestamp(System.currentTimeMillis()));
045        }
046    
047        /**
048         * Setup logic goes here.
049         */
050        void doBeforeRun() {
051            LOG.info("Starting batch job: " + this.getBatchJobName() + " for pay calendar entry: " + this.hrPyCalendarEntryId);
052            startTime = System.currentTimeMillis();
053            this.setBatchJobStatus(TkConstants.BATCH_JOB_ENTRY_STATUS.RUNNING);
054            TkServiceLocator.getBatchJobService().saveBatchJob(this);
055        }
056    
057        public void runJob() {
058            TkServiceLocator.getTransactionTemplate().execute(new TransactionCallbackWithoutResult() {
059                @Override
060                protected void doInTransactionWithoutResult(TransactionStatus status) {
061                    doBeforeRun();
062                    doWork();
063                    doAfterRun();
064                }
065            });
066        }
067    
068        void doWork() {
069            throw new UnsupportedOperationException("You must override this method in a subclass.");
070        }
071    
072        /**
073         * Cleanup logic goes here.
074         */
075        void doAfterRun() {
076            endTime = System.currentTimeMillis();
077            long runtime = endTime - startTime;
078            timeElapsed = (runtime > 0) ? runtime / 1000 : 0; // set to 0, and avoid div by 0.
079            this.setBatchJobStatus(TkConstants.BATCH_JOB_ENTRY_STATUS.FINISHED);
080            TkServiceLocator.getBatchJobService().saveBatchJob(this);
081            LOG.info("Batch job '" + this.getBatchJobName() + "' ("+this.getHrPyCalendarEntryId()+") complete after " + timeElapsed + " seconds.");
082        }
083    
084        public String getNextIpAddressInCluster() {
085            String nextIpAddressInCluster = "";
086            
087            String clusterIps = ConfigContext.getCurrentContextConfig().getProperty("cluster.ips");
088            String[] ips = StringUtils.split(clusterIps, ",");
089            if (ArrayUtils.isNotEmpty(ips)) {
090                if (lastPlace >= ips.length) {
091                    lastPlace = 0;
092                }
093                nextIpAddressInCluster = ips[lastPlace++];
094            }
095            
096            return nextIpAddressInCluster;
097        }
098    
099        protected void populateBatchJobEntry(Object o){
100            throw new UnsupportedOperationException("You must override this method in a subclass.");
101        }
102    
103        public Long getTkBatchJobId() {
104            return tkBatchJobId;
105        }
106    
107        public void setTkBatchJobId(Long tkBatchJobId) {
108            this.tkBatchJobId = tkBatchJobId;
109        }
110    
111        public String getBatchJobName() {
112            return batchJobName;
113        }
114    
115        public void setBatchJobName(String batchJobName) {
116            this.batchJobName = batchJobName;
117        }
118    
119        public String getBatchJobStatus() {
120            return batchJobStatus;
121        }
122    
123        public void setBatchJobStatus(String batchJobStatus) {
124            this.batchJobStatus = batchJobStatus;
125        }
126    
127            public String getHrPyCalendarEntryId() {
128                    return hrPyCalendarEntryId;
129            }
130    
131            public void setHrPyCalendarEntryId(String hrPyCalendarEntryId) {
132                    this.hrPyCalendarEntryId = hrPyCalendarEntryId;
133            }
134    
135        public Long getTimeElapsed() {
136            return timeElapsed;
137        }
138    
139        public void setTimeElapsed(Long timeElapsed) {
140            this.timeElapsed = timeElapsed;
141        }
142    
143        public Timestamp getTimestamp() {
144            return timestamp;
145        }
146    
147        public void setTimestamp(Timestamp timestamp) {
148            this.timestamp = timestamp;
149        }
150    
151        BatchJobEntry createBatchJobEntry(String batchJobName, String ip, String principal, String documentId, String clockLogId) {
152            BatchJobEntry entry = new BatchJobEntry();
153    
154            entry.setBatchJobEntryStatus(TkConstants.BATCH_JOB_ENTRY_STATUS.SCHEDULED);
155            entry.setBatchJobName(batchJobName);
156            entry.setIpAddress(ip);
157            entry.setHrPyCalendarEntryId(this.getHrPyCalendarEntryId());
158            entry.setPrincipalId(principal);
159            entry.setTkBatchJobId(this.getTkBatchJobId());
160            entry.setDocumentId(documentId);
161            entry.setClockLogId(clockLogId);
162    
163            return entry;
164        }
165    
166    }