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