Madis Pukkonen
Madis Pukkonen

Reputation: 1315

Add auth to Oozie workflow notification

Apache Oozie has oozie.wf.workflow.notification.url property to notify custom endpoints about job status updates.

<property>
    <name>oozie.wf.workflow.notification.url</name>
    <value>http://SERVER:8080/endpoint/oozieUpdate?jobId=$jobId%26status=$status</value>
</property>

I have a use case where the endpoint must authenticate incoming requests and I can't find a solution which allows me to configure Oozie so that it will send authentication headers to this notification URL (Basic Auth for example). Is there a way to do that?

Upvotes: 1

Views: 889

Answers (2)

Madis Pukkonen
Madis Pukkonen

Reputation: 1315

As a workaround I create a replacement variable for the notification url.

<property>
    <name>oozie.wf.workflow.notification.url</name>
    <value>_NOTIFICATION_URL_</value>
</property>

Then I include a different secret key inside the url every time I run the job.

confXml.replaceAll("_NOTIFICATION_URL_", server + "/" + getRandomSecret());

The trust anchor in this case is HTTPS. When I receive a notification from the job I can make sure it's not coming from an attacker by comparing the secret keys.

Upvotes: 1

MaxNevermind
MaxNevermind

Reputation: 2933

I doubt you can do that using oozie.wf.workflow.notification.url at current state of oozie. I've checked the oozie source code and found this:

org.apache.oozie.client.OozieClient (property read in a constant):

public static final String WORKFLOW_NOTIFICATION_URL = "oozie.wf.workflow.notification.url";

org.apache.oozie.command.wf.WorkflowNotificationXCommand (the constant is used to form a proxyConf variable):

public WorkflowNotificationXCommand(WorkflowJobBean workflow) {
    super("job.notification", "job.notification", 0);
    ParamChecker.notNull(workflow, "workflow");
    jobId = workflow.getId();
    url = workflow.getWorkflowInstance().getConf().get(OozieClient.WORKFLOW_NOTIFICATION_URL);
    if (url != null) {
        url = url.replaceAll(JOB_ID_PATTERN, workflow.getId());
        url = url.replaceAll(STATUS_PATTERN, workflow.getStatus().toString());
        proxyConf = workflow.getWorkflowInstance().getConf()
                .get(OozieClient.WORKFLOW_NOTIFICATION_PROXY, ConfigurationService.get(NOTIFICATION_PROXY_KEY));
        LOG.debug("Proxy :" + proxyConf);
    }
}

org.apache.oozie.command.NotificationXCommand (the http call itself in a WorkflowNotificationXCommand's superclass using the proxyConf variable):

protected void sendNotification() {
    if (url != null) {
        Proxy proxy = getProxy(proxyConf);
        try {
            URL url = new URL(this.url);
            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(proxy);
            urlConn.setConnectTimeout(getTimeOut());
            urlConn.setReadTimeout(getTimeOut());
            if (urlConn.getResponseCode() != HttpURLConnection.HTTP_OK) {
                handleRetry();
            }
        }
        catch (IOException ex) {
            handleRetry();
        }
    }
    else {
        LOG.info("No Notification URL is defined. Therefore nothing to notify for job " + jobId);

    }

}

As you can see no headers are set here using httpURLConnection.setRequestProperty(,).

You can do a workaround using a custom java action though, you can make http call from it using any headers you like.

Upvotes: 1

Related Questions