org.roda.core.common.notifications.HTTPNotificationProcessor.java Source code

Java tutorial

Introduction

Here is the source code for org.roda.core.common.notifications.HTTPNotificationProcessor.java

Source

/**
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE file at the root of the source
 * tree and available online at
 *
 * https://github.com/keeps/roda
 */
package org.roda.core.common.notifications;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.roda.core.RodaCoreFactory;
import org.roda.core.data.common.RodaConstants;
import org.roda.core.data.utils.JsonUtils;
import org.roda.core.data.v2.jobs.Job;
import org.roda.core.data.v2.notifications.Notification;
import org.roda.core.data.v2.notifications.Notification.NOTIFICATION_STATE;
import org.roda.core.model.ModelService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HTTPNotificationProcessor implements NotificationProcessor {

    private static final Logger LOGGER = LoggerFactory.getLogger(HTTPNotificationProcessor.class);

    public static final String JOB_KEY = "job";

    private String endpoint;
    private Map<String, Object> scope;

    public HTTPNotificationProcessor(String endpoint, Map<String, Object> scope) {
        this.endpoint = endpoint;
        this.scope = scope;
    }

    @Override
    public Notification processNotification(ModelService model, Notification notification) {

        if (scope.containsKey(JOB_KEY)) {
            Job job = (Job) scope.get(JOB_KEY);
            String content = createNotificationContent(job);
            notification.setBody(content);
            if (endpoint != null) {
                LOGGER.debug("Sending notification via HTTP ...");
                int timeout = RodaCoreFactory.getRodaConfiguration().getInt(RodaConstants.NOTIFICATION_HTTP_TIMEOUT,
                        10000);
                boolean success = post(endpoint, content, timeout);

                if (success) {
                    LOGGER.debug("Notification sent");
                    notification.setState(NOTIFICATION_STATE.COMPLETED);
                } else {
                    LOGGER.debug("Notification not sent");
                    notification.setState(NOTIFICATION_STATE.FAILED);
                }
            } else {
                LOGGER.warn("No endpoint, cannot send notification.");
            }
        }

        return notification;
    }

    private String createNotificationContent(Job job) {
        // TODO: create content (XML?) from Job
        return JsonUtils.getJsonFromObject(job);
    }

    private boolean post(String endpoint, String content, int timeout) {
        boolean success = true;
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout)
                .setConnectionRequestTimeout(timeout).build();

        try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
            HttpPost httppost = new HttpPost(endpoint);
            httppost.setConfig(requestConfig);
            httppost.setEntity(new StringEntity(content));

            HttpResponse response = httpclient.execute(httppost);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                success = false;
            } else {
                HttpEntity entity = response.getEntity();
                String responseTxt = processEntity(entity);
                LOGGER.debug("HTTP response: {}", responseTxt);
            }
        } catch (IOException e) {
            LOGGER.debug("HTTP POST error: {}", e.getMessage());
            success = false;
        }

        return success;
    }

    // FIXME 20160905 hsilva: is this method really needed? and, is this the best
    // way to implement it (30 lines)?
    private String processEntity(HttpEntity entity) {
        String responseTxt = null;
        if (entity != null) {
            InputStream is = null;
            try {
                is = entity.getContent();
                StringBuilder sb = new StringBuilder();
                String line;

                try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
                    while ((line = br.readLine()) != null) {
                        sb.append(line);
                    }
                } catch (IOException e) {
                    // do nothing
                }

                responseTxt = sb.toString();
            } catch (UnsupportedOperationException | IOException e1) {
                // do nothing
            } finally {
                IOUtils.closeQuietly(is);
            }
        }
        return responseTxt;
    }
}