org.opendaylight.centinel.alertcallback.CentinelRESTClient.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.centinel.alertcallback.CentinelRESTClient.java

Source

/*
 * Copyright (c) 2015 Tata Consultancy services and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */

package org.opendaylight.centinel.alertcallback;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.json.Json;
import javax.json.JsonBuilderFactory;
import javax.json.JsonObject;
import javax.ws.rs.core.MediaType;

import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData.Record;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.reflect.ReflectData;
import org.apache.commons.codec.binary.Base64;
import org.graylog2.plugin.MessageSummary;
import org.graylog2.plugin.alarms.AlertCondition;
import org.graylog2.plugin.alarms.AlertCondition.CheckResult;
import org.graylog2.plugin.alarms.callbacks.AlarmCallbackException;
import org.graylog2.plugin.streams.Stream;
import org.graylog2.plugin.streams.StreamRule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Monika Verma
 * 
 */
public class CentinelRESTClient {
    private static final Logger LOG = LoggerFactory.getLogger(CentinelRESTClient.class);

    private static CentinelRESTClient singleton = null;
    JsonBuilderFactory factory = null;
    private Properties properties;

    private CentinelRESTClient() {
        factory = Json.createBuilderFactory(null);
        loadPropertiesFile();
    }

    /**
     * Provide single instance of CentinelRestClient across the application
     * throughout its life cycle
     */
    public static synchronized CentinelRESTClient getInstance() {

        if (singleton == null) {
            singleton = new CentinelRESTClient();
        }
        return singleton;
    }

    /**
     * Triggers the alert callback to Centinel Rest Api
     */
    public void trigger(AlertCondition.CheckResult checkResult, Stream stream) throws AlarmCallbackException {

        TriggeredConditionPojo triggeredConditionPojo = new TriggeredConditionPojo(
                checkResult.getTriggeredCondition());
        Schema schemaTriggeredCond = ReflectData.get().getSchema(TriggeredConditionPojo.class);
        GenericRecord recordTriggeredCond = new Record(schemaTriggeredCond);
        recordTriggeredCond.put("alertConditionId", triggeredConditionPojo.getId());
        recordTriggeredCond.put("type", triggeredConditionPojo.getType());
        recordTriggeredCond.put("creatorUserId", triggeredConditionPojo.getCreatorUserId());
        recordTriggeredCond.put("createdAt", triggeredConditionPojo.getCreatedAt());
        recordTriggeredCond.put("grace", triggeredConditionPojo.getGrace());
        recordTriggeredCond.put("parameters", triggeredConditionPojo.getParameters());
        recordTriggeredCond.put("description", triggeredConditionPojo.getDescription());
        recordTriggeredCond.put("backlog", triggeredConditionPojo.getBacklog());

        Schema schemaMatchingMessage = ReflectData.get().getSchema(MatchingMessagePojo.class);
        GenericRecord recordMatchingMessage = new Record(schemaMatchingMessage);
        if (!checkResult.getMatchingMessages().isEmpty()) {
            MatchingMessagePojo matchingMessagePojo = new MatchingMessagePojo(
                    checkResult.getMatchingMessages().get(0));
            recordMatchingMessage.put("index", matchingMessagePojo.getIndex());
            recordMatchingMessage.put("message", matchingMessagePojo.getMessage());
            recordMatchingMessage.put("fields", matchingMessagePojo.getFields());
            recordMatchingMessage.put("id", matchingMessagePojo.getId());
            recordMatchingMessage.put("source", matchingMessagePojo.getSource());
            recordMatchingMessage.put("message_timestamp", matchingMessagePojo.getTimestamp());
        }

        CheckResultPojo checkResultPojo = new CheckResultPojo(checkResult);
        Schema schemaCheckResult = ReflectData.get().getSchema(CheckResultPojo.class);
        GenericRecord avroRecordCheckResult = new Record(schemaCheckResult);

        avroRecordCheckResult.put("resultDescription", checkResultPojo.getResultDescription());
        avroRecordCheckResult.put("triggeredCondition", recordTriggeredCond);
        avroRecordCheckResult.put("triggeredAt", checkResultPojo.getTriggeredAt());
        avroRecordCheckResult.put("triggered", checkResultPojo.isTriggered());
        avroRecordCheckResult.put("matchingMessages", recordMatchingMessage);

        Schema schemaRules = ReflectData.get().getSchema(RulesPojo.class);
        GenericRecord recordRules = new Record(schemaRules);

        StreamPojo streamPojo = new StreamPojo(stream);

        RulesPojo rule = new RulesPojo(streamPojo.getRules().get(0));
        recordRules.put("field", rule.getField());
        recordRules.put("streamId", rule.getStreamId());
        recordRules.put("id", rule.getId());
        recordRules.put("type", rule.getType().toString());
        recordRules.put("inverted", rule.getInverted());
        recordRules.put("value", rule.getValue());

        Schema schemaStream = ReflectData.get().getSchema(StreamPojo.class);
        GenericRecord avroRecordStream = new Record(schemaStream);

        avroRecordStream.put("creatoruserid", streamPojo.getCreatoruserid());
        avroRecordStream.put("matchingtype", streamPojo.getMatchingtype());
        avroRecordStream.put("description", streamPojo.getDescription());
        avroRecordStream.put("disabled", streamPojo.getDisabled());
        avroRecordStream.put("rules", recordRules);
        avroRecordStream.put("streamId", streamPojo.getId());
        avroRecordStream.put("title", streamPojo.getTitle());

        String eventBody = "{\"check_result\":" + avroRecordCheckResult + ",\"stream\":" + avroRecordStream + "}";

        JsonObject inputJson = null;
        inputJson = factory.createObjectBuilder()
                .add("input",
                        factory.createObjectBuilder().add("eventType", "alert").add("eventBodyType", "avro")
                                .add("eventBody", eventBody)
                                .add("eventKeys", factory.createArrayBuilder().add("check_result:triggeredAt")
                                        .add("check_result:resultDescription")
                                        .add("check_result:triggeredCondition:alertConditionId")
                                        .add("check_result:triggeredCondition:type")
                                        .add("check_result:triggeredCondition:description").add("stream:streamId")))
                .build();

        final URL url;
        try {
            url = new URL("http://" + properties.getProperty("centinel_ip") + ":"
                    + properties.getProperty("centinel_port") + "/restconf/operations/eventinput:notify-event");
        } catch (MalformedURLException e) {
            throw new AlarmCallbackException("Error while constructing URL of Centinel API.", e);
        }

        // Create authentication string and encode it to Base64
        final String admin = "admin";
        String authStr = admin + ":" + admin;
        String encodedAuthStr = Base64.encodeBase64String(authStr.getBytes());

        try {
            // Create Http connection
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // Set connection properties
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Authorization", "Basic " + encodedAuthStr);
            connection.setRequestProperty("Accept", MediaType.APPLICATION_JSON);
            connection.setRequestProperty("content-type", MediaType.APPLICATION_JSON);

            // Send post request
            connection.setDoOutput(true);
            OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
            out.write(inputJson.toString());
            out.flush();
            out.close();

            // Get the response from connection's inputStream
            connection.getInputStream();

        } catch (IOException e) {
            throw new AlarmCallbackException("Could not open connection to Rest API - Centinel", e);
        }
    }

    /**
     * To load property file
     */
    private void loadPropertiesFile() {
        properties = new Properties();
        try {
            InputStream inputStream = getClass().getClassLoader().getResourceAsStream("config.properties");
            properties.load(inputStream);
            LOG.info("Properties file for Graylog loaded successfully");
        } catch (IOException e) {
            LOG.error("Problem while loading Properties file for Graylog " + e.getMessage(), e);
        }
    }

    public static String formatTimestamp(String timestamp) {
        timestamp = timestamp.replace("T", " ");
        timestamp = timestamp.replace("Z", "");
        return timestamp;
    }

    /**
     * Pojo for CheckResult - to map checkResult object to avro schema
     */
    public static class CheckResultPojo {
        private String resultDescription;
        private AlertCondition triggeredCondition;
        private String triggeredAt;
        private boolean triggered;
        private List<MessageSummary> matchingMessages;

        public CheckResultPojo(CheckResult checkResult) {
            this.resultDescription = checkResult.getResultDescription();
            this.triggeredCondition = checkResult.getTriggeredCondition();
            this.triggeredAt = checkResult.getTriggeredAt().toString();
            this.triggered = checkResult.isTriggered();
            this.matchingMessages = checkResult.getMatchingMessages();
        }

        public String getResultDescription() {
            resultDescription = resultDescription.replace("\"", "");
            return resultDescription;
        }

        public void setResultDescription(String resultDescription) {
            this.resultDescription = resultDescription;
        }

        public AlertCondition getTriggeredCondition() {
            return triggeredCondition;
        }

        public void setTriggeredCondition(AlertCondition triggeredCondition) {
            this.triggeredCondition = triggeredCondition;
        }

        public String getTriggeredAt() {
            return formatTimestamp(triggeredAt);
        }

        public void setTriggeredAt(String triggeredAt) {
            this.triggeredAt = triggeredAt;
        }

        public boolean isTriggered() {
            return triggered;
        }

        public void setTriggered(boolean triggered) {
            this.triggered = triggered;
        }

        public List<MessageSummary> getMatchingMessages() {
            return matchingMessages;
        }

        public void setMatchingMessages(List<MessageSummary> matchingMessages) {
            this.matchingMessages = matchingMessages;
        }
    }

    /**
     * Pojo for Stream - to map stream object to avro schema
     */
    public static class StreamPojo {

        private String creatoruserid;
        private String matchingtype;
        private String description;
        private Boolean disabled;
        private List<StreamRule> rules;
        private String streamId;
        private String title;

        public StreamPojo(Stream stream) {
            this.creatoruserid = "admin";
            this.matchingtype = "AND";
            this.description = stream.getDescription();
            this.disabled = stream.getDisabled();
            this.rules = stream.getStreamRules();
            this.streamId = stream.getId();
            this.title = stream.getTitle();
        }

        public String getCreatoruserid() {
            return creatoruserid;
        }

        public void setCreatoruserid(String creatoruserid) {
            this.creatoruserid = creatoruserid;
        }

        public String getMatchingtype() {
            return matchingtype;
        }

        public void setMatchingtype(String matchingtype) {
            this.matchingtype = matchingtype;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public Boolean getDisabled() {
            return disabled;
        }

        public void setDisabled(Boolean disabled) {
            this.disabled = disabled;
        }

        public List<StreamRule> getRules() {
            return rules;
        }

        public void setRules(List<StreamRule> rules) {
            this.rules = rules;
        }

        public String getId() {
            return streamId;
        }

        public void setId(String id) {
            this.streamId = id;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }
    }

    /**
     * Pojo for Triggered AlertCondition - to map triggered alertCondition
     * object to avro schema
     */
    public static class TriggeredConditionPojo {

        private String alertConditionId;
        private String type;
        private String creatorUserId;
        private String createdAt;
        private int grace;
        private Map<String, Object> parameters;
        private String description;
        private Integer backlog;

        public TriggeredConditionPojo(AlertCondition alertCondition) {
            this.alertConditionId = alertCondition.getId();
            this.type = alertCondition.getTypeString();
            this.creatorUserId = alertCondition.getCreatorUserId();
            this.createdAt = alertCondition.getCreatedAt().toString();
            this.grace = alertCondition.getGrace();
            this.parameters = alertCondition.getParameters();
            this.description = alertCondition.getDescription();
            this.backlog = alertCondition.getBacklog();
        }

        public String getId() {
            return alertConditionId;
        }

        public void setId(String id) {
            this.alertConditionId = id;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getCreatorUserId() {
            return creatorUserId;
        }

        public void setCreatorUserId(String creatorUserId) {
            this.creatorUserId = creatorUserId;
        }

        public String getCreatedAt() {
            return formatTimestamp(createdAt);
        }

        public void setCreatedAt(String createdAt) {
            this.createdAt = createdAt;
        }

        public int getGrace() {
            return grace;
        }

        public void setGrace(int grace) {
            this.grace = grace;
        }

        public Map<String, Object> getParameters() {
            return parameters;
        }

        public void setParameters(Map<String, Object> parameters) {
            this.parameters = parameters;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public Integer getBacklog() {
            return backlog;
        }

        public void setBacklog(Integer backlog) {
            this.backlog = backlog;
        }
    }

    /**
     * Pojo for StreamRule - to map streamRule object to avro schema
     */
    public static class RulesPojo {

        private String field;
        private String streamId;
        private String id;
        private String type;
        private Boolean inverted;
        private String value;

        public RulesPojo(StreamRule rule) {
            this.field = rule.getField();
            this.streamId = rule.getStreamId();
            this.id = rule.getId();
            this.type = rule.getType().name();
            this.inverted = rule.getInverted();
            this.value = rule.getValue();
        }

        public String getField() {
            return field;
        }

        public void setField(String field) {
            this.field = field;
        }

        public String getStreamId() {
            return streamId;
        }

        public void setStreamId(String streamId) {
            this.streamId = streamId;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public Boolean getInverted() {
            return inverted;
        }

        public void setInverted(Boolean inverted) {
            this.inverted = inverted;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

    /**
     * Pojo for MatchingMessage - to map messageSummary object to avro schema
     */
    public static class MatchingMessagePojo {

        private String index;
        private String message;
        private Map<String, Object> fields;
        private String id;
        private String source;
        private String message_timestamp;

        public MatchingMessagePojo(MessageSummary messageSummary) {
            this.index = messageSummary.getIndex();
            this.message = messageSummary.getMessage();
            this.fields = messageSummary.getFields();
            this.id = messageSummary.getId();
            this.source = messageSummary.getSource();
            this.message_timestamp = messageSummary.getTimestamp().toString();
        }

        public String getIndex() {
            return index;
        }

        public void setIndex(String index) {
            this.index = index;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public Map<String, Object> getFields() {
            return fields;
        }

        public void setFields(Map<String, Object> fields) {
            this.fields = fields;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getSource() {
            return source;
        }

        public void setSource(String source) {
            this.source = source;
        }

        public String getTimestamp() {
            return formatTimestamp(message_timestamp);
        }

        public void setTimestamp(String timestamp) {
            this.message_timestamp = timestamp;
        }
    }

}