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 }