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.wf;
016    
017    import org.apache.oozie.client.OozieClient;
018    import org.apache.oozie.WorkflowActionBean;
019    import org.apache.oozie.WorkflowJobBean;
020    import org.apache.oozie.command.CommandException;
021    import org.apache.oozie.command.PreconditionException;
022    import org.apache.oozie.util.LogUtils;
023    import org.apache.oozie.util.ParamChecker;
024    import org.apache.oozie.util.XLog;
025    
026    import java.io.IOException;
027    import java.net.HttpURLConnection;
028    import java.net.URL;
029    
030    public class NotificationXCommand extends WorkflowXCommand<Void> {
031    
032        private static final String STATUS_PATTERN = "\\$status";
033        private static final String JOB_ID_PATTERN = "\\$jobId";
034        private static final String NODE_NAME_PATTERN = "\\$nodeName";
035    
036        private String url;
037        private int retries = 0;
038    
039        public NotificationXCommand(WorkflowJobBean workflow) {
040            super("job.notification", "job.notification", 0);
041            ParamChecker.notNull(workflow, "workflow");
042            LogUtils.setLogInfo(workflow, logInfo);
043            url = workflow.getWorkflowInstance().getConf().get(OozieClient.WORKFLOW_NOTIFICATION_URL);
044            if (url != null) {
045                url = url.replaceAll(JOB_ID_PATTERN, workflow.getId());
046                url = url.replaceAll(STATUS_PATTERN, workflow.getStatus().toString());
047            }
048        }
049    
050        public NotificationXCommand(WorkflowJobBean workflow, WorkflowActionBean action) {
051            super("action.notification", "job.notification", 0);
052            ParamChecker.notNull(workflow, "workflow");
053            ParamChecker.notNull(action, "action");
054            LogUtils.setLogInfo(workflow, logInfo);
055            LogUtils.setLogInfo(action, logInfo);
056            url = workflow.getWorkflowInstance().getConf().get(OozieClient.ACTION_NOTIFICATION_URL);
057            if (url != null) {
058                url = url.replaceAll(JOB_ID_PATTERN, workflow.getId());
059                url = url.replaceAll(NODE_NAME_PATTERN, action.getName());
060                if (action.isComplete()) {
061                    url = url.replaceAll(STATUS_PATTERN, "T:" + action.getTransition());
062                }
063                else {
064                    url = url.replaceAll(STATUS_PATTERN, "S:" + action.getStatus().toString());
065                }
066            }
067        }
068    
069        @Override
070        protected boolean isLockRequired() {
071            return false;
072        }
073    
074        @Override
075        protected String getEntityKey() {
076            return url;
077        }
078    
079        @Override
080        protected void loadState() throws CommandException {
081        }
082    
083        @Override
084        protected void verifyPrecondition() throws CommandException, PreconditionException {
085        }
086    
087        @Override
088        protected Void execute() throws CommandException {
089            //if command is requeue, the logInfo has to set to thread local Info object again
090            LogUtils.setLogInfo(logInfo);
091            if (url != null) {
092                try {
093                    URL url = new URL(this.url);
094                    HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
095                    if (urlConn.getResponseCode() != HttpURLConnection.HTTP_OK) {
096                        handleRetry();
097                    }
098                }
099                catch (IOException ex) {
100                    handleRetry();
101                }
102            }
103            return null;
104        }
105    
106        private void handleRetry() {
107            if (retries < 3) {
108                retries++;
109                this.resetUsed();
110                queue(this, 60 * 1000);
111            }
112            else {
113                LOG.warn(XLog.OPS, "could not send notification [{0}]", url);
114            }
115        }
116    
117        public String getUrl() {
118            return url;
119        }
120    
121    }