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 019 import org.apache.oozie.BundleActionBean; 020 import org.apache.oozie.CoordinatorJobBean; 021 import org.apache.oozie.ErrorCode; 022 import org.apache.oozie.XException; 023 import org.apache.oozie.client.CoordinatorJob; 024 import org.apache.oozie.client.Job; 025 import org.apache.oozie.command.CommandException; 026 import org.apache.oozie.command.PreconditionException; 027 import org.apache.oozie.command.StatusUpdateXCommand; 028 import org.apache.oozie.executor.jpa.BundleActionGetJPAExecutor; 029 import org.apache.oozie.executor.jpa.BundleActionUpdateJPAExecutor; 030 import org.apache.oozie.executor.jpa.JPAExecutorException; 031 import org.apache.oozie.service.JPAService; 032 import org.apache.oozie.service.Services; 033 034 /** 035 * The command to update Bundle status 036 */ 037 public class BundleStatusUpdateXCommand extends StatusUpdateXCommand { 038 private final CoordinatorJobBean coordjob; 039 private JPAService jpaService = null; 040 private BundleActionBean bundleaction; 041 private final Job.Status prevStatus; 042 043 /** 044 * The constructor for class {@link BundleStatusUpdateXCommand} 045 * 046 * @param coordjob coordinator job bean 047 * @param prevStatus coordinator job old status 048 */ 049 public BundleStatusUpdateXCommand(CoordinatorJobBean coordjob, CoordinatorJob.Status prevStatus) { 050 super("BundleStatusUpdate", "BundleStatusUpdate", 1); 051 this.coordjob = coordjob; 052 this.prevStatus = prevStatus; 053 } 054 055 /* (non-Javadoc) 056 * @see org.apache.oozie.command.XCommand#execute() 057 */ 058 @Override 059 protected Void execute() throws CommandException { 060 try { 061 LOG.debug("STARTED BundleStatusUpdateXCommand with bubdle id : " + coordjob.getBundleId() 062 + " coord job ID: " + coordjob.getId() + " coord Status " + coordjob.getStatus()); 063 Job.Status coordCurrentStatus = coordjob.getStatus(); 064 Job.Status bundleActionStatus = bundleaction.getStatus(); 065 bundleaction.setStatus(coordCurrentStatus); 066 067 if (bundleaction.isPending()) { 068 bundleaction.decrementAndGetPending(); 069 } 070 bundleaction.setLastModifiedTime(new Date()); 071 bundleaction.setCoordId(coordjob.getId()); 072 jpaService.execute(new BundleActionUpdateJPAExecutor(bundleaction)); 073 LOG.info("Updated bundle action [{0}] from prev status [{1}] to current coord status [{2}], and new bundle action pending [{3}]", bundleaction 074 .getBundleActionId(), bundleActionStatus, coordCurrentStatus, bundleaction.getPending()); 075 076 LOG.debug("ENDED BundleStatusUpdateXCommand with bubdle id : " + coordjob.getBundleId() + " coord job ID: " 077 + coordjob.getId() + " coord Status " + coordjob.getStatus()); 078 } 079 catch (Exception ex) { 080 throw new CommandException(ErrorCode.E1309, bundleaction.getBundleId(), bundleaction.getCoordName()); 081 } 082 return null; 083 } 084 085 /* (non-Javadoc) 086 * @see org.apache.oozie.command.XCommand#getEntityKey() 087 */ 088 @Override 089 protected String getEntityKey() { 090 return this.bundleaction.getBundleActionId(); 091 } 092 093 /* (non-Javadoc) 094 * @see org.apache.oozie.command.XCommand#isLockRequired() 095 */ 096 @Override 097 protected boolean isLockRequired() { 098 return true; 099 } 100 101 /* (non-Javadoc) 102 * @see org.apache.oozie.command.XCommand#eagerLoadState() 103 */ 104 @Override 105 protected void eagerLoadState() throws CommandException{ 106 loadState(); 107 } 108 109 /* (non-Javadoc) 110 * @see org.apache.oozie.command.XCommand#loadState() 111 */ 112 @Override 113 protected void loadState() throws CommandException { 114 try { 115 if (jpaService == null) { 116 jpaService = Services.get().get(JPAService.class); 117 } 118 119 if (jpaService != null) { 120 this.bundleaction = jpaService.execute(new BundleActionGetJPAExecutor(coordjob.getBundleId(), coordjob 121 .getAppName())); 122 } 123 else { 124 throw new CommandException(ErrorCode.E0610); 125 } 126 } 127 catch (XException ex) { 128 throw new CommandException(ex); 129 } 130 } 131 132 /* (non-Javadoc) 133 * @see org.apache.oozie.command.XCommand#verifyPrecondition() 134 */ 135 @Override 136 protected void verifyPrecondition() throws CommandException, PreconditionException { 137 if (bundleaction.getStatusStr().compareToIgnoreCase(prevStatus.toString()) != 0) { 138 // Previous status are not matched with bundle action status 139 // So that's the error and we should not be updating the Bundle Action status 140 // however we need to decrement the pending flag. 141 if (bundleaction.isPending()) { 142 bundleaction.decrementAndGetPending(); 143 } 144 bundleaction.setLastModifiedTime(new Date()); 145 try { 146 jpaService.execute(new BundleActionUpdateJPAExecutor(bundleaction)); 147 } 148 catch (JPAExecutorException je) { 149 throw new CommandException(je); 150 } 151 LOG.info("Bundle action [{0}] status [{1}] is different from prev coord status [{2}], decrement pending so new pending = [{3}]", 152 bundleaction.getBundleActionId(), bundleaction.getStatusStr(), prevStatus.toString(), 153 bundleaction.getPending()); 154 throw new PreconditionException(ErrorCode.E1308, bundleaction.getStatusStr(), prevStatus.toString()); 155 } 156 } 157 158 }