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.command.coord;
016    
017    import java.io.IOException;
018    import java.io.StringReader;
019    import java.net.HttpURLConnection;
020    import java.net.URL;
021    
022    import org.apache.hadoop.conf.Configuration;
023    import org.apache.oozie.CoordinatorActionBean;
024    import org.apache.oozie.ErrorCode;
025    import org.apache.oozie.client.OozieClient;
026    import org.apache.oozie.command.CommandException;
027    import org.apache.oozie.store.CoordinatorStore;
028    import org.apache.oozie.store.StoreException;
029    import org.apache.oozie.util.XConfiguration;
030    import org.apache.oozie.util.XLog;
031    
032    public class CoordActionNotification extends CoordinatorCommand<Void> {
033    
034        private CoordinatorActionBean actionBean;
035        private static final String STATUS_PATTERN = "\\$status";
036        private static final String ACTION_ID_PATTERN = "\\$actionId";
037    
038        private int retries = 0;
039        private final XLog log = XLog.getLog(getClass());
040    
041            public CoordActionNotification(CoordinatorActionBean actionBean) {
042                    super("coord_action_notification", "coord_action_notification", 0,
043                                    XLog.STD);
044                    this.actionBean = actionBean;
045            }
046    
047        @Override
048        protected Void call(CoordinatorStore store) throws StoreException,
049                CommandException {
050            setLogInfo(actionBean);
051            log.info("STARTED Coordinator Notification actionId="
052                    + actionBean.getId() + " : " + actionBean.getStatus());
053            Configuration conf;
054            try {
055                conf = new XConfiguration(new StringReader(actionBean.getRunConf()));
056            }
057            catch (IOException e1) {
058                log.warn("Configuration parse error. read from DB :"
059                        + actionBean.getRunConf());
060                throw new CommandException(ErrorCode.E1005, e1.getMessage(), e1);
061            }
062            String url = conf.get(OozieClient.COORD_ACTION_NOTIFICATION_URL);
063            if (url != null) {
064                url = url.replaceAll(ACTION_ID_PATTERN, actionBean.getId());
065                url = url.replaceAll(STATUS_PATTERN, actionBean.getStatus()
066                        .toString());
067                log.debug("Notification URL :" + url);
068                try {
069                    URL urlObj = new URL(url);
070                    HttpURLConnection urlConn = (HttpURLConnection) urlObj
071                            .openConnection();
072                    if (urlConn.getResponseCode() != HttpURLConnection.HTTP_OK) {
073                        handleRetry(url);
074                    }
075                }
076                catch (IOException ex) {
077                    handleRetry(url);
078                }
079            }
080            else {
081                log
082                        .info("No Notification URL is defined. Therefore nothing to notify for job "
083                                + actionBean.getJobId()
084                                + " action ID "
085                                + actionBean.getId());
086                // System.out.println("No Notification URL is defined. Therefore nothing is notified");
087            }
088            log.info("ENDED Coordinator Notification actionId="
089                    + actionBean.getId());
090            return null;
091        }
092    
093        private void handleRetry(String url) {
094            if (retries < 3) {
095                retries++;
096                queueCallable(this, 60 * 1000);
097            }
098            else {
099                XLog.getLog(getClass()).warn(XLog.OPS,
100                                             "could not send notification [{0}]", url);
101            }
102        }
103    
104    }