/**
* Copyright (c) 2010 Yahoo! Inc. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. See accompanying LICENSE file.
*/
package org.apache.oozie.command.wf;
import org.apache.oozie.client.WorkflowJob;
import org.apache.oozie.client.SLAEvent.SlaAppType;
import org.apache.oozie.client.SLAEvent.Status;
import org.apache.oozie.WorkflowActionBean;
import org.apache.oozie.WorkflowJobBean;
import org.apache.oozie.command.Command;
import org.apache.oozie.command.CommandException;
import org.apache.oozie.store.StoreException;
import org.apache.oozie.store.WorkflowStore;
import org.apache.oozie.store.Store;
import org.apache.oozie.workflow.WorkflowException;
import org.apache.oozie.workflow.WorkflowInstance;
import org.apache.oozie.workflow.lite.LiteWorkflowInstance;
import org.apache.oozie.util.ParamChecker;
import org.apache.oozie.util.XLog;
import org.apache.oozie.util.db.SLADbOperations;
import java.util.Date;
public class KillCommand extends WorkflowCommand<Void> {
private String id;
private final XLog log = XLog.getLog(getClass());
public KillCommand(String id) {
super("kill", "kill", 1, XLog.STD);
this.id = ParamChecker.notEmpty(id, "id");
}
@Override
protected Void call(WorkflowStore store) throws StoreException, CommandException {
try {
log.info("In Workflow KillCommand.call() for jobId=" + id);
WorkflowJobBean workflow = store.getWorkflow(id, false);
setLogInfo(workflow);
if (workflow.getStatus() == WorkflowJob.Status.PREP || workflow.getStatus() == WorkflowJob.Status.RUNNING
|| workflow.getStatus() == WorkflowJob.Status.SUSPENDED
|| workflow.getStatus() == WorkflowJob.Status.FAILED) {
workflow.setEndTime(new Date());
if (workflow.getStatus() != WorkflowJob.Status.FAILED) {
incrJobCounter(1);
workflow.setStatus(WorkflowJob.Status.KILLED);
SLADbOperations.writeStausEvent(workflow.getSlaXml(), workflow.getId(), store, Status.KILLED,
SlaAppType.WORKFLOW_JOB);
workflow.getWorkflowInstance().kill();
WorkflowInstance wfInstance = workflow.getWorkflowInstance();
((LiteWorkflowInstance) wfInstance).setStatus(WorkflowInstance.Status.KILLED);
workflow.setWorkflowInstance(wfInstance);
}
for (WorkflowActionBean action : store.getActionsForWorkflow(id, true)) {
if (action.getStatus() == WorkflowActionBean.Status.RUNNING
|| action.getStatus() == WorkflowActionBean.Status.DONE) {
action.setPending();
action.setStatus(WorkflowActionBean.Status.KILLED);
store.updateAction(action);
queueCallable(new ActionKillCommand(action.getId(), action.getType()));
}
if (action.getStatus() == WorkflowActionBean.Status.PREP
|| action.getStatus() == WorkflowActionBean.Status.START_RETRY
|| action.getStatus() == WorkflowActionBean.Status.START_MANUAL
|| action.getStatus() == WorkflowActionBean.Status.END_RETRY
|| action.getStatus() == WorkflowActionBean.Status.END_MANUAL) {
action.setStatus(WorkflowActionBean.Status.KILLED);
action.resetPending();
SLADbOperations.writeStausEvent(action.getSlaXml(), action.getId(), store, Status.KILLED,
SlaAppType.WORKFLOW_ACTION);
store.updateAction(action);
}
}
store.updateWorkflow(workflow);
queueCallable(new NotificationCommand(workflow));
}
return null;
}
catch (WorkflowException ex) {
throw new CommandException(ex);
}
}
@Override
protected Void execute(WorkflowStore store) throws CommandException, StoreException {
try {
XLog.getLog(getClass()).debug("STARTED KillCommand for job " + id);
if (lock(id)) {
call(store);
}
else {
queueCallable(new KillCommand(id), LOCK_FAILURE_REQUEUE_INTERVAL);
XLog.getLog(getClass()).warn("KillCommand lock was not acquired - failed {0}", id);
}
}
catch (InterruptedException e) {
queueCallable(new KillCommand(id), LOCK_FAILURE_REQUEUE_INTERVAL);
XLog.getLog(getClass()).warn("KillCommand lock was not acquired - interrupted exception failed {0}", id);
}
XLog.getLog(getClass()).debug("ENDED KillCommand for job " + id);
return null;
}
}