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.wf;
016    
017    import java.util.Date;
018    
019    import org.apache.oozie.ErrorCode;
020    import org.apache.oozie.WorkflowActionBean;
021    import org.apache.oozie.WorkflowJobBean;
022    import org.apache.oozie.client.WorkflowJob;
023    import org.apache.oozie.command.CommandException;
024    import org.apache.oozie.command.PreconditionException;
025    import org.apache.oozie.command.coord.CoordActionUpdateXCommand;
026    import org.apache.oozie.executor.jpa.JPAExecutorException;
027    import org.apache.oozie.executor.jpa.WorkflowActionUpdateJPAExecutor;
028    import org.apache.oozie.executor.jpa.WorkflowJobGetActionsJPAExecutor;
029    import org.apache.oozie.executor.jpa.WorkflowJobGetJPAExecutor;
030    import org.apache.oozie.executor.jpa.WorkflowJobUpdateJPAExecutor;
031    import org.apache.oozie.service.JPAService;
032    import org.apache.oozie.service.Services;
033    import org.apache.oozie.util.InstrumentUtils;
034    import org.apache.oozie.util.LogUtils;
035    import org.apache.oozie.util.ParamChecker;
036    import org.apache.oozie.workflow.WorkflowException;
037    import org.apache.oozie.workflow.WorkflowInstance;
038    import org.apache.oozie.workflow.lite.LiteWorkflowInstance;
039    
040    public class ResumeXCommand extends WorkflowXCommand<Void> {
041    
042        private String id;
043        private JPAService jpaService = null;
044        private WorkflowJobBean workflow = null;
045    
046        public ResumeXCommand(String id) {
047            super("resume", "resume", 1);
048            this.id = ParamChecker.notEmpty(id, "id");
049        }
050    
051        @Override
052        protected Void execute() throws CommandException {
053            try {
054                if (workflow.getStatus() == WorkflowJob.Status.SUSPENDED) {
055                    InstrumentUtils.incrJobCounter(getName(), 1, getInstrumentation());
056                    workflow.getWorkflowInstance().resume();
057                    WorkflowInstance wfInstance = workflow.getWorkflowInstance();
058                    ((LiteWorkflowInstance) wfInstance).setStatus(WorkflowInstance.Status.RUNNING);
059                    workflow.setWorkflowInstance(wfInstance);
060                    workflow.setStatus(WorkflowJob.Status.RUNNING);
061    
062    
063                    //for (WorkflowActionBean action : store.getActionsForWorkflow(id, false)) {
064                    for (WorkflowActionBean action : jpaService.execute(new WorkflowJobGetActionsJPAExecutor(id))) {
065    
066                        // Set pending flag to true for the actions that are START_RETRY or
067                        // START_MANUAL or END_RETRY or END_MANUAL
068                        if (action.isRetryOrManual()) {
069                            action.setPendingOnly();
070                            jpaService.execute(new WorkflowActionUpdateJPAExecutor(action));
071                        }
072    
073                        if (action.isPending()) {
074                            if (action.getStatus() == WorkflowActionBean.Status.PREP
075                                    || action.getStatus() == WorkflowActionBean.Status.START_MANUAL) {
076                                queue(new ActionStartXCommand(action.getId(), action.getType()));
077                            }
078                            else {
079                                if (action.getStatus() == WorkflowActionBean.Status.START_RETRY) {
080                                    Date nextRunTime = action.getPendingAge();
081                                    queue(new ActionStartXCommand(action.getId(), action.getType()),
082                                                  nextRunTime.getTime() - System.currentTimeMillis());
083                                }
084                                else {
085                                    if (action.getStatus() == WorkflowActionBean.Status.DONE
086                                            || action.getStatus() == WorkflowActionBean.Status.END_MANUAL) {
087                                        queue(new ActionEndXCommand(action.getId(), action.getType()));
088                                    }
089                                    else {
090                                        if (action.getStatus() == WorkflowActionBean.Status.END_RETRY) {
091                                            Date nextRunTime = action.getPendingAge();
092                                            queue(new ActionEndXCommand(action.getId(), action.getType()),
093                                                          nextRunTime.getTime() - System.currentTimeMillis());
094                                        }
095                                    }
096                                }
097                            }
098    
099                        }
100                    }
101    
102                    jpaService.execute(new WorkflowJobUpdateJPAExecutor(workflow));
103                    queue(new NotificationXCommand(workflow));
104                }
105                return null;
106            }
107            catch (WorkflowException ex) {
108                throw new CommandException(ex);
109            }
110            catch (JPAExecutorException e) {
111                throw new CommandException(e);
112            }
113            finally {
114                // update coordinator action
115                new CoordActionUpdateXCommand(workflow).call();
116            }
117        }
118    
119        @Override
120        protected String getEntityKey() {
121            return id;
122        }
123    
124        @Override
125        protected boolean isLockRequired() {
126            return true;
127        }
128    
129        @Override
130        protected void loadState() throws CommandException {
131            jpaService = Services.get().get(JPAService.class);
132            if (jpaService == null) {
133                throw new CommandException(ErrorCode.E0610);
134            }
135            try {
136                workflow = jpaService.execute(new WorkflowJobGetJPAExecutor(id));
137            }
138            catch (JPAExecutorException e) {
139                throw new CommandException(e);
140            }
141            LogUtils.setLogInfo(workflow, logInfo);
142        }
143    
144        @Override
145        protected void verifyPrecondition() throws CommandException, PreconditionException {
146            if (workflow.getStatus() != WorkflowJob.Status.SUSPENDED) {
147                throw new PreconditionException(ErrorCode.E1100, "workflow's status is " + workflow.getStatusStr() + " is not SUSPENDED");
148            }
149        }
150    }