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    package org.apache.oozie.sla;
019    
020    import java.sql.Timestamp;
021    import java.util.Date;
022    import java.util.List;
023    
024    import javax.persistence.Basic;
025    import javax.persistence.Column;
026    import javax.persistence.Entity;
027    import javax.persistence.Id;
028    import javax.persistence.NamedQueries;
029    import javax.persistence.NamedQuery;
030    import javax.persistence.Table;
031    
032    import org.apache.oozie.AppType;
033    import org.apache.oozie.client.event.SLAEvent;
034    import org.apache.oozie.client.rest.JsonBean;
035    import org.apache.oozie.client.rest.JsonTags;
036    import org.apache.oozie.client.rest.JsonUtils;
037    import org.apache.oozie.util.DateUtils;
038    import org.apache.openjpa.persistence.jdbc.Index;
039    import org.json.simple.JSONArray;
040    import 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     */
057    public 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    }