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