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.XException;
023    import org.apache.oozie.client.CoordinatorJob;
024    import org.apache.oozie.command.CommandException;
025    import org.apache.oozie.command.wf.SuspendCommand;
026    import org.apache.oozie.store.CoordinatorStore;
027    import org.apache.oozie.store.StoreException;
028    import org.apache.oozie.util.ParamChecker;
029    import org.apache.oozie.util.XLog;
030    
031    public class CoordSuspendCommand extends CoordinatorCommand<Void> {
032    
033        private String jobId;
034        private final XLog log = XLog.getLog(getClass());
035    
036        public CoordSuspendCommand(String id) {
037            super("coord_suspend", "coord_suspend", 1, XLog.STD);
038            this.jobId = ParamChecker.notEmpty(id, "id");
039        }
040    
041        @Override
042        protected Void call(CoordinatorStore store) throws StoreException, CommandException {
043            try {
044                // CoordinatorJobBean coordJob = store.getCoordinatorJob(jobId,
045                // false);
046                CoordinatorJobBean coordJob = store.getEntityManager().find(CoordinatorJobBean.class, jobId);
047                setLogInfo(coordJob);
048                if (coordJob.getStatus() != CoordinatorJob.Status.SUCCEEDED
049                        && coordJob.getStatus() != CoordinatorJob.Status.FAILED) {
050                    incrJobCounter(1);
051                    coordJob.setStatus(CoordinatorJob.Status.SUSPENDED);
052                    coordJob.setSuspendedTime(new Date());
053                    List<CoordinatorActionBean> actionList = store.getActionsForCoordinatorJob(jobId, false);
054                    for (CoordinatorActionBean action : actionList) {
055                        if (action.getStatus() == CoordinatorActionBean.Status.RUNNING) {
056                            // queue a SuspendCommand
057                            if (action.getExternalId() != null) {
058                                queueCallable(new SuspendCommand(action.getExternalId()));
059                            }
060                        }
061                    }
062                    store.updateCoordinatorJob(coordJob);
063                }
064                // TODO queueCallable(new NotificationCommand(coordJob));
065                else {
066                    log.info("CoordSuspendCommand not suspended - " + "job finished or does not exist " + jobId);
067                }
068                return null;
069            }
070            catch (XException ex) {
071                throw new CommandException(ex);
072            }
073        }
074    
075        @Override
076        protected Void execute(CoordinatorStore store) throws StoreException, CommandException {
077            log.info("STARTED CoordSuspendCommand for jobId=" + jobId);
078            try {
079                if (lock(jobId)) {
080                    call(store);
081                }
082                else {
083                    queueCallable(new CoordSuspendCommand(jobId), LOCK_FAILURE_REQUEUE_INTERVAL);
084                    log.warn("CoordSuspendCommand lock was not acquired - " + " failed " + jobId + ". Requeing the same.");
085                }
086            }
087            catch (InterruptedException e) {
088                queueCallable(new CoordSuspendCommand(jobId), LOCK_FAILURE_REQUEUE_INTERVAL);
089                log.warn("CoordSuspendCommand lock acquiring failed " + " with exception " + e.getMessage()
090                        + " for job id " + jobId + ". Requeing the same.");
091            }
092            finally {
093                log.info("ENDED CoordSuspendCommand for jobId=" + jobId);
094            }
095            return null;
096        }
097    
098    }