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