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
019package org.apache.oozie.command;
020
021import org.apache.oozie.ErrorCode;
022import org.apache.oozie.client.Job;
023import org.apache.oozie.util.StatusUtils;
024
025/**
026 * Transition command for rerun the job. The derived class has to override these following functions:
027 * <p>
028 * updateJob() : update job status and attributes
029 * rerunChildren() : submit or queue commands to rerun children
030 * notifyParent() : update the status to upstream if any
031 *
032 * @param <T>
033 */
034public abstract class RerunTransitionXCommand<T> extends TransitionXCommand<T> {
035    protected String jobId;
036    protected T ret;
037    protected Job.Status prevStatus;
038
039    /**
040     * The constructor for abstract class {@link RerunTransitionXCommand}
041     *
042     * @param name the command name
043     * @param type the command type
044     * @param priority the command priority
045     */
046    public RerunTransitionXCommand(String name, String type, int priority) {
047        super(name, type, priority);
048    }
049
050    /**
051     * The constructor for abstract class {@link RerunTransitionXCommand}
052     *
053     * @param name the command name
054     * @param type the command type
055     * @param priority the command priority
056     * @param dryrun true if dryrun is enable
057     */
058    public RerunTransitionXCommand(String name, String type, int priority, boolean dryrun) {
059        super(name, type, priority, dryrun);
060    }
061
062    /* (non-Javadoc)
063     * @see org.apache.oozie.command.TransitionXCommand#transitToNext()
064     */
065    @Override
066    public void transitToNext() {
067        if (job == null) {
068            job = this.getJob();
069        }
070        prevStatus = job.getStatus();
071        if (prevStatus == Job.Status.SUCCEEDED || prevStatus == Job.Status.PAUSED
072                || prevStatus == Job.Status.SUSPENDED || prevStatus == Job.Status.RUNNING) {
073            job.setStatus(Job.Status.RUNNING);
074        }
075        else {
076            // Check for backward compatibility
077            job.setStatus(StatusUtils.getStatusIfBackwardSupportTrue(Job.Status.RUNNINGWITHERROR));
078        }
079        job.setPending();
080    }
081
082    /**
083     * Rerun actions associated with the job
084     *
085     * @throws CommandException thrown if failed to rerun actions
086     */
087    public abstract void rerunChildren() throws CommandException;
088
089    /* (non-Javadoc)
090     * @see org.apache.oozie.command.TransitionXCommand#execute()
091     */
092    @Override
093    protected T execute() throws CommandException {
094        getLog().info("STARTED " + getClass().getSimpleName() + " for jobId=" + jobId);
095        try {
096            transitToNext();
097            rerunChildren();
098            updateJob();
099            performWrites();
100        }
101        finally {
102            notifyParent();
103        }
104        getLog().info("ENDED " + getClass().getSimpleName() + " for jobId=" + jobId);
105        return ret;
106    }
107
108    /* (non-Javadoc)
109     * @see org.apache.oozie.command.XCommand#verifyPrecondition()
110     */
111    @Override
112    protected void verifyPrecondition() throws CommandException, PreconditionException {
113        eagerVerifyPrecondition();
114    }
115
116    /* (non-Javadoc)
117     * @see org.apache.oozie.command.XCommand#eagerLoadState()
118     */
119    @Override
120    protected void eagerLoadState() throws CommandException {
121        loadState();
122    }
123
124    /* (non-Javadoc)
125     * @see org.apache.oozie.command.XCommand#eagerVerifyPrecondition()
126     */
127    @Override
128    protected void eagerVerifyPrecondition() throws CommandException, PreconditionException {
129        if (getJob().getStatus() == Job.Status.KILLED || getJob().getStatus() == Job.Status.FAILED
130                || getJob().getStatus() == Job.Status.PREP || getJob().getStatus() == Job.Status.PREPPAUSED
131                || getJob().getStatus() == Job.Status.PREPSUSPENDED) {
132            getLog().warn(
133                    "RerunCommand is not able to run because job status=" + getJob().getStatus() + ", jobid="
134                            + getJob().getId());
135            throw new PreconditionException(ErrorCode.E1100, "Not able to rerun the job Id= " + getJob().getId()
136                    + ". job is in wrong state= " + getJob().getStatus());
137        }
138    }
139
140    /**
141     * This method will return the previous status.
142     *
143     * @return JOB Status
144     */
145    public Job.Status getPrevStatus() {
146        if (prevStatus != null) {
147            return prevStatus;
148        }
149        else {
150            return job.getStatus();
151        }
152    }
153}