001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.oozie.command.wf; 019 020 import java.util.List; 021 022 import org.apache.oozie.ErrorCode; 023 import org.apache.oozie.WorkflowActionBean; 024 import org.apache.oozie.WorkflowJobBean; 025 import org.apache.oozie.client.WorkflowJob; 026 import org.apache.oozie.command.CommandException; 027 import org.apache.oozie.command.PreconditionException; 028 import org.apache.oozie.command.coord.CoordActionUpdateXCommand; 029 import org.apache.oozie.executor.jpa.JPAExecutorException; 030 import org.apache.oozie.executor.jpa.WorkflowActionRetryManualGetJPAExecutor; 031 import org.apache.oozie.executor.jpa.WorkflowActionUpdateJPAExecutor; 032 import org.apache.oozie.executor.jpa.WorkflowJobGetJPAExecutor; 033 import org.apache.oozie.executor.jpa.WorkflowJobUpdateJPAExecutor; 034 import org.apache.oozie.service.JPAService; 035 import org.apache.oozie.service.Services; 036 import org.apache.oozie.util.InstrumentUtils; 037 import org.apache.oozie.util.LogUtils; 038 import org.apache.oozie.util.ParamChecker; 039 import org.apache.oozie.workflow.WorkflowException; 040 import org.apache.oozie.workflow.WorkflowInstance; 041 import org.apache.oozie.workflow.lite.LiteWorkflowInstance; 042 043 public class SuspendXCommand extends WorkflowXCommand<Void> { 044 private final String wfid; 045 private WorkflowJobBean wfJobBean; 046 private JPAService jpaService; 047 048 public SuspendXCommand(String id) { 049 super("suspend", "suspend", 1); 050 this.wfid = ParamChecker.notEmpty(id, "wfid"); 051 } 052 053 /* (non-Javadoc) 054 * @see org.apache.oozie.command.XCommand#execute() 055 */ 056 @Override 057 protected Void execute() throws CommandException { 058 InstrumentUtils.incrJobCounter(getName(), 1, getInstrumentation()); 059 try { 060 suspendJob(this.jpaService, this.wfJobBean, this.wfid, null); 061 jpaService.execute(new WorkflowJobUpdateJPAExecutor(this.wfJobBean)); 062 queue(new NotificationXCommand(this.wfJobBean)); 063 } 064 catch (WorkflowException e) { 065 throw new CommandException(e); 066 } 067 catch (JPAExecutorException je) { 068 throw new CommandException(je); 069 } 070 finally { 071 // update coordinator action 072 new CoordActionUpdateXCommand(wfJobBean).call(); 073 } 074 return null; 075 } 076 077 /** 078 * Suspend the workflow job and pending flag to false for the actions that are START_RETRY or START_MANUAL or 079 * END_RETRY or END_MANUAL 080 * 081 * @param jpaService jpa service 082 * @param workflow workflow job 083 * @param id workflow job id 084 * @param actionId workflow action id 085 * @throws WorkflowException thrown if failed to suspend workflow instance 086 * @throws CommandException thrown if unable set pending false for actions 087 */ 088 public static void suspendJob(JPAService jpaService, WorkflowJobBean workflow, String id, String actionId) 089 throws WorkflowException, CommandException { 090 if (workflow.getStatus() == WorkflowJob.Status.RUNNING) { 091 workflow.getWorkflowInstance().suspend(); 092 WorkflowInstance wfInstance = workflow.getWorkflowInstance(); 093 ((LiteWorkflowInstance) wfInstance).setStatus(WorkflowInstance.Status.SUSPENDED); 094 workflow.setStatus(WorkflowJob.Status.SUSPENDED); 095 workflow.setWorkflowInstance(wfInstance); 096 097 setPendingFalseForActions(jpaService, id, actionId); 098 } 099 } 100 101 /** 102 * Set pending flag to false for the actions that are START_RETRY or START_MANUAL or END_RETRY or END_MANUAL 103 * <p/> 104 * 105 * @param jpaService jpa service 106 * @param id workflow job id 107 * @param actionId workflow action id 108 * @throws CommandException thrown if failed to update workflow action 109 */ 110 private static void setPendingFalseForActions(JPAService jpaService, String id, String actionId) 111 throws CommandException { 112 List<WorkflowActionBean> actions; 113 try { 114 actions = jpaService.execute(new WorkflowActionRetryManualGetJPAExecutor(id)); 115 116 for (WorkflowActionBean action : actions) { 117 if (actionId != null && actionId.equals(action.getId())) { 118 // this action has been changed in handleNonTransient() 119 continue; 120 } 121 else { 122 action.resetPendingOnly(); 123 } 124 jpaService.execute(new WorkflowActionUpdateJPAExecutor(action)); 125 126 } 127 } 128 catch (JPAExecutorException je) { 129 throw new CommandException(je); 130 } 131 } 132 133 /* (non-Javadoc) 134 * @see org.apache.oozie.command.XCommand#eagerLoadState() 135 */ 136 @Override 137 protected void eagerLoadState() throws CommandException { 138 super.eagerLoadState(); 139 try { 140 jpaService = Services.get().get(JPAService.class); 141 if (jpaService != null) { 142 this.wfJobBean = jpaService.execute(new WorkflowJobGetJPAExecutor(this.wfid)); 143 } 144 else { 145 throw new CommandException(ErrorCode.E0610); 146 } 147 } 148 catch (Exception ex) { 149 throw new CommandException(ErrorCode.E0603, ex); 150 } 151 LogUtils.setLogInfo(this.wfJobBean, logInfo); 152 } 153 154 /* (non-Javadoc) 155 * @see org.apache.oozie.command.XCommand#eagerVerifyPrecondition() 156 */ 157 @Override 158 protected void eagerVerifyPrecondition() throws CommandException, PreconditionException { 159 super.eagerVerifyPrecondition(); 160 if (this.wfJobBean.getStatus() != WorkflowJob.Status.RUNNING) { 161 throw new PreconditionException(ErrorCode.E0727, this.wfJobBean.getStatus()); 162 } 163 } 164 165 /* (non-Javadoc) 166 * @see org.apache.oozie.command.XCommand#getEntityKey() 167 */ 168 @Override 169 protected String getEntityKey() { 170 return this.wfid; 171 } 172 173 /* (non-Javadoc) 174 * @see org.apache.oozie.command.XCommand#isLockRequired() 175 */ 176 @Override 177 protected boolean isLockRequired() { 178 return true; 179 } 180 181 /* (non-Javadoc) 182 * @see org.apache.oozie.command.XCommand#loadState() 183 */ 184 @Override 185 protected void loadState() throws CommandException { 186 187 } 188 189 /* (non-Javadoc) 190 * @see org.apache.oozie.command.XCommand#verifyPrecondition() 191 */ 192 @Override 193 protected void verifyPrecondition() throws CommandException, PreconditionException { 194 } 195 }