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.util.Date; 018 import java.util.List; 019 020 import org.apache.oozie.CoordinatorActionBean; 021 import org.apache.oozie.CoordinatorJobBean; 022 import org.apache.oozie.ErrorCode; 023 import org.apache.oozie.XException; 024 import org.apache.oozie.client.CoordinatorJob; 025 import org.apache.oozie.client.Job; 026 import org.apache.oozie.command.CommandException; 027 import org.apache.oozie.command.PreconditionException; 028 import org.apache.oozie.command.ResumeTransitionXCommand; 029 import org.apache.oozie.command.bundle.BundleStatusUpdateXCommand; 030 import org.apache.oozie.command.wf.ResumeXCommand; 031 import org.apache.oozie.executor.jpa.CoordActionUpdateJPAExecutor; 032 import org.apache.oozie.executor.jpa.CoordJobGetActionsJPAExecutor; 033 import org.apache.oozie.executor.jpa.CoordJobGetJPAExecutor; 034 import org.apache.oozie.executor.jpa.CoordJobUpdateJPAExecutor; 035 import org.apache.oozie.executor.jpa.JPAExecutorException; 036 import org.apache.oozie.service.JPAService; 037 import org.apache.oozie.service.Services; 038 import org.apache.oozie.util.InstrumentUtils; 039 import org.apache.oozie.util.LogUtils; 040 import org.apache.oozie.util.ParamChecker; 041 042 /** 043 * Resume coordinator job and actions. 044 * 045 */ 046 public class CoordResumeXCommand extends ResumeTransitionXCommand { 047 private final String jobId; 048 private CoordinatorJobBean coordJob = null; 049 private JPAService jpaService = null; 050 private boolean exceptionOccured = false; 051 CoordinatorJob.Status prevStatus; 052 053 public CoordResumeXCommand(String id) { 054 super("coord_resume", "coord_resume", 1); 055 this.jobId = ParamChecker.notEmpty(id, "id"); 056 } 057 058 /* (non-Javadoc) 059 * @see org.apache.oozie.command.XCommand#getEntityKey() 060 */ 061 @Override 062 protected String getEntityKey() { 063 return jobId; 064 } 065 066 /* (non-Javadoc) 067 * @see org.apache.oozie.command.XCommand#isLockRequired() 068 */ 069 @Override 070 protected boolean isLockRequired() { 071 return true; 072 } 073 074 /* (non-Javadoc) 075 * @see org.apache.oozie.command.XCommand#loadState() 076 */ 077 @Override 078 protected void loadState() throws CommandException { 079 jpaService = Services.get().get(JPAService.class); 080 if (jpaService == null) { 081 throw new CommandException(ErrorCode.E0610); 082 } 083 try { 084 coordJob = jpaService.execute(new CoordJobGetJPAExecutor(jobId)); 085 } 086 catch (JPAExecutorException e) { 087 throw new CommandException(e); 088 } 089 setJob(coordJob); 090 prevStatus = coordJob.getStatus(); 091 LogUtils.setLogInfo(coordJob, logInfo); 092 } 093 094 /* (non-Javadoc) 095 * @see org.apache.oozie.command.XCommand#verifyPrecondition() 096 */ 097 @Override 098 protected void verifyPrecondition() throws CommandException, PreconditionException { 099 if (coordJob.getStatus() != CoordinatorJob.Status.SUSPENDED && coordJob.getStatus() != Job.Status.PREPSUSPENDED) { 100 throw new PreconditionException(ErrorCode.E1100, "CoordResumeXCommand not Resumed - " 101 + "job not in SUSPENDED/PREPSUSPENDED state, job = " + jobId); 102 } 103 } 104 105 /* (non-Javadoc) 106 * @see org.apache.oozie.command.TransitionXCommand#updateJob() 107 */ 108 @Override 109 public void updateJob() throws CommandException { 110 InstrumentUtils.incrJobCounter(getName(), 1, getInstrumentation()); 111 coordJob.setSuspendedTime(null); 112 coordJob.setLastModifiedTime(new Date()); 113 LOG.debug("Resume coordinator job id = " + jobId + ", status = " + coordJob.getStatus() + ", pending = " + coordJob.isPending()); 114 try { 115 jpaService.execute(new CoordJobUpdateJPAExecutor(coordJob)); 116 } 117 catch (JPAExecutorException e) { 118 throw new CommandException(e); 119 } 120 } 121 122 /* (non-Javadoc) 123 * @see org.apache.oozie.command.ResumeTransitionXCommand#resumeChildren() 124 */ 125 @Override 126 public void resumeChildren() throws CommandException { 127 try { 128 List<CoordinatorActionBean> actionList = jpaService.execute(new CoordJobGetActionsJPAExecutor(jobId)); 129 130 for (CoordinatorActionBean action : actionList) { 131 if(action.getStatus() == CoordinatorActionBean.Status.SUSPENDED){ 132 // queue a ResumeXCommand 133 if (action.getExternalId() != null) { 134 queue(new ResumeXCommand(action.getExternalId())); 135 updateCoordAction(action); 136 LOG.debug("Resume coord action = [{0}], new status = [{1}], pending = [{2}] and queue ResumeXCommand for [{3}]", 137 action.getId(), action.getStatus(), action.getPending(), action.getExternalId()); 138 }else { 139 updateCoordAction(action); 140 LOG.debug("Resume coord action = [{0}], new status = [{1}], pending = [{2}] and external id is null", 141 action.getId(), action.getStatus(), action.getPending()); 142 } 143 } 144 } 145 } 146 catch (XException ex) { 147 exceptionOccured = true; 148 throw new CommandException(ex); 149 } 150 finally { 151 if (exceptionOccured) { 152 coordJob.setStatus(CoordinatorJob.Status.FAILED); 153 coordJob.resetPending(); 154 LOG.warn("Resume children failed so fail coordinator, coordinator job id = " + jobId 155 + ", status = " + coordJob.getStatus()); 156 try { 157 jpaService.execute(new CoordJobUpdateJPAExecutor(coordJob)); 158 } 159 catch (JPAExecutorException je) { 160 LOG.error("Failed to update coordinator job : " + jobId, je); 161 } 162 } 163 } 164 } 165 166 /* (non-Javadoc) 167 * @see org.apache.oozie.command.TransitionXCommand#notifyParent() 168 */ 169 @Override 170 public void notifyParent() throws CommandException { 171 // update bundle action 172 if (this.coordJob.getBundleId() != null) { 173 BundleStatusUpdateXCommand bundleStatusUpdate = new BundleStatusUpdateXCommand(coordJob, prevStatus); 174 bundleStatusUpdate.call(); 175 } 176 } 177 178 private void updateCoordAction(CoordinatorActionBean action) throws CommandException { 179 action.setStatus(CoordinatorActionBean.Status.RUNNING); 180 action.incrementAndGetPending(); 181 action.setLastModifiedTime(new Date()); 182 try { 183 jpaService.execute(new CoordActionUpdateJPAExecutor(action)); 184 } 185 catch (JPAExecutorException e) { 186 throw new CommandException(e); 187 } 188 } 189 190 /* (non-Javadoc) 191 * @see org.apache.oozie.command.TransitionXCommand#getJob() 192 */ 193 @Override 194 public Job getJob() { 195 return coordJob; 196 } 197 }