blob: 83421892cb36d3cca042c567648f67f4da302cbb [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.oozie.sla;
import java.text.ParseException;
import java.util.Date;
import org.apache.oozie.AppType;
import org.apache.oozie.ErrorCode;
import org.apache.oozie.client.OozieClient;
import org.apache.oozie.client.event.SLAEvent.EventStatus;
import org.apache.oozie.command.CommandException;
import org.apache.oozie.executor.jpa.JPAExecutorException;
import org.apache.oozie.executor.jpa.SLARegistrationQueryExecutor;
import org.apache.oozie.executor.jpa.SLARegistrationQueryExecutor.SLARegQuery;
import org.apache.oozie.service.ServiceException;
import org.apache.oozie.service.Services;
import org.apache.oozie.sla.service.SLAService;
import org.apache.oozie.util.DateUtils;
import org.apache.oozie.util.XLog;
import org.apache.oozie.util.XmlUtils;
import org.jdom.Element;
public class SLAOperations {
public static final String NOMINAL_TIME = "nominal-time";
public static final String SHOULD_START = "should-start";
public static final String SHOULD_END = "should-end";
public static final String MAX_DURATION = "max-duration";
public static final String ALERT_EVENTS = "alert-events";
public static final String ALL_VALUE = "ALL";
static public XLog LOG = XLog.getLog(SLAOperations.class);
public static SLARegistrationBean createSlaRegistrationEvent(Element eSla, String jobId, String parentId,
AppType appType, String user, String appName, XLog log, boolean rerun, boolean disableAlert)
throws CommandException {
if (eSla == null || !SLAService.isEnabled()) {
log.debug("Not registering SLA for job [{0}]. Sla-Xml null OR SLAService not enabled", jobId);
return null;
}
SLARegistrationBean sla = new SLARegistrationBean();
// Setting nominal time
String strNominalTime = getTagElement(eSla, NOMINAL_TIME);
Date nominalTime = setNominalTime(strNominalTime, sla);
// Setting expected start time
String strExpectedStart = getTagElement(eSla, SHOULD_START);
setExpectedStart(strExpectedStart, nominalTime, sla);
// Setting expected end time
String strExpectedEnd = getTagElement(eSla, SHOULD_END);
setExpectedEnd(strExpectedEnd, nominalTime, sla);
// Setting expected duration in milliseconds
String expectedDurationStr = getTagElement(eSla, MAX_DURATION);
setExpectedDuration(expectedDurationStr, sla);
// Parse desired alert-types i.e. start-miss, end-miss, start-met etc..
String alertEvents = getTagElement(eSla, ALERT_EVENTS);
if (alertEvents != null) {
String events[] = alertEvents.split(",");
StringBuilder alertsStr = new StringBuilder();
for (int i = 0; i < events.length; i++) {
String event = events[i].trim().toUpperCase();
try {
EventStatus.valueOf(event);
}
catch (IllegalArgumentException iae) {
XLog.getLog(SLAService.class).warn(
"Invalid value: [" + event + "]" + " for SLA Alert-event. Should be one of "
+ EventStatus.values() + ". Setting it to default [" + EventStatus.END_MISS.name()
+ "]");
event = EventStatus.END_MISS.name();
}
alertsStr.append(event).append(",");
}
sla.setAlertEvents(alertsStr.toString().substring(0, alertsStr.lastIndexOf(",")));
}
// Other sla config
sla.setNotificationMsg(getTagElement(eSla, "notification-msg"));
sla.setAlertContact(getTagElement(eSla, "alert-contact"));
sla.setUpstreamApps(getTagElement(eSla, "upstream-apps"));
//disable Alert flag in slaConfig
if (disableAlert) {
sla.addToSLAConfigMap(OozieClient.SLA_DISABLE_ALERT, Boolean.toString(disableAlert));
}
// Oozie defined
sla.setId(jobId);
sla.setAppType(appType);
sla.setAppName(appName);
sla.setUser(user);
sla.setParentId(parentId);
SLAService slaService = Services.get().get(SLAService.class);
try {
if (!rerun) {
slaService.addRegistrationEvent(sla);
}
else {
slaService.updateRegistrationEvent(sla);
}
}
catch (ServiceException e) {
throw new CommandException(ErrorCode.E1007, " id " + jobId, e.getMessage(), e);
}
log.debug("Job [{0}] reg for SLA. Size of Sla Xml = [{1}]", jobId, XmlUtils.prettyPrint(eSla).toString().length());
return sla;
}
public static Date setNominalTime(String strNominalTime, SLARegistrationBean sla) throws CommandException {
if (strNominalTime == null || strNominalTime.length() == 0) {
return sla.getNominalTime();
}
Date nominalTime;
try {
nominalTime = DateUtils.parseDateOozieTZ(strNominalTime);
sla.setNominalTime(nominalTime);
}
catch (ParseException pex) {
throw new CommandException(ErrorCode.E0302, strNominalTime, pex);
}
return nominalTime;
}
public static void setExpectedStart(String strExpectedStart, Date nominalTime, SLARegistrationBean sla)
throws CommandException {
if (strExpectedStart != null) {
float expectedStart = Float.parseFloat(strExpectedStart);
if (expectedStart < 0) {
throw new CommandException(ErrorCode.E0302, strExpectedStart, "for SLA Expected start time");
}
else {
Date expectedStartTime = new Date(nominalTime.getTime() + (long) (expectedStart * 60 * 1000));
sla.setExpectedStart(expectedStartTime);
LOG.debug("Setting expected start to " + expectedStartTime + " for job " + sla.getId());
}
}
}
public static void setExpectedEnd(String strExpectedEnd, Date nominalTime, SLARegistrationBean sla)
throws CommandException {
if (strExpectedEnd != null) {
float expectedEnd = Float.parseFloat(strExpectedEnd);
if (expectedEnd < 0) {
throw new CommandException(ErrorCode.E0302, strExpectedEnd, "for SLA Expected end time");
}
else {
Date expectedEndTime = new Date(nominalTime.getTime() + (long) (expectedEnd * 60 * 1000));
sla.setExpectedEnd(expectedEndTime);
LOG.debug("Setting expected end to " + expectedEndTime + " for job " + sla.getId());
}
}
}
public static void setExpectedDuration(String expectedDurationStr, SLARegistrationBean sla) {
if (expectedDurationStr != null && expectedDurationStr.length() > 0) {
float expectedDuration = Float.parseFloat(expectedDurationStr);
if (expectedDuration > 0) {
long duration = (long) (expectedDuration * 60 * 1000);
LOG.debug("Setting expected duration to " + duration + " for job " + sla.getId());
sla.setExpectedDuration(duration);
}
}
else if (sla.getExpectedStart() != null) {
long duration = sla.getExpectedEnd().getTime() - sla.getExpectedStart().getTime();
LOG.debug("Setting expected duration to " + duration + " for job " + sla.getId());
sla.setExpectedDuration(sla.getExpectedEnd().getTime() - sla.getExpectedStart().getTime());
}
}
/**
* Retrieve registration event
* @param jobId the jobId
* @throws CommandException update failure
* @throws JPAExecutorException if JPA related issue occurs
*/
public static void updateRegistrationEvent(String jobId) throws CommandException, JPAExecutorException {
SLAService slaService = Services.get().get(SLAService.class);
try {
SLARegistrationBean reg = SLARegistrationQueryExecutor.getInstance().get(SLARegQuery.GET_SLA_REG_ALL, jobId);
if (reg != null) { //handle coord rerun with different config without sla
slaService.updateRegistrationEvent(reg);
}
}
catch (ServiceException e) {
throw new CommandException(ErrorCode.E1007, " id " + jobId, e.getMessage(), e);
}
}
/*
* parentId null
*/
public static SLARegistrationBean createSlaRegistrationEvent(Element eSla, String jobId, AppType appType,
String user, String appName, XLog log) throws CommandException {
return createSlaRegistrationEvent(eSla, jobId, null, appType, user, appName, log, false);
}
/*
* appName null
*/
public static SLARegistrationBean createSlaRegistrationEvent(Element eSla, String jobId, String parentId,
AppType appType, String user, XLog log) throws CommandException {
return createSlaRegistrationEvent(eSla, jobId, parentId, appType, user, null, log, false);
}
/*
* parentId + appName null
*/
public static SLARegistrationBean createSlaRegistrationEvent(Element eSla, String jobId, AppType appType,
String user, XLog log) throws CommandException {
return createSlaRegistrationEvent(eSla, jobId, null, appType, user, null, log, false);
}
/*
* default disableAlert flag
*/
public static SLARegistrationBean createSlaRegistrationEvent(Element eSla, String jobId, String parentId,
AppType appType, String user, String appName, XLog log, boolean rerun) throws CommandException {
return createSlaRegistrationEvent(eSla, jobId, null, appType, user, appName, log, rerun, false);
}
public static String getTagElement(Element elem, String tagName) {
if (elem != null && elem.getChild(tagName, elem.getNamespace("sla")) != null) {
return elem.getChild(tagName, elem.getNamespace("sla")).getText().trim();
}
else {
return null;
}
}
}