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.util;
020
021import org.apache.hadoop.conf.Configuration;
022import org.apache.oozie.CoordinatorJobBean;
023import org.apache.oozie.client.Job;
024import org.apache.oozie.service.ConfigurationService;
025import org.apache.oozie.service.SchemaService;
026import org.apache.oozie.service.Services;
027import org.apache.oozie.service.StatusTransitService;
028
029public class StatusUtils {
030
031    /**
032     * This Function transforms the statuses based on the name space of the coordinator App
033     *
034     * @param coordJob This will be the coordinator job bean for which we need to get the status based on version
035     * @return Job.Status This would be the new status based on the app version.
036     */
037    public static Job.Status getStatus(CoordinatorJobBean coordJob) {
038        Job.Status newStatus = null;
039        if (coordJob != null) {
040            newStatus = coordJob.getStatus();
041            boolean backwardSupportForCoordStatus = ConfigUtils.isBackwardSupportForCoordStatus();
042            if (backwardSupportForCoordStatus) {
043                if (coordJob.getAppNamespace() != null
044                        && coordJob.getAppNamespace().equals(SchemaService.COORDINATOR_NAMESPACE_URI_1)) {
045
046                    if (coordJob.getStatus() == Job.Status.DONEWITHERROR) {
047                        newStatus = Job.Status.SUCCEEDED;
048                    }
049                    else if (coordJob.getStatus() == Job.Status.PAUSED
050                            || coordJob.getStatus() == Job.Status.PAUSEDWITHERROR) {
051                        newStatus = Job.Status.RUNNING;
052                    }
053                    else if ((coordJob.getStatus() == Job.Status.RUNNING || coordJob.getStatus() == Job.Status.RUNNINGWITHERROR)
054                            && coordJob.isDoneMaterialization()) {
055                        newStatus = Job.Status.SUCCEEDED;
056                    }
057                    else if (coordJob.getStatus() == Job.Status.PREPSUSPENDED) {
058                        newStatus = Job.Status.SUSPENDED;
059                    }
060                    else if (coordJob.getStatus() == Job.Status.PREPPAUSED) {
061                        newStatus = Job.Status.PREP;
062                    }
063                }
064            }
065        }
066        return newStatus;
067    }
068
069    /**
070     * This function changes back the status for coordinator rerun if the job was SUCCEEDED or SUSPENDED when rerun
071     * with backward support is true.
072     *
073     * @param coordJob This will be the coordinator job bean for which we need to get the status based on version
074     * @param prevStatus coordinator job previous status
075     * @return Job.Status This would be the new status based on the app version.
076     */
077    public static Job.Status getStatusForCoordRerun(CoordinatorJobBean coordJob, Job.Status prevStatus) {
078        Job.Status newStatus = null;
079        if (coordJob != null) {
080            newStatus = coordJob.getStatus();
081            boolean backwardSupportForCoordStatus = ConfigUtils.isBackwardSupportForCoordStatus();
082            if (backwardSupportForCoordStatus) {
083                if (coordJob.getAppNamespace() != null
084                        && coordJob.getAppNamespace().equals(SchemaService.COORDINATOR_NAMESPACE_URI_1)) {
085
086                    if (prevStatus == Job.Status.SUSPENDED) {
087                        newStatus = Job.Status.SUSPENDED;
088                    }
089                    else if (coordJob.isDoneMaterialization() || prevStatus == Job.Status.SUCCEEDED) {
090                        newStatus = Job.Status.SUCCEEDED;
091                        coordJob.setDoneMaterialization();
092                    }
093                }
094            }
095        }
096        return newStatus;
097    }
098
099    /**
100     * This function check if eligible to do action input check  when running with backward support is true.
101     *
102     * @param coordJob This will be the coordinator job bean for which we need to get the status based on version
103     * @return true if eligible to do action input check
104     */
105    public static boolean getStatusForCoordActionInputCheck(CoordinatorJobBean coordJob) {
106        boolean ret = false;
107        if (coordJob != null) {
108            boolean backwardSupportForCoordStatus = ConfigUtils.isBackwardSupportForCoordStatus();
109            if (backwardSupportForCoordStatus) {
110                if (coordJob.getAppNamespace() != null
111                        && coordJob.getAppNamespace().equals(SchemaService.COORDINATOR_NAMESPACE_URI_1)) {
112
113                    if (coordJob.getStatus() == Job.Status.SUCCEEDED) {
114                        ret = true;
115                    }
116                    else if (coordJob.getStatus() == Job.Status.SUSPENDED) {
117                        ret = true;
118                    }
119                }
120            }
121        }
122        return ret;
123    }
124
125    /**
126     * If namespace 0.1 is used and backward support is true, SUCCEEDED coord job can be killed
127     *
128     * @param coordJob the coordinator job
129     * @return true if namespace 0.1 is used and backward support is true, SUCCEEDED coord job can be killed
130     */
131    public static boolean isV1CoordjobKillable(CoordinatorJobBean coordJob) {
132        boolean ret = false;
133        if (coordJob != null) {
134            Configuration conf = Services.get().getConf();
135            boolean backwardSupportForCoordStatus = ConfigUtils.isBackwardSupportForCoordStatus();
136            if (backwardSupportForCoordStatus) {
137                if (coordJob.getAppNamespace() != null
138                        && coordJob.getAppNamespace().equals(SchemaService.COORDINATOR_NAMESPACE_URI_1)) {
139                    if (coordJob.getStatus() == Job.Status.SUCCEEDED) {
140                        ret = true;
141                    }
142                }
143            }
144        }
145        return ret;
146    }
147
148    /**
149     * Get the status of coordinator job for Oozie versions (3.2 and before) when RUNNINGWITHERROR,
150     * SUSPENDEDWITHERROR and PAUSEDWITHERROR are not supported
151     * @param currentJobStatus
152     * @return
153     */
154    public static Job.Status getStatusIfBackwardSupportTrue(Job.Status currentJobStatus) {
155        Job.Status newStatus = currentJobStatus;
156        boolean backwardSupportForStatesWithoutError = ConfigurationService.getBoolean(StatusTransitService
157                .CONF_BACKWARD_SUPPORT_FOR_STATES_WITHOUT_ERROR);
158        if (backwardSupportForStatesWithoutError) {
159            if (currentJobStatus == Job.Status.PAUSEDWITHERROR) {
160                newStatus = Job.Status.PAUSED;
161            }
162            else if (currentJobStatus == Job.Status.SUSPENDEDWITHERROR) {
163                newStatus = Job.Status.SUSPENDED;
164            }
165            else if (currentJobStatus == Job.Status.RUNNINGWITHERROR) {
166                newStatus = Job.Status.RUNNING;
167            }
168        }
169
170        return newStatus;
171    }
172
173}