This project has retired. For details please refer to its
Attic page.
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.text.ParseException;
021 import java.util.Date;
022 import org.apache.oozie.AppType;
023 import org.apache.oozie.ErrorCode;
024 import org.apache.oozie.client.event.SLAEvent.EventStatus;
025 import org.apache.oozie.command.CommandException;
026 import org.apache.oozie.executor.jpa.JPAExecutorException;
027 import org.apache.oozie.executor.jpa.sla.SLARegistrationGetJPAExecutor;
028 import org.apache.oozie.service.JPAService;
029 import org.apache.oozie.service.ServiceException;
030 import org.apache.oozie.service.Services;
031 import org.apache.oozie.sla.SLARegistrationBean;
032 import org.apache.oozie.sla.service.SLAService;
033 import org.apache.oozie.util.DateUtils;
034 import org.apache.oozie.util.XLog;
035 import org.apache.oozie.util.XmlUtils;
036 import org.jdom.Element;
037
038 public class SLAOperations {
039
040 private static final String NOMINAL_TIME = "nominal-time";
041 private static final String SHOULD_START = "should-start";
042 private static final String SHOULD_END = "should-end";
043 private static final String MAX_DURATION = "max-duration";
044 private static final String ALERT_EVENTS = "alert-events";
045
046 public static SLARegistrationBean createSlaRegistrationEvent(Element eSla, String jobId, String parentId,
047 AppType appType, String user, String appName, XLog log, boolean rerun) throws CommandException {
048 if (eSla == null || !SLAService.isEnabled()) {
049 log.debug("Not registering SLA for job [{0}]. Sla-Xml null OR SLAService not enabled", jobId);
050 return null;
051 }
052 SLARegistrationBean sla = new SLARegistrationBean();
053
054 // Setting nominal time
055 String strNominalTime = getTagElement(eSla, NOMINAL_TIME);
056 if (strNominalTime == null || strNominalTime.length() == 0) {
057 throw new CommandException(ErrorCode.E1101, NOMINAL_TIME);
058 }
059 Date nominalTime;
060 try {
061 nominalTime = DateUtils.parseDateOozieTZ(strNominalTime);
062 sla.setNominalTime(nominalTime);
063 }
064 catch (ParseException pex) {
065 throw new CommandException(ErrorCode.E0302, strNominalTime, pex);
066 }
067
068 // Setting expected start time
069 String strExpectedStart = getTagElement(eSla, SHOULD_START);
070 if (strExpectedStart != null) {
071 float expectedStart = Float.parseFloat(strExpectedStart);
072 if (expectedStart < 0) {
073 throw new CommandException(ErrorCode.E0302, strExpectedStart, "for SLA Expected start time");
074 }
075 else {
076 Date expectedStartTime = new Date(nominalTime.getTime() + (long) (expectedStart * 60 * 1000));
077 sla.setExpectedStart(expectedStartTime);
078 }
079 }
080
081 // Setting expected end time
082 String strExpectedEnd = getTagElement(eSla, SHOULD_END);
083 if (strExpectedEnd == null || strExpectedEnd.length() == 0) {
084 throw new CommandException(ErrorCode.E1101, SHOULD_END);
085 }
086 float expectedEnd = Float.parseFloat(strExpectedEnd);
087 if (expectedEnd < 0) {
088 throw new CommandException(ErrorCode.E0302, strExpectedEnd, "for SLA Expected end time");
089 }
090 else {
091 Date expectedEndTime = new Date(nominalTime.getTime() + (long) (expectedEnd * 60 * 1000));
092 sla.setExpectedEnd(expectedEndTime);
093 }
094
095 // Setting expected duration in milliseconds
096 String expectedDurationStr = getTagElement(eSla, MAX_DURATION);
097 if (expectedDurationStr != null && expectedDurationStr.length() > 0) {
098 float expectedDuration = Float.parseFloat(expectedDurationStr);
099 if (expectedDuration > 0) {
100 sla.setExpectedDuration((long) (expectedDuration * 60 * 1000));
101 }
102 }
103 else if (sla.getExpectedStart() != null) {
104 sla.setExpectedDuration(sla.getExpectedEnd().getTime() - sla.getExpectedStart().getTime());
105 }
106
107 // Parse desired alert-types i.e. start-miss, end-miss, start-met etc..
108 String alertEvents = getTagElement(eSla, ALERT_EVENTS);
109 if (alertEvents != null) {
110 String events[] = alertEvents.split(",");
111 StringBuilder alertsStr = new StringBuilder();
112 for (int i = 0; i < events.length; i++) {
113 String event = events[i].trim().toUpperCase();
114 try {
115 EventStatus.valueOf(event);
116 }
117 catch (IllegalArgumentException iae) {
118 XLog.getLog(SLAService.class).warn(
119 "Invalid value: [" + event + "]" + " for SLA Alert-event. Should be one of "
120 + EventStatus.values() + ". Setting it to default [" + EventStatus.END_MISS.name()
121 + "]");
122 event = EventStatus.END_MISS.name();
123 }
124 alertsStr.append(event).append(",");
125 }
126 sla.setAlertEvents(alertsStr.toString().substring(0, alertsStr.lastIndexOf(",")));
127 }
128
129 // Other sla config
130 sla.setNotificationMsg(getTagElement(eSla, "notification-msg"));
131 sla.setAlertContact(getTagElement(eSla, "alert-contact"));
132 sla.setUpstreamApps(getTagElement(eSla, "upstream-apps"));
133
134 // Oozie defined
135 sla.setId(jobId);
136 sla.setAppType(appType);
137 sla.setAppName(appName);
138 sla.setUser(user);
139 sla.setParentId(parentId);
140
141 SLAService slaService = Services.get().get(SLAService.class);
142 try {
143 if (!rerun) {
144 slaService.addRegistrationEvent(sla);
145 }
146 else {
147 slaService.updateRegistrationEvent(sla);
148 }
149 }
150 catch (ServiceException e) {
151 throw new CommandException(ErrorCode.E1007, " id " + jobId, e.getMessage(), e);
152 }
153
154 log.debug("Job [{0}] reg for SLA. Size of Sla Xml = [{1}]", jobId, XmlUtils.prettyPrint(eSla).toString().length());
155 return sla;
156 }
157
158 /**
159 * Retrieve registration event
160 * @param jobId the jobId
161 * @throws CommandException
162 * @throws JPAExecutorException
163 */
164 public static void updateRegistrationEvent(String jobId) throws CommandException, JPAExecutorException {
165 JPAService jpaService = Services.get().get(JPAService.class);
166 SLAService slaService = Services.get().get(SLAService.class);
167 try {
168 SLARegistrationBean reg = jpaService.execute(new SLARegistrationGetJPAExecutor(jobId));
169 if (reg != null) { //handle coord rerun with different config without sla
170 slaService.updateRegistrationEvent(reg);
171 }
172 }
173 catch (ServiceException e) {
174 throw new CommandException(ErrorCode.E1007, " id " + jobId, e.getMessage(), e);
175 }
176
177 }
178
179 /*
180 * parentId null
181 */
182 public static SLARegistrationBean createSlaRegistrationEvent(Element eSla, String jobId, AppType appType,
183 String user, String appName, XLog log) throws CommandException {
184 return createSlaRegistrationEvent(eSla, jobId, null, appType, user, appName, log, false);
185 }
186
187 /*
188 * appName null
189 */
190 public static SLARegistrationBean createSlaRegistrationEvent(Element eSla, String jobId, String parentId,
191 AppType appType, String user, XLog log) throws CommandException {
192 return createSlaRegistrationEvent(eSla, jobId, parentId, appType, user, null, log, false);
193 }
194
195 /*
196 * parentId + appName null
197 */
198 public static SLARegistrationBean createSlaRegistrationEvent(Element eSla, String jobId, AppType appType,
199 String user, XLog log) throws CommandException {
200 return createSlaRegistrationEvent(eSla, jobId, null, appType, user, null, log, false);
201 }
202
203 private static String getTagElement(Element elem, String tagName) {
204 if (elem != null && elem.getChild(tagName, elem.getNamespace("sla")) != null) {
205 return elem.getChild(tagName, elem.getNamespace("sla")).getText().trim();
206 }
207 else {
208 return null;
209 }
210 }
211
212 }