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.wf; 016 017 import java.util.List; 018 019 import org.apache.oozie.ErrorCode; 020 import org.apache.oozie.WorkflowActionBean; 021 import org.apache.oozie.WorkflowJobBean; 022 import org.apache.oozie.client.WorkflowJob; 023 import org.apache.oozie.command.CommandException; 024 import org.apache.oozie.command.PreconditionException; 025 import org.apache.oozie.command.coord.CoordActionUpdateXCommand; 026 import org.apache.oozie.executor.jpa.JPAExecutorException; 027 import org.apache.oozie.executor.jpa.WorkflowActionRetryManualGetJPAExecutor; 028 import org.apache.oozie.executor.jpa.WorkflowActionUpdateJPAExecutor; 029 import org.apache.oozie.executor.jpa.WorkflowJobGetJPAExecutor; 030 import org.apache.oozie.executor.jpa.WorkflowJobUpdateJPAExecutor; 031 import org.apache.oozie.service.JPAService; 032 import org.apache.oozie.service.Services; 033 import org.apache.oozie.util.InstrumentUtils; 034 import org.apache.oozie.util.LogUtils; 035 import org.apache.oozie.util.ParamChecker; 036 import org.apache.oozie.workflow.WorkflowException; 037 import org.apache.oozie.workflow.WorkflowInstance; 038 import org.apache.oozie.workflow.lite.LiteWorkflowInstance; 039 040 public class SuspendXCommand extends WorkflowXCommand<Void> { 041 private final String wfid; 042 private WorkflowJobBean wfJobBean; 043 private JPAService jpaService; 044 045 public SuspendXCommand(String id) { 046 super("suspend", "suspend", 1); 047 this.wfid = ParamChecker.notEmpty(id, "wfid"); 048 } 049 050 /* (non-Javadoc) 051 * @see org.apache.oozie.command.XCommand#execute() 052 */ 053 @Override 054 protected Void execute() throws CommandException { 055 InstrumentUtils.incrJobCounter(getName(), 1, getInstrumentation()); 056 try { 057 suspendJob(this.jpaService, this.wfJobBean, this.wfid, null); 058 jpaService.execute(new WorkflowJobUpdateJPAExecutor(this.wfJobBean)); 059 queue(new NotificationXCommand(this.wfJobBean)); 060 } 061 catch (WorkflowException e) { 062 throw new CommandException(e); 063 } 064 catch (JPAExecutorException je) { 065 throw new CommandException(je); 066 } 067 finally { 068 // update coordinator action 069 new CoordActionUpdateXCommand(wfJobBean).call(); 070 } 071 return null; 072 } 073 074 /** 075 * Suspend the workflow job and pending flag to false for the actions that are START_RETRY or START_MANUAL or 076 * END_RETRY or END_MANUAL 077 * 078 * @param jpaService jpa service 079 * @param workflow workflow job 080 * @param id workflow job id 081 * @param actionId workflow action id 082 * @throws WorkflowException thrown if failed to suspend workflow instance 083 * @throws CommandException thrown if unable set pending false for actions 084 */ 085 public static void suspendJob(JPAService jpaService, WorkflowJobBean workflow, String id, String actionId) 086 throws WorkflowException, CommandException { 087 if (workflow.getStatus() == WorkflowJob.Status.RUNNING) { 088 workflow.getWorkflowInstance().suspend(); 089 WorkflowInstance wfInstance = workflow.getWorkflowInstance(); 090 ((LiteWorkflowInstance) wfInstance).setStatus(WorkflowInstance.Status.SUSPENDED); 091 workflow.setStatus(WorkflowJob.Status.SUSPENDED); 092 workflow.setWorkflowInstance(wfInstance); 093 094 setPendingFalseForActions(jpaService, id, actionId); 095 } 096 } 097 098 /** 099 * Set pending flag to false for the actions that are START_RETRY or START_MANUAL or END_RETRY or END_MANUAL 100 * <p/> 101 * 102 * @param jpaService jpa service 103 * @param id workflow job id 104 * @param actionId workflow action id 105 * @throws CommandException thrown if failed to update workflow action 106 */ 107 private static void setPendingFalseForActions(JPAService jpaService, String id, String actionId) 108 throws CommandException { 109 List<WorkflowActionBean> actions; 110 try { 111 actions = jpaService.execute(new WorkflowActionRetryManualGetJPAExecutor(id)); 112 113 for (WorkflowActionBean action : actions) { 114 if (actionId != null && actionId.equals(action.getId())) { 115 // this action has been changed in handleNonTransient() 116 continue; 117 } 118 else { 119 action.resetPendingOnly(); 120 } 121 jpaService.execute(new WorkflowActionUpdateJPAExecutor(action)); 122 123 } 124 } 125 catch (JPAExecutorException je) { 126 throw new CommandException(je); 127 } 128 } 129 130 /* (non-Javadoc) 131 * @see org.apache.oozie.command.XCommand#eagerLoadState() 132 */ 133 @Override 134 protected void eagerLoadState() throws CommandException { 135 super.eagerLoadState(); 136 try { 137 jpaService = Services.get().get(JPAService.class); 138 if (jpaService != null) { 139 this.wfJobBean = jpaService.execute(new WorkflowJobGetJPAExecutor(this.wfid)); 140 } 141 else { 142 throw new CommandException(ErrorCode.E0610); 143 } 144 } 145 catch (Exception ex) { 146 throw new CommandException(ErrorCode.E0603, ex); 147 } 148 LogUtils.setLogInfo(this.wfJobBean, logInfo); 149 } 150 151 /* (non-Javadoc) 152 * @see org.apache.oozie.command.XCommand#eagerVerifyPrecondition() 153 */ 154 @Override 155 protected void eagerVerifyPrecondition() throws CommandException, PreconditionException { 156 super.eagerVerifyPrecondition(); 157 if (this.wfJobBean.getStatus() != WorkflowJob.Status.RUNNING) { 158 throw new PreconditionException(ErrorCode.E0727, this.wfJobBean.getStatus()); 159 } 160 } 161 162 /* (non-Javadoc) 163 * @see org.apache.oozie.command.XCommand#getEntityKey() 164 */ 165 @Override 166 protected String getEntityKey() { 167 return this.wfid; 168 } 169 170 /* (non-Javadoc) 171 * @see org.apache.oozie.command.XCommand#isLockRequired() 172 */ 173 @Override 174 protected boolean isLockRequired() { 175 return true; 176 } 177 178 /* (non-Javadoc) 179 * @see org.apache.oozie.command.XCommand#loadState() 180 */ 181 @Override 182 protected void loadState() throws CommandException { 183 184 } 185 186 /* (non-Javadoc) 187 * @see org.apache.oozie.command.XCommand#verifyPrecondition() 188 */ 189 @Override 190 protected void verifyPrecondition() throws CommandException, PreconditionException { 191 } 192 }