001    /**
002     * Copyright (c) 2010 Yahoo! Inc. All rights reserved.
003     * Licensed under the Apache License, Version 2.0 (the "License");
004     * you may not use this file except in compliance with the License.
005     * You may obtain a copy of the License at
006     *
007     *   http://www.apache.org/licenses/LICENSE-2.0
008     *
009     *  Unless required by applicable law or agreed to in writing, software
010     *  distributed under the License is distributed on an "AS IS" BASIS,
011     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012     *  See the License for the specific language governing permissions and
013     *  limitations under the License. See accompanying LICENSE file.
014     */
015    package org.apache.oozie.command.coord;
016    
017    import java.sql.Timestamp;
018    
019    import org.apache.oozie.CoordinatorJobBean;
020    import org.apache.oozie.client.CoordinatorJob;
021    import org.apache.oozie.command.CommandException;
022    import org.apache.oozie.store.CoordinatorStore;
023    import org.apache.oozie.store.StoreException;
024    import org.apache.oozie.util.DateUtils;
025    import org.apache.oozie.util.XLog;
026    
027    public class CoordJobMatLookupCommand extends CoordinatorCommand<Void> {
028        private final XLog log = XLog.getLog(getClass());
029        private int materializationWindow;
030        private String jobId;
031    
032        public CoordJobMatLookupCommand(String id, int materializationWindow) {
033            super("materialization_lookup", "materialization_lookup", 1, XLog.STD);
034            this.jobId = id;
035            this.materializationWindow = materializationWindow;
036        }
037    
038        @Override
039        protected Void call(CoordinatorStore store) throws StoreException, CommandException {
040            //CoordinatorJobBean coordJob = store.getCoordinatorJob(jobId, true);
041            CoordinatorJobBean coordJob = store.getEntityManager().find(CoordinatorJobBean.class, jobId);
042            setLogInfo(coordJob);
043    
044            if (!(coordJob.getStatus() == CoordinatorJobBean.Status.PREP || coordJob.getStatus() == CoordinatorJobBean.Status.RUNNING)) {
045                log.debug("CoordJobMatLookupCommand for jobId=" + jobId + " job is not in PREP or RUNNING but in "
046                        + coordJob.getStatus());
047                return null;
048            }
049    
050            if (coordJob.getNextMaterializedTimestamp() != null
051                    && coordJob.getNextMaterializedTimestamp().compareTo(coordJob.getEndTimestamp()) >= 0) {
052                log.debug("CoordJobMatLookupCommand for jobId=" + jobId + " job is already materialized");
053                return null;
054            }
055    
056            if (coordJob.getNextMaterializedTimestamp() != null
057                    && coordJob.getNextMaterializedTimestamp().compareTo(new Timestamp(System.currentTimeMillis())) >= 0) {
058                log.debug("CoordJobMatLookupCommand for jobId=" + jobId + " job is already materialized");
059                return null;
060            }
061    
062            Timestamp startTime = coordJob.getNextMaterializedTimestamp();
063            if (startTime == null) {
064                startTime = coordJob.getStartTimestamp();
065            }
066            // calculate end time by adding materializationWindow to start time.
067            // need to convert materializationWindow from secs to milliseconds
068            long startTimeMilli = startTime.getTime();
069            long endTimeMilli = startTimeMilli + (materializationWindow * 1000);
070            Timestamp endTime = new Timestamp(endTimeMilli);
071            // if MaterializationWindow end time is greater than endTime
072            // for job, then set it to endTime of job
073            Timestamp jobEndTime = coordJob.getEndTimestamp();
074            if (endTime.compareTo(jobEndTime) > 0) {
075                endTime = jobEndTime;
076            }
077            // update status of job from PREP or RUNNING to PREMATER in coordJob
078            coordJob.setStatus(CoordinatorJob.Status.PREMATER);
079            store.updateCoordinatorJobStatus(coordJob);
080    
081            log.debug("Materializing coord job id=" + jobId + ", start=" + DateUtils.toDate(startTime) + ", end=" + DateUtils.toDate(endTime)
082                    + ", window=" + materializationWindow + ", status=PREMATER");
083            queueCallable(new CoordActionMaterializeCommand(jobId, DateUtils.toDate(startTime), DateUtils.toDate(endTime)),
084                    100);
085            return null;
086        }
087    
088        @Override
089        protected Void execute(CoordinatorStore store) throws StoreException, CommandException {
090            log.info("STARTED CoordJobMatLookupCommand jobId=" + jobId + ", materializationWindow="
091                    + materializationWindow);
092            try {
093                if (lock(jobId)) {
094                    call(store);
095                }
096                else {
097                    queueCallable(new CoordJobMatLookupCommand(jobId, materializationWindow), LOCK_FAILURE_REQUEUE_INTERVAL);
098                    log.warn("CoordJobMatLookupCommand lock was not acquired - failed jobId=" + jobId
099                            + ". Requeing the same.");
100                }
101            }
102            catch (InterruptedException e) {
103                queueCallable(new CoordJobMatLookupCommand(jobId, materializationWindow), LOCK_FAILURE_REQUEUE_INTERVAL);
104                log.warn("CoordJobMatLookupCommand lock acquiring failed with exception " + e.getMessage() + " for jobId="
105                        + jobId + " Requeing the same.");
106            }
107            finally {
108                log.info("ENDED CoordJobMatLookupCommand jobId=" + jobId + ", materializationWindow="
109                        + materializationWindow);
110            }
111            return null;
112        }
113    }