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.bundle; 016 017 import java.util.Date; 018 import java.util.List; 019 020 import org.apache.oozie.BundleActionBean; 021 import org.apache.oozie.BundleJobBean; 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.KillTransitionXCommand; 028 import org.apache.oozie.command.PreconditionException; 029 import org.apache.oozie.command.coord.CoordKillXCommand; 030 import org.apache.oozie.executor.jpa.BundleActionUpdateJPAExecutor; 031 import org.apache.oozie.executor.jpa.BundleActionsGetJPAExecutor; 032 import org.apache.oozie.executor.jpa.BundleJobGetJPAExecutor; 033 import org.apache.oozie.executor.jpa.BundleJobUpdateJPAExecutor; 034 import org.apache.oozie.executor.jpa.JPAExecutorException; 035 import org.apache.oozie.service.JPAService; 036 import org.apache.oozie.service.Services; 037 import org.apache.oozie.util.LogUtils; 038 import org.apache.oozie.util.ParamChecker; 039 040 public class BundleKillXCommand extends KillTransitionXCommand { 041 private final String jobId; 042 private BundleJobBean bundleJob; 043 private List<BundleActionBean> bundleActions; 044 private JPAService jpaService = null; 045 046 public BundleKillXCommand(String jobId) { 047 super("bundle_kill", "bundle_kill", 1); 048 this.jobId = ParamChecker.notEmpty(jobId, "jobId"); 049 } 050 051 /* (non-Javadoc) 052 * @see org.apache.oozie.command.XCommand#getEntityKey() 053 */ 054 @Override 055 protected String getEntityKey() { 056 return jobId; 057 } 058 059 /* (non-Javadoc) 060 * @see org.apache.oozie.command.XCommand#isLockRequired() 061 */ 062 @Override 063 protected boolean isLockRequired() { 064 return true; 065 } 066 067 /* (non-Javadoc) 068 * @see org.apache.oozie.command.XCommand#loadState() 069 */ 070 @Override 071 public void loadState() throws CommandException { 072 try { 073 jpaService = Services.get().get(JPAService.class); 074 075 if (jpaService != null) { 076 this.bundleJob = jpaService.execute(new BundleJobGetJPAExecutor(jobId)); 077 this.bundleActions = jpaService.execute(new BundleActionsGetJPAExecutor(jobId)); 078 LogUtils.setLogInfo(bundleJob, logInfo); 079 super.setJob(bundleJob); 080 081 } 082 else { 083 throw new CommandException(ErrorCode.E0610); 084 } 085 } 086 catch (XException ex) { 087 throw new CommandException(ex); 088 } 089 } 090 091 /* (non-Javadoc) 092 * @see org.apache.oozie.command.XCommand#verifyPrecondition() 093 */ 094 @Override 095 protected void verifyPrecondition() throws CommandException, PreconditionException { 096 if (bundleJob.getStatus() == CoordinatorJob.Status.SUCCEEDED 097 || bundleJob.getStatus() == CoordinatorJob.Status.FAILED 098 || bundleJob.getStatus() == CoordinatorJob.Status.DONEWITHERROR) { 099 LOG.info("BundleKillXCommand not killed - job either finished SUCCEEDED, FAILED or DONEWITHERROR, job id = " 100 + jobId + ", status = " + bundleJob.getStatus()); 101 throw new PreconditionException(ErrorCode.E1020, jobId); 102 } 103 } 104 105 /* (non-Javadoc) 106 * @see org.apache.oozie.command.KillTransitionXCommand#killChildren() 107 */ 108 @Override 109 public void killChildren() throws CommandException { 110 if (bundleActions != null) { 111 for (BundleActionBean action : bundleActions) { 112 if (action.getCoordId() != null) { 113 queue(new CoordKillXCommand(action.getCoordId())); 114 updateBundleAction(action); 115 LOG.debug("Killed bundle action = [{0}], new status = [{1}], pending = [{2}] and queue CoordKillXCommand for [{3}]", 116 action.getBundleActionId(), action.getStatus(), action.getPending(), action.getCoordId()); 117 } else { 118 updateBundleAction(action); 119 LOG.debug("Killed bundle action = [{0}], current status = [{1}], pending = [{2}]", action.getBundleActionId(), action 120 .getStatus(), action.getPending()); 121 } 122 123 } 124 } 125 LOG.debug("Killed coord jobs for the bundle=[{0}]", jobId); 126 } 127 128 /** 129 * Update bundle action 130 * 131 * @param action 132 * @throws CommandException 133 */ 134 private void updateBundleAction(BundleActionBean action) throws CommandException { 135 action.incrementAndGetPending(); 136 action.setLastModifiedTime(new Date()); 137 action.setStatus(Job.Status.KILLED); 138 try { 139 jpaService.execute(new BundleActionUpdateJPAExecutor(action)); 140 } 141 catch (JPAExecutorException e) { 142 throw new CommandException(e); 143 } 144 } 145 146 /* (non-Javadoc) 147 * @see org.apache.oozie.command.TransitionXCommand#notifyParent() 148 */ 149 @Override 150 public void notifyParent() { 151 } 152 153 /* (non-Javadoc) 154 * @see org.apache.oozie.command.TransitionXCommand#getJob() 155 */ 156 @Override 157 public Job getJob() { 158 return bundleJob; 159 } 160 161 /* (non-Javadoc) 162 * @see org.apache.oozie.command.TransitionXCommand#updateJob() 163 */ 164 @Override 165 public void updateJob() throws CommandException { 166 try { 167 jpaService.execute(new BundleJobUpdateJPAExecutor(bundleJob)); 168 } 169 catch (JPAExecutorException e) { 170 throw new CommandException(e); 171 } 172 } 173 174 }