Skip to content

Commit

Permalink
Updated for 3.0 + new callback support
Browse files Browse the repository at this point in the history
  • Loading branch information
itchannel committed Jul 25, 2021
1 parent 70bc8e4 commit a017f2f
Show file tree
Hide file tree
Showing 28 changed files with 1,639 additions and 270 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

A Graylog plugin to allow for pushover intergration. This plugin is designed to allow quick sending of alarm notifications to pushover users or groups.

**Required Graylog version:** 2.0 and later
## Beta support for 4.0
Plugin works with 4.0 but I have fully rewritten the codebase to no longer be a "Legacy" callback so there may be small bugs.

**Required Graylog version:** 3.0 and later

Installation
------------
Expand Down
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "Notifications",
"version": "1.0.0-SNAPSHOT",
"name": "PushNotification",
"version": "2.0.0",
"description": "",
"repository": {
"type": "git",
"url": "github.com/itchannel/graylognotifications"
"url": "graylogpushover"
},
"scripts": {
"build": "webpack",
Expand All @@ -14,11 +14,13 @@
"keywords": [
"graylog"
],
"author": "Steve <steve@itchannel.me>",
"author": "Steve <graylog@itchannel.me>",
"license": "MIT",
"dependencies": {
"react-select": "^3.1.0"
},
"devDependencies": {
"graylog-web-plugin": "file:../graylog2-server/graylog2-web-interface/packages/graylog-web-plugin"
"graylog-web-plugin": "file:../graylog2-server/graylog2-web-interface/packages/graylog-web-plugin",
"react": "^16.13.1"
}
}
48 changes: 28 additions & 20 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.graylog.plugins</groupId>
<artifactId>graylog-plugin-web-parent</artifactId>
<version>3.0.1-SNAPSHOT</version>
<version>3.3.6</version>
<relativePath>../graylog2-server/graylog-plugin-parent/graylog-plugin-web-parent</relativePath>
</parent>

<groupId>itchannel</groupId>
<artifactId>graylog-plugin-pushnotifications</artifactId>
<version>1.0.0-SNAPSHOT</version>
<groupId>com.itchannel</groupId>
<artifactId>graylog-plugin-push-notification</artifactId>
<version>3.3.6</version>
<packaging>jar</packaging>

<name>${project.artifactId}</name>
Expand All @@ -22,31 +21,29 @@

<developers>
<developer>
<name>itchannel</name>
<email>steve@itchannel.me</email>
<name>Steve</name>
<email>graylog@itchannel.me</email>
</developer>
</developers>

<scm>
<connection>scm:git:git@github.com:itchannel/graylognotifications.git</connection>
<developerConnection>scm:git:git@github.com:/itchannel/graylognotifications.git</developerConnection>
<url>https://github.com/itchannel/graylognotifications</url>
<connection>scm:git:git@github.com:graylogpushover.git</connection>
<developerConnection>scm:git:git@github.com:graylogpushover.git</developerConnection>
<url>https://github.com/graylogpushover</url>
<tag>HEAD</tag>
</scm>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>

<!-- Plugins will not be deployed by default - set to `false` if you actually want to deploy it -->
<maven.deploy.skip>true</maven.deploy.skip>

<graylog.version>${project.parent.version}</graylog.version>
<jackson.version>2.10.2</jackson.version>
<graylog.version>3.3.6</graylog.version>
<graylog.plugin-dir>/usr/share/graylog-server/plugin</graylog.plugin-dir>
</properties>

<distributionManagement>
<distributionManagement>
<snapshotRepository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
Expand All @@ -60,7 +57,6 @@
</distributionManagement>

<repositories>
<!-- to make our snapshot releases work with Travis et al -->
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
Expand Down Expand Up @@ -92,11 +88,17 @@
<version>${graylog.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
<resources>
<resource><directory>build</directory></resource>
<resource><directory>${web.build-dir}</directory></resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
Expand All @@ -113,7 +115,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<version>3.2.0</version>
<configuration>
<archive>
<manifestEntries>
Expand All @@ -122,7 +124,13 @@
</archive>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion src/deb/control/control
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: [[name]]
Version: [[version]]
Architecture: all
Maintainer: Steve <steve@itchannel.me>
Maintainer: Steve <graylog@itchannel.me>
Section: web
Priority: optional
Depends: graylog-server | graylog-radio
Expand Down
192 changes: 192 additions & 0 deletions src/main/java/com/itchannel/PushNotification.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package com.itchannel;

import org.graylog.events.notifications.EventNotification;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.graylog.events.notifications.EventNotification;
import org.graylog.events.notifications.EventNotificationContext;
import org.graylog2.notifications.NotificationService;
import org.graylog.events.notifications.EventNotificationModelData;
import org.graylog.events.notifications.EventNotificationService;
import org.graylog.events.notifications.PermanentEventNotificationException;
import org.graylog.events.notifications.TemporaryEventNotificationException;
import org.graylog2.notifications.Notification;
import org.graylog2.plugin.MessageSummary;
import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.ImmutableList;
import org.graylog2.notifications.NotificationService;
import org.graylog2.streams.StreamService;
import org.graylog2.plugin.system.NodeId;
import com.floreysoft.jmte.Engine;
import javax.inject.Inject;
import com.itchannel.template.PushHTMLEncoder;
import com.itchannel.template.RawNoopRenderer;
import org.graylog.events.notifications.*;
import org.graylog.events.processor.EventDefinitionDto;
import java.util.Optional;
import org.graylog2.plugin.streams.Stream;
//Classes specific to pushover
import java.net.URL;
import java.io.OutputStream;
import com.itchannel.models.MessageModelData;
import com.itchannel.models.StreamModelData;
import com.google.common.collect.ImmutableList;
import java.net.URLEncoder;
import java.net.HttpURLConnection;
import static java.util.Objects.requireNonNull;
import org.graylog.scheduler.JobTriggerDto;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.List;
import java.util.stream.Collectors;
import java.io.UnsupportedEncodingException;
import org.graylog2.jackson.TypeReferences;
import org.graylog.events.processor.aggregation.AggregationEventProcessorConfig;
/**
* This is the plugin. Your class should implement one of the existing plugin
* interfaces. (i.e. AlarmCallback, MessageInput, MessageOutput)
*/
public class PushNotification implements EventNotification {
public interface Factory extends EventNotification.Factory {
@Override
PushNotification create();
}

private static final String UNKNOWN = "<unknown>";
private final EventNotificationService notificationCallbackService;
private final StreamService streamService;
private final NotificationService notificationService;
private final NodeId nodeId;
private final ObjectMapper objectMapper;
private final Engine templateEngine;

@Inject
public PushNotification(EventNotificationService notificationCallbackService,
StreamService streamService,
NotificationService notificationService,
NodeId nodeId,
ObjectMapper objectMapper,
Engine templateEngine) {
this.notificationCallbackService = notificationCallbackService;
this.streamService = streamService;
this.notificationService = requireNonNull(notificationService, "notificationService");
this.nodeId = requireNonNull(nodeId, "nodeId");
this.objectMapper = requireNonNull(objectMapper, "objectMapper");
this.templateEngine = requireNonNull(templateEngine, "templateEngine");
templateEngine.registerNamedRenderer(new RawNoopRenderer());
templateEngine.setEncoder(new PushHTMLEncoder());
}

@Override
public void execute(EventNotificationContext ctx) throws TemporaryEventNotificationException, PermanentEventNotificationException {
final PushNotificationConfig config = (PushNotificationConfig) ctx.notificationConfig();
ImmutableList<MessageSummary> backlog = notificationCallbackService.getBacklogForEvent(ctx);
final Map<String, Object> model = getModel(ctx, backlog, config);



try {
//Current pushover API Endpoint
URL obj = new URL("https://api.pushover.net/1/messages.json");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
String message = buildMessage(config.messageField(), model);
String priority = "";
if (message == "") {
message = "This is a test";
}
if (config.priorityToken() == "")
{
priority = "0";
}else
{
priority = config.priorityToken();
}
String POST_PARAMS = "token=" + config.apiToken() + "&user=" + config.userToken() + "&priority=" + priority + "&html=1&title=" + model.get("event_definition_title") + "&message=" + URLEncoder.encode(message, "UTF-8");
os.write(POST_PARAMS.getBytes(Charset.forName("UTF-8")));
os.flush();
os.close();
int responseCode = con.getResponseCode();
System.out.println("Post Response Code :: " + responseCode);

} catch (Exception exception) {
errorNotification(exception.getMessage());

}


}

private String buildMessage(String template, Map<String, Object> model) {
return this.templateEngine.transform(template, model);
}

private Map<String, Object> getModel(EventNotificationContext ctx, ImmutableList<MessageSummary> backlog, PushNotificationConfig config) {
final Optional<EventDefinitionDto> definitionDto = ctx.eventDefinition();
final Optional<JobTriggerDto> jobTriggerDto = ctx.jobTrigger();


List<StreamModelData> streams = streamService.loadByIds(ctx.event().sourceStreams())
.stream()
.map(stream -> buildStreamWithUrl(stream, ctx, "https://graylog.dcrs.tech"))
.collect(Collectors.toList());

final MessageModelData modelData = MessageModelData.builder()
.eventDefinition(definitionDto)
.eventDefinitionId(definitionDto.map(EventDefinitionDto::id).orElse(UNKNOWN))
.eventDefinitionType(definitionDto.map(d -> d.config().type()).orElse(UNKNOWN))
.eventDefinitionTitle(definitionDto.map(EventDefinitionDto::title).orElse(UNKNOWN))
.eventDefinitionDescription(definitionDto.map(EventDefinitionDto::description).orElse(UNKNOWN))
.jobDefinitionId(jobTriggerDto.map(JobTriggerDto::jobDefinitionId).orElse(UNKNOWN))
.jobTriggerId(jobTriggerDto.map(JobTriggerDto::id).orElse(UNKNOWN))
.event(ctx.event())
.backlog(backlog)
.backlogSize(backlog.size())
.graylogUrl("https://graylog.dcrs.tech")
.streams(streams)
.build();

return objectMapper.convertValue(modelData, TypeReferences.MAP_STRING_OBJECT);
}


private StreamModelData buildStreamWithUrl(Stream stream, EventNotificationContext ctx, String graylogURL) {
String streamUrl = null;
if (StringUtils.isNotBlank(graylogURL)) {
streamUrl = StringUtils.appendIfMissing(graylogURL, "/") + "streams/" + stream.getId() + "/search";

if (ctx.eventDefinition().isPresent()) {
EventDefinitionDto eventDefinitionDto = ctx.eventDefinition().get();
if (eventDefinitionDto.config() instanceof AggregationEventProcessorConfig) {
String query = ((AggregationEventProcessorConfig) eventDefinitionDto.config()).query();
try {
streamUrl += "?q=" + URLEncoder.encode(query, "UTF-8");
} catch (UnsupportedEncodingException e) {
// url without query as fallback
}
}
}
}
return StreamModelData.builder()
.id(stream.getId())
.title(stream.getTitle())
.description(stream.getDescription())
.url(Optional.ofNullable(streamUrl).orElse(UNKNOWN))
.build();
}

private void errorNotification (String error){
//LOG.warn(error);

final Notification systemNotification = notificationService.buildNow()
.addNode(nodeId.toString())
.addType(Notification.Type.GENERIC)
.addSeverity(Notification.Severity.NORMAL)
.addDetail("title", "Failed to send Pushover messages.")
.addDetail("description", error)
.addDetail("exception", error);
notificationService.publishIfFirst(systemNotification);
}

}
Loading

0 comments on commit a017f2f

Please sign in to comment.