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.CoordinatorActionBean;
020 import org.apache.oozie.WorkflowJobBean;
021 import org.apache.oozie.XException;
022 import org.apache.oozie.service.Services;
023 import org.apache.oozie.service.StoreService;
024 import org.apache.oozie.store.CoordinatorStore;
025 import org.apache.oozie.store.StoreException;
026 import org.apache.oozie.store.WorkflowStore;
027 import org.apache.oozie.util.XLog;
028 import org.apache.oozie.util.db.SLADbOperations;
029 import org.apache.oozie.client.CoordinatorAction;
030 import org.apache.oozie.client.WorkflowJob;
031 import org.apache.oozie.client.SLAEvent.SlaAppType;
032 import org.apache.oozie.client.SLAEvent.Status;
033 import org.apache.oozie.command.CommandException;
034
035 public class CoordActionCheckCommand extends CoordinatorCommand<Void> {
036 private String actionId;
037 private int actionCheckDelay;
038 private final XLog log = XLog.getLog(getClass());
039 private CoordinatorActionBean coordAction = null;
040
041 public CoordActionCheckCommand(String actionId, int actionCheckDelay) {
042 super("coord_action_check", "coord_action_check", 0, XLog.OPS);
043 this.actionId = actionId;
044 this.actionCheckDelay = actionCheckDelay;
045 }
046
047 protected Void call(CoordinatorStore cstore) throws StoreException, CommandException {
048 try {
049 //if the action has been updated, quit this command
050 Timestamp actionCheckTs = new Timestamp(System.currentTimeMillis() - actionCheckDelay * 1000);
051 Timestamp cactionLmt = coordAction.getLastModifiedTimestamp();
052 if (cactionLmt.after(actionCheckTs)) {
053 log.info("The coord action :" + actionId + " has been udated. Ignore CoordActionCheckCommand!");
054 return null;
055 }
056 if (coordAction.getStatus().equals(CoordinatorAction.Status.SUCCEEDED)
057 || coordAction.getStatus().equals(CoordinatorAction.Status.FAILED)
058 || coordAction.getStatus().equals(CoordinatorAction.Status.KILLED)) {
059 // do nothing
060 }
061 else {
062 incrJobCounter(1);
063 WorkflowStore wstore = Services.get().get(StoreService.class).getStore(WorkflowStore.class, cstore);
064 WorkflowJobBean wf = wstore.getWorkflow(coordAction.getExternalId(), false);
065
066 Status slaStatus = null;
067
068 if (wf.getStatus() == WorkflowJob.Status.SUCCEEDED) {
069 coordAction.setStatus(CoordinatorAction.Status.SUCCEEDED);
070 slaStatus = Status.SUCCEEDED;
071 }
072 else {
073 if (wf.getStatus() == WorkflowJob.Status.FAILED) {
074 coordAction.setStatus(CoordinatorAction.Status.FAILED);
075 slaStatus = Status.FAILED;
076 }
077 else {
078 if (wf.getStatus() == WorkflowJob.Status.KILLED) {
079 coordAction.setStatus(CoordinatorAction.Status.KILLED);
080 slaStatus = Status.KILLED;
081 }
082 else {
083 log.warn("Unexpected workflow " + wf.getId() + " STATUS " + wf.getStatus());
084 cstore.updateCoordinatorAction(coordAction);
085 return null;
086 }
087 }
088 }
089
090 log.debug("Updating Coordintaor actionId :" + coordAction.getId() + "status to =" + coordAction.getStatus());
091 cstore.updateCoordinatorAction(coordAction);
092 if (slaStatus != null) {
093 SLADbOperations.writeStausEvent(coordAction.getSlaXml(), coordAction.getId(), cstore, slaStatus,
094 SlaAppType.COORDINATOR_ACTION);
095 }
096 }
097
098 }
099 catch (XException ex) {
100 log.warn("CoordActionCheckCommand Failed ", ex);
101 throw new CommandException(ex);
102 }
103 return null;
104 }
105
106 @Override
107 protected Void execute(CoordinatorStore store) throws StoreException, CommandException {
108 log.info("STARTED CoordActionCheckCommand for actionId = " + actionId);
109 try {
110 coordAction = store.getEntityManager().find(CoordinatorActionBean.class, actionId);
111 setLogInfo(coordAction);
112 if (lock(coordAction.getJobId())) {
113 call(store);
114 }
115 else {
116 queueCallable(new CoordActionCheckCommand(actionId, actionCheckDelay), LOCK_FAILURE_REQUEUE_INTERVAL);
117 log.warn("CoordActionCheckCommand lock was not acquired - failed jobId=" + coordAction.getJobId()
118 + ", actionId=" + actionId + ". Requeing the same.");
119 }
120 }
121 catch (InterruptedException e) {
122 queueCallable(new CoordActionCheckCommand(actionId, actionCheckDelay), LOCK_FAILURE_REQUEUE_INTERVAL);
123 log.warn("CoordActionCheckCommand lock acquiring failed with exception " + e.getMessage() + " for jobId="
124 + coordAction.getJobId() + ", actionId=" + actionId + " Requeing the same.");
125 }
126 finally {
127 log.info("ENDED CoordActionCheckCommand for actionId:" + actionId);
128 }
129 return null;
130 }
131 }