001    /**
002     * Copyright (c) 2010 Yahoo! Inc. All rights reserved.
003     * Licensed under the Apache License, Version 2.0 (the "License");
004     * you may not use this file except in compliance with the License.
005     * You may obtain a copy of the License at
006     *
007     *   http://www.apache.org/licenses/LICENSE-2.0
008     *
009     *  Unless required by applicable law or agreed to in writing, software
010     *  distributed under the License is distributed on an "AS IS" BASIS,
011     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012     *  See the License for the specific language governing permissions and
013     *  limitations under the License. See accompanying LICENSE file.
014     */
015    package org.apache.oozie.util.db;
016    
017    import java.util.Date;
018    
019    import org.apache.oozie.ErrorCode;
020    import org.apache.oozie.SLAEventBean;
021    import org.apache.oozie.client.SLAEvent.SlaAppType;
022    import org.apache.oozie.client.SLAEvent.Status;
023    import org.apache.oozie.command.CommandException;
024    import org.apache.oozie.executor.jpa.SLAEventInsertJPAExecutor;
025    import org.apache.oozie.service.JPAService;
026    import org.apache.oozie.service.Services;
027    import org.apache.oozie.util.DateUtils;
028    import org.jdom.Element;
029    
030    public class SLADbXOperations {
031        public static final String CLIENT_ID_TAG = "oozie:sla:client-id";
032    
033        /**
034         * Create SLA registration event
035         *
036         * @param eSla SLA xml element
037         * @param slaId SLA Id
038         * @param appType SLA app type
039         * @param user user name
040         * @param groupName group name
041         * @throws Exception
042         */
043        public static void writeSlaRegistrationEvent(Element eSla, String slaId,
044                                                     SlaAppType appType, String user, String groupName)
045                throws Exception {
046            if (eSla == null) {
047                return;
048            }
049            SLAEventBean sla = new SLAEventBean();
050            // sla.setClientId(getTagElement( eSla, "client-id"));
051            // sla.setClientId(getClientId());
052            sla.setAppName(getTagElement(eSla, "app-name"));
053            sla.setParentClientId(getTagElement(eSla, "parent-child-id"));
054            sla.setParentSlaId(getTagElement(eSla, "parent-sla-id"));
055            String strNominalTime = getTagElement(eSla, "nominal-time");
056            if (strNominalTime == null || strNominalTime.length() == 0) {
057                throw new CommandException(ErrorCode.E1101);
058            }
059            Date nominalTime = DateUtils.parseDateUTC(strNominalTime);
060            // Setting expected start time
061            String strRelExpectedStart = getTagElement(eSla, "should-start");
062            if (strRelExpectedStart == null || strRelExpectedStart.length() == 0) {
063                throw new CommandException(ErrorCode.E1102);
064            }
065            int relExpectedStart = Integer.parseInt(strRelExpectedStart);
066            if (relExpectedStart < 0) {
067                sla.setExpectedStart(null);
068            }
069            else {
070                Date expectedStart = new Date(nominalTime.getTime()
071                        + relExpectedStart * 60 * 1000);
072                sla.setExpectedStart(expectedStart);
073            }
074    
075            // Setting expected end time
076            String strRelExpectedEnd = getTagElement(eSla, "should-end");
077            if (strRelExpectedEnd == null || strRelExpectedEnd.length() == 0) {
078                throw new RuntimeException("should-end can't be empty");
079            }
080            int relExpectedEnd = Integer.parseInt(strRelExpectedEnd);
081            if (relExpectedEnd < 0) {
082                sla.setExpectedEnd(null);
083            }
084            else {
085                Date expectedEnd = new Date(nominalTime.getTime() + relExpectedEnd * 60 * 1000);
086                sla.setExpectedEnd(expectedEnd);
087            }
088    
089            sla.setNotificationMsg(getTagElement(eSla, "notification-msg"));
090            sla.setAlertContact(getTagElement(eSla, "alert-contact"));
091            sla.setDevContact(getTagElement(eSla, "dev-contact"));
092            sla.setQaContact(getTagElement(eSla, "qa-contact"));
093            sla.setSeContact(getTagElement(eSla, "se-contact"));
094            sla.setAlertFrequency(getTagElement(eSla, "alert-frequency"));
095            sla.setAlertPercentage(getTagElement(eSla, "alert-percentage"));
096    
097            sla.setUpstreamApps(getTagElement(eSla, "upstream-apps"));
098    
099            // Oozie defined
100            sla.setSlaId(slaId);
101            sla.setAppType(appType);
102            sla.setUser(user);
103            sla.setGroupName(groupName);
104            sla.setJobStatus(Status.CREATED);
105            sla.setStatusTimestamp(new Date());
106    
107            JPAService jpaService = Services.get().get(JPAService.class);
108    
109            if (jpaService != null) {
110                jpaService.execute(new SLAEventInsertJPAExecutor(sla));
111            }
112            else {
113                throw new CommandException(ErrorCode.E0610, "unable to write sla event.");
114            }
115    
116        }
117    
118        /**
119         * Create SLA status event
120         *
121         * @param id SLA Id
122         * @param status SLA status
123         * @param appType SLA app type
124         * @throws Exception
125         */
126        public static void writeSlaStatusEvent(String id,
127                                               Status status, SlaAppType appType) throws Exception {
128            SLAEventBean sla = new SLAEventBean();
129            sla.setSlaId(id);
130            sla.setJobStatus(status);
131            sla.setAppType(appType);
132            sla.setStatusTimestamp(new Date());
133    
134            JPAService jpaService = Services.get().get(JPAService.class);
135    
136            if (jpaService != null) {
137                jpaService.execute(new SLAEventInsertJPAExecutor(sla));
138            }
139            else {
140                throw new CommandException(ErrorCode.E0610, "unable to write sla event.");
141            }
142        }
143    
144        /**
145         * Create SLA status event
146         *
147         * @param slaXml SLA xml element
148         * @param id SLA Id
149         * @param stat SLA status
150         * @param appType SLA app type
151         * @throws CommandException
152         */
153        public static void writeStausEvent(String slaXml, String id, Status stat,
154                                           SlaAppType appType) throws CommandException {
155            if (slaXml == null || slaXml.length() == 0) {
156                return;
157            }
158            try {
159                writeSlaStatusEvent(id, stat, appType);
160            }
161            catch (Exception e) {
162                throw new CommandException(ErrorCode.E1007, " id " + id, e);
163            }
164        }
165    
166        /**
167         * Return client id
168         *
169         * @return client id
170         */
171        public static String getClientId() {
172            Services services = Services.get();
173            if (services == null) {
174                throw new RuntimeException("Services is not initialized");
175            }
176            String clientId = services.getConf().get(CLIENT_ID_TAG,
177                                                     "oozie-default-instance"); // TODO remove default
178            if (clientId == null) {
179                throw new RuntimeException(
180                        "No SLA_CLIENT_ID defined in oozie-site.xml with property name "
181                                + CLIENT_ID_TAG);
182            }
183            return clientId;
184        }
185    
186        private static String getTagElement(Element elem, String tagName) {
187            if (elem != null
188                    && elem.getChild(tagName, elem.getNamespace("sla")) != null) {
189                return elem.getChild(tagName, elem.getNamespace("sla")).getText()
190                        .trim();
191            }
192            else {
193                return null;
194            }
195        }
196    
197    }