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