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