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.sql.Timestamp;
022import java.util.Date;
023import java.util.List;
024
025import javax.persistence.Basic;
026import javax.persistence.Column;
027import javax.persistence.Entity;
028import javax.persistence.Id;
029import javax.persistence.NamedQueries;
030import javax.persistence.NamedQuery;
031import javax.persistence.Table;
032
033import org.apache.oozie.AppType;
034import org.apache.oozie.client.event.SLAEvent;
035import org.apache.oozie.client.rest.JsonBean;
036import org.apache.oozie.client.rest.JsonTags;
037import org.apache.oozie.client.rest.JsonUtils;
038import org.apache.oozie.util.DateUtils;
039import org.apache.openjpa.persistence.jdbc.Index;
040import org.json.simple.JSONArray;
041import org.json.simple.JSONObject;
042
043@Entity
044@Table(name = "SLA_SUMMARY")
045@NamedQueries({
046
047 @NamedQuery(name = "UPDATE_SLA_SUMMARY_FOR_SLA_STATUS", query = "update  SLASummaryBean w set w.slaStatus = :slaStatus, w.eventStatus = :eventStatus, w.eventProcessed = :eventProcessed, w.lastModifiedTS = :lastModifiedTS where w.jobId = :jobId"),
048
049 @NamedQuery(name = "UPDATE_SLA_SUMMARY_FOR_STATUS_ACTUAL_TIMES", query = "update SLASummaryBean w set w.slaStatus = :slaStatus, w.eventStatus = :eventStatus, w.eventProcessed = :eventProcessed, w.jobStatus = :jobStatus, w.lastModifiedTS = :lastModifiedTS, w.actualStartTS = :actualStartTS, w.actualEndTS = :actualEndTS, w.actualDuration = :actualDuration where w.jobId = :jobId"),
050
051 @NamedQuery(name = "UPDATE_SLA_SUMMARY_FOR_ACTUAL_TIMES", query = "update SLASummaryBean w set w.eventProcessed = :eventProcessed, w.actualStartTS = :actualStartTS, w.actualEndTS = :actualEndTS, w.actualEndTS = :actualEndTS, w.actualDuration = :actualDuration, w.lastModifiedTS = :lastModifiedTS where w.jobId = :jobId"),
052
053 @NamedQuery(name = "UPDATE_SLA_SUMMARY_EVENTPROCESSED", query = "update SLASummaryBean w set w.eventProcessed = :eventProcessed where w.jobId = :jobId"),
054
055 @NamedQuery(name = "UPDATE_SLA_SUMMARY_ALL", query = "update SLASummaryBean w set w.jobId = :jobId, w.appName = :appName, w.appType = :appType, w.nominalTimeTS = :nominalTime, w.expectedStartTS = :expectedStartTime, w.expectedEndTS = :expectedEndTime, w.expectedDuration = :expectedDuration, w.jobStatus = :jobStatus, w.slaStatus = :slaStatus, w.eventStatus = :eventStatus, w.lastModifiedTS = :lastModTime, w.user = :user, w.parentId = :parentId, w.eventProcessed = :eventProcessed, w.actualDuration = :actualDuration, w.actualEndTS = :actualEndTS, w.actualStartTS = :actualStartTS where w.jobId = :jobId"),
056
057 @NamedQuery(name = "GET_SLA_SUMMARY", query = "select OBJECT(w) from SLASummaryBean w where w.jobId = :id"),
058
059 @NamedQuery(name = "GET_SLA_SUMMARY_RECORDS_RESTART", query = "select OBJECT(w) from SLASummaryBean w where w.eventProcessed <= 7 AND w.lastModifiedTS >= :lastModifiedTime"),
060
061 @NamedQuery(name = "GET_SLA_SUMMARY_EVENTPROCESSED", query = "select w.eventProcessed from SLASummaryBean w where w.jobId = :id"),
062
063 @NamedQuery(name = "GET_SLA_SUMMARY_ALL", query = "select OBJECT(w) from SLASummaryBean w")
064})
065
066/**
067 * Class to store all the SLA related details (summary) per job
068 */
069public class SLASummaryBean implements JsonBean {
070
071    @Id
072    @Basic
073    @Column(name = "job_id")
074    private String jobId;
075
076    @Basic
077    @Index
078    @Column(name = "parent_id")
079    private String parentId;
080
081    @Basic
082    @Index
083    @Column(name = "app_name")
084    private String appName;
085
086    @Basic
087    @Column(name = "app_type")
088    private String appType;
089
090    @Basic
091    @Column(name = "user_name")
092    private String user;
093
094    @Basic
095    @Column(name = "created_time")
096    private Timestamp createdTimeTS = null;
097
098    @Basic
099    @Index
100    @Column(name = "nominal_time")
101    private Timestamp nominalTimeTS = null;
102
103    @Basic
104    @Column(name = "expected_start")
105    private Timestamp expectedStartTS = null;
106
107    @Basic
108    @Column(name = "expected_end")
109    private Timestamp expectedEndTS = null;
110
111    @Basic
112    @Column(name = "expected_duration")
113    private long expectedDuration = -1;
114
115    @Basic
116    @Column(name = "actual_start")
117    private Timestamp actualStartTS = null;
118
119    @Basic
120    @Column(name = "actual_end")
121    private Timestamp actualEndTS = null;
122
123    @Basic
124    @Column(name = "actual_duration")
125    private long actualDuration = -1;
126
127    @Basic
128    @Column(name = "job_status")
129    private String jobStatus;
130
131    @Basic
132    @Column(name = "event_status")
133    private String eventStatus;
134
135    @Basic
136    @Column(name = "sla_status")
137    private String slaStatus;
138
139    @Basic
140    @Index
141    @Column(name = "event_processed")
142    private byte eventProcessed = 0;
143
144    @Basic
145    @Index
146    @Column(name = "last_modified")
147    private Timestamp lastModifiedTS = null;
148
149    public SLASummaryBean() {
150    }
151
152    public SLASummaryBean(SLACalcStatus slaCalc) {
153        SLARegistrationBean reg = slaCalc.getSLARegistrationBean();
154        setId(slaCalc.getId());
155        setAppName(reg.getAppName());
156        setAppType(reg.getAppType());
157        setNominalTime(reg.getNominalTime());
158        setExpectedStart(reg.getExpectedStart());
159        setExpectedEnd(reg.getExpectedEnd());
160        setExpectedDuration(reg.getExpectedDuration());
161        setJobStatus(slaCalc.getJobStatus());
162        setSLAStatus(slaCalc.getSLAStatus());
163        setEventStatus(slaCalc.getEventStatus());
164        setLastModifiedTime(slaCalc.getLastModifiedTime());
165        setUser(reg.getUser());
166        setParentId(reg.getParentId());
167        setEventProcessed(slaCalc.getEventProcessed());
168        setActualDuration(slaCalc.getActualDuration());
169        setActualEnd(slaCalc.getActualEnd());
170        setActualStart(slaCalc.getActualStart());
171    }
172
173    public String getId() {
174        return jobId;
175    }
176
177    public void setId(String jobId) {
178        this.jobId = jobId;
179    }
180
181    public String getParentId() {
182        return parentId;
183    }
184
185    public void setParentId(String parentId) {
186        this.parentId = parentId;
187    }
188
189    public Timestamp getCreatedTimestamp() {
190        return createdTimeTS;
191    }
192
193    public void setCreatedTimestamp(Timestamp createdTime) {
194        this.createdTimeTS = createdTime;
195    }
196
197    public Date getCreatedTime() {
198        return DateUtils.toDate(createdTimeTS);
199    }
200
201    public void setCreatedTime(Date createdTime) {
202        this.createdTimeTS = DateUtils.convertDateToTimestamp(createdTime);
203    }
204
205    public Date getNominalTime() {
206        return DateUtils.toDate(nominalTimeTS);
207    }
208
209    public Timestamp getNominalTimestamp() {
210        return this.nominalTimeTS;
211    }
212
213    public void setNominalTime(Date nominalTime) {
214        this.nominalTimeTS = DateUtils.convertDateToTimestamp(nominalTime);
215    }
216
217
218    public Date getExpectedStart() {
219        return DateUtils.toDate(expectedStartTS);
220    }
221
222    public Timestamp getExpectedStartTimestamp() {
223        return this.expectedStartTS;
224    }
225
226    public void setExpectedStart(Date expectedStart) {
227        this.expectedStartTS = DateUtils.convertDateToTimestamp(expectedStart);
228    }
229
230    public Date getExpectedEnd() {
231        return DateUtils.toDate(expectedEndTS);
232    }
233
234    public Timestamp getExpectedEndTimestamp() {
235        return this.expectedEndTS;
236    }
237    public void setExpectedEnd(Date expectedEnd) {
238        this.expectedEndTS = DateUtils.convertDateToTimestamp(expectedEnd);
239    }
240
241    public long getExpectedDuration() {
242        return expectedDuration;
243    }
244
245    public void setExpectedDuration(long expectedDuration) {
246        this.expectedDuration = expectedDuration;
247    }
248
249    public Date getActualStart() {
250        return DateUtils.toDate(actualStartTS);
251    }
252
253    public Timestamp getActualStartTimestamp() {
254        return this.actualStartTS;
255    }
256
257    public void setActualStart(Date actualStart) {
258        this.actualStartTS = DateUtils.convertDateToTimestamp(actualStart);
259    }
260
261    public Date getActualEnd() {
262        return DateUtils.toDate(actualEndTS);
263    }
264
265    public Timestamp getActualEndTimestamp() {
266        return this.actualEndTS;
267    }
268
269    public void setActualEnd(Date actualEnd) {
270        this.actualEndTS = DateUtils.convertDateToTimestamp(actualEnd);
271    }
272
273    public long getActualDuration() {
274        return actualDuration;
275    }
276
277    public void setActualDuration(long actualDuration) {
278        this.actualDuration = actualDuration;
279    }
280
281    public String getJobStatus() {
282        return jobStatus;
283    }
284
285    public void setJobStatus(String status) {
286        this.jobStatus = status;
287    }
288
289    public SLAEvent.EventStatus getEventStatus() {
290        return (eventStatus != null ? SLAEvent.EventStatus.valueOf(eventStatus) : null);
291    }
292
293    public void setEventStatus(SLAEvent.EventStatus eventStatus) {
294        this.eventStatus = (eventStatus != null ? eventStatus.name() : null);
295    }
296
297    public SLAEvent.SLAStatus getSLAStatus() {
298        return (slaStatus != null ? SLAEvent.SLAStatus.valueOf(slaStatus) : null);
299    }
300
301    public String getSLAStatusString() {
302        return slaStatus;
303    }
304
305    public String getEventStatusString() {
306        return eventStatus;
307    }
308
309    public void setSLAStatus(SLAEvent.SLAStatus stage) {
310        this.slaStatus = (stage != null ? stage.name() : null);
311    }
312
313    public String getUser() {
314        return user;
315    }
316
317    public void setUser(String user) {
318        this.user = user;
319    }
320
321    public String getAppName() {
322        return appName;
323    }
324
325    public void setAppName(String appName) {
326        this.appName = appName;
327    }
328
329    public AppType getAppType() {
330        return AppType.valueOf(appType);
331    }
332
333    public void setAppType(AppType appType) {
334        this.appType = appType.toString();
335    }
336
337    public byte getEventProcessed() {
338        return eventProcessed;
339    }
340
341    public void setEventProcessed(int eventProcessed) {
342        this.eventProcessed = (byte)eventProcessed;
343    }
344
345    public Date getLastModifiedTime() {
346        return DateUtils.toDate(lastModifiedTS);
347    }
348
349    public Timestamp getLastModifiedTimestamp() {
350        return this.lastModifiedTS;
351    }
352
353    public void setLastModifiedTime(Date lastModified) {
354        this.lastModifiedTS = DateUtils.convertDateToTimestamp(lastModified);
355    }
356
357    @SuppressWarnings("unchecked")
358    @Override
359    public JSONObject toJSONObject() {
360        JSONObject json = new JSONObject();
361        json.put(JsonTags.SLA_SUMMARY_ID, jobId);
362        if (parentId != null) {
363            json.put(JsonTags.SLA_SUMMARY_PARENT_ID, parentId);
364        }
365        json.put(JsonTags.SLA_SUMMARY_APP_NAME, appName);
366        json.put(JsonTags.SLA_SUMMARY_APP_TYPE, appType);
367        json.put(JsonTags.SLA_SUMMARY_USER, user);
368        json.put(JsonTags.SLA_SUMMARY_NOMINAL_TIME, nominalTimeTS.getTime());
369        if (expectedStartTS != null) {
370            json.put(JsonTags.SLA_SUMMARY_EXPECTED_START, expectedStartTS.getTime());
371        }
372        else {
373            json.put(JsonTags.SLA_SUMMARY_EXPECTED_START, null);
374        }
375        if (actualStartTS != null) {
376            json.put(JsonTags.SLA_SUMMARY_ACTUAL_START, actualStartTS.getTime());
377        }
378        else {
379            json.put(JsonTags.SLA_SUMMARY_ACTUAL_START, null);
380        }
381        json.put(JsonTags.SLA_SUMMARY_EXPECTED_END, expectedEndTS.getTime());
382        if (actualEndTS != null) {
383            json.put(JsonTags.SLA_SUMMARY_ACTUAL_END, actualEndTS.getTime());
384        }
385        else {
386            json.put(JsonTags.SLA_SUMMARY_ACTUAL_END, null);
387        }
388        json.put(JsonTags.SLA_SUMMARY_EXPECTED_DURATION, expectedDuration);
389        json.put(JsonTags.SLA_SUMMARY_ACTUAL_DURATION, actualDuration);
390        json.put(JsonTags.SLA_SUMMARY_JOB_STATUS, jobStatus);
391        json.put(JsonTags.SLA_SUMMARY_SLA_STATUS, slaStatus);
392        json.put(JsonTags.SLA_SUMMARY_LAST_MODIFIED, lastModifiedTS.getTime());
393        return json;
394    }
395
396    @SuppressWarnings("unchecked")
397    @Override
398    public JSONObject toJSONObject(String timeZoneId) {
399        if (timeZoneId == null) {
400            return toJSONObject();
401        }
402        else {
403            JSONObject json = new JSONObject();
404            json.put(JsonTags.SLA_SUMMARY_ID, jobId);
405            if (parentId != null) {
406                json.put(JsonTags.SLA_SUMMARY_PARENT_ID, parentId);
407            }
408            json.put(JsonTags.SLA_SUMMARY_APP_NAME, appName);
409            json.put(JsonTags.SLA_SUMMARY_APP_TYPE, appType);
410            json.put(JsonTags.SLA_SUMMARY_USER, user);
411            json.put(JsonTags.SLA_SUMMARY_NOMINAL_TIME, JsonUtils.formatDateRfc822(nominalTimeTS, timeZoneId));
412            if (expectedStartTS != null) {
413                json.put(JsonTags.SLA_SUMMARY_EXPECTED_START, JsonUtils.formatDateRfc822(expectedStartTS, timeZoneId));
414            }
415            else {
416                json.put(JsonTags.SLA_SUMMARY_EXPECTED_START, null);
417            }
418            if (actualStartTS != null) {
419                json.put(JsonTags.SLA_SUMMARY_ACTUAL_START, JsonUtils.formatDateRfc822(actualStartTS, timeZoneId));
420            }
421            else {
422                json.put(JsonTags.SLA_SUMMARY_ACTUAL_START, null);
423            }
424            json.put(JsonTags.SLA_SUMMARY_EXPECTED_END, JsonUtils.formatDateRfc822(expectedEndTS, timeZoneId));
425            if (actualEndTS != null) {
426                json.put(JsonTags.SLA_SUMMARY_ACTUAL_END, JsonUtils.formatDateRfc822(actualEndTS, timeZoneId));
427            }
428            else {
429                json.put(JsonTags.SLA_SUMMARY_ACTUAL_END, null);
430            }
431            json.put(JsonTags.SLA_SUMMARY_EXPECTED_DURATION, expectedDuration);
432            json.put(JsonTags.SLA_SUMMARY_ACTUAL_DURATION, actualDuration);
433            json.put(JsonTags.SLA_SUMMARY_JOB_STATUS, jobStatus);
434            json.put(JsonTags.SLA_SUMMARY_SLA_STATUS, slaStatus);
435            json.put(JsonTags.SLA_SUMMARY_LAST_MODIFIED, JsonUtils.formatDateRfc822(lastModifiedTS, timeZoneId));
436            return json;
437        }
438    }
439
440    /**
441     * Convert a sla summary list into a json object.
442     *
443     * @param slaSummaryList sla summary list.
444     * @param timeZoneId time zone to use for dates in the JSON array.
445     * @return the corresponding JSON object.
446     */
447    @SuppressWarnings("unchecked")
448    public static JSONObject toJSONObject(List<? extends SLASummaryBean> slaSummaryList, String timeZoneId) {
449        JSONObject json = new JSONObject();
450        JSONArray array = new JSONArray();
451        if (slaSummaryList != null) {
452            for (SLASummaryBean summary : slaSummaryList) {
453                array.add(summary.toJSONObject(timeZoneId));
454            }
455        }
456        json.put(JsonTags.SLA_SUMMARY_LIST, array);
457        return json;
458    }
459
460}