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
019
020package org.apache.oozie.sla;
021
022import java.util.Date;
023
024import org.apache.oozie.AppType;
025import org.apache.oozie.client.event.SLAEvent;
026import org.apache.oozie.lock.LockToken;
027import org.apache.oozie.service.JobsConcurrencyService;
028import org.apache.oozie.service.MemoryLocksService;
029import org.apache.oozie.service.Services;
030import org.apache.oozie.sla.service.SLAService;
031import org.apache.oozie.util.LogUtils;
032import org.apache.oozie.util.XLog;
033
034/**
035 * Class used by SLAService to store SLA objects and perform calculations and
036 * sla decisions
037 */
038public class SLACalcStatus extends SLAEvent {
039
040    public static String SLA_ENTITYKEY_PREFIX = "sla-";
041    private SLARegistrationBean regBean;
042    private String jobStatus;
043    private SLAStatus slaStatus;
044    private EventStatus eventStatus;
045    private Date actualStart;
046    private Date actualEnd;
047    private long actualDuration = -1;
048    private Date lastModifiedTime;
049    private byte eventProcessed;
050    private LockToken lock;
051
052    private XLog LOG;
053
054    public SLACalcStatus(SLARegistrationBean reg) {
055        this();
056        setSLARegistrationBean(reg);
057        LOG = LogUtils.setLogPrefix(LOG, this);
058    }
059
060    public SLACalcStatus(SLASummaryBean summary, SLARegistrationBean regBean) {
061        this();
062        SLARegistrationBean reg = new SLARegistrationBean();
063        reg.setNotificationMsg(regBean.getNotificationMsg());
064        reg.setUpstreamApps(regBean.getUpstreamApps());
065        reg.setAlertContact(regBean.getAlertContact());
066        reg.setAlertEvents(regBean.getAlertEvents());
067        reg.setJobData(regBean.getJobData());
068        reg.setId(summary.getId());
069        reg.setAppType(summary.getAppType());
070        reg.setUser(summary.getUser());
071        reg.setAppName(summary.getAppName());
072        reg.setParentId(summary.getParentId());
073        reg.setNominalTime(summary.getNominalTime());
074        reg.setExpectedStart(summary.getExpectedStart());
075        reg.setExpectedEnd(summary.getExpectedEnd());
076        reg.setExpectedDuration(summary.getExpectedDuration());
077        setSLARegistrationBean(reg);
078        setActualStart(summary.getActualStart());
079        setActualEnd(summary.getActualEnd());
080        setActualDuration(summary.getActualDuration());
081        setSLAStatus(summary.getSLAStatus());
082        setJobStatus(summary.getJobStatus());
083        setEventStatus(summary.getEventStatus());
084        setLastModifiedTime(summary.getLastModifiedTime());
085        setEventProcessed(summary.getEventProcessed());
086        LOG = LogUtils.setLogPrefix(LOG, this);
087    }
088
089    /**
090     * copy constructor
091     * @return SLACalcStatus
092     */
093    public SLACalcStatus(SLACalcStatus a) {
094        this();
095        setSLARegistrationBean(a.getSLARegistrationBean());
096        setJobStatus(a.getJobStatus());
097        setSLAStatus(a.getSLAStatus());
098        setEventStatus(a.getEventStatus());
099        setActualStart(a.getActualStart());
100        setActualEnd(a.getActualEnd());
101        setActualDuration(a.getActualDuration());
102        setEventProcessed(a.getEventProcessed());
103        LOG = LogUtils.setLogPrefix(LOG, this);
104    }
105
106    public SLACalcStatus() {
107        setMsgType(MessageType.SLA);
108        setLastModifiedTime(new Date());
109        LOG = XLog.getLog(getClass());
110    }
111
112    public SLARegistrationBean getSLARegistrationBean() {
113        return regBean;
114    }
115
116    public void setSLARegistrationBean(SLARegistrationBean slaBean) {
117        this.regBean = slaBean;
118    }
119
120    @Override
121    public String getId() {
122        return regBean.getId();
123    }
124
125    public void setId(String id) {
126        regBean.setId(id);
127    }
128
129    @Override
130    public Date getActualStart() {
131        return actualStart;
132    }
133
134    public void setActualStart(Date actualStart) {
135        this.actualStart = actualStart;
136    }
137
138    @Override
139    public Date getActualEnd() {
140        return actualEnd;
141    }
142
143    public void setActualEnd(Date actualEnd) {
144        this.actualEnd = actualEnd;
145    }
146
147    @Override
148    public long getActualDuration() {
149        return actualDuration;
150    }
151
152    public void setActualDuration(long actualDuration) {
153        this.actualDuration = actualDuration;
154    }
155
156    @Override
157    public String getJobStatus() {
158        return jobStatus;
159    }
160
161    public void setJobStatus(String status) {
162        this.jobStatus = status;
163    }
164
165    @Override
166    public SLAStatus getSLAStatus() {
167        return slaStatus;
168    }
169
170    public void setSLAStatus(SLAStatus slaStatus) {
171        this.slaStatus = slaStatus;
172    }
173
174    @Override
175    public EventStatus getEventStatus() {
176        return eventStatus;
177    }
178
179    public void setEventStatus(EventStatus es) {
180        this.eventStatus = es;
181    }
182
183    public void setLastModifiedTime(Date lastModifiedTime) {
184        this.lastModifiedTime = lastModifiedTime;
185    }
186
187    /**
188     * Get which type of sla event has been processed needed when calculator
189     * periodically loops to update all jobs' sla
190     *
191     * @return byte 1st bit set (from LSB) = start processed
192     * 2nd bit set = duration processed
193     * 3rd bit set = end processed
194     * only 4th bit set = everything processed
195     */
196    public byte getEventProcessed() {
197        return eventProcessed;
198    }
199
200    public void setEventProcessed(int eventProcessed) {
201        this.eventProcessed = (byte) eventProcessed;
202    }
203
204    @Override
205    public String getParentId() {
206        return regBean.getParentId();
207    }
208
209    @Override
210    public AppType getAppType() {
211        return regBean.getAppType();
212    }
213
214    @Override
215    public String getAppName() {
216        return regBean.getAppName();
217    }
218
219    @Override
220    public Date getNominalTime() {
221        return regBean.getNominalTime();
222    }
223
224    @Override
225    public Date getExpectedStart() {
226        return regBean.getExpectedStart();
227    }
228
229    @Override
230    public Date getExpectedEnd() {
231        return regBean.getExpectedEnd();
232    }
233
234    @Override
235    public long getExpectedDuration() {
236        return regBean.getExpectedDuration();
237    }
238
239    @Override
240    public String getNotificationMsg() {
241        return regBean.getNotificationMsg();
242    }
243
244    @Override
245    public String getAlertEvents() {
246        return regBean.getAlertEvents();
247    }
248
249    @Override
250    public String getAlertContact() {
251        return regBean.getAlertContact();
252    }
253
254    @Override
255    public String getUpstreamApps() {
256        return regBean.getUpstreamApps();
257    }
258
259    @Override
260    public String getJobData() {
261        return regBean.getJobData();
262    }
263
264    @Override
265    public String getUser() {
266        return regBean.getUser();
267    }
268
269    @Override
270    public String getSlaConfig() {
271        return regBean.getSlaConfig();
272    }
273
274    @Override
275    public MessageType getMsgType() {
276        return regBean.getMsgType();
277    }
278
279    @Override
280    public Date getLastModifiedTime() {
281        return lastModifiedTime;
282    }
283
284    public String getEntityKey() {
285        return SLA_ENTITYKEY_PREFIX + this.getId();
286    }
287    /**
288     * Obtain an exclusive lock on the {link #getEntityKey}.
289     * <p/>
290     * A timeout of {link #getLockTimeOut} is used when trying to obtain the lock.
291     *
292     * @throws InterruptedException thrown if an interruption happened while trying to obtain the lock
293     */
294    public void acquireLock() throws InterruptedException {
295        // only get ZK lock when multiple servers running
296        if (Services.get().get(JobsConcurrencyService.class).isHighlyAvailableMode()) {
297            lock = Services.get().get(MemoryLocksService.class).getWriteLock(getEntityKey(), getLockTimeOut());
298            if (lock == null) {
299            LOG.debug("Could not aquire lock for [{0}]", getEntityKey());
300            }
301            else {
302                LOG.debug("Acquired lock for [{0}]", getEntityKey());
303            }
304        }
305        else {
306            lock = new DummyToken();
307        }
308    }
309
310    private static class DummyToken implements LockToken {
311        @Override
312        public void release() {
313        }
314    }
315
316    public boolean isLocked() {
317        boolean locked = false;
318        if(lock != null) {
319            locked = true;
320        }
321        return locked;
322    }
323
324    public void releaseLock(){
325        if (lock != null) {
326            lock.release();
327            lock = null;
328            LOG.debug("Released lock for [{0}]", getEntityKey());
329        }
330    }
331
332    public long getLockTimeOut() {
333        return Services.get().getConf().getLong(SLAService.CONF_SLA_CALC_LOCK_TIMEOUT, 5 * 1000);
334    }
335
336}