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 static final int LOOKAHEAD_WINDOW = 300; // We look ahead 5 minutes for materialization; 029 030 private final XLog log = XLog.getLog(getClass()); 031 private int materializationWindow; 032 private String jobId; 033 034 public CoordJobMatLookupCommand(String id, int materializationWindow) { 035 super("materialization_lookup", "materialization_lookup", 1, XLog.STD); 036 this.jobId = id; 037 this.materializationWindow = materializationWindow; 038 } 039 040 @Override 041 protected Void call(CoordinatorStore store) throws StoreException, CommandException { 042 //CoordinatorJobBean coordJob = store.getCoordinatorJob(jobId, true); 043 CoordinatorJobBean coordJob = store.getEntityManager().find(CoordinatorJobBean.class, jobId); 044 setLogInfo(coordJob); 045 046 if (!(coordJob.getStatus() == CoordinatorJobBean.Status.PREP || coordJob.getStatus() == CoordinatorJobBean.Status.RUNNING)) { 047 log.debug("CoordJobMatLookupCommand for jobId=" + jobId + " job is not in PREP or RUNNING but in " 048 + coordJob.getStatus()); 049 return null; 050 } 051 052 if (coordJob.getNextMaterializedTimestamp() != null 053 && coordJob.getNextMaterializedTimestamp().compareTo(coordJob.getEndTimestamp()) >= 0) { 054 log.debug("CoordJobMatLookupCommand for jobId=" + jobId + " job is already materialized"); 055 return null; 056 } 057 058 if (coordJob.getNextMaterializedTimestamp() != null 059 && coordJob.getNextMaterializedTimestamp().compareTo(new Timestamp(System.currentTimeMillis())) >= 0) { 060 log.debug("CoordJobMatLookupCommand for jobId=" + jobId + " job is already materialized"); 061 return null; 062 } 063 064 Timestamp startTime = coordJob.getNextMaterializedTimestamp(); 065 if (startTime == null) { 066 startTime = coordJob.getStartTimestamp(); 067 068 if (startTime.after(new Timestamp(System.currentTimeMillis() + LOOKAHEAD_WINDOW * 1000))) { 069 log.debug("CoordJobMatLookupCommand for jobId=" + jobId + " job's start time is not reached yet - nothing to materialize"); 070 return null; 071 } 072 } 073 // calculate end time by adding materializationWindow to start time. 074 // need to convert materializationWindow from secs to milliseconds 075 long startTimeMilli = startTime.getTime(); 076 long endTimeMilli = startTimeMilli + (materializationWindow * 1000); 077 Timestamp endTime = new Timestamp(endTimeMilli); 078 // if MaterializationWindow end time is greater than endTime 079 // for job, then set it to endTime of job 080 Timestamp jobEndTime = coordJob.getEndTimestamp(); 081 if (endTime.compareTo(jobEndTime) > 0) { 082 endTime = jobEndTime; 083 } 084 // update status of job from PREP or RUNNING to PREMATER in coordJob 085 coordJob.setStatus(CoordinatorJob.Status.PREMATER); 086 store.updateCoordinatorJobStatus(coordJob); 087 088 log.debug("Materializing coord job id=" + jobId + ", start=" + DateUtils.toDate(startTime) + ", end=" + DateUtils.toDate(endTime) 089 + ", window=" + materializationWindow + ", status=PREMATER"); 090 queueCallable(new CoordActionMaterializeCommand(jobId, DateUtils.toDate(startTime), DateUtils.toDate(endTime)), 091 100); 092 return null; 093 } 094 095 @Override 096 protected Void execute(CoordinatorStore store) throws StoreException, CommandException { 097 log.info("STARTED CoordJobMatLookupCommand jobId=" + jobId + ", materializationWindow=" 098 + materializationWindow); 099 try { 100 if (lock(jobId)) { 101 call(store); 102 } 103 else { 104 queueCallable(new CoordJobMatLookupCommand(jobId, materializationWindow), LOCK_FAILURE_REQUEUE_INTERVAL); 105 log.warn("CoordJobMatLookupCommand lock was not acquired - failed jobId=" + jobId 106 + ". Requeing the same."); 107 } 108 } 109 catch (InterruptedException e) { 110 queueCallable(new CoordJobMatLookupCommand(jobId, materializationWindow), LOCK_FAILURE_REQUEUE_INTERVAL); 111 log.warn("CoordJobMatLookupCommand lock acquiring failed with exception " + e.getMessage() + " for jobId=" 112 + jobId + " Requeing the same."); 113 } 114 finally { 115 log.info("ENDED CoordJobMatLookupCommand jobId=" + jobId + ", materializationWindow=" 116 + materializationWindow); 117 } 118 return null; 119 } 120 }