--- /dev/null
+ip: 0.0.0.0
+port: 8085
+reportChannel: "#a"
+reportStates: [ Alerting ]
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2016, Adam <Adam@rizon.net>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" 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>net.rizon</groupId>
+ <artifactId>moo</artifactId>
+ <version>3.0</version>
+ </parent>
+
+ <groupId>net.rizon.moo</groupId>
+ <artifactId>grafana</artifactId>
+ <name>Grafana</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>net.rizon.moo</groupId>
+ <artifactId>moo</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.rizon.moo</groupId>
+ <artifactId>test-utils</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>net.rizon.moo.plugin.grafana.Grafana</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016, Adam <Adam@rizon.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.rizon.moo.plugin.grafana;
+
+import com.google.inject.Inject;
+import com.google.inject.Provides;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import net.rizon.moo.Command;
+import net.rizon.moo.Moo;
+import net.rizon.moo.Plugin;
+import net.rizon.moo.conf.ConfigurationException;
+import net.rizon.moo.plugin.grafana.conf.GrafanaConfiguration;
+
+public class Grafana extends Plugin
+{
+ @Inject
+ private Moo moo;
+
+ @Inject
+ private HttpServerInitializer handler;
+
+ private Channel channel;
+ private GrafanaConfiguration conf;
+
+ public Grafana()
+ {
+ super("Grafana", "Shows Grafana notifications");
+ }
+
+ @Override
+ public void start() throws ConfigurationException, IOException
+ {
+ conf = GrafanaConfiguration.load();
+
+ ServerBootstrap bootstrap = new ServerBootstrap()
+ .group(moo.getGroup())
+ .channel(NioServerSocketChannel.class)
+ .childHandler(handler);
+
+ channel = bootstrap.bind(conf.getIp(), conf.getPort()).channel();
+ }
+
+ @Override
+ public void stop()
+ {
+ channel.close().awaitUninterruptibly();
+ }
+
+ @Override
+ public List<Command> getCommands()
+ {
+ return Collections.EMPTY_LIST;
+ }
+
+ @Override
+ protected void configure()
+ {
+ bind(Grafana.class).toInstance(this);
+
+ bind(HttpServerInitializer.class);
+ bind(HttpServerHandler.class);
+ }
+
+ @Provides
+ public GrafanaConfiguration provideConfig()
+ {
+ return conf;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016, Adam <Adam@rizon.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.rizon.moo.plugin.grafana;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import io.netty.channel.ChannelHandler.Sharable;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import net.rizon.moo.irc.Protocol;
+import net.rizon.moo.plugin.grafana.beans.GrafanaNotification;
+import net.rizon.moo.plugin.grafana.conf.GrafanaConfiguration;
+
+@Sharable
+public class HttpServerHandler extends SimpleChannelInboundHandler<GrafanaNotification>
+{
+ @Inject
+ private Protocol protocol;
+
+ @Inject
+ private Provider<GrafanaConfiguration> providerConfig;
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, GrafanaNotification notification) throws Exception
+ {
+ GrafanaConfiguration conf = providerConfig.get();
+
+ if (conf.getReportStates().contains(notification.getState()) == false || notification.getEvalMatches().isEmpty())
+ {
+ return;
+ }
+
+ protocol.privmsg(conf.getReportChannel(), "Grafana: " + notification.getRuleName() + " is now in state " + notification.getState() + " for metric " + notification.getEvalMatches().get(0).getMetric());
+
+ ctx.close();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016, Adam <Adam@rizon.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.rizon.moo.plugin.grafana;
+
+import com.google.inject.Inject;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.handler.codec.http.HttpObjectAggregator;
+import io.netty.handler.codec.http.HttpServerCodec;
+import net.rizon.moo.plugin.grafana.beans.GrafanaNotification;
+
+public class HttpServerInitializer extends ChannelInitializer<SocketChannel>
+{
+ private static final int SIZE = 65536;
+
+ @Inject
+ private HttpServerHandler handler;
+
+ @Override
+ public void initChannel(SocketChannel ch)
+ {
+ ChannelPipeline pipeline = ch.pipeline();
+ pipeline.addLast("http", new HttpServerCodec());
+ pipeline.addLast("dechunker", new HttpObjectAggregator(SIZE));
+ pipeline.addLast("decoder", new JsonDecoder(GrafanaNotification.class));
+ pipeline.addLast("handler", handler);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016, Adam <Adam@rizon.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.rizon.moo.plugin.grafana;
+
+import com.google.gson.Gson;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToMessageDecoder;
+import io.netty.handler.codec.http.FullHttpRequest;
+import java.nio.charset.Charset;
+import java.util.List;
+
+public class JsonDecoder extends MessageToMessageDecoder<FullHttpRequest>
+{
+ private final Gson gson = new Gson();
+
+ private final Class<?> clazz;
+
+ public JsonDecoder(Class<?> clazz)
+ {
+ this.clazz = clazz;
+ }
+
+ @Override
+ protected void decode(ChannelHandlerContext ctx, FullHttpRequest msg, List<Object> out) throws Exception
+ {
+ String content = msg.content().toString(Charset.forName("UTF-8"));
+ Object object = gson.fromJson(content, clazz);
+ out.add(object);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016, Adam <Adam@rizon.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.rizon.moo.plugin.grafana.beans;
+
+import java.util.List;
+
+public class GrafanaNotification
+{
+ private String title;
+ private String ruleId;
+ private String ruleName;
+ private String ruleUrl;
+ private String state;
+ private String imageUrl;
+ private String message;
+ private List<Metric> evalMatches;
+
+ public String getTitle()
+ {
+ return title;
+ }
+
+ public void setTitle(String title)
+ {
+ this.title = title;
+ }
+
+ public String getRuleId()
+ {
+ return ruleId;
+ }
+
+ public void setRuleId(String ruleId)
+ {
+ this.ruleId = ruleId;
+ }
+
+ public String getRuleName()
+ {
+ return ruleName;
+ }
+
+ public void setRuleName(String ruleName)
+ {
+ this.ruleName = ruleName;
+ }
+
+ public String getRuleUrl()
+ {
+ return ruleUrl;
+ }
+
+ public void setRuleUrl(String ruleUrl)
+ {
+ this.ruleUrl = ruleUrl;
+ }
+
+ public String getState()
+ {
+ return state;
+ }
+
+ public void setState(String state)
+ {
+ this.state = state;
+ }
+
+ public String getImageUrl()
+ {
+ return imageUrl;
+ }
+
+ public void setImageUrl(String imageUrl)
+ {
+ this.imageUrl = imageUrl;
+ }
+
+ public String getMessage()
+ {
+ return message;
+ }
+
+ public void setMessage(String message)
+ {
+ this.message = message;
+ }
+
+ public List<Metric> getEvalMatches()
+ {
+ return evalMatches;
+ }
+
+ public void setEvalMatches(List<Metric> evalMatches)
+ {
+ this.evalMatches = evalMatches;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016, Adam <Adam@rizon.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.rizon.moo.plugin.grafana.beans;
+
+public class Metric
+{
+ private String metric;
+
+ public String getMetric()
+ {
+ return metric;
+ }
+
+ public void setMetric(String metric)
+ {
+ this.metric = metric;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016, Adam <Adam@rizon.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.rizon.moo.plugin.grafana.conf;
+
+import java.io.IOException;
+import java.util.List;
+import net.rizon.moo.conf.Configuration;
+import net.rizon.moo.conf.ConfigurationException;
+import net.rizon.moo.conf.Validator;
+
+public class GrafanaConfiguration extends Configuration
+{
+ private static final String CONF_NAME = "grafana.yml";
+
+ private String ip;
+ private int port;
+ private String reportChannel;
+ private List<String> reportStates;
+
+ public static GrafanaConfiguration load() throws ConfigurationException, IOException
+ {
+ return load(CONF_NAME, GrafanaConfiguration.class);
+ }
+
+ @Override
+ public void validate() throws ConfigurationException
+ {
+ Validator.validateNotEmpty("ip", ip);
+ Validator.validatePort("port", port, false);
+ Validator.validateChannelName("reportChannel", reportChannel);
+ Validator.validateNotEmpty("reportStates", reportStates);
+ }
+
+ public String getIp()
+ {
+ return ip;
+ }
+
+ public void setIp(String ip)
+ {
+ this.ip = ip;
+ }
+
+ public int getPort()
+ {
+ return port;
+ }
+
+ public void setPort(int port)
+ {
+ this.port = port;
+ }
+
+ public String getReportChannel()
+ {
+ return reportChannel;
+ }
+
+ public void setReportChannel(String reportChannel)
+ {
+ this.reportChannel = reportChannel;
+ }
+
+ public List<String> getReportStates()
+ {
+ return reportStates;
+ }
+
+ public void setReportStates(List<String> reportStates)
+ {
+ this.reportStates = reportStates;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016, Adam <Adam@rizon.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.rizon.moo.plugin.grafana;
+
+import io.netty.buffer.Unpooled;
+import io.netty.handler.codec.http.FullHttpRequest;
+import java.util.ArrayList;
+import java.util.List;
+import net.rizon.moo.plugin.grafana.beans.GrafanaNotification;
+import net.rizon.moo.test.MooJUnitRunner;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MooJUnitRunner.class)
+public class JsonDecoderTest
+{
+ private static final String NOTIFICATION = "{\n"
+ + " \"title\": \"My alert\",\n"
+ + " \"ruleId\": 1,\n"
+ + " \"ruleName\": \"Load peaking!\",\n"
+ + " \"ruleUrl\": \"http://url.to.grafana/db/dashboard/my_dashboard?panelId=2\",\n"
+ + " \"state\": \"Alerting\",\n"
+ + " \"imageUrl\": \"http://s3.image.url\",\n"
+ + " \"message\": \"Load is peaking. Make sure the traffic is real and spin up more webfronts\",\n"
+ + " \"evalMatches\": [\n"
+ + " {\n"
+ + " \"metric\": \"requests\",\n"
+ + " \"tags\": {},\n"
+ + " \"value\": 122\n"
+ + " }\n"
+ + " ]\n"
+ + "}";
+
+ @Mock
+ private FullHttpRequest request;
+
+ @Test
+ public void testDecode() throws Exception
+ {
+ when(request.content()).thenReturn(Unpooled.wrappedBuffer(NOTIFICATION.getBytes()));
+
+ JsonDecoder decoder = new JsonDecoder(GrafanaNotification.class);
+
+ List<Object> objects = new ArrayList<>();
+ decoder.decode(null, request, objects);
+
+ GrafanaNotification notification = (GrafanaNotification) objects.get(0);
+
+ Assert.assertEquals("My alert", notification.getTitle());
+ Assert.assertEquals(1, notification.getEvalMatches().size());
+ }
+
+}
- groupId: net.rizon.moo
artifactId: fun
version: 3.0
+ - groupId: net.rizon.moo
+ artifactId: grafana
+ version: 3.0
- groupId: net.rizon.moo
artifactId: wiki
version: 3.0
catch (Throwable ex)
{
logger.error("Error loading plugin", ex);
- //logger.error("Error loading plugin " + pkg, ex);
System.exit(-1);
}
}
public static void stop()
{
- moo.channel.close();
+ channel.close();
}
public static final String getCreated()
package net.rizon.moo.conf;
import java.io.FileInputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.util.List;
{
/**
* Loads the specified file as a YAML configuration.
+ *
+ * @param <T>
* @param file File.
* @param c Class of configuration file.
* @return Loaded configuration.
- * @throws Exception When something is wrong :D
+ * @throws net.rizon.moo.conf.ConfigurationException
+ * @throws java.io.IOException
*/
- public static <T extends Configuration> T load(final String file, final Class<T> c) throws Exception
+ public static <T extends Configuration> T load(final String file, final Class<T> c) throws ConfigurationException, IOException
{
Yaml yaml = new Yaml(new CustomClassLoaderConstructor(c, c.getClassLoader()));
- InputStream io = null;
- try
+ try (InputStream io = new FileInputStream(file))
{
- io = new FileInputStream(file);
@SuppressWarnings("unchecked")
T conf = (T) yaml.load(io);
conf.validate();
return conf;
}
- finally
- {
- try
- {
- io.close();
- }
- catch (Exception ex) { }
- }
}
// TODO: Below classes should really be in some utilities.
-
/**
* Checks if the string is in the list, ignoring case.
+ *
* @param text String to check.
* @param list List of Strings.
* @return True if string is in list, False otherwise.
public static boolean containsIgnoreCase(final String text, final List<String> list)
{
for (String s : list)
+ {
if (s.equalsIgnoreCase(text))
+ {
return true;
+ }
+ }
return false;
}
/**
* Checks if the string is in the array, ignoring case.
+ *
* @param text String to check.
* @param array Array of Strings.
* @return True if string is in array, False otherwise.
public static boolean containsIgnoreCase(final String text, final String[] array)
{
for (String s : array)
+ {
if (s.equalsIgnoreCase(text))
+ {
return true;
+ }
+ }
return false;
}
}
<module>dnsbl</module>
<module>dnsblstats</module>
<module>fun</module>
+ <module>grafana</module>
<module>grapher</module>
<module>logging</module>
<module>mxbl</module>