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.Command; 021 import org.apache.oozie.service.Services; 022 import org.apache.oozie.store.WorkflowStore; 023 import org.apache.oozie.store.Store; 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 NotificationCommand extends WorkflowCommand<Void> { 031 032 public static final String NOTIFICATION_URL_CONNECTION_TIMEOUT_KEY = "oozie.notification.url.connection.timeout"; 033 public static final int NOTIFICATION_URL_CONNECTION_TIMEOUT_DEFAULT = 10 * 1000; // 10 seconds 034 035 private static final String STATUS_PATTERN = "\\$status"; 036 private static final String JOB_ID_PATTERN = "\\$jobId"; 037 private static final String NODE_NAME_PATTERN = "\\$nodeName"; 038 039 private String url; 040 //this variable is package private only for test purposes 041 int retries = 0; 042 043 public NotificationCommand(WorkflowJobBean workflow) { 044 super("job.notification", "job.notification", 0, XLog.STD, false); 045 url = workflow.getWorkflowInstance().getConf().get(OozieClient.WORKFLOW_NOTIFICATION_URL); 046 if (url != null) { 047 url = url.replaceAll(JOB_ID_PATTERN, workflow.getId()); 048 url = url.replaceAll(STATUS_PATTERN, workflow.getStatus().toString()); 049 } 050 } 051 052 public NotificationCommand(WorkflowJobBean workflow, WorkflowActionBean action) { 053 super("action.notification", "job.notification", 0, XLog.STD); 054 url = workflow.getWorkflowInstance().getConf().get(OozieClient.ACTION_NOTIFICATION_URL); 055 if (url != null) { 056 url = url.replaceAll(JOB_ID_PATTERN, workflow.getId()); 057 url = url.replaceAll(NODE_NAME_PATTERN, action.getName()); 058 if (action.isComplete()) { 059 url = url.replaceAll(STATUS_PATTERN, "T:" + action.getTransition()); 060 } 061 else { 062 url = url.replaceAll(STATUS_PATTERN, "S:" + action.getStatus().toString()); 063 } 064 } 065 } 066 067 public Void call(WorkflowStore store) { 068 if (url != null) { 069 int timeout = Services.get().getConf().getInt(NOTIFICATION_URL_CONNECTION_TIMEOUT_KEY, 070 NOTIFICATION_URL_CONNECTION_TIMEOUT_DEFAULT); 071 try { 072 URL url = new URL(this.url); 073 HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); 074 urlConn.setConnectTimeout(timeout); 075 urlConn.setReadTimeout(timeout); 076 if (urlConn.getResponseCode() != HttpURLConnection.HTTP_OK) { 077 handleRetry(); 078 } 079 } 080 catch (IOException ex) { 081 handleRetry(); 082 } 083 } 084 return null; 085 } 086 087 private void handleRetry() { 088 if (retries < 3) { 089 retries++; 090 queueCallable(this, 60 * 1000); 091 } 092 else { 093 XLog.getLog(getClass()).warn(XLog.OPS, "could not send notification [{0}]", url); 094 } 095 } 096 097 }