From 88f4f1ff84345f380b11455331437b722867ac27 Mon Sep 17 00:00:00 2001 From: Lucas Ponce Date: Thu, 22 Jan 2015 18:01:20 +0100 Subject: [PATCH] HWKALERTS-1 Prepare an initial version --- .gitignore | 10 + README.adoc | 38 ++ examples/example-alerts-ui/pom.xml | 94 +++ .../src/main/webapp/WEB-INF/jboss-web.xml | 22 + .../src/main/webapp/WEB-INF/web.xml | 24 + .../src/main/webapp/index.jsp | 26 + hawkular-alerts-api/pom.xml | 55 ++ .../alerts/api/model/condition/Alert.java | 94 +++ .../condition/AvailabilityCondition.java | 116 ++++ .../condition/AvailabilityConditionEval.java | 109 +++ .../api/model/condition/CompareCondition.java | 148 ++++ .../model/condition/CompareConditionEval.java | 121 ++++ .../alerts/api/model/condition/Condition.java | 108 +++ .../api/model/condition/ConditionEval.java | 86 +++ .../api/model/condition/StringCondition.java | 153 +++++ .../model/condition/StringConditionEval.java | 107 +++ .../model/condition/ThresholdCondition.java | 130 ++++ .../condition/ThresholdConditionEval.java | 107 +++ .../condition/ThresholdRangeCondition.java | 206 ++++++ .../ThresholdRangeConditionEval.java | 107 +++ .../alerts/api/model/dampening/Dampening.java | 216 ++++++ .../alerts/api/model/data/Availability.java | 76 +++ .../hawkular/alerts/api/model/data/Data.java | 71 ++ .../alerts/api/model/data/NumericData.java | 75 +++ .../alerts/api/model/data/StringData.java | 75 +++ .../api/model/notification/Notification.java | 76 +++ .../alerts/api/model/trigger/Trigger.java | 96 +++ .../api/model/trigger/TriggerTemplate.java | 174 +++++ .../alerts/api/services/AlertsService.java | 47 ++ .../api/services/DefinitionsService.java | 95 +++ .../api/services/NotificationsService.java | 44 ++ .../alerts/api/services/NotifierListener.java | 36 + hawkular-alerts-bus/pom.xml | 111 +++ .../alerts/bus/init/AlertEngineRegister.java | 49 ++ .../bus/listener/AlertDataListener.java | 52 ++ .../bus/listener/NotifierTypeListener.java | 67 ++ .../alerts/bus/messages/AlertData.java | 105 +++ .../alerts/bus/messages/AlertDataMessage.java | 80 +++ .../alerts/bus/sender/NotificationSender.java | 107 +++ hawkular-alerts-ear/pom.xml | 128 ++++ .../META-INF/jboss-deployment-structure.xml | 31 + hawkular-alerts-engine/pom.xml | 132 ++++ .../engine/impl/BasicAlertsServiceImpl.java | 186 ++++++ .../engine/impl/DroolsRulesEngineImpl.java | 136 ++++ .../impl/MemDefinitionsServiceImpl.java | 630 ++++++++++++++++++ .../impl/MemNotificationsServiceImpl.java | 78 +++ .../alerts/engine/rules/RulesEngine.java | 42 ++ .../src/main/resources/META-INF/kmodule.xml | 24 + .../resources/META-INF/maven/pom.properties | 20 + .../resources/hawkular-alerts/conditions.data | 29 + .../resources/hawkular-alerts/dampening.data | 2 + .../resources/hawkular-alerts/notifiers.data | 5 + .../resources/hawkular-alerts/triggers.data | 7 + .../alerts/engine/rules/ConditionMatch.drl | 195 ++++++ .../alerts/engine/RulesEngineTest.java | 152 +++++ .../test/resources/simplelogger.properties | 51 ++ hawkular-alerts-rest/pom.xml | 75 +++ .../hawkular/alerts/rest/AlertsHandler.java | 82 +++ .../alerts/rest/HawkularAlertsApp.java | 38 ++ .../alerts/rest/NotificationHandler.java | 64 ++ .../hawkular/alerts/rest/TriggersHandler.java | 173 +++++ .../src/main/webapp/WEB-INF/beans.xml | 24 + .../src/main/webapp/WEB-INF/jboss-web.xml | 22 + .../src/main/webapp/WEB-INF/web.xml | 24 + .../src/main/webapp/index.jsp | 26 + hawkular-notifiers-api/pom.xml | 56 ++ .../api/model/NotificationMessage.java | 83 +++ .../model/NotifierRegistrationMessage.java | 99 +++ .../NotifierTypeRegistrationMessage.java | 101 +++ hawkular-notifiers-email/pom.xml | 132 ++++ .../email/notifications/EmailListener.java | 44 ++ .../email/registration/RegisterListener.java | 44 ++ .../email/registration/RegistrationInit.java | 81 +++ .../WEB-INF/jboss-deployment-structure.xml | 26 + .../src/main/webapp/WEB-INF/jboss-web.xml | 22 + .../src/main/webapp/WEB-INF/web.xml | 24 + .../src/main/webapp/index.jsp | 26 + hawkular-notifiers-sms/pom.xml | 132 ++++ .../sms/notifications/SmsListener.java | 44 ++ .../sms/registration/RegisterListener.java | 44 ++ .../sms/registration/RegistrationInit.java | 81 +++ .../WEB-INF/jboss-deployment-structure.xml | 26 + .../src/main/webapp/WEB-INF/jboss-web.xml | 22 + .../src/main/webapp/WEB-INF/web.xml | 24 + .../src/main/webapp/index.jsp | 26 + hawkular-notifiers-snmp/pom.xml | 132 ++++ .../snmp/notifications/SnmpListener.java | 44 ++ .../snmp/registration/RegisterListener.java | 44 ++ .../snmp/registration/RegistrationInit.java | 81 +++ .../WEB-INF/jboss-deployment-structure.xml | 26 + .../src/main/webapp/WEB-INF/jboss-web.xml | 22 + .../src/main/webapp/WEB-INF/web.xml | 24 + .../src/main/webapp/index.jsp | 26 + pom.xml | 260 ++++++++ 94 files changed, 7685 insertions(+) create mode 100644 README.adoc create mode 100644 examples/example-alerts-ui/pom.xml create mode 100644 examples/example-alerts-ui/src/main/webapp/WEB-INF/jboss-web.xml create mode 100644 examples/example-alerts-ui/src/main/webapp/WEB-INF/web.xml create mode 100644 examples/example-alerts-ui/src/main/webapp/index.jsp create mode 100644 hawkular-alerts-api/pom.xml create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/Alert.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/AvailabilityCondition.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/AvailabilityConditionEval.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/CompareCondition.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/CompareConditionEval.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/Condition.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ConditionEval.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/StringCondition.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/StringConditionEval.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdCondition.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdConditionEval.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdRangeCondition.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdRangeConditionEval.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/dampening/Dampening.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/Availability.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/Data.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/NumericData.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/StringData.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/notification/Notification.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/trigger/Trigger.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/trigger/TriggerTemplate.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/AlertsService.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/DefinitionsService.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/NotificationsService.java create mode 100644 hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/NotifierListener.java create mode 100644 hawkular-alerts-bus/pom.xml create mode 100644 hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/init/AlertEngineRegister.java create mode 100644 hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/listener/AlertDataListener.java create mode 100644 hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/listener/NotifierTypeListener.java create mode 100644 hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/messages/AlertData.java create mode 100644 hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/messages/AlertDataMessage.java create mode 100644 hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/sender/NotificationSender.java create mode 100644 hawkular-alerts-ear/pom.xml create mode 100644 hawkular-alerts-ear/src/main/application/META-INF/jboss-deployment-structure.xml create mode 100644 hawkular-alerts-engine/pom.xml create mode 100644 hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/BasicAlertsServiceImpl.java create mode 100644 hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/DroolsRulesEngineImpl.java create mode 100644 hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/MemDefinitionsServiceImpl.java create mode 100644 hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/MemNotificationsServiceImpl.java create mode 100644 hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/rules/RulesEngine.java create mode 100644 hawkular-alerts-engine/src/main/resources/META-INF/kmodule.xml create mode 100644 hawkular-alerts-engine/src/main/resources/META-INF/maven/pom.properties create mode 100644 hawkular-alerts-engine/src/main/resources/hawkular-alerts/conditions.data create mode 100644 hawkular-alerts-engine/src/main/resources/hawkular-alerts/dampening.data create mode 100644 hawkular-alerts-engine/src/main/resources/hawkular-alerts/notifiers.data create mode 100644 hawkular-alerts-engine/src/main/resources/hawkular-alerts/triggers.data create mode 100644 hawkular-alerts-engine/src/main/resources/org/hawkular/alerts/engine/rules/ConditionMatch.drl create mode 100644 hawkular-alerts-engine/src/test/java/org/hawkular/alerts/engine/RulesEngineTest.java create mode 100644 hawkular-alerts-engine/src/test/resources/simplelogger.properties create mode 100644 hawkular-alerts-rest/pom.xml create mode 100644 hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/AlertsHandler.java create mode 100644 hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/HawkularAlertsApp.java create mode 100644 hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/NotificationHandler.java create mode 100644 hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/TriggersHandler.java create mode 100644 hawkular-alerts-rest/src/main/webapp/WEB-INF/beans.xml create mode 100644 hawkular-alerts-rest/src/main/webapp/WEB-INF/jboss-web.xml create mode 100644 hawkular-alerts-rest/src/main/webapp/WEB-INF/web.xml create mode 100644 hawkular-alerts-rest/src/main/webapp/index.jsp create mode 100644 hawkular-notifiers-api/pom.xml create mode 100644 hawkular-notifiers-api/src/main/java/org/hawkular/notifiers/api/model/NotificationMessage.java create mode 100644 hawkular-notifiers-api/src/main/java/org/hawkular/notifiers/api/model/NotifierRegistrationMessage.java create mode 100644 hawkular-notifiers-api/src/main/java/org/hawkular/notifiers/api/model/NotifierTypeRegistrationMessage.java create mode 100644 hawkular-notifiers-email/pom.xml create mode 100644 hawkular-notifiers-email/src/main/java/org/hawkular/notifiers/email/notifications/EmailListener.java create mode 100644 hawkular-notifiers-email/src/main/java/org/hawkular/notifiers/email/registration/RegisterListener.java create mode 100644 hawkular-notifiers-email/src/main/java/org/hawkular/notifiers/email/registration/RegistrationInit.java create mode 100644 hawkular-notifiers-email/src/main/webapp/WEB-INF/jboss-deployment-structure.xml create mode 100644 hawkular-notifiers-email/src/main/webapp/WEB-INF/jboss-web.xml create mode 100644 hawkular-notifiers-email/src/main/webapp/WEB-INF/web.xml create mode 100644 hawkular-notifiers-email/src/main/webapp/index.jsp create mode 100644 hawkular-notifiers-sms/pom.xml create mode 100644 hawkular-notifiers-sms/src/main/java/org/hawkular/notifiers/sms/notifications/SmsListener.java create mode 100644 hawkular-notifiers-sms/src/main/java/org/hawkular/notifiers/sms/registration/RegisterListener.java create mode 100644 hawkular-notifiers-sms/src/main/java/org/hawkular/notifiers/sms/registration/RegistrationInit.java create mode 100644 hawkular-notifiers-sms/src/main/webapp/WEB-INF/jboss-deployment-structure.xml create mode 100644 hawkular-notifiers-sms/src/main/webapp/WEB-INF/jboss-web.xml create mode 100644 hawkular-notifiers-sms/src/main/webapp/WEB-INF/web.xml create mode 100644 hawkular-notifiers-sms/src/main/webapp/index.jsp create mode 100644 hawkular-notifiers-snmp/pom.xml create mode 100644 hawkular-notifiers-snmp/src/main/java/org/hawkular/notifiers/snmp/notifications/SnmpListener.java create mode 100644 hawkular-notifiers-snmp/src/main/java/org/hawkular/notifiers/snmp/registration/RegisterListener.java create mode 100644 hawkular-notifiers-snmp/src/main/java/org/hawkular/notifiers/snmp/registration/RegistrationInit.java create mode 100644 hawkular-notifiers-snmp/src/main/webapp/WEB-INF/jboss-deployment-structure.xml create mode 100644 hawkular-notifiers-snmp/src/main/webapp/WEB-INF/jboss-web.xml create mode 100644 hawkular-notifiers-snmp/src/main/webapp/WEB-INF/web.xml create mode 100644 hawkular-notifiers-snmp/src/main/webapp/index.jsp create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore index 32858aad3..4f0d3152e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,13 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +# maven target directories +target/ + +# IntelliJ +.idea +*.iml + +# KDE +.directory diff --git a/README.adoc b/README.adoc new file mode 100644 index 000000000..a099581df --- /dev/null +++ b/README.adoc @@ -0,0 +1,38 @@ += hawkular-alerts + +== hawkular-bus + +1. `cd hawkular-bus ; mvn clean install -Pdev` + +Note: + +Verify that Bus is configured in failover mode due: +https://issues.jboss.org/browse/HAWKULAR-14 + +== hawkular-alerts + +1. `cd hawkular-alerts ; mvn clean install -Pdev` + +In case you don't have hawkular-bus and hawkular-alerts project in the same folder you should indicate path of bus: + +1. `NEST_HOME=$PATH_TO/hawkular-bus/hawkular-nest/hawkular-nest-distro/target/wildfly-8.2.0.Final` +2. `cd hawkular-alerts ; mvn clean install -Pdev -Dorg.hawkular.wildfly.home=$NEST_HOME` + +== Tests + +1. Send metrics to Hawkular Bus: + +curl -X POST -H "Content-Type: application/json" \ +--data "{\"data\" : [ { \"id\": \"NumericData-01\", \"type\" : \"numeric\", \"value\" : 0.1} ]}" \ +http://localhost:8080/hawkular-bus/message/MetricsTopic + +curl -X POST -H "Content-Type: application/json" \ +--data "{\"data\" : [ { \"id\": \"StringData-01\", \"type\" : \"string\", \"value\" : \"Barney\"} ]}" \ +http://localhost:8080/hawkular-bus/message/MetricsTopic + +curl -X POST -H "Content-Type: application/json" \ +--data "{\"data\" : [ { \"id\": \"Availability-01\", \"type\" : \"availability\", \"value\" : \"UP\"} ]}" \ +http://localhost:8080/hawkular-bus/message/MetricsTopic + + + diff --git a/examples/example-alerts-ui/pom.xml b/examples/example-alerts-ui/pom.xml new file mode 100644 index 000000000..d70217a9b --- /dev/null +++ b/examples/example-alerts-ui/pom.xml @@ -0,0 +1,94 @@ + + + + + 4.0.0 + + + org.hawkular.alerts + hawkular-alerts + 1.0.0.Alpha1-SNAPSHOT + + + org.hawkular.alerts + example-alerts-ui + war + Example Alerts UI REST Client + + + ${project.basedir}/../../../hawkular-bus/hawkular-nest/hawkular-nest-distro/target/wildfly-${version.org.wildfly} + ${org.hawkular.wildfly.home}/modules/system/layers/base/org/hawkular/nest/main/deployments + + + + + + + org.jboss.spec.javax.servlet + jboss-servlet-api_3.1_spec + ${version.org.jboss.spec} + provided + + + + junit + junit + ${version.junit} + test + + + + + + ${project.artifactId} + + + + + dev + + + + org.apache.maven.plugins + maven-antrun-plugin + + + deploy + install + + + + + + + run + + + + + + + + + + diff --git a/examples/example-alerts-ui/src/main/webapp/WEB-INF/jboss-web.xml b/examples/example-alerts-ui/src/main/webapp/WEB-INF/jboss-web.xml new file mode 100644 index 000000000..d5d8195a9 --- /dev/null +++ b/examples/example-alerts-ui/src/main/webapp/WEB-INF/jboss-web.xml @@ -0,0 +1,22 @@ + + + + example-alerts-ui + diff --git a/examples/example-alerts-ui/src/main/webapp/WEB-INF/web.xml b/examples/example-alerts-ui/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..87653b40d --- /dev/null +++ b/examples/example-alerts-ui/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,24 @@ + + + + diff --git a/examples/example-alerts-ui/src/main/webapp/index.jsp b/examples/example-alerts-ui/src/main/webapp/index.jsp new file mode 100644 index 000000000..4fb6e1874 --- /dev/null +++ b/examples/example-alerts-ui/src/main/webapp/index.jsp @@ -0,0 +1,26 @@ +<%-- + + Copyright 2015 Red Hat, Inc. and/or its affiliates + and other contributors as indicated by the @author tags. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--%> + + + Example Hawkular Alerts UI + + +

Example Hawkular Alerts UI

+ + diff --git a/hawkular-alerts-api/pom.xml b/hawkular-alerts-api/pom.xml new file mode 100644 index 000000000..2effd2953 --- /dev/null +++ b/hawkular-alerts-api/pom.xml @@ -0,0 +1,55 @@ + + + + + 4.0.0 + + + org.hawkular.alerts + hawkular-alerts + 1.0.0.Alpha1-SNAPSHOT + + + org.hawkular.alerts + hawkular-alerts-api + jar + Hawkular Alerts Api + + + + + org.slf4j + slf4j-api + ${version.org.slf4j} + provided + + + + junit + junit + ${version.junit} + test + + + + + diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/Alert.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/Alert.java new file mode 100644 index 000000000..db09e3678 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/Alert.java @@ -0,0 +1,94 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +import java.util.List; +import java.util.Set; + +/** + * A status of an alert thrown by several matched conditions. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class Alert { + + private String triggerId; + private List> evals; + private long time; + + public Alert(String triggerId, List> evals) { + this.triggerId = triggerId; + this.evals = evals; + this.time = System.currentTimeMillis(); + } + + public List> getEvals() { + return evals; + } + + public void setEvals(List> evals) { + this.evals = evals; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public String getTriggerId() { + return triggerId; + } + + public void setTriggerId(String triggerId) { + this.triggerId = triggerId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Alert alert = (Alert) o; + + if (time != alert.time) return false; + if (evals != null ? !evals.equals(alert.evals) : alert.evals != null) return false; + if (triggerId != null ? !triggerId.equals(alert.triggerId) : alert.triggerId != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = triggerId != null ? triggerId.hashCode() : 0; + result = 31 * result + (evals != null ? evals.hashCode() : 0); + result = 31 * result + (int) (time ^ (time >>> 32)); + return result; + } + + @Override + public String toString() { + return "Alert{" + + "evals=" + evals + + ", triggerId='" + triggerId + '\'' + + ", time=" + time + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/AvailabilityCondition.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/AvailabilityCondition.java new file mode 100644 index 000000000..003b8a071 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/AvailabilityCondition.java @@ -0,0 +1,116 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +import org.hawkular.alerts.api.model.data.Availability.AvailabilityType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * An availability condition definition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class AvailabilityCondition extends Condition { + private static final Logger log = LoggerFactory.getLogger(AvailabilityCondition.class); + + public enum Operator { + DOWN, NOT_UP, UP + } + + private String dataId; + private Operator operator; + + public AvailabilityCondition() { + /* + Default constructor is needed for JSON libraries in JAX-RS context. + */ + this("DefaultId", 1, 1, null, null); + } + + public AvailabilityCondition(String triggerId, int conditionSetSize, int conditionSetIndex, + String dataId, Operator operator) { + super(triggerId, conditionSetSize, conditionSetIndex); + this.dataId = dataId; + this.operator = operator; + } + + public String getDataId() { + return dataId; + } + + public void setDataId(String dataId) { + this.dataId = dataId; + } + + public Operator getOperator() { + return operator; + } + + public void setOperator(Operator operator) { + this.operator = operator; + } + + public String getLog(AvailabilityType value) { + return triggerId + " : " + value + " " + operator.name(); + } + + public boolean match(AvailabilityType value) { + switch (operator) { + case DOWN: + return value == AvailabilityType.DOWN; + case UP: + return value == AvailabilityType.UP; + case NOT_UP: + return value != AvailabilityType.UP; + default: + log.warn("Unknown operator: " + operator.name()); + return false; + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + AvailabilityCondition that = (AvailabilityCondition) o; + + if (dataId != null ? !dataId.equals(that.dataId) : that.dataId != null) return false; + if (operator != that.operator) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (dataId != null ? dataId.hashCode() : 0); + result = 31 * result + (operator != null ? operator.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "AvailabilityCondition{triggerId='" + triggerId + '\'' + + "dataId='" + dataId + '\'' + + ", operator=" + operator + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/AvailabilityConditionEval.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/AvailabilityConditionEval.java new file mode 100644 index 000000000..3db6262bd --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/AvailabilityConditionEval.java @@ -0,0 +1,109 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +import org.hawkular.alerts.api.model.data.Availability.AvailabilityType; + +/** + * An evaluation state for availability condition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class AvailabilityConditionEval extends ConditionEval { + + private AvailabilityCondition condition; + private AvailabilityType value; + + public AvailabilityConditionEval() { + super(false); + this.condition = null; + this.value = null; + } + + public AvailabilityConditionEval(AvailabilityCondition condition, AvailabilityType value) { + super(condition.match(value)); + this.condition = condition; + this.value = value; + } + + public AvailabilityCondition getCondition() { + return condition; + } + + public void setCondition(AvailabilityCondition condition) { + this.condition = condition; + } + + public AvailabilityType getValue() { + return value; + } + + public void setValue(AvailabilityType value) { + this.value = value; + } + + @Override + public String getTriggerId() { + return condition.getTriggerId(); + } + + @Override + public int getConditionSetSize() { + return condition.getConditionSetSize(); + } + + @Override + public int getConditionSetIndex() { + return condition.getConditionSetIndex(); + } + + @Override + public String getLog() { + return condition.getLog(value); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + AvailabilityConditionEval that = (AvailabilityConditionEval) o; + + if (condition != null ? !condition.equals(that.condition) : that.condition != null) return false; + if (value != that.value) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (condition != null ? condition.hashCode() : 0); + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "AvailabilityConditionEval{" + + "condition=" + condition + + ", value=" + value + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/CompareCondition.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/CompareCondition.java new file mode 100644 index 000000000..3a11c817d --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/CompareCondition.java @@ -0,0 +1,148 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A numeric comparison condition. + * i.e. "X > 80% of Y" or "FreeSpace < 20% of TotalSpace" + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class CompareCondition extends Condition { + private static final Logger log = LoggerFactory.getLogger(CompareCondition.class); + + public enum Operator { + LT, GT, LTE, GTE + } + + private String data1Id; + private Operator operator; + private String data2Id; + private Double data2Multiplier; + + public CompareCondition() { + /* + Default constructor is needed for JSON libraries in JAX-RS context. + */ + this("DefaultId", 1, 1, null, null, null, null); + } + + public CompareCondition(String triggerId, int conditionSetSize, int conditionSetIndex, + String data1Id, Operator operator, Double data2Multiplier, String data2Id) { + super(triggerId, conditionSetSize, conditionSetIndex); + this.data1Id = data1Id; + this.operator = operator; + this.data2Id = data2Id; + this.data2Multiplier = data2Multiplier; + } + + public String getData1Id() { + return data1Id; + } + + public void setData1Id(String data1Id) { + this.data1Id = data1Id; + } + + public String getData2Id() { + return data2Id; + } + + public void setData2Id(String data2Id) { + this.data2Id = data2Id; + } + + public Double getData2Multiplier() { + return data2Multiplier; + } + + public void setData2Multiplier(Double data2Multiplier) { + this.data2Multiplier = data2Multiplier; + } + + public Operator getOperator() { + return operator; + } + + public void setOperator(Operator operator) { + this.operator = operator; + } + + public String getLog(double data1Value, double data2Value) { + Double val = data2Multiplier * data2Value; + return triggerId + " : " + data1Value + " " + operator.name() + " " + + val + " (" + data2Multiplier + "*" + data2Value + ")"; + } + + public boolean match(double data1Value, double data2Value) { + double threshold = (data2Multiplier * data2Value); + switch (operator) { + case LT: + return data1Value < threshold; + case GT: + return data1Value > threshold; + case LTE: + return data1Value <= threshold; + case GTE: + return data1Value >= threshold; + default: + log.warn("Unknown operator: " + operator.name()); + return false; + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + CompareCondition that = (CompareCondition) o; + + if (data1Id != null ? !data1Id.equals(that.data1Id) : that.data1Id != null) return false; + if (data2Id != null ? !data2Id.equals(that.data2Id) : that.data2Id != null) return false; + if (data2Multiplier != null ? !data2Multiplier.equals(that.data2Multiplier) : that.data2Multiplier != null) + return false; + if (operator != that.operator) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (data1Id != null ? data1Id.hashCode() : 0); + result = 31 * result + (operator != null ? operator.hashCode() : 0); + result = 31 * result + (data2Id != null ? data2Id.hashCode() : 0); + result = 31 * result + (data2Multiplier != null ? data2Multiplier.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "CompareCondition{triggerId='" + triggerId + '\'' + + "data1Id='" + data1Id + '\'' + + ", operator=" + operator + + ", data2Id='" + data2Id + '\'' + + ", data2Multiplier=" + data2Multiplier + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/CompareConditionEval.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/CompareConditionEval.java new file mode 100644 index 000000000..8c7c24459 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/CompareConditionEval.java @@ -0,0 +1,121 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +/** + * An evaluation state for compare condition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class CompareConditionEval extends ConditionEval { + + private CompareCondition condition; + private Double value1; + private Double value2; + + public CompareConditionEval() { + super(false); + this.condition = null; + this.value1 = null; + this.value2 = null; + } + + public CompareConditionEval(CompareCondition condition, Double value1, Double value2) { + super(condition.match(value1, value2)); + this.condition = condition; + this.value1 = value1; + this.value2 = value2; + } + + public CompareCondition getCondition() { + return condition; + } + + public void setCondition(CompareCondition condition) { + this.condition = condition; + } + + public Double getValue1() { + return value1; + } + + public void setValue1(Double value1) { + this.value1 = value1; + } + + public Double getValue2() { + return value2; + } + + public void setValue2(Double value2) { + this.value2 = value2; + } + + @Override + public String getTriggerId() { + return condition.getTriggerId(); + } + + @Override + public int getConditionSetSize() { + return condition.getConditionSetSize(); + } + + @Override + public int getConditionSetIndex() { + return condition.getConditionSetIndex(); + } + + @Override + public String getLog() { + return condition.getLog(value1, value2); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + CompareConditionEval that = (CompareConditionEval) o; + + if (condition != null ? !condition.equals(that.condition) : that.condition != null) return false; + if (value1 != null ? !value1.equals(that.value1) : that.value1 != null) return false; + if (value2 != null ? !value2.equals(that.value2) : that.value2 != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (condition != null ? condition.hashCode() : 0); + result = 31 * result + (value1 != null ? value1.hashCode() : 0); + result = 31 * result + (value2 != null ? value2.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "CompareConditionEval{" + + "condition=" + condition + + ", value1=" + value1 + + ", value2=" + value2 + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/Condition.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/Condition.java new file mode 100644 index 000000000..b8b34d050 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/Condition.java @@ -0,0 +1,108 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +/** + * A base class for condition definition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public abstract class Condition { + + /** + * The owning trigger + */ + protected String triggerId; + + /** + * Number of conditions associated with a particular trigger. + * i.e. 2 [ conditions ] + */ + protected int conditionSetSize; + + /** + * Index of the current condition + * i.e. 1 [ of 2 conditions ] + */ + protected int conditionSetIndex; + + public Condition(String triggerId, int conditionSetSize, int conditionSetIndex) { + this.triggerId = triggerId; + this.conditionSetSize = conditionSetSize; + this.conditionSetIndex = conditionSetIndex; + } + + public int getConditionSetIndex() { + return conditionSetIndex; + } + + public void setConditionSetIndex(int conditionSetIndex) { + this.conditionSetIndex = conditionSetIndex; + } + + public int getConditionSetSize() { + return conditionSetSize; + } + + public void setConditionSetSize(int conditionSetSize) { + this.conditionSetSize = conditionSetSize; + } + + public String getTriggerId() { + return triggerId; + } + + public void setTriggerId(String triggerId) { + this.triggerId = triggerId; + } + + public String getConditionId() { + return triggerId + "/" + conditionSetSize + "/" + conditionSetIndex; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Condition condition = (Condition) o; + + if (conditionSetIndex != condition.conditionSetIndex) return false; + if (conditionSetSize != condition.conditionSetSize) return false; + if (triggerId != null ? !triggerId.equals(condition.triggerId) : condition.triggerId != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = triggerId != null ? triggerId.hashCode() : 0; + result = 31 * result + conditionSetSize; + result = 31 * result + conditionSetIndex; + return result; + } + + @Override + public String toString() { + return "Condition{" + + "conditionSetIndex=" + conditionSetIndex + + ", triggerId='" + triggerId + '\'' + + ", conditionSetSize=" + conditionSetSize + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ConditionEval.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ConditionEval.java new file mode 100644 index 000000000..4bcf7aa0a --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ConditionEval.java @@ -0,0 +1,86 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +/** + * An evaluation state of a specific condition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public abstract class ConditionEval { + + protected boolean match; + protected long time; + + public ConditionEval(boolean match) { + this.match = match; + this.time = System.currentTimeMillis(); + } + + public boolean isMatch() { + return match; + } + + public void setMatch(boolean match) { + this.match = match; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public abstract String getTriggerId(); + + public abstract int getConditionSetSize(); + + public abstract int getConditionSetIndex(); + + public abstract String getLog(); + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ConditionEval that = (ConditionEval) o; + + if (match != that.match) return false; + if (time != that.time) return false; + + return true; + } + + @Override + public int hashCode() { + int result = (match ? 1 : 0); + result = 31 * result + (int) (time ^ (time >>> 32)); + return result; + } + + @Override + public String toString() { + return "ConditionEval{" + + "match=" + match + + ", time=" + time + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/StringCondition.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/StringCondition.java new file mode 100644 index 000000000..156524786 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/StringCondition.java @@ -0,0 +1,153 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A string comparison condition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class StringCondition extends Condition { + private static final Logger log = LoggerFactory.getLogger(StringCondition.class); + + public enum Operator { + EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, MATCH + } + + private String dataId; + private Operator operator; + private String pattern; + private boolean ignoreCase; + + public StringCondition() { + /* + Default constructor is needed for JSON libraries in JAX-RS context. + */ + this("DefaultId", 1, 1, null, null, null, false); + } + + public StringCondition(String triggerId, int conditionSetSize, int conditionSetIndex, + String dataId, Operator operator, String pattern, boolean ignoreCase) { + super(triggerId, conditionSetSize, conditionSetIndex); + this.dataId = dataId; + this.operator = operator; + this.pattern = pattern; + this.ignoreCase = ignoreCase; + } + + public String getDataId() { + return dataId; + } + + public void setDataId(String dataId) { + this.dataId = dataId; + } + + public boolean isIgnoreCase() { + return ignoreCase; + } + + public void setIgnoreCase(boolean ignoreCase) { + this.ignoreCase = ignoreCase; + } + + public Operator getOperator() { + return operator; + } + + public void setOperator(Operator operator) { + this.operator = operator; + } + + public String getPattern() { + return pattern; + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } + + public String getLog(String value) { + return triggerId + " : " + value + " " + operator.name() + " " + + pattern + " " + "ignoreCase=" + ignoreCase; + } + + public boolean match(String value) { + + if (ignoreCase && operator != Operator.MATCH) { + pattern = pattern.toLowerCase(); + value = value.toLowerCase(); + } + switch (operator) { + case EQUAL: + return value.equals(pattern); + case NOT_EQUAL: + return !value.equals(pattern); + case ENDS_WITH: + return value.endsWith(pattern); + case STARTS_WITH: + return value.startsWith(pattern); + case CONTAINS: + return value.contains(pattern); + case MATCH: + return value.matches(pattern); + default: + log.warn("Unknown operator: " + operator.name()); + return false; + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + StringCondition that = (StringCondition) o; + + if (ignoreCase != that.ignoreCase) return false; + if (dataId != null ? !dataId.equals(that.dataId) : that.dataId != null) return false; + if (operator != that.operator) return false; + if (pattern != null ? !pattern.equals(that.pattern) : that.pattern != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (dataId != null ? dataId.hashCode() : 0); + result = 31 * result + (operator != null ? operator.hashCode() : 0); + result = 31 * result + (pattern != null ? pattern.hashCode() : 0); + result = 31 * result + (ignoreCase ? 1 : 0); + return result; + } + + @Override + public String toString() { + return "StringCondition{triggerId='" + triggerId + '\'' + + "dataId='" + dataId + '\'' + + ", operator=" + operator + + ", pattern='" + pattern + '\'' + + ", ignoreCase=" + ignoreCase + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/StringConditionEval.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/StringConditionEval.java new file mode 100644 index 000000000..679814148 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/StringConditionEval.java @@ -0,0 +1,107 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +/** + * An evaluation state for string condition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class StringConditionEval extends ConditionEval { + + private StringCondition condition; + private String value; + + public StringConditionEval() { + super(false); + this.condition = null; + this.value = null; + } + + public StringConditionEval(StringCondition condition, String value) { + super(condition.match(value)); + this.condition = condition; + this.value = value; + } + + public StringCondition getCondition() { + return condition; + } + + public void setCondition(StringCondition condition) { + this.condition = condition; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String getTriggerId() { + return condition.getTriggerId(); + } + + @Override + public int getConditionSetSize() { + return condition.getConditionSetSize(); + } + + @Override + public int getConditionSetIndex() { + return condition.getConditionSetIndex(); + } + + @Override + public String getLog() { + return condition.getLog(value); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + StringConditionEval that = (StringConditionEval) o; + + if (condition != null ? !condition.equals(that.condition) : that.condition != null) return false; + if (value != null ? !value.equals(that.value) : that.value != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (condition != null ? condition.hashCode() : 0); + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "StringConditionEval{" + + "condition=" + condition + + ", value='" + value + '\'' + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdCondition.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdCondition.java new file mode 100644 index 000000000..6d9123293 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdCondition.java @@ -0,0 +1,130 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A numeric threshold condition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class ThresholdCondition extends Condition { + private static final Logger log = LoggerFactory.getLogger(ThresholdCondition.class); + + public enum Operator { + LT, GT, LTE, GTE + } + + private String dataId; + private Operator operator; + private Double threshold; + + public ThresholdCondition() { + /* + Default constructor is needed for JSON libraries in JAX-RS context. + */ + this("DefaultId", 1, 1, null, null, null); + } + + public ThresholdCondition(String triggerId, int conditionSetSize, int conditionSetIndex, + String dataId, Operator operator, Double threshold) { + super(triggerId, conditionSetSize, conditionSetIndex); + this.dataId = dataId; + this.operator = operator; + this.threshold = threshold; + } + + public String getDataId() { + return dataId; + } + + public void setDataId(String dataId) { + this.dataId = dataId; + } + + public Operator getOperator() { + return operator; + } + + public void setOperator(Operator operator) { + this.operator = operator; + } + + public Double getThreshold() { + return threshold; + } + + public void setThreshold(Double threshold) { + this.threshold = threshold; + } + + public String getLog(double value) { + return triggerId + " : " + value + " " + operator.name() + " " + threshold; + } + + public boolean match(double value) { + switch (operator) { + case LT: + return value < threshold; + case GT: + return value > threshold; + case LTE: + return value <= threshold; + case GTE: + return value >= threshold; + default: + log.warn("Unknown operator: " + operator.name()); + return false; + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + ThresholdCondition that = (ThresholdCondition) o; + + if (dataId != null ? !dataId.equals(that.dataId) : that.dataId != null) return false; + if (operator != that.operator) return false; + if (threshold != null ? !threshold.equals(that.threshold) : that.threshold != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (dataId != null ? dataId.hashCode() : 0); + result = 31 * result + (operator != null ? operator.hashCode() : 0); + result = 31 * result + (threshold != null ? threshold.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "ThresholdCondition{triggerId='" + triggerId + '\'' + + "dataId='" + dataId + '\'' + + ", operator=" + operator + + ", threshold=" + threshold + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdConditionEval.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdConditionEval.java new file mode 100644 index 000000000..69f25d09a --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdConditionEval.java @@ -0,0 +1,107 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +/** + * An evaluation state for threshold condition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class ThresholdConditionEval extends ConditionEval { + + private ThresholdCondition condition; + private Double value; + + public ThresholdConditionEval() { + super(false); + this.condition = null; + this.value = null; + } + + public ThresholdConditionEval(ThresholdCondition condition, Double value) { + super(condition.match(value)); + this.condition = condition; + this.value = value; + } + + public ThresholdCondition getCondition() { + return condition; + } + + public void setCondition(ThresholdCondition condition) { + this.condition = condition; + } + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } + + @Override + public String getTriggerId() { + return condition.getTriggerId(); + } + + @Override + public int getConditionSetSize() { + return condition.getConditionSetSize(); + } + + @Override + public int getConditionSetIndex() { + return condition.getConditionSetIndex(); + } + + @Override + public String getLog() { + return condition.getLog(value); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + ThresholdConditionEval that = (ThresholdConditionEval) o; + + if (condition != null ? !condition.equals(that.condition) : that.condition != null) return false; + if (value != null ? !value.equals(that.value) : that.value != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (condition != null ? condition.hashCode() : 0); + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "ThresholdConditionEval{" + + "condition=" + condition + + ", value=" + value + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdRangeCondition.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdRangeCondition.java new file mode 100644 index 000000000..68df1f420 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdRangeCondition.java @@ -0,0 +1,206 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A numeric threshold range condition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class ThresholdRangeCondition extends Condition { + private static final Logger log = LoggerFactory.getLogger(ThresholdRangeCondition.class); + + public enum Operator { + INCLUSIVE("[", "]"), EXCLUSIVE("(", ")"); + + private String low, high; + + Operator(String low, String high) { + this.low = low; + this.high = high; + } + + public String getLow() { + return low; + } + + public String getHigh() { + return high; + } + } + + private String dataId; + private Operator operatorLow; + private Operator operatorHigh; + private Double thresholdLow; + private Double thresholdHigh; + private boolean inRange; + + public ThresholdRangeCondition() { + /* + Default constructor is needed for JSON libraries in JAX-RS context. + */ + this("DefaultId", 1, 1, null, null, null, null, null, false); + } + + public ThresholdRangeCondition(String triggerId, int conditionSetSize, int conditionSetIndex, + String dataId, Operator operatorLow, Operator operatorHigh, + Double thresholdLow, Double thresholdHigh, boolean inRange) { + super(triggerId, conditionSetSize, conditionSetIndex); + this.dataId = dataId; + this.operatorLow = operatorLow; + this.operatorHigh = operatorHigh; + this.thresholdLow = thresholdLow; + this.thresholdHigh = thresholdHigh; + this.inRange = inRange; + } + + public String getDataId() { + return dataId; + } + + public void setDataId(String dataId) { + this.dataId = dataId; + } + + public boolean isInRange() { + return inRange; + } + + public void setInRange(boolean inRange) { + this.inRange = inRange; + } + + public Operator getOperatorHigh() { + return operatorHigh; + } + + public void setOperatorHigh(Operator operatorHigh) { + this.operatorHigh = operatorHigh; + } + + public Operator getOperatorLow() { + return operatorLow; + } + + public void setOperatorLow(Operator operatorLow) { + this.operatorLow = operatorLow; + } + + public Double getThresholdHigh() { + return thresholdHigh; + } + + public void setThresholdHigh(Double thresholdHigh) { + this.thresholdHigh = thresholdHigh; + } + + public Double getThresholdLow() { + return thresholdLow; + } + + public void setThresholdLow(Double thresholdLow) { + this.thresholdLow = thresholdLow; + } + + public String getLog(double value) { + String range = operatorLow.getLow() + thresholdLow + " , " + thresholdHigh + operatorHigh.getHigh(); + return triggerId + " : " + value + " " + range; + } + + public boolean match(double value) { + boolean aboveLow = false; + boolean belowHigh = false; + + switch (operatorLow) { + case INCLUSIVE: + aboveLow = value >= thresholdLow; + break; + case EXCLUSIVE: + aboveLow = value > thresholdLow; + break; + default: + log.warn("Unknown operator low: " + operatorLow.name()); + return false; + } + + if (!aboveLow && inRange) { + return false; + } + + switch (operatorHigh) { + case INCLUSIVE: + belowHigh = value <= thresholdHigh; + break; + case EXCLUSIVE: + belowHigh = value < thresholdHigh; + break; + default: + log.warn("Unknown operator high: " + operatorHigh.name()); + return false; + } + + return (belowHigh == inRange); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + ThresholdRangeCondition that = (ThresholdRangeCondition) o; + + if (inRange != that.inRange) return false; + if (dataId != null ? !dataId.equals(that.dataId) : that.dataId != null) return false; + if (operatorHigh != that.operatorHigh) return false; + if (operatorLow != that.operatorLow) return false; + if (thresholdHigh != null ? !thresholdHigh.equals(that.thresholdHigh) : that.thresholdHigh != null) + return false; + if (thresholdLow != null ? !thresholdLow.equals(that.thresholdLow) : that.thresholdLow != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (dataId != null ? dataId.hashCode() : 0); + result = 31 * result + (operatorLow != null ? operatorLow.hashCode() : 0); + result = 31 * result + (operatorHigh != null ? operatorHigh.hashCode() : 0); + result = 31 * result + (thresholdLow != null ? thresholdLow.hashCode() : 0); + result = 31 * result + (thresholdHigh != null ? thresholdHigh.hashCode() : 0); + result = 31 * result + (inRange ? 1 : 0); + return result; + } + + @Override + public String toString() { + return "ThresholdRangeCondition{triggerId='" + triggerId + '\'' + + "dataId='" + dataId + '\'' + + ", operatorLow=" + operatorLow + + ", operatorHigh=" + operatorHigh + + ", thresholdLow=" + thresholdLow + + ", thresholdHigh=" + thresholdHigh + + ", inRange=" + inRange + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdRangeConditionEval.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdRangeConditionEval.java new file mode 100644 index 000000000..3439b656b --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/condition/ThresholdRangeConditionEval.java @@ -0,0 +1,107 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.condition; + +/** + * An evaluation state for threshold range condition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class ThresholdRangeConditionEval extends ConditionEval { + + private ThresholdRangeCondition condition; + private Double value; + + public ThresholdRangeConditionEval() { + super(false); + this.condition = null; + this.value = null; + } + + public ThresholdRangeConditionEval(ThresholdRangeCondition condition, Double value) { + super(condition.match(value)); + this.condition = condition; + this.value = value; + } + + public ThresholdRangeCondition getCondition() { + return condition; + } + + public void setCondition(ThresholdRangeCondition condition) { + this.condition = condition; + } + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } + + @Override + public String getTriggerId() { + return condition.getTriggerId(); + } + + @Override + public int getConditionSetSize() { + return condition.getConditionSetSize(); + } + + @Override + public int getConditionSetIndex() { + return condition.getConditionSetIndex(); + } + + @Override + public String getLog() { + return condition.getLog(value); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + ThresholdRangeConditionEval that = (ThresholdRangeConditionEval) o; + + if (condition != null ? !condition.equals(that.condition) : that.condition != null) return false; + if (value != null ? !value.equals(that.value) : that.value != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (condition != null ? condition.hashCode() : 0); + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "ThresholdRangeConditionEval{" + + "condition=" + condition + + ", value=" + value + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/dampening/Dampening.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/dampening/Dampening.java new file mode 100644 index 000000000..dae3f99a4 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/dampening/Dampening.java @@ -0,0 +1,216 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.dampening; + +import org.hawkular.alerts.api.model.condition.ConditionEval; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * A representation of dampening status. + * + * @author Jay Shaughnessy + */ +public class Dampening { + + public enum Type { + STRICT, RELAXED_COUNT, RELAXED_TIME + }; + + private String triggerId; + private Type type; + private int evalTrueSetting; + private int evalTotalSetting; + private long evalTimeSetting; + + private int numTrueEvals; + private int numEvals; + private long trueEvalsStartTime; + private boolean satisfied; + private List> satisfyingEvals = new ArrayList>(); + + public Dampening(String triggerId, Type type, int evalTrueSetting, int evalTotalSetting, long evalTimeSetting) { + super(); + this.triggerId = triggerId; + this.type = type; + this.evalTrueSetting = evalTrueSetting; + this.evalTotalSetting = evalTotalSetting; + this.evalTimeSetting = evalTimeSetting; + + reset(); + } + + public String getTriggerId() { + return triggerId; + } + + public int getNumTrueEvals() { + return numTrueEvals; + } + + public void setNumTrueEvals(int numTrueEvals) { + this.numTrueEvals = numTrueEvals; + } + + public long getTrueEvalsStartTime() { + return trueEvalsStartTime; + } + + public void setTrueEvalsStartTime(long trueEvalsStartTime) { + this.trueEvalsStartTime = trueEvalsStartTime; + } + + public int getNumEvals() { + return numEvals; + } + + public void setNumEvals(int numEvals) { + this.numEvals = numEvals; + } + + public Type getType() { + return type; + } + + public int getEvalTrueSetting() { + return evalTrueSetting; + } + + public int getEvalTotalSetting() { + return evalTotalSetting; + } + + public long getEvalTimeSetting() { + return evalTimeSetting; + } + + public boolean isSatisfied() { + return satisfied; + } + + public List> getSatisfyingEvals() { + return satisfyingEvals; + } + + public void addSatisfyingEvals(Set satisfyingEvals) { + this.satisfyingEvals.add(satisfyingEvals); + } + + public void addSatisfyingEvals(ConditionEval... satisfyingEvals) { + this.satisfyingEvals.add(new HashSet(Arrays.asList(satisfyingEvals))); + } + + public void perform(ConditionEval... conditionEvals) { + boolean trueEval = true; + for (ConditionEval ce : conditionEvals) { + if (!ce.isMatch()) { + trueEval = false; + break; + } + } + + // If we had previously started our time and now have exceeded our time limit then we must start over + long now = System.currentTimeMillis(); + if (type == Type.RELAXED_TIME && trueEvalsStartTime != 0L) { + if ((now - trueEvalsStartTime) > evalTimeSetting) { + reset(); + } + } + + numEvals += 1; + if (trueEval) { + numTrueEvals += 1; + addSatisfyingEvals(conditionEvals); + + switch (type) { + case STRICT: + case RELAXED_COUNT: + if (numTrueEvals == evalTrueSetting) { + satisfied = true; + } + break; + + case RELAXED_TIME: + if (trueEvalsStartTime == 0L) { + trueEvalsStartTime = now; + } + if ((numTrueEvals == evalTrueSetting) && ((now - trueEvalsStartTime) < evalTimeSetting)) { + satisfied = true; + } + break; + } + } else { + switch (type) { + case STRICT: + reset(); + break; + case RELAXED_COUNT: + int numNeeded = evalTrueSetting - numTrueEvals; + int chancesLeft = evalTotalSetting - numEvals; + if (numNeeded > chancesLeft) { + reset(); + } + break; + case RELAXED_TIME: + break; + } + } + } + + public void reset() { + this.numTrueEvals = 0; + this.numEvals = 0; + this.trueEvalsStartTime = 0L; + this.satisfied = false; + this.satisfyingEvals.clear(); + } + + public String getLog() { + StringBuilder sb = new StringBuilder("[" + triggerId + ", numTrueEvals=" + + numTrueEvals + ", numEvals=" + numEvals + ", trueEvalsStartTime=" + trueEvalsStartTime + + ", satisfied=" + satisfied); + if (satisfied) { + for (Set ces : satisfyingEvals) { + sb.append("\n\t["); + String space = ""; + for (ConditionEval ce : ces) { + sb.append(space); + sb.append("["); + sb.append(ce.getLog()); + sb.append("]"); + space = " "; + } + sb.append("]"); + + } + } + return sb.toString(); + } + + @Override + public String toString() { + return "Dampening [triggerId=" + triggerId + ", type=" + type + ", evalTrueSetting=" + evalTrueSetting + + ", evalTotalSetting=" + evalTotalSetting + ", evalTimeSetting=" + evalTimeSetting + ", numTrueEvals=" + + numTrueEvals + ", numEvals=" + numEvals + ", trueEvalsStartTime=" + trueEvalsStartTime + + ", satisfied=" + satisfied + ", satisfyingEvals=" + satisfyingEvals + "]"; + } + +} \ No newline at end of file diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/Availability.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/Availability.java new file mode 100644 index 000000000..81134d53d --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/Availability.java @@ -0,0 +1,76 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.data; + +/** + * An availability incoming data. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class Availability extends Data { + + public enum AvailabilityType { + UP, DOWN, UNAVAILABLE + } + + private AvailabilityType value; + + public Availability() { + this(null, null); + } + + public Availability(String id, AvailabilityType value) { + this.id = id; + this.value = value; + } + + public AvailabilityType getValue() { + return value; + } + + public void setValue(AvailabilityType value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + Availability that = (Availability) o; + + if (value != that.value) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "Availability{id='" + id + '\'' + + "value=" + value + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/Data.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/Data.java new file mode 100644 index 000000000..785efe365 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/Data.java @@ -0,0 +1,71 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.data; + +/** + * A base class for incoming data into alerts subsystem. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class Data { + + protected String id; + + public Data() { + /* + Default constructor is needed for JSON libraries in JAX-RS context. + */ + this.id = null; + } + + public Data(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Data data = (Data) o; + + if (id != null ? !id.equals(data.id) : data.id != null) return false; + + return true; + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + @Override + public String toString() { + return "Data{" + + "id='" + id + '\'' + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/NumericData.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/NumericData.java new file mode 100644 index 000000000..6e8a7b1a4 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/NumericData.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.data; + +/** + * A numeric incoming data. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class NumericData extends Data { + + private Double value; + + public NumericData() { + /* + Default constructor is needed for JSON libraries in JAX-RS context. + */ + this(null, null); + } + + public NumericData(String id, Double value) { + this.id = id; + this.value = value; + } + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + NumericData that = (NumericData) o; + + if (value != null ? !value.equals(that.value) : that.value != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "NumericData{id='" + id + '\'' + + ", value=" + value + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/StringData.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/StringData.java new file mode 100644 index 000000000..429b878bb --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/data/StringData.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.data; + +/** + * A string incoming data. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class StringData extends Data { + + private String value; + + public StringData() { + /* + Default constructor is needed for JSON libraries in JAX-RS context. + */ + this(null, null); + } + + public StringData(String id, String value) { + this.id = id; + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + StringData that = (StringData) o; + + if (value != null ? !value.equals(that.value) : that.value != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "StringData{id='" + id + '\'' + + ", value='" + value + '\'' + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/notification/Notification.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/notification/Notification.java new file mode 100644 index 000000000..0f6176ab1 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/notification/Notification.java @@ -0,0 +1,76 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.notification; + +/** + * A base class for notification representation from the perspective of the alerts engine. + * Alert engine only needs to know a destination id and message to send. + * + * Notifiers plugin will be responsible to process these notifications according with specific configuration. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class Notification { + + private String notifierId; + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getNotifierId() { + return notifierId; + } + + public void setNotifierId(String notifierId) { + this.notifierId = notifierId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Notification that = (Notification) o; + + if (message != null ? !message.equals(that.message) : that.message != null) return false; + if (notifierId != null ? !notifierId.equals(that.notifierId) : that.notifierId != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = notifierId != null ? notifierId.hashCode() : 0; + result = 31 * result + (message != null ? message.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "Notification{" + + "message='" + message + '\'' + + ", notifierId='" + notifierId + '\'' + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/trigger/Trigger.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/trigger/Trigger.java new file mode 100644 index 000000000..f3730c2c5 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/trigger/Trigger.java @@ -0,0 +1,96 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.trigger; + +/** + * A trigger definition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class Trigger extends TriggerTemplate { + + private String id; + private boolean active; + + public Trigger() { + /* + Default constructor is needed for JSON libraries in JAX-RS context. + */ + this("DefaultId", null); + } + + public Trigger(String id, String name) { + this(id, name, true); + } + + public Trigger(String id, String name, boolean active) { + super(name); + + if (id == null || id.isEmpty()) { + throw new IllegalArgumentException("Trigger id must be non-empty"); + } + this.id = id; + this.active = active; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + Trigger trigger = (Trigger) o; + + if (active != trigger.active) return false; + if (id != null ? !id.equals(trigger.id) : trigger.id != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (id != null ? id.hashCode() : 0); + result = 31 * result + (active ? 1 : 0); + return result; + } + + @Override + public String toString() { + return "Trigger{" + + "active=" + active + + ", id='" + id + '\'' + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/trigger/TriggerTemplate.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/trigger/TriggerTemplate.java new file mode 100644 index 000000000..a89b832c7 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/model/trigger/TriggerTemplate.java @@ -0,0 +1,174 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.model.trigger; + +import org.hawkular.alerts.api.model.condition.Condition; + +import java.util.HashSet; +import java.util.Set; + +/** + * A base template for trigger definition. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class TriggerTemplate { + + public enum Match { + ALL, ANY + }; + + private String name; + private String description; + private Match match; + private Set conditions; + + /** + * A group of notifier's ids. + */ + private Set notifiers; + + public TriggerTemplate(String name) { + this.name = name; + this.match = Match.ALL; + this.conditions = new HashSet(); + this.notifiers = new HashSet(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Trigger name must be non-empty."); + } + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Match getMatch() { + return match; + } + + public void setMatch(Match match) { + this.match = match; + } + + public Set getConditions() { + return conditions; + } + + public void setConditions(Set conditions) { + this.conditions = conditions; + } + + public void addCondition(Condition condition) { + if (condition == null) { + return; + } + conditions.add(condition); + } + + public void addConditions(Set conditions) { + if (conditions == null) { + return; + } + this.conditions.addAll(conditions); + } + + public void removeCondition(Condition condition) { + if (condition == null) { + return; + } + conditions.remove(condition); + } + + public Set getNotifiers() { + return notifiers; + } + + public void setNotifiers(Set notifiers) { + this.notifiers = notifiers; + } + + public void addNotifier(String id) { + if (id == null || id.isEmpty()) { + throw new IllegalArgumentException("Notifier id must be non-empty."); + } + notifiers.add(id); + } + + public void addNotifiers(Set ids) { + if (ids == null) { + return; + } + notifiers.addAll(ids); + } + + public void removeNotifier(String id) { + if (id == null || id.isEmpty()) { + throw new IllegalArgumentException("Notifier id must be non-empty."); + } + notifiers.remove(id); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TriggerTemplate)) return false; + + TriggerTemplate that = (TriggerTemplate) o; + + if (conditions != null ? !conditions.equals(that.conditions) : that.conditions != null) return false; + if (description != null ? !description.equals(that.description) : that.description != null) return false; + if (match != that.match) return false; + if (name != null ? !name.equals(that.name) : that.name != null) return false; + if (notifiers != null ? !notifiers.equals(that.notifiers) : that.notifiers != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (description != null ? description.hashCode() : 0); + result = 31 * result + (match != null ? match.hashCode() : 0); + result = 31 * result + (conditions != null ? conditions.hashCode() : 0); + result = 31 * result + (notifiers != null ? notifiers.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "TriggerTemplate{" + + "name='" + name + '\'' + + ", description='" + description + '\'' + + ", match=" + match + + ", conditions=" + conditions + + ", notifiers=" + notifiers + + '}'; + } +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/AlertsService.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/AlertsService.java new file mode 100644 index 000000000..ed6c1704f --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/AlertsService.java @@ -0,0 +1,47 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.services; + +import org.hawkular.alerts.api.model.condition.Alert; +import org.hawkular.alerts.api.model.data.Data; + +import java.util.Collection; + +/** + * Interface that allows to send data to the alerts engine and check resulting state. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public interface AlertsService { + + void sendData(Data data); + void sendData(Collection data); + + Collection checkAlerts(); + + /** + * Reload all alerts definitions. + */ + void reload(); + + /** + * Reset session state. + */ + void clear(); + +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/DefinitionsService.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/DefinitionsService.java new file mode 100644 index 000000000..767e8e32b --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/DefinitionsService.java @@ -0,0 +1,95 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.services; + +import org.hawkular.alerts.api.model.condition.Condition; +import org.hawkular.alerts.api.model.dampening.Dampening; +import org.hawkular.alerts.api.model.trigger.Trigger; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +/** + * A interface used to create new triggers, conditions and init new notifiers. + * + * Implementation should manage the persistence of the definitions. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public interface DefinitionsService { + + /* + CRUD interface for Trigger + */ + void addTrigger(Trigger trigger); + void removeTrigger(String triggerId); + void updateTrigger(Trigger trigger); + Collection getTriggers(); + Trigger getTrigger(String triggerId); + + /* + CRUD interface for Trigger + */ + void addDampening(Dampening dampening); + void removeDampening(String triggerId); + void updateDampening(Dampening dampening); + Collection getDampenings(); + Dampening getDampening(String triggerId); + + /* + CRUD interface for Condition + */ + void addCondition(Condition condition); + void removeCondition(String conditionId); + void updateCondition(Condition condition); + Collection getConditions(); + Collection getConditions(String triggerId); + Condition getCondition(String conditionId); + + + /* + A notifier type is representation of a notifier capability. + i.e. email, snmp or sms. + It will have a set of specific properties to fill per a specific notifier. + + Notifier plugin should be responsible to init a notifier type before to send notifications. + + NotifierType API will be useful for future UI to help to define new notifiers. + i.e. querying for properties to fill for a specific notifier type. + */ + void addNotifierType(String notifierType, Set properties); + void removeNotifierType(String notifierType); + void updateNotifierType(String notifierType, Set properties); + Collection getNotifierTypes(); + Set getNotifierType(String notifierType); + + /* + A notifier is a specific instance of notification. + i.e. email to admin@mycompany.com. + send a specific TRAP with specific details. + send a SMS mobile to an admin number. + */ + void addNotifier(String notifierId, Map properties); + void removeNotifier(String notifierId); + void updateNotifier(String notifierId, Map properties); + Collection getNotifiers(); + Collection getNotifiers(String notifierType); + Map getNotifier(String notifierId); + +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/NotificationsService.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/NotificationsService.java new file mode 100644 index 000000000..93dfb4171 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/NotificationsService.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.services; + +import org.hawkular.alerts.api.model.notification.Notification; + +/** + * A interface used to send notifications. + * + * Notifications will be created inside of the alerts engine and will be send them to the bus + * where they will be read for specific notifier-plugins. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public interface NotificationsService { + + /** + * Send a notification to an internal queue. + * Primary used by the alerts-engine implementation to send a notification. + * + * @param notification Notification to send + */ + void send(Notification notification); + + /** + * Register a listener that will process a notification send to the service asynchronously. + */ + void register(NotifierListener listener); +} diff --git a/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/NotifierListener.java b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/NotifierListener.java new file mode 100644 index 000000000..bd2de2796 --- /dev/null +++ b/hawkular-alerts-api/src/main/java/org/hawkular/alerts/api/services/NotifierListener.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.api.services; + +import org.hawkular.alerts.api.model.notification.Notification; + +/** + * A listener that will process a notification sent to the NotificationService. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public interface NotifierListener { + + /** + * Process a notification sent to {@link org.hawkular.alerts.api.services.NotifierListener}. + * It is responsability of NotifierListener implementation how this listener it will be invoked. + * + * @param notification Notification to be processed. + */ + void process(Notification notification); +} diff --git a/hawkular-alerts-bus/pom.xml b/hawkular-alerts-bus/pom.xml new file mode 100644 index 000000000..0d8f89b83 --- /dev/null +++ b/hawkular-alerts-bus/pom.xml @@ -0,0 +1,111 @@ + + + + + 4.0.0 + + + org.hawkular.alerts + hawkular-alerts + 1.0.0.Alpha1-SNAPSHOT + + + hawkular-alerts-bus + jar + Hawkular Alerts Bus Listener + + + + + org.hawkular.alerts + hawkular-alerts-api + ${project.version} + + + + org.hawkular.alerts + hawkular-notifiers-api + ${project.version} + + + + + org.hawkular.bus + hawkular-bus-mdb + ${project.version} + provided + + + + + com.google.guava + guava + ${version.com.google.guava} + provided + + + + com.google.code.gson + gson + ${version.com.google.code.gson} + provided + + + + + org.apache.activemq + activemq-all + ${version.org.apache.activemq} + provided + + + + org.apache.activemq + activemq-jaas + ${version.org.apache.activemq} + provided + + + + org.slf4j + slf4j-api + ${version.org.slf4j} + provided + + + + javax + javaee-api + ${version.javaee.spec} + provided + + + + junit + junit + ${version.junit} + test + + + + + diff --git a/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/init/AlertEngineRegister.java b/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/init/AlertEngineRegister.java new file mode 100644 index 000000000..b5d664f57 --- /dev/null +++ b/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/init/AlertEngineRegister.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.bus.init; + +import org.hawkular.alerts.api.services.NotificationsService; +import org.hawkular.alerts.bus.sender.NotificationSender; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.PostConstruct; +import javax.ejb.EJB; +import javax.ejb.Singleton; +import javax.ejb.Startup; + +/** + * A helper class to initialize bus callbacks into the alerts engine. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@Startup +@Singleton +public class AlertEngineRegister { + private final Logger log = LoggerFactory.getLogger(AlertEngineRegister.class); + + @EJB + NotificationsService notifications; + + @PostConstruct + public void init() { + NotificationSender sender = new NotificationSender(); + notifications.register(sender); + log.info("Registering sender: " + sender); + } +} diff --git a/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/listener/AlertDataListener.java b/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/listener/AlertDataListener.java new file mode 100644 index 000000000..7be5a40af --- /dev/null +++ b/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/listener/AlertDataListener.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.bus.listener; + +import org.hawkular.alerts.api.services.AlertsService; +import org.hawkular.alerts.bus.messages.AlertDataMessage; +import org.hawkular.bus.common.consumer.BasicMessageListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.EJB; +import javax.ejb.MessageDriven; +import javax.jms.MessageListener; + +/** + * A component that listens from the bus data to send into the alerts engine. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@MessageDriven(messageListenerInterface = MessageListener.class, activationConfig = { + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "MetricsTopic")}) +public class AlertDataListener extends BasicMessageListener { + private final Logger log = LoggerFactory.getLogger(AlertDataListener.class); + + @EJB + AlertsService alerts; + + @Override + protected void onBasicMessage(AlertDataMessage msg) { + if (log.isDebugEnabled()) { + log.debug("Message received: [{}]", msg); + } + alerts.sendData(msg.getData()); + } +} diff --git a/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/listener/NotifierTypeListener.java b/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/listener/NotifierTypeListener.java new file mode 100644 index 000000000..17440eb81 --- /dev/null +++ b/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/listener/NotifierTypeListener.java @@ -0,0 +1,67 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.bus.listener; + +import org.hawkular.alerts.api.services.DefinitionsService; +import org.hawkular.bus.common.consumer.BasicMessageListener; +import org.hawkular.notifiers.api.model.NotifierTypeRegistrationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.EJB; +import javax.ejb.MessageDriven; +import javax.jms.MessageListener; +import java.util.Set; + +/** + * A component that listens from the bus new notifier plugins to be registered into the alerts engine. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@MessageDriven(messageListenerInterface = MessageListener.class, activationConfig = { + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "NotifierTypeRegisterQueue")}) +public class NotifierTypeListener extends BasicMessageListener { + private final Logger log = LoggerFactory.getLogger(NotifierTypeListener.class); + + @EJB + DefinitionsService definitions; + + @Override + protected void onBasicMessage(NotifierTypeRegistrationMessage msg) { + if (log.isDebugEnabled()) { + log.debug("Message received: [{}]", msg); + } + String op = msg.getOp(); + if (op == null || op.isEmpty()) { + log.warn("Notifier type registration received without op."); + } else if (op.equals("init")) { + String notifierType = msg.getNotifierType(); + if (definitions.getNotifierType(notifierType) == null) { + Set properties = msg.getProperties(); + definitions.addNotifierType(notifierType, properties); + log.info("Notifier type {} registered.", notifierType); + } else { + log.warn("Notifier type {} is already registered", notifierType); + } + } else { + log.warn("Notifier type registration received with unknown op {} ", op); + } + } +} diff --git a/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/messages/AlertData.java b/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/messages/AlertData.java new file mode 100644 index 000000000..8643ef1f4 --- /dev/null +++ b/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/messages/AlertData.java @@ -0,0 +1,105 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.bus.messages; + +import com.google.gson.annotations.Expose; +import org.hawkular.alerts.api.model.data.Availability; +import org.hawkular.alerts.api.model.data.Data; +import org.hawkular.alerts.api.model.data.NumericData; +import org.hawkular.alerts.api.model.data.StringData; + +/** + * A basic data to be consumed by the alerts subsystem. + * This data will come from a JSON representation, so it will define target type as a field member. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class AlertData { + + @Expose + private final String id; + + @Expose + private final String value; + + @Expose + private final String type; + + public AlertData() { + this(null, null, null); + } + + public AlertData(String id, String value, String type) { + this.id = id; + this.value = value; + this.type = type; + } + + public Data convert() { + if (type != null && !type.isEmpty() && type.equalsIgnoreCase("numeric")) { + return new NumericData(id, Double.valueOf(value)); + } else if (type != null && !type.isEmpty() && type.equalsIgnoreCase("availability")) { + return new Availability(id, Availability.AvailabilityType.valueOf(value)); + } else { + return new StringData(id, value); + } + } + + public String getId() { + return id; + } + + public String getType() { + return type; + } + + public String getValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AlertData alertData = (AlertData) o; + + if (id != null ? !id.equals(alertData.id) : alertData.id != null) return false; + if (type != null ? !type.equals(alertData.type) : alertData.type != null) return false; + if (value != null ? !value.equals(alertData.value) : alertData.value != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = id != null ? id.hashCode() : 0; + result = 31 * result + (value != null ? value.hashCode() : 0); + result = 31 * result + (type != null ? type.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "AlertData{" + + "id='" + id + '\'' + + ", value='" + value + '\'' + + ", type='" + type + '\'' + + '}'; + } +} diff --git a/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/messages/AlertDataMessage.java b/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/messages/AlertDataMessage.java new file mode 100644 index 000000000..0b102bc0f --- /dev/null +++ b/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/messages/AlertDataMessage.java @@ -0,0 +1,80 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.bus.messages; + +import com.google.gson.annotations.Expose; +import org.hawkular.alerts.api.model.data.Data; +import org.hawkular.bus.common.BasicMessage; + +import java.util.ArrayList; +import java.util.List; + +/** + * A bus message used to receive data for the alerts subsystem. + * One message can store a collection of {@link org.hawkular.alerts.bus.messages.AlertData}. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class AlertDataMessage extends BasicMessage { + + @Expose + List data; + + protected AlertDataMessage() { } + + public AlertDataMessage(List data) { + this.data = new ArrayList(data); + } + + public AlertDataMessage(AlertData... data) { + this.data = new ArrayList(); + if (data != null) { + for (AlertData item : data) { + this.data.add(item); + } + } + } + + public List getData() { + if (data == null) { + return null; + } + List converted = new ArrayList(); + for (AlertData item : data) { + converted.add(item.convert()); + } + return converted; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AlertDataMessage that = (AlertDataMessage) o; + + if (data != null ? !data.equals(that.data) : that.data != null) return false; + + return true; + } + + @Override + public int hashCode() { + return data != null ? data.hashCode() : 0; + } +} diff --git a/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/sender/NotificationSender.java b/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/sender/NotificationSender.java new file mode 100644 index 000000000..b1d590487 --- /dev/null +++ b/hawkular-alerts-bus/src/main/java/org/hawkular/alerts/bus/sender/NotificationSender.java @@ -0,0 +1,107 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.bus.sender; + +import org.hawkular.alerts.api.model.notification.Notification; +import org.hawkular.alerts.api.services.DefinitionsService; +import org.hawkular.alerts.api.services.NotifierListener; +import org.hawkular.bus.common.ConnectionContextFactory; +import org.hawkular.bus.common.Endpoint; +import org.hawkular.bus.common.MessageId; +import org.hawkular.bus.common.MessageProcessor; +import org.hawkular.bus.common.producer.ProducerConnectionContext; +import org.hawkular.notifiers.api.model.NotificationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.jms.TopicConnectionFactory; +import javax.naming.InitialContext; +import java.util.HashMap; +import java.util.Map; + +/** + * An implementation of {@link org.hawkular.alerts.api.services.NotifierListener} that will send notifications + * messages through the bus. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class NotificationSender implements NotifierListener { + private final Logger log = LoggerFactory.getLogger(NotificationSender.class); + private final String CONNECTION_FACTORY = "java:/HawkularBusConnectionFactory"; + private final String NOTIFICATIONS_TOPIC = "NotificationsTopic"; + private final String DEFINITIONS_SERVICE = + "java:global/hawkular-alerts/hawkular-alerts-engine/MemDefinitionsServiceImpl"; + + private TopicConnectionFactory conFactory; + private ConnectionContextFactory ccf; + private ProducerConnectionContext pcc; + InitialContext ctx; + + DefinitionsService definitions; + + public NotificationSender() { + } + + @Override + public void process(Notification notification) { + try { + init(); + if (pcc == null) { + log.warn("Send " + notification); + } + NotificationMessage nMsg = new NotificationMessage(); + nMsg.setNotifierId(notification.getNotifierId()); + nMsg.setMessage(notification.getMessage()); + if (definitions != null) { + Map properties = definitions.getNotifier(notification.getNotifierId()); + MessageId mid; + if (properties != null && properties.containsKey("NotifierType")) { + String notifierType = properties.get("NotifierType"); + mid = new MessageProcessor().send(pcc, nMsg, notifierTypeFilter(notifierType)); + } else { + mid = new MessageProcessor().send(pcc, nMsg); + } + log.info("Sent {}", mid); + } else { + log.warn("Could not accesss to DefinitionsService"); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + + private void init() throws Exception { + if (ctx == null) { + ctx = new InitialContext(); + } + if (conFactory == null) { + conFactory = (TopicConnectionFactory) ctx.lookup(CONNECTION_FACTORY); + ccf = new ConnectionContextFactory(conFactory); + pcc = ccf.createProducerConnectionContext(new Endpoint(Endpoint.Type.TOPIC, NOTIFICATIONS_TOPIC)); + } + if (definitions == null) { + definitions = (DefinitionsService) ctx.lookup(DEFINITIONS_SERVICE); + } + } + + private static Map notifierTypeFilter(String notifierType) { + Map map = new HashMap(1); + map.put("NotifierType", notifierType); + return map; + } +} diff --git a/hawkular-alerts-ear/pom.xml b/hawkular-alerts-ear/pom.xml new file mode 100644 index 000000000..9b0472934 --- /dev/null +++ b/hawkular-alerts-ear/pom.xml @@ -0,0 +1,128 @@ + + + + + 4.0.0 + + + org.hawkular.alerts + hawkular-alerts + 1.0.0.Alpha1-SNAPSHOT + + + hawkular-alerts-ear + ear + Hawkular Alerts EAR + + + + + org.hawkular.alerts + hawkular-alerts-api + ${project.version} + jar + + + + org.hawkular.alerts + hawkular-notifiers-api + ${project.version} + jar + + + + org.hawkular.alerts + hawkular-alerts-engine + ${project.version} + ejb + + + + org.hawkular.alerts + hawkular-alerts-rest + ${project.version} + war + + + + org.hawkular.alerts + hawkular-alerts-bus + ${project.version} + ejb + + + + + + ${project.parent.artifactId} + + + + org.apache.maven.plugins + maven-ear-plugin + ${plugin.version.ear} + + 6 + lib + + + org.hawkular.alerts + hawkular-alerts-rest + /hawkular-alerts + + + no-version + + + + + + + + dev + + + + org.apache.maven.plugins + maven-antrun-plugin + + + deploy + install + + + + + + + run + + + + + + + + + + diff --git a/hawkular-alerts-ear/src/main/application/META-INF/jboss-deployment-structure.xml b/hawkular-alerts-ear/src/main/application/META-INF/jboss-deployment-structure.xml new file mode 100644 index 000000000..818e02036 --- /dev/null +++ b/hawkular-alerts-ear/src/main/application/META-INF/jboss-deployment-structure.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hawkular-alerts-engine/pom.xml b/hawkular-alerts-engine/pom.xml new file mode 100644 index 000000000..8f41e593f --- /dev/null +++ b/hawkular-alerts-engine/pom.xml @@ -0,0 +1,132 @@ + + + + + 4.0.0 + + + org.hawkular.alerts + hawkular-alerts + 1.0.0.Alpha1-SNAPSHOT + + + hawkular-alerts-engine + jar + Hawkular Alerts Engine + + + + + org.hawkular.alerts + hawkular-alerts-api + ${project.version} + + + + org.slf4j + slf4j-api + ${version.org.slf4j} + provided + + + + javax + javaee-api + ${version.javaee.spec} + provided + + + + org.kie + kie-api + ${version.org.drools} + + + org.drools + drools-core + ${version.org.drools} + + + org.drools + drools-compiler + ${version.org.drools} + + + + junit + junit + ${version.junit} + test + + + + org.slf4j + slf4j-simple + ${version.org.slf4j} + test + + + + + + + + src/main/resources + + hawkular-alerts/** + + false + + + + + + + dev + + + + org.apache.maven.plugins + maven-antrun-plugin + + + deploy + install + + + + + + + + + run + + + + + + + + + + diff --git a/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/BasicAlertsServiceImpl.java b/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/BasicAlertsServiceImpl.java new file mode 100644 index 000000000..f2886f426 --- /dev/null +++ b/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/BasicAlertsServiceImpl.java @@ -0,0 +1,186 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.engine.impl; + +import org.hawkular.alerts.api.model.condition.Alert; +import org.hawkular.alerts.api.model.condition.Condition; +import org.hawkular.alerts.api.model.dampening.Dampening; +import org.hawkular.alerts.api.model.data.Data; +import org.hawkular.alerts.api.model.trigger.Trigger; +import org.hawkular.alerts.api.services.AlertsService; +import org.hawkular.alerts.api.services.DefinitionsService; +import org.hawkular.alerts.api.services.NotificationsService; +import org.hawkular.alerts.engine.rules.RulesEngine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.PostConstruct; +import javax.ejb.EJB; +import javax.ejb.Singleton; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Basic implementation for {@link org.hawkular.alerts.api.services.AlertsService}. + * This implementation processes data asynchronously using a buffer queue. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@Singleton +public class BasicAlertsServiceImpl implements AlertsService { + private static final Logger log = LoggerFactory.getLogger(BasicAlertsServiceImpl.class); + private boolean debug = false; + private static final int DELAY; + private static final int PERIOD; + + private final List pendingData; + private final List alerts; + + private final Timer wakeUpTimer; + private TimerTask rulesTask; + + @EJB + RulesEngine rules; + + @EJB + DefinitionsService definitions; + + @EJB + NotificationsService notifications; + + /* + Init properties + */ + static { + String sDelay = System.getProperty("org.hawkular.alerts.engine.DELAY"); + String sPeriod = System.getProperty("org.hawkular.alerts.engine.PERIOD"); + int dDelay = 1000; + int dPeriod = 2000; + try { + dDelay = new Integer(sDelay).intValue(); + dPeriod = new Integer(sPeriod).intValue(); + } catch (Exception ignored) { } + DELAY = dDelay; + PERIOD = dPeriod; + } + + public BasicAlertsServiceImpl() { + if (log.isDebugEnabled()) { + log.debug("Creating instance."); + debug = true; + } + pendingData = new CopyOnWriteArrayList(); + alerts = new CopyOnWriteArrayList(); + wakeUpTimer = new Timer("BasicAlertsServiceImpl-Timer"); + } + + @PostConstruct + public void initServices() { + reload(); + } + + @Override + public Collection checkAlerts() { + return Collections.unmodifiableCollection(alerts); + } + + @Override + public void clear() { + rulesTask.cancel(); + + rules.clear(); + + pendingData.clear(); + alerts.clear(); + + rulesTask = new RulesInvoker(); + wakeUpTimer.schedule(rulesTask, DELAY, PERIOD); + } + + @Override + public void reload() { + rules.reset(); + if (rulesTask != null) { + rulesTask.cancel(); + } + + Collection triggers = definitions.getTriggers(); + if (triggers != null && !triggers.isEmpty()) { + rules.addFacts(triggers); + } + + Collection dampenings = definitions.getDampenings(); + if (dampenings != null && !dampenings.isEmpty()) { + rules.addFacts(dampenings); + } + + Collection conditions = definitions.getConditions(); + if (conditions != null && !conditions.isEmpty()) { + rules.addFacts(conditions); + } + + rules.addGlobal("log", log); + rules.addGlobal("notifications", notifications); + rules.addGlobal("alerts", alerts); + + rulesTask = new RulesInvoker(); + wakeUpTimer.schedule(rulesTask, DELAY, PERIOD); + } + + @Override + public void sendData(Collection data) { + if (data == null) { + throw new IllegalArgumentException("Data must be not null"); + } + pendingData.addAll(data); + } + + @Override + public void sendData(Data data) { + if (data == null) { + throw new IllegalArgumentException("Data must be not null"); + } + pendingData.add(data); + } + + private class RulesInvoker extends TimerTask { + @Override + public void run() { + if (!pendingData.isEmpty()) { + if (debug) { + log.debug("Pending {} data found. Adding to rules engine.", pendingData.size()); + } + for (Data data : pendingData) { + rules.addFact(data); + } + + pendingData.clear(); + + try { + rules.fire(); + } catch (Exception e) { + log.error("Error on rules processing: " + e.getMessage(), e); + } + } + } + } +} diff --git a/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/DroolsRulesEngineImpl.java b/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/DroolsRulesEngineImpl.java new file mode 100644 index 000000000..fa32c8beb --- /dev/null +++ b/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/DroolsRulesEngineImpl.java @@ -0,0 +1,136 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.engine.impl; + +import org.hawkular.alerts.engine.rules.RulesEngine; +import org.kie.api.KieServices; +import org.kie.api.runtime.KieContainer; +import org.kie.api.runtime.KieSession; +import org.kie.api.runtime.rule.FactHandle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.Singleton; +import java.util.Collection; + +/** + * An implementation of RulesEngine based on drools framework. + * + * This implementations has an approach of fixed rules based on filesystem. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@Singleton +public class DroolsRulesEngineImpl implements RulesEngine { + private static final Logger log = LoggerFactory.getLogger(DroolsRulesEngineImpl.class); + private boolean debug = false; + private static final String SESSION_NAME = "hawkular-alerts-engine-session"; + + private KieServices ks; + private KieContainer kc; + private KieSession kSession; + + public DroolsRulesEngineImpl() { + if (log.isDebugEnabled()) { + debug = true; + log.debug("Creating instance."); + } + ks = KieServices.Factory.get(); + kc = ks.getKieClasspathContainer(); + kSession = kc.newKieSession(SESSION_NAME); + } + + @Override + public void addFact(Object fact) { + if (debug) { + log.debug("Insert {} ", fact); + } + kSession.insert(fact); + } + + @Override + public void addFacts(Collection facts) { + for (Object fact : facts) { + if (debug) { + log.debug("Insert {} ", fact); + } + kSession.insert(fact); + } + } + + @Override + public void addGlobal(String name, Object global) { + if (debug) { + log.debug("Add Global {} = {}", name, global); + } + kSession.setGlobal(name, global); + } + + @Override + public void clear() { + for (FactHandle factHandle : kSession.getFactHandles()) { + if (debug) { + log.debug("Delete {} ", factHandle); + } + kSession.delete(factHandle); + } + } + + @Override + public void fire() { + if (debug) { + log.debug("Firing rules !!"); + } + kSession.fireAllRules(); + } + + @Override + public void removeFact(Object fact) { + FactHandle factHandle = kSession.getFactHandle(fact); + if (factHandle != null) { + if (debug) { + log.debug("Delete {} ", factHandle); + } + kSession.delete(factHandle); + } + } + + @Override + public void removeFacts(Collection facts) { + for (Object fact : facts) { + removeFact(fact); + } + } + + @Override + public void removeGlobal(String name) { + if (debug) { + log.debug("Remove Global {} ", name); + } + kSession.setGlobal(name, null); + } + + @Override + public void reset() { + if (debug) { + log.debug("Reset session"); + } + kSession.dispose(); + kSession = kc.newKieSession(SESSION_NAME); + } +} diff --git a/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/MemDefinitionsServiceImpl.java b/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/MemDefinitionsServiceImpl.java new file mode 100644 index 000000000..e663e9301 --- /dev/null +++ b/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/MemDefinitionsServiceImpl.java @@ -0,0 +1,630 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.engine.impl; + +import org.hawkular.alerts.api.model.condition.AvailabilityCondition; +import org.hawkular.alerts.api.model.condition.CompareCondition; +import org.hawkular.alerts.api.model.condition.Condition; +import org.hawkular.alerts.api.model.condition.StringCondition; +import org.hawkular.alerts.api.model.condition.ThresholdCondition; +import org.hawkular.alerts.api.model.condition.ThresholdRangeCondition; +import org.hawkular.alerts.api.model.dampening.Dampening; +import org.hawkular.alerts.api.model.trigger.Trigger; +import org.hawkular.alerts.api.model.trigger.TriggerTemplate; +import org.hawkular.alerts.api.services.DefinitionsService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.PostConstruct; +import javax.ejb.Singleton; +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * A memory implementation of {@link org.hawkular.alerts.api.services.DefinitionsService}. + * It is intended only for early prototype phases. + * It will be replaced for a proper implementation based on a persistence repository. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@Singleton +public class MemDefinitionsServiceImpl implements DefinitionsService { + private static final Logger log = LoggerFactory.getLogger(MemDefinitionsServiceImpl.class); + private boolean debug = false; + + private static final String JBOSS_DATA_DIR = "jboss.server.data.dir"; + private static final String INIT_FOLDER = "hawkular-alerts"; + + private Map triggers = new ConcurrentHashMap(); + private Map conditions = new ConcurrentHashMap(); + private Map dampenings = new ConcurrentHashMap(); + private Map> notifierTypes = new ConcurrentHashMap>(); + private Map> notifiers = new ConcurrentHashMap>(); + + public MemDefinitionsServiceImpl() { + if (log.isDebugEnabled()) { + log.debug("Creating instance."); + debug = true; + } + } + + @PostConstruct + public void init() { + if (debug) { + log.debug("Initial load from file"); + } + String data = System.getProperty(JBOSS_DATA_DIR); + if (data == null) { + log.error(JBOSS_DATA_DIR + " folder is null"); + return; + } + String folder = data + "/" + INIT_FOLDER; + initFiles(folder); + } + + /* + Helper method to initialize data from files. + It doesn't validate all possible incorrect situations. + It expects a good file. + Used only for demo/poc purposes. + */ + private void initFiles(String folder) { + + if (folder == null) { + log.error("folder must not be null"); + return; + } + + File initFolder = new File(folder); + + /* + Triggers + */ + File triggers = new File(initFolder, "triggers.data"); + if (triggers.exists() && triggers.isFile()) { + List lines = null; + try { + lines = Files.readAllLines(Paths.get(triggers.toURI()), Charset.forName("UTF-8")); + } catch (IOException e) { + log.error(e.toString(), e); + } + if (lines != null && !lines.isEmpty()) { + for (String line : lines) { + if (line.startsWith("#")) { + continue; + } + String[] fields = line.split(","); + if (fields.length == 6) { + String triggerId = fields[0]; + boolean active = new Boolean(fields[1]).booleanValue(); + String name = fields[2]; + String description = fields[3]; + TriggerTemplate.Match match = TriggerTemplate.Match.valueOf(fields[4]); + String[] notifiers = fields[5].split("\\|"); + + Trigger trigger = new Trigger(triggerId, name, active); + trigger.setDescription(description); + trigger.setMatch(match); + for (String notifier : notifiers) { + trigger.addNotifier(notifier); + } + + if (debug){ + log.debug("Init file - Inserting [{}]", trigger); + } + this.triggers.put(triggerId, trigger); + } + } + } + } else { + log.error("triggers.data file not found. Skipping triggers initialization."); + } + + /* + Conditions + */ + File conditions = new File(initFolder, "conditions.data"); + if (conditions.exists() && conditions.isFile()) { + List lines = null; + try { + lines = Files.readAllLines(Paths.get(conditions.toURI()), Charset.forName("UTF-8")); + } catch (IOException e) { + log.error(e.toString(), e); + } + if (lines != null && !lines.isEmpty()) { + for (String line : lines) { + if (line.startsWith("#")) { + continue; + } + String[] fields = line.split(","); + if (fields.length > 3) { + String triggerId = fields[0]; + int conditionSetSize = new Integer(fields[1]).intValue(); + int conditionSetIndex = new Integer(fields[2]).intValue(); + String type = fields[3]; + if (type != null && !type.isEmpty() && type.equals("threshold") && fields.length == 7) { + String dataId = fields[4]; + String operator = fields[5]; + Double threshold = new Double(fields[6]).doubleValue(); + + ThresholdCondition newCondition = new ThresholdCondition(); + newCondition.setTriggerId(triggerId); + newCondition.setConditionSetSize(conditionSetSize); + newCondition.setConditionSetIndex(conditionSetIndex); + newCondition.setDataId(dataId); + newCondition.setOperator(ThresholdCondition.Operator.valueOf(operator)); + newCondition.setThreshold(threshold); + + this.conditions.put(newCondition.getConditionId(), newCondition); + if (debug){ + log.debug("Init file - Inserting [{}]", newCondition); + } + } + if (type != null && !type.isEmpty() && type.equals("range") && fields.length == 10) { + String dataId = fields[4]; + String operatorLow = fields[5]; + String operatorHigh = fields[6]; + Double thresholdLow = new Double(fields[7]).doubleValue(); + Double thresholdHigh = new Double(fields[8]).doubleValue(); + boolean inRange = new Boolean(fields[9]).booleanValue(); + + ThresholdRangeCondition newCondition = new ThresholdRangeCondition(); + newCondition.setTriggerId(triggerId); + newCondition.setConditionSetSize(conditionSetSize); + newCondition.setConditionSetIndex(conditionSetIndex); + newCondition.setDataId(dataId); + newCondition.setOperatorLow(ThresholdRangeCondition.Operator.valueOf(operatorLow)); + newCondition.setOperatorHigh(ThresholdRangeCondition.Operator.valueOf(operatorHigh)); + newCondition.setThresholdLow(thresholdLow); + newCondition.setThresholdHigh(thresholdHigh); + newCondition.setInRange(inRange); + + this.conditions.put(newCondition.getConditionId(), newCondition); + if (debug){ + log.debug("Init file - Inserting [{}]", newCondition); + } + } + if (type != null && !type.isEmpty() && type.equals("compare") && fields.length == 8) { + String data1Id = fields[4]; + String operator = fields[5]; + Double data2Multiplier = new Double(fields[6]).doubleValue(); + String data2Id = fields[7]; + + CompareCondition newCondition = new CompareCondition(); + newCondition.setTriggerId(triggerId); + newCondition.setConditionSetSize(conditionSetSize); + newCondition.setConditionSetIndex(conditionSetIndex); + newCondition.setData1Id(data1Id); + newCondition.setOperator(CompareCondition.Operator.valueOf(operator)); + newCondition.setData2Multiplier(data2Multiplier); + newCondition.setData2Id(data2Id); + + this.conditions.put(newCondition.getConditionId(), newCondition); + if (debug) { + log.debug("Init file - Inserting [{}]", newCondition); + } + } + if (type != null && !type.isEmpty() && type.equals("string") && fields.length == 8) { + String dataId = fields[4]; + String operator = fields[5]; + String pattern = fields[6]; + boolean ignoreCase = new Boolean(fields[7]).booleanValue(); + + StringCondition newCondition = new StringCondition(); + newCondition.setTriggerId(triggerId); + newCondition.setConditionSetSize(conditionSetSize); + newCondition.setConditionSetIndex(conditionSetIndex); + newCondition.setDataId(dataId); + newCondition.setOperator(StringCondition.Operator.valueOf(operator)); + newCondition.setPattern(pattern); + newCondition.setIgnoreCase(ignoreCase); + + this.conditions.put(newCondition.getConditionId(), newCondition); + if (debug) { + log.debug("Init file - Inserting [{}]", newCondition); + } + } + if (type != null && !type.isEmpty() && type.equals("availability") && fields.length == 6) { + String dataId = fields[4]; + String operator = fields[5]; + + AvailabilityCondition newCondition = new AvailabilityCondition(); + newCondition.setTriggerId(triggerId); + newCondition.setConditionSetSize(conditionSetSize); + newCondition.setConditionSetIndex(conditionSetIndex); + newCondition.setDataId(dataId); + newCondition.setOperator(AvailabilityCondition.Operator.valueOf(operator)); + + this.conditions.put(newCondition.getConditionId(), newCondition); + if (debug) { + log.debug("Init file - Inserting [{}]", newCondition); + } + } + } + } + } + } else { + log.error("conditions.data file not found. Skipping conditions initialization."); + } + + /* + Dampening + */ + File dampening = new File(initFolder, "dampening.data"); + if (dampening.exists() && dampening.isFile()) { + List lines = null; + try { + lines = Files.readAllLines(Paths.get(dampening.toURI()), Charset.forName("UTF-8")); + } catch (IOException e) { + log.error(e.toString(), e); + } + if (lines != null && !lines.isEmpty()) { + for (String line : lines) { + if (line.startsWith("#")) { + continue; + } + String[] fields = line.split(","); + if (fields.length == 5) { + String triggerId = fields[0]; + String type = fields[1]; + int evalTrueSetting = new Integer(fields[2]); + int evalTotalSetting = new Integer(fields[3]); + int evalTimeSetting = new Integer(fields[4]); + + Dampening newDampening = new Dampening(triggerId, Dampening.Type.valueOf(type), + evalTrueSetting, evalTotalSetting, evalTimeSetting); + + if (debug) { + log.debug("Init file - Inserting [{}]", newDampening); + } + this.dampenings.put(triggerId, newDampening); + } + } + } + } else { + log.error("dampening.data file not found. Skipping dampening initialization."); + } + + /* + Notifiers + */ + File notifiers = new File(initFolder, "notifiers.data"); + if (notifiers.exists() && notifiers.isFile()) { + List lines = null; + try { + lines = Files.readAllLines(Paths.get(notifiers.toURI()), Charset.forName("UTF-8")); + } catch (IOException e) { + log.error(e.toString(), e); + } + if (lines != null && !lines.isEmpty()) { + for (String line : lines) { + if (line.startsWith("#")) { + continue; + } + String[] fields = line.split(","); + if (fields.length == 3) { + String notifierId = fields[0]; + String notifierType = fields[1]; + String description = fields[2]; + Map newNotifier = new HashMap(); + newNotifier.put("NotifierID", notifierId); + newNotifier.put("NotifierType", notifierType); + newNotifier.put("description", description); + + if (debug) { + log.debug("Init file - Inserting [{}]", newNotifier); + } + this.notifiers.put(notifierId, newNotifier); + } + } + } + } else { + log.error("notifiers.data file not found. Skipping notifiers initialization."); + } + + } + + @Override + public void addCondition(Condition condition) { + if (condition == null || condition.getConditionId() == null || condition.getConditionId().isEmpty()) { + throw new IllegalArgumentException("Condition must be not null"); + } + if (conditions.containsKey(condition.getConditionId())) { + throw new IllegalArgumentException("Condition already exists on repository"); + } + conditions.put(condition.getConditionId(), condition); + } + + @Override + public void addNotifier(String notifierId, Map properties) { + if (notifierId == null || notifierId.isEmpty()) { + throw new IllegalArgumentException("NotifierId must be not null"); + } + if (properties == null) { + throw new IllegalArgumentException("Properties must be not null"); + } + if (notifiers.containsKey(notifierId)) { + throw new IllegalArgumentException("Notifier already exists on repository"); + } + notifiers.put(notifierId, properties); + } + + @Override + public void addNotifierType(String notifierType, Set properties) { + if (notifierType == null || notifierType.isEmpty()) { + throw new IllegalArgumentException("NotifierType must be not null"); + } + if (properties == null) { + throw new IllegalArgumentException("Properties must be not null"); + } + if (notifierTypes.containsKey(notifierType)) { + throw new IllegalArgumentException("NotifierType already exists on repository"); + } + notifierTypes.put(notifierType, properties); + } + + @Override + public void addTrigger(Trigger trigger) { + if (trigger == null || trigger.getId() == null || trigger.getId().isEmpty()) { + throw new IllegalArgumentException("Trigger must be not null"); + } + if (triggers.containsKey(trigger.getId())) { + throw new IllegalArgumentException("Trigger already exists on repository"); + } + triggers.put(trigger.getId(), trigger); + } + + @Override + public void addDampening(Dampening dampening) { + if (dampening == null || dampening.getTriggerId() == null || dampening.getTriggerId().isEmpty()) { + throw new IllegalArgumentException("Dampening must be not null"); + } + if (dampenings.containsKey(dampening.getTriggerId())) { + throw new IllegalArgumentException("Dampening already exists on repository"); + } + dampenings.put(dampening.getTriggerId(), dampening); + } + + @Override + public Condition getCondition(String conditionId) { + if (conditionId == null || conditionId.isEmpty()) { + throw new IllegalArgumentException("ConditionId must be not null"); + } + return conditions.get(conditionId); + } + + @Override + public Collection getConditions() { + return Collections.unmodifiableCollection(conditions.values()); + } + + @Override + public Collection getConditions(String triggerId) { + /* + Not indexed search. + This method is not optimized in any way, it's just for demo purposes. + */ + if (triggerId == null || triggerId.isEmpty()) { + throw new IllegalArgumentException("TriggerId must be not null"); + } + Collection search = new ArrayList(); + Collection values = conditions.values(); + for (Condition cond : values) { + if (cond.getTriggerId().equals(triggerId)) { + search.add(cond); + } + } + return Collections.unmodifiableCollection(search); + } + + @Override + public Map getNotifier(String notifierId) { + if (notifierId == null || notifierId.isEmpty()) { + throw new IllegalArgumentException("NotifierId must be not null"); + } + return notifiers.get(notifierId); + } + + @Override + public Collection getNotifiers() { + return Collections.unmodifiableSet(notifiers.keySet()); + } + + @Override + public Set getNotifierType(String notifierType) { + if (notifierType == null || notifierType.isEmpty()) { + throw new IllegalArgumentException("NotifierType must be not null"); + } + return notifierTypes.get(notifierType); + } + + @Override + public Collection getNotifiers(String notifierType) { + if (notifierType == null || notifierType.isEmpty()) { + throw new IllegalArgumentException("NotifierType must be not null"); + } + /* + This is a non optimized search example. + It is used just for demo/poc purposes. + */ + List filtered = new ArrayList(); + Set keys = notifiers.keySet(); + for (String notifierId: keys) { + Map properties = notifiers.get(notifierId); + if (properties != null && properties.isEmpty() + && properties.containsKey("NotifierType") + && properties.get("NotifierType").equals(notifierType)) { + filtered.add(notifierId); + } + } + return Collections.unmodifiableCollection(filtered); + } + + @Override + public Collection getNotifierTypes() { + return Collections.unmodifiableSet(notifierTypes.keySet()); + } + + @Override + public Trigger getTrigger(String triggerId) { + if (triggerId == null || triggerId.isEmpty()) { + throw new IllegalArgumentException("TriggerId must be not null"); + } + return triggers.get(triggerId); + } + + @Override + public Collection getTriggers() { + return Collections.unmodifiableCollection(triggers.values()); + } + + @Override + public Collection getDampenings() { + return Collections.unmodifiableCollection(dampenings.values()); + } + + @Override + public Dampening getDampening(String triggerId) { + if (triggerId == null || triggerId.isEmpty()) { + throw new IllegalArgumentException("TriggerId must be not null"); + } + return dampenings.get(triggerId); + } + + @Override + public void removeCondition(String conditionId) { + if (conditionId == null || conditionId.isEmpty()) { + throw new IllegalArgumentException("ConditionId must be not null"); + } + if (conditions.containsValue(conditionId)) { + conditions.remove(conditionId); + } + } + + @Override + public void removeNotifier(String notifierId) { + if (notifierId == null || notifierId.isEmpty()) { + throw new IllegalArgumentException("NotifierId must be not null"); + } + if (notifiers.containsKey(notifierId)) { + notifiers.remove(notifierId); + } + } + + @Override + public void removeNotifierType(String notifierType) { + if (notifierType == null || notifierType.isEmpty()) { + throw new IllegalArgumentException("NotifierType must be not null"); + } + if (notifierTypes.containsKey(notifierType)) { + notifierTypes.remove(notifierType); + } + } + + @Override + public void removeTrigger(String triggerId) { + if (triggerId == null || triggerId.isEmpty()) { + throw new IllegalArgumentException("TriggerId must be not null"); + } + if (triggers.containsKey(triggerId)) { + triggers.remove(triggerId); + } + } + + @Override + public void removeDampening(String triggerId) { + if (triggerId == null || triggerId.isEmpty()) { + throw new IllegalArgumentException("TriggerId must be not null"); + } + if (dampenings.containsKey(triggerId)) { + dampenings.remove(triggerId); + } + } + + @Override + public void updateCondition(Condition condition) { + if (condition == null || condition.getConditionId() == null || condition.getConditionId().isEmpty()) { + throw new IllegalArgumentException("Condition must be not null"); + } + if (!conditions.containsKey(condition.getConditionId())) { + throw new IllegalArgumentException("Condition must exist on repository"); + } + conditions.put(condition.getConditionId(), condition); + } + + @Override + public void updateNotifier(String notifierId, Map properties) { + if (notifierId == null || notifierId.isEmpty()) { + throw new IllegalArgumentException("NotifierId must be not null"); + } + if (properties == null) { + throw new IllegalArgumentException("Properties must be not null"); + } + if (!notifiers.containsKey(notifierId)) { + throw new IllegalArgumentException("Notifier must exist on repository"); + } + notifiers.put(notifierId, properties); + } + + @Override + public void updateNotifierType(String notifierType, Set properties) { + if (notifierType == null || notifierType.isEmpty()) { + throw new IllegalArgumentException("NotifierType must be not null"); + } + if (properties == null) { + throw new IllegalArgumentException("Properties must be not null"); + } + if (!notifierTypes.containsKey(notifierType)) { + throw new IllegalArgumentException("NotifierType must exist on repository"); + } + notifierTypes.put(notifierType, properties); + } + + @Override + public void updateTrigger(Trigger trigger) { + if (trigger == null || trigger.getId() == null || trigger.getId().isEmpty()) { + throw new IllegalArgumentException("Trigger must be not null"); + } + if (!triggers.containsKey(trigger.getId())) { + throw new IllegalArgumentException("Trigger must exist on repository"); + } + triggers.put(trigger.getId(), trigger); + } + + @Override + public void updateDampening(Dampening dampening) { + if (dampening == null || dampening.getTriggerId() == null || dampening.getTriggerId().isEmpty()) { + throw new IllegalArgumentException("Dampening must be not null"); + } + if (!dampenings.containsKey(dampening.getTriggerId())) { + throw new IllegalArgumentException("Dampening must exists on repository"); + } + dampenings.put(dampening.getTriggerId(), dampening); + } +} diff --git a/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/MemNotificationsServiceImpl.java b/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/MemNotificationsServiceImpl.java new file mode 100644 index 000000000..094a1546e --- /dev/null +++ b/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/impl/MemNotificationsServiceImpl.java @@ -0,0 +1,78 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.engine.impl; + +import org.hawkular.alerts.api.model.notification.Notification; +import org.hawkular.alerts.api.services.NotificationsService; +import org.hawkular.alerts.api.services.NotifierListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.Singleton; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * A memory implementation of {@link org.hawkular.alerts.api.services.NotificationsService}. + * It is intended only for early prototype phases. + * It will be replaced for a proper implementation based on a persistence repository. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@Singleton +public class MemNotificationsServiceImpl implements NotificationsService { + private static final Logger log = LoggerFactory.getLogger(MemNotificationsServiceImpl.class); + private boolean debug = false; + + Queue pending = new ConcurrentLinkedDeque(); + List listeners = new CopyOnWriteArrayList(); + + public MemNotificationsServiceImpl() { + if (log.isDebugEnabled()) { + log.debug("Creating instance."); + debug = true; + } + } + + @Override + public void send(Notification notification) { + if (notification == null || notification.getNotifierId() == null || notification.getNotifierId().isEmpty()) { + throw new IllegalArgumentException("Notification must be not null"); + } + pending.add(notification); + + /* + In this implementation we invoke listeners as soon as we receive an event. + This can be modified per implementation basis adding asynchronously behaviour at this level. + */ + for (NotifierListener listener : listeners) { + listener.process(notification); + } + } + + @Override + public void register(NotifierListener listener) { + if (listener == null) { + throw new IllegalArgumentException("NotifierListener must not be null"); + } + listeners.add(listener); + log.info("NotifierListener {} registered ", listener); + } +} diff --git a/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/rules/RulesEngine.java b/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/rules/RulesEngine.java new file mode 100644 index 000000000..9e01a9843 --- /dev/null +++ b/hawkular-alerts-engine/src/main/java/org/hawkular/alerts/engine/rules/RulesEngine.java @@ -0,0 +1,42 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.engine.rules; + +import java.util.Collection; + +/** + * Interface that defines an abstract API with the rules engine implementation + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public interface RulesEngine { + + void addGlobal(String name, Object global); + void removeGlobal(String name); + + void addFact(Object fact); + void removeFact(Object fact); + void addFacts(Collection facts); + void removeFacts(Collection facts); + + void fire(); + + void clear(); + + void reset(); +} diff --git a/hawkular-alerts-engine/src/main/resources/META-INF/kmodule.xml b/hawkular-alerts-engine/src/main/resources/META-INF/kmodule.xml new file mode 100644 index 000000000..413111072 --- /dev/null +++ b/hawkular-alerts-engine/src/main/resources/META-INF/kmodule.xml @@ -0,0 +1,24 @@ + + + + + + + diff --git a/hawkular-alerts-engine/src/main/resources/META-INF/maven/pom.properties b/hawkular-alerts-engine/src/main/resources/META-INF/maven/pom.properties new file mode 100644 index 000000000..7bf262ab5 --- /dev/null +++ b/hawkular-alerts-engine/src/main/resources/META-INF/maven/pom.properties @@ -0,0 +1,20 @@ +# +# Copyright 2015 Red Hat, Inc. and/or its affiliates +# and other contributors as indicated by the @author tags. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +groupId=org.hawkular.alerts +artifactId=hawkular-alerts-engine +version=1.0.0.Alpha1-SNAPSHOT diff --git a/hawkular-alerts-engine/src/main/resources/hawkular-alerts/conditions.data b/hawkular-alerts-engine/src/main/resources/hawkular-alerts/conditions.data new file mode 100644 index 000000000..ec6e74f26 --- /dev/null +++ b/hawkular-alerts-engine/src/main/resources/hawkular-alerts/conditions.data @@ -0,0 +1,29 @@ +# triggerId,conditionSetSize,conditionSetIndex, +# == threshold +# ..., dataId,operator,value +# +trigger-1,1,1,threshold,NumericData-01,LT,10.0 +trigger-2,2,1,threshold,NumericData-01,GTE,15.0 +trigger-2,2,2,threshold,NumericData-02,GTE,15.0 +# +# == range +# ...,dataId,operatorLow,operatorHigh,thresholdLow,thresholdHigh,inRange +# +trigger-3,1,1,range,NumericData-03,INCLUSIVE,INCLUSIVE,10.0,15.0,true +# +# == compare +# ...,data1Id,operator,data2Multiplier,data2Id +# +trigger-4,1,1,compare,NumericData-01,LT,0.5,NumericData-02 +# +# == string +# ...,dataId,operator,pattern,ignoreCase +# +trigger-5,1,1,string,StringData-01,STARTS_WITH,Fred,false +# +# == availability +# ...,dataId,operator +# +trigger-6,1,1,availability,Availability-01,NOT_UP + + diff --git a/hawkular-alerts-engine/src/main/resources/hawkular-alerts/dampening.data b/hawkular-alerts-engine/src/main/resources/hawkular-alerts/dampening.data new file mode 100644 index 000000000..8d41010b2 --- /dev/null +++ b/hawkular-alerts-engine/src/main/resources/hawkular-alerts/dampening.data @@ -0,0 +1,2 @@ +# triggerId,type,evalTrueSetting,evalTotalSetting,evalTimeSetting +trigger-1,STRICT,2,2,0 \ No newline at end of file diff --git a/hawkular-alerts-engine/src/main/resources/hawkular-alerts/notifiers.data b/hawkular-alerts-engine/src/main/resources/hawkular-alerts/notifiers.data new file mode 100644 index 000000000..66ca7d8c7 --- /dev/null +++ b/hawkular-alerts-engine/src/main/resources/hawkular-alerts/notifiers.data @@ -0,0 +1,5 @@ +#notifier id, notifier type,description +SNMP-Trap-1,snmp,description +SNMP-Trap-2,snmp,description +admin@email.com,email,description +SMS-555-12345,sms,description \ No newline at end of file diff --git a/hawkular-alerts-engine/src/main/resources/hawkular-alerts/triggers.data b/hawkular-alerts-engine/src/main/resources/hawkular-alerts/triggers.data new file mode 100644 index 000000000..9dfe2288e --- /dev/null +++ b/hawkular-alerts-engine/src/main/resources/hawkular-alerts/triggers.data @@ -0,0 +1,7 @@ +# ,,,,,|||... +trigger-1,true,NumericData-01-low,description,ALL,SNMP-Trap-1|SNMP-Trap-2|admin@email.com +trigger-2,true,NumericData-01-02-high,description,ALL,SNMP-Trap-1|SNMP-Trap-2|admin@email.com +trigger-3,true,NumericData-03-range,description,ALL,SNMP-Trap-1|SNMP-Trap-2|admin@email.com +trigger-4,true,CompareData-01-d1-lthalf-d2,description,ALL,SNMP-Trap-1|SNMP-Trap-2|admin@email.com +trigger-5,true,StringData-01-starts,description,ALL,SNMP-Trap-1|SNMP-Trap-2|admin@email.com +trigger-6,true,Availability-01-NOT-UP,description,ALL,SNMP-Trap-1|SNMP-Trap-2|admin@email.com \ No newline at end of file diff --git a/hawkular-alerts-engine/src/main/resources/org/hawkular/alerts/engine/rules/ConditionMatch.drl b/hawkular-alerts-engine/src/main/resources/org/hawkular/alerts/engine/rules/ConditionMatch.drl new file mode 100644 index 000000000..027a34c3d --- /dev/null +++ b/hawkular-alerts-engine/src/main/resources/org/hawkular/alerts/engine/rules/ConditionMatch.drl @@ -0,0 +1,195 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.engine.rules + +import org.hawkular.alerts.api.model.condition.Alert; +import org.hawkular.alerts.api.model.condition.AvailabilityCondition; +import org.hawkular.alerts.api.model.condition.AvailabilityConditionEval; +import org.hawkular.alerts.api.model.condition.ConditionEval; +import org.hawkular.alerts.api.model.condition.CompareCondition; +import org.hawkular.alerts.api.model.condition.CompareConditionEval; +import org.hawkular.alerts.api.model.condition.StringCondition; +import org.hawkular.alerts.api.model.condition.StringConditionEval; +import org.hawkular.alerts.api.model.condition.ThresholdCondition; +import org.hawkular.alerts.api.model.condition.ThresholdConditionEval; +import org.hawkular.alerts.api.model.condition.ThresholdRangeCondition; +import org.hawkular.alerts.api.model.condition.ThresholdRangeConditionEval; +import org.hawkular.alerts.api.model.dampening.Dampening; +import org.hawkular.alerts.api.model.data.Availability; +import org.hawkular.alerts.api.model.data.Availability.AvailabilityType +import org.hawkular.alerts.api.model.data.NumericData; +import org.hawkular.alerts.api.model.data.StringData; +import org.hawkular.alerts.api.model.notification.Notification; +import org.hawkular.alerts.api.model.trigger.Trigger; +import org.hawkular.alerts.api.services.NotificationsService; + +import org.slf4j.Logger; + +import java.util.HashSet; +import java.util.List; + +global Logger log; +global NotificationsService notifications; +global List alerts; + +////// CONDITION MATCHING + +rule Threshold + when + $t : Trigger( active == true, $tid : id ) + $c : ThresholdCondition ( triggerId == $tid, $did : dataId ) + NumericData( $did == id, $value : value) + then + ThresholdConditionEval ce = new ThresholdConditionEval($c, (Double)$value); + if (log != null && log.isDebugEnabled()) { + log.debug("Threshold Eval: " + (ce.isMatch() ? " Match! " : "no match ") + ce.getLog()); + } + insert( ce ); +end + +rule ThresholdRange + when + $t : Trigger( active == true, $tid : id ) + $c : ThresholdRangeCondition ( triggerId == $tid, $did : dataId ) + NumericData( $did == id, $value : value) + then + ThresholdRangeConditionEval ce = new ThresholdRangeConditionEval($c, (Double)$value); + if (log != null && log.isDebugEnabled()) { + log.debug("ThresholdRange Eval: " + (ce.isMatch() ? " Match! " : "no match ") + ce.getLog()); + } + insert( ce ); +end + +rule Compare + when + $t : Trigger( active == true, $tid : id ) + $c : CompareCondition ( triggerId == $tid, $d1id : data1Id, $d2id : data2Id ) + NumericData( $d1id == id, $value1 : value) + NumericData( $d2id == id, $value2 : value) + then + CompareConditionEval ce = new CompareConditionEval($c, (Double)$value1, (Double)$value2); + if (log != null && log.isDebugEnabled()) { + log.debug("Compare Eval: " + (ce.isMatch() ? " Match! " : "no match ") + ce.getLog()); + } + insert( ce ); +end + +rule Availability + when + $t : Trigger( active == true, $tid : id ) + $c : AvailabilityCondition ( triggerId == $tid, $did : dataId ) + Availability( $did == id, $value : value) + then + AvailabilityConditionEval ce = new AvailabilityConditionEval($c, (AvailabilityType)$value); + if (log != null && log.isDebugEnabled()) { + log.debug("Availability Eval: " + (ce.isMatch() ? " Match! " : "no match ") + ce.getLog()); + } + insert( ce ); +end + +rule String + when + $t : Trigger( active == true, $tid : id ) + $c : StringCondition ( triggerId == $tid, $did : dataId ) + StringData( $did == id, $value : value) + then + StringConditionEval ce = new StringConditionEval($c, (String)$value); + if (log != null && log.isDebugEnabled()) { + log.debug("String Eval: " + (ce.isMatch() ? " Match! " : "no match ") + ce.getLog()); + } + insert( ce ); +end + +rule RemoveProcessedData + when + $d : NumericData() + then + if (log != null && log.isDebugEnabled()) { + log.debug("Retracting " + $d + "..." ); + } + retract ( $d ); +end + +////// DAMPENING + +rule ProvideDefaultDampening + when + $t : Trigger( active == true, $tid : id ) + not Dampening( triggerId == $tid ) + then + if (log != null && log.isDebugEnabled()) { + log.debug("Adding default dampening for trigger! " + $t.getId()); + } + Dampening d = new Dampening( $tid, Dampening.Type.STRICT, 1, 1, 0L ); + insert( d ); +end + + +rule DampenOneConditionTrigger + when + $t : Trigger( active == true, $tid : id ) + $d : Dampening( triggerId == $tid, satisfied == false ) + $ce : ConditionEval ( triggerId == $tid, conditionSetSize == 1, conditionSetIndex == 1 ) + then + if (log != null && log.isDebugEnabled()) { + log.debug("Updating dampening for and then retracting " + $ce); + } + $d.perform( $ce ); + update( $d ); + retract ( $ce ); +end + +rule DampenTwoConditionTrigger + when + $t : Trigger( active == true, $tid : id ) + $d : Dampening( triggerId == $tid, satisfied == false ) + $ce1 : ConditionEval ( triggerId == $tid, conditionSetSize == 2, conditionSetIndex == 1 ) + $ce2 : ConditionEval ( triggerId == $tid, conditionSetSize == 2, conditionSetIndex == 2 ) + then + if (log != null && log.isDebugEnabled()) { + log.debug("Updating dampening for and then retracting " + $ce1 + $ce2); + } + $d.perform( $ce1, $ce2 ); + update( $d ); + retract ( $ce1 ); + retract ( $ce2 ); +end + +////// ALERT GENERATION + +rule AlertOnSatisfiedDampening + when + $t : Trigger( active == true, $tid : id ) + $d : Dampening( triggerId == $tid, satisfied == true ) + then + if (log != null && log.isDebugEnabled()) { + log.debug("AlertDampeningOneCondition! " + $d.getLog()); + } + Alert newAlert = new Alert( $tid, $d.getSatisfyingEvals() ); + alerts.add(newAlert); + if (notifications != null) { + for (String notifierId : $t.getNotifiers()) { + Notification notification = new Notification(); + notification.setNotifierId(notifierId); + notification.setMessage(newAlert.toString()); + notifications.send(notification); + } + } + insert( newAlert ); + $d.reset(); + update( $d ) +end diff --git a/hawkular-alerts-engine/src/test/java/org/hawkular/alerts/engine/RulesEngineTest.java b/hawkular-alerts-engine/src/test/java/org/hawkular/alerts/engine/RulesEngineTest.java new file mode 100644 index 000000000..877fe4e90 --- /dev/null +++ b/hawkular-alerts-engine/src/test/java/org/hawkular/alerts/engine/RulesEngineTest.java @@ -0,0 +1,152 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.engine; + +import org.hawkular.alerts.api.model.condition.AvailabilityCondition; +import org.hawkular.alerts.api.model.condition.CompareCondition; +import org.hawkular.alerts.api.model.condition.StringCondition; +import org.hawkular.alerts.api.model.condition.ThresholdCondition; +import org.hawkular.alerts.api.model.condition.ThresholdRangeCondition; +import org.hawkular.alerts.api.model.dampening.Dampening; +import org.hawkular.alerts.api.model.data.Availability; +import org.hawkular.alerts.api.model.data.Data; +import org.hawkular.alerts.api.model.data.NumericData; +import org.hawkular.alerts.api.model.data.StringData; +import org.hawkular.alerts.api.model.trigger.Trigger; +import org.hawkular.alerts.engine.impl.DroolsRulesEngineImpl; +import org.hawkular.alerts.engine.rules.RulesEngine; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +import static org.hawkular.alerts.api.model.data.Availability.AvailabilityType; + +/** + * Basic test of RulesEngine implementation. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class RulesEngineTest { + private static final Logger log = LoggerFactory.getLogger(RulesEngineTest.class); + + Set < Data > datums; + + @Before + public void initDatum() { + datums = new HashSet(); + Random r = new Random(); + for (int i = 0; i < 10; ++i) { + NumericData m = new NumericData("NumericData-01", r.nextDouble() * 20); + datums.add(m); + } + for (int i = 0; i < 10; ++i) { + NumericData m = new NumericData("NumericData-02", r.nextDouble() * 20); + datums.add(m); + } + for (int i = 0; i < 10; ++i) { + NumericData m = new NumericData("NumericData-03", r.nextDouble() * 20); + datums.add(m); + } + + datums.add(new StringData("StringData-01", "Barney")); + datums.add(new StringData("StringData-01", "Fred and Barney")); + datums.add(new StringData("StringData-02", "Fred Flintstone")); + + datums.add(new Availability("Availability-01", AvailabilityType.UP)); + datums.add(new Availability("Availability-01", AvailabilityType.UP)); + datums.add(new Availability("Availability-01", AvailabilityType.UNAVAILABLE)); + } + + @Test + public void basicAlertsTest() { + + List alerts = new ArrayList(); + RulesEngine rulesEngine = new DroolsRulesEngineImpl(); + rulesEngine.addGlobal("log", log); + rulesEngine.addGlobal("alerts", alerts); + + // go ! + Trigger t1 = new Trigger("trigger-1", "NumericData-01-low"); + ThresholdCondition t1c1 = new ThresholdCondition("trigger-1", 1, 1, + "NumericData-01", + ThresholdCondition.Operator.LT, 10.0); + Dampening t1d = new Dampening("trigger-1", Dampening.Type.STRICT, 2, 2, 0); + + Trigger t2 = new Trigger("trigger-2", "NumericData-01-02-high"); + ThresholdCondition t2c1 = new ThresholdCondition("trigger-2", 2, 1, + "NumericData-01", + ThresholdCondition.Operator.GTE, 15.0); + ThresholdCondition t2c2 = new ThresholdCondition("trigger-2", 2, 2, + "NumericData-02", + ThresholdCondition.Operator.GTE, 15.0); + + Trigger t3 = new Trigger("trigger-3", "NumericData-03-range"); + ThresholdRangeCondition t3c1 = new ThresholdRangeCondition("trigger-3", 1, 1, + "NumericData-03", + ThresholdRangeCondition.Operator.INCLUSIVE, + ThresholdRangeCondition.Operator.INCLUSIVE, + 10.0, 15.0, + true); + + Trigger t4 = new Trigger("trigger-4", "CompareData-01-d1-lthalf-d2"); + CompareCondition t4c1 = new CompareCondition("trigger-4", 1, 1, + "NumericData-01", + CompareCondition.Operator.LT, 0.5, "NumericData-02"); + + Trigger t5 = new Trigger("trigger-5", "StringData-01-starts"); + StringCondition t5c1 = new StringCondition("trigger-5", 1, 1, + "StringData-01", + StringCondition.Operator.STARTS_WITH, "Fred", false); + + Trigger t6 = new Trigger("trigger-6", "Availability-01-NOT-UP"); + AvailabilityCondition t6c1 = new AvailabilityCondition("trigger-6", 1, 1, + "Availability-01", + AvailabilityCondition.Operator.NOT_UP); + + rulesEngine.addFact(t1); + rulesEngine.addFact(t1c1); + rulesEngine.addFact(t1d); + + rulesEngine.addFact(t2); + rulesEngine.addFact(t2c1); + rulesEngine.addFact(t2c2); + + rulesEngine.addFact(t3); + rulesEngine.addFact(t3c1); + + rulesEngine.addFact(t4); + rulesEngine.addFact(t4c1); + + rulesEngine.addFact(t5); + rulesEngine.addFact(t5c1); + + rulesEngine.addFact(t6); + rulesEngine.addFact(t6c1); + + rulesEngine.addFacts(datums); + + rulesEngine.fire(); + } +} diff --git a/hawkular-alerts-engine/src/test/resources/simplelogger.properties b/hawkular-alerts-engine/src/test/resources/simplelogger.properties new file mode 100644 index 000000000..e01f4c3ca --- /dev/null +++ b/hawkular-alerts-engine/src/test/resources/simplelogger.properties @@ -0,0 +1,51 @@ +# +# Copyright 2015 Red Hat, Inc. and/or its affiliates +# and other contributors as indicated by the @author tags. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# SLF4J's SimpleLogger configuration file +# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err. + +# Default logging detail level for all instances of SimpleLogger. +# Must be one of ("trace", "debug", "info", "warn", or "error"). +# If not specified, defaults to "info". +org.slf4j.simpleLogger.defaultLogLevel=debug + +# Logging detail level for a SimpleLogger instance named "xxxxx". +# Must be one of ("trace", "debug", "info", "warn", or "error"). +# If not specified, the default logging detail level is used. +#org.slf4j.simpleLogger.log.xxxxx= + +# Set to true if you want the current date and time to be included in output messages. +# Default is false, and will output the number of milliseconds elapsed since startup. +#org.slf4j.simpleLogger.showDateTime=false + +# The date and time format to be used in the output messages. +# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat. +# If the format is not specified or is invalid, the default format is used. +# The default format is yyyy-MM-dd HH:mm:ss:SSS Z. +#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z + +# Set to true if you want to output the current thread name. +# Defaults to true. +#org.slf4j.simpleLogger.showThreadName=true + +# Set to true if you want the Logger instance name to be included in output messages. +# Defaults to true. +#org.slf4j.simpleLogger.showLogName=true + +# Set to true if you want the last component of the name to be included in output messages. +# Defaults to false. +#org.slf4j.simpleLogger.showShortLogName=false \ No newline at end of file diff --git a/hawkular-alerts-rest/pom.xml b/hawkular-alerts-rest/pom.xml new file mode 100644 index 000000000..8edbdfb27 --- /dev/null +++ b/hawkular-alerts-rest/pom.xml @@ -0,0 +1,75 @@ + + + + + 4.0.0 + + + org.hawkular.alerts + hawkular-alerts + 1.0.0.Alpha1-SNAPSHOT + + + hawkular-alerts-rest + war + Hawkular Alerts REST Api + + + + + org.hawkular.alerts + hawkular-alerts-api + ${project.version} + provided + + + + org.hawkular.alerts + hawkular-alerts-engine + ${project.version} + provided + + + + org.slf4j + slf4j-api + ${version.org.slf4j} + provided + + + + javax + javaee-api + ${version.javaee.spec} + provided + + + + junit + junit + ${version.junit} + test + + + + + diff --git a/hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/AlertsHandler.java b/hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/AlertsHandler.java new file mode 100644 index 000000000..23fd1a9af --- /dev/null +++ b/hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/AlertsHandler.java @@ -0,0 +1,82 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.rest; + +import org.hawkular.alerts.api.model.condition.Alert; +import org.hawkular.alerts.api.services.AlertsService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.EJB; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; +import javax.ws.rs.core.Response; + +import java.util.Collection; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; + +/** + * REST endpoint for alerts + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@Path("/alerts") +public class AlertsHandler { + private static final Logger log = LoggerFactory.getLogger(AlertsHandler.class); + private boolean debug = false; + + public AlertsHandler() { + if (log.isDebugEnabled()) { + log.debug("Creating instance."); + debug = true; + } + } + + @EJB + AlertsService alerts; + + @GET + @Path("/") + @Produces(APPLICATION_JSON) + public void findAllAlerts(@Suspended final AsyncResponse response) { + Collection alertList = alerts.checkAlerts(); + if (alertList.isEmpty()) { + if (debug) { + log.debug("GET - findAllAlerts - Empty"); + } + response.resume(Response.status(Response.Status.NO_CONTENT).type(APPLICATION_JSON_TYPE).build()); + } else { + if (debug) { + log.debug("GET - findAllAlerts - " + alertList.size() + " alerts"); + } + response.resume(Response.status(Response.Status.OK).entity(alertList).type(APPLICATION_JSON_TYPE).build()); + } + } + + @GET + @Path("/reload") + public void reloadAlerts(@Suspended final AsyncResponse response) { + alerts.reload(); + response.resume(Response.status(Response.Status.OK).build()); + } +} diff --git a/hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/HawkularAlertsApp.java b/hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/HawkularAlertsApp.java new file mode 100644 index 000000000..d736babb1 --- /dev/null +++ b/hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/HawkularAlertsApp.java @@ -0,0 +1,38 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.rest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +/** + * Base class for REST module. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@ApplicationPath("/api") +public class HawkularAlertsApp extends Application { + private static final Logger log = LoggerFactory.getLogger(HawkularAlertsApp.class); + + public HawkularAlertsApp() { + log.info("Hawkular Alerts REST starting..."); + } +} diff --git a/hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/NotificationHandler.java b/hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/NotificationHandler.java new file mode 100644 index 000000000..f92fabf84 --- /dev/null +++ b/hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/NotificationHandler.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.rest; + +import org.hawkular.alerts.api.model.notification.Notification; +import org.hawkular.alerts.api.services.NotificationsService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.EJB; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; +import javax.ws.rs.core.Response; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +/** + * REST endpoint for notifications + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@Path("/notifications") +public class NotificationHandler { + private static final Logger log = LoggerFactory.getLogger(NotificationHandler.class); + private boolean debug = false; + + @EJB + NotificationsService notifications; + + public NotificationHandler() { + if (log.isDebugEnabled()) { + log.debug("Creating instance."); + debug = true; + } + } + + @POST + @Path("/notify") + @Consumes(APPLICATION_JSON) + @Produces(APPLICATION_JSON) + public void notify(@Suspended final AsyncResponse response, Notification notification) { + notifications.send(notification); + response.resume(Response.status(Response.Status.OK).build()); + } +} diff --git a/hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/TriggersHandler.java b/hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/TriggersHandler.java new file mode 100644 index 000000000..54e4cc71f --- /dev/null +++ b/hawkular-alerts-rest/src/main/java/org/hawkular/alerts/rest/TriggersHandler.java @@ -0,0 +1,173 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.alerts.rest; + +import org.hawkular.alerts.api.model.trigger.Trigger; +import org.hawkular.alerts.api.services.DefinitionsService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.EJB; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; +import javax.ws.rs.core.Response; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; + +/** + * REST endpoint for triggers + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@Path("/triggers") +public class TriggersHandler { + private static final Logger log = LoggerFactory.getLogger(TriggersHandler.class); + private boolean debug = false; + + @EJB + DefinitionsService definitions; + + public TriggersHandler() { + if (log.isDebugEnabled()) { + log.debug("Creating instance."); + debug = true; + } + } + + @GET + @Path("/") + @Produces(APPLICATION_JSON) + public void findAllTriggers(@Suspended final AsyncResponse response) { + Collection triggerList = definitions.getTriggers(); + if (triggerList.isEmpty()) { + if (debug) { + log.debug("GET - findAllTriggers - Empty"); + } + response.resume(Response.status(Response.Status.NO_CONTENT).type(APPLICATION_JSON_TYPE).build()); + } else { + if (debug) { + log.debug("GET - findAllTriggers - " + triggerList.size() + " triggers"); + } + response.resume(Response.status(Response.Status.OK) + .entity(triggerList).type(APPLICATION_JSON_TYPE).build()); + } + } + + @POST + @Path("/") + @Consumes(APPLICATION_JSON) + @Produces(APPLICATION_JSON) + public void createTrigger(@Suspended final AsyncResponse response, final Trigger trigger) { + if (trigger != null && trigger.getId() != null && definitions.getTrigger(trigger.getId()) == null) { + if (debug) { + log.debug("POST - createTrigger - triggerId " + trigger.getId()); + } + definitions.addTrigger(trigger); + response.resume(Response.status(Response.Status.OK).entity(trigger).type(APPLICATION_JSON_TYPE).build()); + } else { + if (debug) { + log.debug("POST - createTrigger - ID not valid or existing trigger"); + } + Map errors = new HashMap(); + errors.put("errorMsg", "Existing trigger or invalid ID"); + response.resume(Response.status(Response.Status.BAD_REQUEST) + .entity(errors).type(APPLICATION_JSON_TYPE).build()); + } + } + + @GET + @Path("/{triggerId}") + @Produces(APPLICATION_JSON) + public void getTrigger(@Suspended final AsyncResponse response, @PathParam("triggerId") final String triggerId) { + Trigger found = null; + if (triggerId != null && !triggerId.isEmpty()) { + found = definitions.getTrigger(triggerId); + } + if (found != null) { + if (debug) { + log.debug("GET - getTrigger - triggerId: " + found.getId()); + } + response.resume(Response.status(Response.Status.OK).entity(found).type(APPLICATION_JSON_TYPE).build()); + } else { + if (debug) { + log.debug("GET - getTrigger - triggerId : " + triggerId + " not found or invalid. "); + } + Map errors = new HashMap(); + errors.put("errorMsg", "Trigger ID " + triggerId + " not found or invalid ID"); + response.resume(Response.status(Response.Status.NOT_FOUND) + .entity(errors).type(APPLICATION_JSON_TYPE).build()); + } + } + + @PUT + @Path("/{triggerId}") + @Consumes(APPLICATION_JSON) + public void updateTrigger(@Suspended final AsyncResponse response, @PathParam("triggerId") final String triggerId, + final Trigger trigger) { + if (triggerId != null && !triggerId.isEmpty() && + trigger != null && trigger.getId() != null && + triggerId.equals(trigger.getId()) && + definitions.getTrigger(triggerId) != null) { + if (debug) { + log.debug("PUT - updateTrigger - triggerId: " + triggerId); + } + definitions.removeTrigger(triggerId); + definitions.addTrigger(trigger); + response.resume(Response.status(Response.Status.OK).build()); + } else { + log.debug("PUT - updateTrigger - triggerId: " + triggerId + " not found or invalid. "); + Map errors = new HashMap(); + errors.put("errorMsg", "Trigger ID " + triggerId + " not found or invalid ID"); + response.resume(Response.status(Response.Status.NOT_FOUND) + .entity(errors).type(APPLICATION_JSON_TYPE).build()); + } + } + + @DELETE + @Path("/{triggerId}") + public void deleteTrigger(@Suspended final AsyncResponse response, @PathParam("triggerId") final String triggerId) { + if (triggerId != null && !triggerId.isEmpty() && definitions.getTrigger(triggerId) != null) { + if (debug) { + log.debug("DELETE - deleteTrigger - triggerId: " + triggerId); + } + definitions.removeTrigger(triggerId); + response.resume(Response.status(Response.Status.OK).build()); + } else { + if (debug) { + log.debug("DELETE - deleteTrigger - triggerId: " + triggerId + " not found or invalid. "); + } + Map errors = new HashMap(); + errors.put("errorMsg", "Trigger ID " + triggerId + " not found or invalid ID"); + response.resume(Response.status(Response.Status.NOT_FOUND) + .entity(errors).type(APPLICATION_JSON_TYPE).build()); + } + } + +} diff --git a/hawkular-alerts-rest/src/main/webapp/WEB-INF/beans.xml b/hawkular-alerts-rest/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 000000000..d4ac2fa32 --- /dev/null +++ b/hawkular-alerts-rest/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,24 @@ + + + + diff --git a/hawkular-alerts-rest/src/main/webapp/WEB-INF/jboss-web.xml b/hawkular-alerts-rest/src/main/webapp/WEB-INF/jboss-web.xml new file mode 100644 index 000000000..136167fc2 --- /dev/null +++ b/hawkular-alerts-rest/src/main/webapp/WEB-INF/jboss-web.xml @@ -0,0 +1,22 @@ + + + + hawkular-alerts + diff --git a/hawkular-alerts-rest/src/main/webapp/WEB-INF/web.xml b/hawkular-alerts-rest/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..87653b40d --- /dev/null +++ b/hawkular-alerts-rest/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,24 @@ + + + + diff --git a/hawkular-alerts-rest/src/main/webapp/index.jsp b/hawkular-alerts-rest/src/main/webapp/index.jsp new file mode 100644 index 000000000..89fed1637 --- /dev/null +++ b/hawkular-alerts-rest/src/main/webapp/index.jsp @@ -0,0 +1,26 @@ +<%-- + + Copyright 2015 Red Hat, Inc. and/or its affiliates + and other contributors as indicated by the @author tags. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--%> + + + Hawkular Alerts Engine + + +

Hawkular Alerts Engine

+ + diff --git a/hawkular-notifiers-api/pom.xml b/hawkular-notifiers-api/pom.xml new file mode 100644 index 000000000..4a296730d --- /dev/null +++ b/hawkular-notifiers-api/pom.xml @@ -0,0 +1,56 @@ + + + + + 4.0.0 + + + org.hawkular.alerts + hawkular-alerts + 1.0.0.Alpha1-SNAPSHOT + + + org.hawkular.alerts + hawkular-notifiers-api + jar + Hawkular Notifiers Api + + + + + + org.hawkular.bus + hawkular-bus-mdb + ${project.version} + provided + + + + junit + junit + ${version.junit} + test + + + + + diff --git a/hawkular-notifiers-api/src/main/java/org/hawkular/notifiers/api/model/NotificationMessage.java b/hawkular-notifiers-api/src/main/java/org/hawkular/notifiers/api/model/NotificationMessage.java new file mode 100644 index 000000000..c1c02ec00 --- /dev/null +++ b/hawkular-notifiers-api/src/main/java/org/hawkular/notifiers/api/model/NotificationMessage.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.notifiers.api.model; + +import com.google.gson.annotations.Expose; +import org.hawkular.bus.common.BasicMessage; + +/** + * A notification message generated from the alerts engine through alert-bus subsystem. + * Notifier plugin must listen per notifierType of message in the filter. + * Notifier plugin should resolve notifierId and process message. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class NotificationMessage extends BasicMessage { + + @Expose + String notifierId; + + @Expose + String message; + + public NotificationMessage() { } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getNotifierId() { + return notifierId; + } + + public void setNotifierId(String notifierId) { + this.notifierId = notifierId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + NotificationMessage that = (NotificationMessage) o; + + if (message != null ? !message.equals(that.message) : that.message != null) return false; + if (notifierId != null ? !notifierId.equals(that.notifierId) : that.notifierId != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = notifierId != null ? notifierId.hashCode() : 0; + result = 31 * result + (message != null ? message.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "NotificationMessage{" + + "message='" + message + '\'' + + ", notifierId='" + notifierId + '\'' + + '}'; + } +} diff --git a/hawkular-notifiers-api/src/main/java/org/hawkular/notifiers/api/model/NotifierRegistrationMessage.java b/hawkular-notifiers-api/src/main/java/org/hawkular/notifiers/api/model/NotifierRegistrationMessage.java new file mode 100644 index 000000000..015af0d7e --- /dev/null +++ b/hawkular-notifiers-api/src/main/java/org/hawkular/notifiers/api/model/NotifierRegistrationMessage.java @@ -0,0 +1,99 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.notifiers.api.model; + +import com.google.gson.annotations.Expose; +import org.hawkular.bus.common.BasicMessage; + +import java.util.Set; + +/** + * A notifier registration message. + * i.e. email to admin, send trap #1 to OID B, send SMS to 555-12345 + * It helps to centralize into the alerts engine how many notifiers are available. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class NotifierRegistrationMessage extends BasicMessage { + + @Expose + String op; + + @Expose + String notifierId; + + @Expose + Set properties; + + public NotifierRegistrationMessage() { } + + public String getNotifierId() { + return notifierId; + } + + public void setNotifierId(String notifierId) { + this.notifierId = notifierId; + } + + public String getOp() { + return op; + } + + public void setOp(String op) { + this.op = op; + } + + public Set getProperties() { + return properties; + } + + public void setProperties(Set properties) { + this.properties = properties; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + NotifierRegistrationMessage that = (NotifierRegistrationMessage) o; + + if (notifierId != null ? !notifierId.equals(that.notifierId) : that.notifierId != null) return false; + if (op != null ? !op.equals(that.op) : that.op != null) return false; + if (properties != null ? !properties.equals(that.properties) : that.properties != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = op != null ? op.hashCode() : 0; + result = 31 * result + (notifierId != null ? notifierId.hashCode() : 0); + result = 31 * result + (properties != null ? properties.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "NotifierRegistrationMessage{" + + "notifierId='" + notifierId + '\'' + + ", op='" + op + '\'' + + ", properties=" + properties + + '}'; + } +} diff --git a/hawkular-notifiers-api/src/main/java/org/hawkular/notifiers/api/model/NotifierTypeRegistrationMessage.java b/hawkular-notifiers-api/src/main/java/org/hawkular/notifiers/api/model/NotifierTypeRegistrationMessage.java new file mode 100644 index 000000000..39f8ca4ca --- /dev/null +++ b/hawkular-notifiers-api/src/main/java/org/hawkular/notifiers/api/model/NotifierTypeRegistrationMessage.java @@ -0,0 +1,101 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.notifiers.api.model; + +import com.google.gson.annotations.Expose; +import org.hawkular.bus.common.BasicMessage; + +import java.util.Set; + +/** + * A notifier type registration message. + * i.e. sms, snmp, email + * + * This message is generated by the notifier plugin at registration phase. + * It helps to centralize into the alerts engine how many types of notifier are available. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +public class NotifierTypeRegistrationMessage extends BasicMessage { + + @Expose + String op; + + @Expose + String notifierType; + + @Expose + Set properties; + + public NotifierTypeRegistrationMessage() { } + + public String getNotifierType() { + return notifierType; + } + + public void setNotifierType(String notifierType) { + this.notifierType = notifierType; + } + + public String getOp() { + return op; + } + + public void setOp(String op) { + this.op = op; + } + + public Set getProperties() { + return properties; + } + + public void setProperties(Set properties) { + this.properties = properties; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + NotifierTypeRegistrationMessage that = (NotifierTypeRegistrationMessage) o; + + if (notifierType != null ? !notifierType.equals(that.notifierType) : that.notifierType != null) return false; + if (op != null ? !op.equals(that.op) : that.op != null) return false; + if (properties != null ? !properties.equals(that.properties) : that.properties != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = op != null ? op.hashCode() : 0; + result = 31 * result + (notifierType != null ? notifierType.hashCode() : 0); + result = 31 * result + (properties != null ? properties.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "NotifierTypeRegistrationMessage{" + + "notifierType='" + notifierType + '\'' + + ", op='" + op + '\'' + + ", properties=" + properties + + '}'; + } +} diff --git a/hawkular-notifiers-email/pom.xml b/hawkular-notifiers-email/pom.xml new file mode 100644 index 000000000..5d17e7ec0 --- /dev/null +++ b/hawkular-notifiers-email/pom.xml @@ -0,0 +1,132 @@ + + + + + 4.0.0 + + + org.hawkular.alerts + hawkular-alerts + 1.0.0.Alpha1-SNAPSHOT + + + org.hawkular.alerts + hawkular-notifiers-email + war + Hawkular Notifiers Email Plugin + + + + + org.hawkular.alerts + hawkular-notifiers-api + ${project.version} + + + + + org.hawkular.bus + hawkular-bus-mdb + ${project.version} + provided + + + + + com.google.guava + guava + ${version.com.google.guava} + provided + + + + com.google.code.gson + gson + ${version.com.google.code.gson} + provided + + + + + org.apache.activemq + activemq-all + ${version.org.apache.activemq} + provided + + + + org.apache.activemq + activemq-jaas + ${version.org.apache.activemq} + provided + + + + javax + javaee-api + ${version.javaee.spec} + provided + + + + junit + junit + ${version.junit} + test + + + + + + ${project.artifactId} + + + + + dev + + + + org.apache.maven.plugins + maven-antrun-plugin + + + deploy + install + + + + + + + run + + + + + + + + + + diff --git a/hawkular-notifiers-email/src/main/java/org/hawkular/notifiers/email/notifications/EmailListener.java b/hawkular-notifiers-email/src/main/java/org/hawkular/notifiers/email/notifications/EmailListener.java new file mode 100644 index 000000000..59182a067 --- /dev/null +++ b/hawkular-notifiers-email/src/main/java/org/hawkular/notifiers/email/notifications/EmailListener.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.notifiers.email.notifications; + +import org.hawkular.bus.common.consumer.BasicMessageListener; +import org.hawkular.notifiers.api.model.NotificationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.MessageListener; + +/** + * An example of listener for emails processing. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@MessageDriven(messageListenerInterface = MessageListener.class, activationConfig = { + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "NotificationsTopic"), + @ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "NotifierType like 'email'")}) +public class EmailListener extends BasicMessageListener { + private final Logger log = LoggerFactory.getLogger(EmailListener.class); + + protected void onBasicMessage(NotificationMessage msg) { + log.info("Email request message [{}]", msg); + } +} diff --git a/hawkular-notifiers-email/src/main/java/org/hawkular/notifiers/email/registration/RegisterListener.java b/hawkular-notifiers-email/src/main/java/org/hawkular/notifiers/email/registration/RegisterListener.java new file mode 100644 index 000000000..011b8c8b1 --- /dev/null +++ b/hawkular-notifiers-email/src/main/java/org/hawkular/notifiers/email/registration/RegisterListener.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.notifiers.email.registration; + +import org.hawkular.bus.common.consumer.BasicMessageListener; +import org.hawkular.notifiers.api.model.NotifierRegistrationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.MessageListener; + +/** + * An example of listener for email notifiers. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@MessageDriven(messageListenerInterface = MessageListener.class, activationConfig = { + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "NotifierRegisterTopic"), + @ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "NotifierType like 'email'")}) +public class RegisterListener extends BasicMessageListener { + private final Logger log = LoggerFactory.getLogger(RegisterListener.class); + + protected void onBasicMessage(NotifierRegistrationMessage msg) { + log.info("Received message [{}] registering a new NotifierID", msg); + } +} diff --git a/hawkular-notifiers-email/src/main/java/org/hawkular/notifiers/email/registration/RegistrationInit.java b/hawkular-notifiers-email/src/main/java/org/hawkular/notifiers/email/registration/RegistrationInit.java new file mode 100644 index 000000000..a3204b009 --- /dev/null +++ b/hawkular-notifiers-email/src/main/java/org/hawkular/notifiers/email/registration/RegistrationInit.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.notifiers.email.registration; + +import org.hawkular.bus.common.ConnectionContextFactory; +import org.hawkular.bus.common.Endpoint; +import org.hawkular.bus.common.MessageId; +import org.hawkular.bus.common.MessageProcessor; +import org.hawkular.bus.common.producer.ProducerConnectionContext; +import org.hawkular.notifiers.api.model.NotifierTypeRegistrationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.Resource; +import javax.jms.JMSException; +import javax.jms.QueueConnectionFactory; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; +import java.util.HashSet; +import java.util.Set; + +/** + * A initialization class to init the email plugin + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@WebListener +public class RegistrationInit implements ServletContextListener { + private final Logger log = LoggerFactory.getLogger(RegistrationInit.class); + private static final String NOTIFIER_TYPE_REGISTER = "NotifierTypeRegisterQueue"; + + @Resource(mappedName = "java:/HawkularBusConnectionFactory") + private QueueConnectionFactory conFactory; + private ConnectionContextFactory ccf; + private ProducerConnectionContext pcc; + + @Override + public void contextDestroyed(ServletContextEvent sce) { + log.info("Unregistering plugin email"); + } + + @Override + public void contextInitialized(ServletContextEvent sce) { + try { + ccf = new ConnectionContextFactory(conFactory); + pcc = ccf.createProducerConnectionContext(new Endpoint(Endpoint.Type.QUEUE, NOTIFIER_TYPE_REGISTER)); + + NotifierTypeRegistrationMessage ntrMsg = new NotifierTypeRegistrationMessage(); + ntrMsg.setOp("init"); + ntrMsg.setNotifierType("email"); + Set properties = new HashSet(); + properties.add("prop1"); + properties.add("prop2"); + properties.add("prop3"); + ntrMsg.setProperties(properties); + + MessageId mid = new MessageProcessor().send(pcc, ntrMsg); + + log.info("Sent registration request for email plugin. "); + + } catch (JMSException e) { + log.error(e.getMessage(), e); + } + } +} diff --git a/hawkular-notifiers-email/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/hawkular-notifiers-email/src/main/webapp/WEB-INF/jboss-deployment-structure.xml new file mode 100644 index 000000000..885ba4008 --- /dev/null +++ b/hawkular-notifiers-email/src/main/webapp/WEB-INF/jboss-deployment-structure.xml @@ -0,0 +1,26 @@ + + + + + + + + + \ No newline at end of file diff --git a/hawkular-notifiers-email/src/main/webapp/WEB-INF/jboss-web.xml b/hawkular-notifiers-email/src/main/webapp/WEB-INF/jboss-web.xml new file mode 100644 index 000000000..f870915cc --- /dev/null +++ b/hawkular-notifiers-email/src/main/webapp/WEB-INF/jboss-web.xml @@ -0,0 +1,22 @@ + + + + hawkular-notifiers-email + diff --git a/hawkular-notifiers-email/src/main/webapp/WEB-INF/web.xml b/hawkular-notifiers-email/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..87653b40d --- /dev/null +++ b/hawkular-notifiers-email/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,24 @@ + + + + diff --git a/hawkular-notifiers-email/src/main/webapp/index.jsp b/hawkular-notifiers-email/src/main/webapp/index.jsp new file mode 100644 index 000000000..b2e050949 --- /dev/null +++ b/hawkular-notifiers-email/src/main/webapp/index.jsp @@ -0,0 +1,26 @@ +<%-- + + Copyright 2015 Red Hat, Inc. and/or its affiliates + and other contributors as indicated by the @author tags. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--%> + + + Hawkular Notifiers Email + + +

Hawkular Notifiers Email

+ + diff --git a/hawkular-notifiers-sms/pom.xml b/hawkular-notifiers-sms/pom.xml new file mode 100644 index 000000000..d239e8417 --- /dev/null +++ b/hawkular-notifiers-sms/pom.xml @@ -0,0 +1,132 @@ + + + + + 4.0.0 + + + org.hawkular.alerts + hawkular-alerts + 1.0.0.Alpha1-SNAPSHOT + + + org.hawkular.alerts + hawkular-notifiers-sms + war + Hawkular Notifiers Sms Plugin + + + + + org.hawkular.alerts + hawkular-notifiers-api + ${project.version} + + + + + org.hawkular.bus + hawkular-bus-mdb + ${project.version} + provided + + + + + com.google.guava + guava + ${version.com.google.guava} + provided + + + + com.google.code.gson + gson + ${version.com.google.code.gson} + provided + + + + + org.apache.activemq + activemq-all + ${version.org.apache.activemq} + provided + + + + org.apache.activemq + activemq-jaas + ${version.org.apache.activemq} + provided + + + + javax + javaee-api + ${version.javaee.spec} + provided + + + + junit + junit + ${version.junit} + test + + + + + + ${project.artifactId} + + + + + dev + + + + org.apache.maven.plugins + maven-antrun-plugin + + + deploy + install + + + + + + + run + + + + + + + + + + diff --git a/hawkular-notifiers-sms/src/main/java/org/hawkular/notifiers/sms/notifications/SmsListener.java b/hawkular-notifiers-sms/src/main/java/org/hawkular/notifiers/sms/notifications/SmsListener.java new file mode 100644 index 000000000..e0f1ebfee --- /dev/null +++ b/hawkular-notifiers-sms/src/main/java/org/hawkular/notifiers/sms/notifications/SmsListener.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.notifiers.sms.notifications; + +import org.hawkular.bus.common.consumer.BasicMessageListener; +import org.hawkular.notifiers.api.model.NotificationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.MessageListener; + +/** + * An example of listener for sms processing. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@MessageDriven(messageListenerInterface = MessageListener.class, activationConfig = { + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "NotificationsTopic"), + @ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "NotifierType like 'sms'")}) +public class SmsListener extends BasicMessageListener { + private final Logger log = LoggerFactory.getLogger(SmsListener.class); + + protected void onBasicMessage(NotificationMessage msg) { + log.info("SMS request message [{}]", msg); + } +} diff --git a/hawkular-notifiers-sms/src/main/java/org/hawkular/notifiers/sms/registration/RegisterListener.java b/hawkular-notifiers-sms/src/main/java/org/hawkular/notifiers/sms/registration/RegisterListener.java new file mode 100644 index 000000000..0e70b0255 --- /dev/null +++ b/hawkular-notifiers-sms/src/main/java/org/hawkular/notifiers/sms/registration/RegisterListener.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.notifiers.sms.registration; + +import org.hawkular.bus.common.consumer.BasicMessageListener; +import org.hawkular.notifiers.api.model.NotifierRegistrationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.MessageListener; + +/** + * An example of listener for sms notifiers. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@MessageDriven(messageListenerInterface = MessageListener.class, activationConfig = { + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "NotifierRegisterTopic"), + @ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "NotifierType like 'sms'")}) +public class RegisterListener extends BasicMessageListener { + private final Logger log = LoggerFactory.getLogger(RegisterListener.class); + + protected void onBasicMessage(NotifierRegistrationMessage msg) { + log.info("Received message [{}] registering a new NotifierID", msg); + } +} diff --git a/hawkular-notifiers-sms/src/main/java/org/hawkular/notifiers/sms/registration/RegistrationInit.java b/hawkular-notifiers-sms/src/main/java/org/hawkular/notifiers/sms/registration/RegistrationInit.java new file mode 100644 index 000000000..ed1d6f87a --- /dev/null +++ b/hawkular-notifiers-sms/src/main/java/org/hawkular/notifiers/sms/registration/RegistrationInit.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.notifiers.sms.registration; + +import org.hawkular.bus.common.ConnectionContextFactory; +import org.hawkular.bus.common.Endpoint; +import org.hawkular.bus.common.MessageId; +import org.hawkular.bus.common.MessageProcessor; +import org.hawkular.bus.common.producer.ProducerConnectionContext; +import org.hawkular.notifiers.api.model.NotifierTypeRegistrationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.Resource; +import javax.jms.JMSException; +import javax.jms.QueueConnectionFactory; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; +import java.util.HashSet; +import java.util.Set; + +/** + * A initialization class to init the sms plugin + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@WebListener +public class RegistrationInit implements ServletContextListener { + private final Logger log = LoggerFactory.getLogger(RegistrationInit.class); + private static final String NOTIFIER_TYPE_REGISTER = "NotifierTypeRegisterQueue"; + + @Resource(mappedName = "java:/HawkularBusConnectionFactory") + private QueueConnectionFactory conFactory; + private ConnectionContextFactory ccf; + private ProducerConnectionContext pcc; + + @Override + public void contextDestroyed(ServletContextEvent sce) { + log.info("Unregistering plugin sms"); + } + + @Override + public void contextInitialized(ServletContextEvent sce) { + try { + ccf = new ConnectionContextFactory(conFactory); + pcc = ccf.createProducerConnectionContext(new Endpoint(Endpoint.Type.QUEUE, NOTIFIER_TYPE_REGISTER)); + + NotifierTypeRegistrationMessage ntrMsg = new NotifierTypeRegistrationMessage(); + ntrMsg.setOp("init"); + ntrMsg.setNotifierType("sms"); + Set properties = new HashSet(); + properties.add("prop1"); + properties.add("prop2"); + properties.add("prop3"); + ntrMsg.setProperties(properties); + + MessageId mid = new MessageProcessor().send(pcc, ntrMsg); + + log.info("Sent registration request for sms plugin. "); + + } catch (JMSException e) { + log.error(e.getMessage(), e); + } + } +} diff --git a/hawkular-notifiers-sms/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/hawkular-notifiers-sms/src/main/webapp/WEB-INF/jboss-deployment-structure.xml new file mode 100644 index 000000000..885ba4008 --- /dev/null +++ b/hawkular-notifiers-sms/src/main/webapp/WEB-INF/jboss-deployment-structure.xml @@ -0,0 +1,26 @@ + + + + + + + + + \ No newline at end of file diff --git a/hawkular-notifiers-sms/src/main/webapp/WEB-INF/jboss-web.xml b/hawkular-notifiers-sms/src/main/webapp/WEB-INF/jboss-web.xml new file mode 100644 index 000000000..4b6356758 --- /dev/null +++ b/hawkular-notifiers-sms/src/main/webapp/WEB-INF/jboss-web.xml @@ -0,0 +1,22 @@ + + + + hawkular-notifiers-sms + diff --git a/hawkular-notifiers-sms/src/main/webapp/WEB-INF/web.xml b/hawkular-notifiers-sms/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..87653b40d --- /dev/null +++ b/hawkular-notifiers-sms/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,24 @@ + + + + diff --git a/hawkular-notifiers-sms/src/main/webapp/index.jsp b/hawkular-notifiers-sms/src/main/webapp/index.jsp new file mode 100644 index 000000000..de142adb9 --- /dev/null +++ b/hawkular-notifiers-sms/src/main/webapp/index.jsp @@ -0,0 +1,26 @@ +<%-- + + Copyright 2015 Red Hat, Inc. and/or its affiliates + and other contributors as indicated by the @author tags. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--%> + + + Hawkular Notifiers Sms + + +

Hawkular Notifiers Sms

+ + diff --git a/hawkular-notifiers-snmp/pom.xml b/hawkular-notifiers-snmp/pom.xml new file mode 100644 index 000000000..cae03df1c --- /dev/null +++ b/hawkular-notifiers-snmp/pom.xml @@ -0,0 +1,132 @@ + + + + + 4.0.0 + + + org.hawkular.alerts + hawkular-alerts + 1.0.0.Alpha1-SNAPSHOT + + + org.hawkular.alerts + hawkular-notifiers-snmp + war + Hawkular Notifiers Snmp Plugin + + + + + org.hawkular.alerts + hawkular-notifiers-api + ${project.version} + + + + + org.hawkular.bus + hawkular-bus-mdb + ${project.version} + provided + + + + + com.google.guava + guava + ${version.com.google.guava} + provided + + + + com.google.code.gson + gson + ${version.com.google.code.gson} + provided + + + + + org.apache.activemq + activemq-all + ${version.org.apache.activemq} + provided + + + + org.apache.activemq + activemq-jaas + ${version.org.apache.activemq} + provided + + + + javax + javaee-api + ${version.javaee.spec} + provided + + + + junit + junit + ${version.junit} + test + + + + + + ${project.artifactId} + + + + + dev + + + + org.apache.maven.plugins + maven-antrun-plugin + + + deploy + install + + + + + + + run + + + + + + + + + + diff --git a/hawkular-notifiers-snmp/src/main/java/org/hawkular/notifiers/snmp/notifications/SnmpListener.java b/hawkular-notifiers-snmp/src/main/java/org/hawkular/notifiers/snmp/notifications/SnmpListener.java new file mode 100644 index 000000000..85e87b99a --- /dev/null +++ b/hawkular-notifiers-snmp/src/main/java/org/hawkular/notifiers/snmp/notifications/SnmpListener.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.notifiers.snmp.notifications; + +import org.hawkular.bus.common.consumer.BasicMessageListener; +import org.hawkular.notifiers.api.model.NotificationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.MessageListener; + +/** + * An example of listener for sms processing. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@MessageDriven(messageListenerInterface = MessageListener.class, activationConfig = { + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "NotificationsTopic"), + @ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "NotifierType like 'snmp'")}) +public class SnmpListener extends BasicMessageListener { + private final Logger log = LoggerFactory.getLogger(SnmpListener.class); + + protected void onBasicMessage(NotificationMessage msg) { + log.info("SNMP request message [{}]", msg); + } +} diff --git a/hawkular-notifiers-snmp/src/main/java/org/hawkular/notifiers/snmp/registration/RegisterListener.java b/hawkular-notifiers-snmp/src/main/java/org/hawkular/notifiers/snmp/registration/RegisterListener.java new file mode 100644 index 000000000..352fdccf6 --- /dev/null +++ b/hawkular-notifiers-snmp/src/main/java/org/hawkular/notifiers/snmp/registration/RegisterListener.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.notifiers.snmp.registration; + +import org.hawkular.bus.common.consumer.BasicMessageListener; +import org.hawkular.notifiers.api.model.NotifierRegistrationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.MessageListener; + +/** + * An example of listener for snmp notifiers. + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@MessageDriven(messageListenerInterface = MessageListener.class, activationConfig = { + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "NotifierRegisterTopic"), + @ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "NotifierType like 'snmp'")}) +public class RegisterListener extends BasicMessageListener { + private final Logger log = LoggerFactory.getLogger(RegisterListener.class); + + protected void onBasicMessage(NotifierRegistrationMessage msg) { + log.info("Received message [{}] registering a new NotifierID", msg); + } +} diff --git a/hawkular-notifiers-snmp/src/main/java/org/hawkular/notifiers/snmp/registration/RegistrationInit.java b/hawkular-notifiers-snmp/src/main/java/org/hawkular/notifiers/snmp/registration/RegistrationInit.java new file mode 100644 index 000000000..6e5e263d8 --- /dev/null +++ b/hawkular-notifiers-snmp/src/main/java/org/hawkular/notifiers/snmp/registration/RegistrationInit.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hawkular.notifiers.snmp.registration; + +import org.hawkular.bus.common.ConnectionContextFactory; +import org.hawkular.bus.common.Endpoint; +import org.hawkular.bus.common.MessageId; +import org.hawkular.bus.common.MessageProcessor; +import org.hawkular.bus.common.producer.ProducerConnectionContext; +import org.hawkular.notifiers.api.model.NotifierTypeRegistrationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.Resource; +import javax.jms.JMSException; +import javax.jms.QueueConnectionFactory; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; +import java.util.HashSet; +import java.util.Set; + +/** + * A initialization class to init the snmp plugin + * + * @author Jay Shaughnessy + * @author Lucas Ponce + */ +@WebListener +public class RegistrationInit implements ServletContextListener { + private final Logger log = LoggerFactory.getLogger(RegistrationInit.class); + private static final String NOTIFIER_TYPE_REGISTER = "NotifierTypeRegisterQueue"; + + @Resource(mappedName = "java:/HawkularBusConnectionFactory") + private QueueConnectionFactory conFactory; + private ConnectionContextFactory ccf; + private ProducerConnectionContext pcc; + + @Override + public void contextDestroyed(ServletContextEvent sce) { + log.info("Unregistering plugin snmp"); + } + + @Override + public void contextInitialized(ServletContextEvent sce) { + try { + ccf = new ConnectionContextFactory(conFactory); + pcc = ccf.createProducerConnectionContext(new Endpoint(Endpoint.Type.QUEUE, NOTIFIER_TYPE_REGISTER)); + + NotifierTypeRegistrationMessage ntrMsg = new NotifierTypeRegistrationMessage(); + ntrMsg.setOp("init"); + ntrMsg.setNotifierType("snmp"); + Set properties = new HashSet(); + properties.add("prop1"); + properties.add("prop2"); + properties.add("prop3"); + ntrMsg.setProperties(properties); + + MessageId mid = new MessageProcessor().send(pcc, ntrMsg); + + log.info("Sent registration request for snmp plugin. "); + + } catch (JMSException e) { + log.error(e.getMessage(), e); + } + } +} diff --git a/hawkular-notifiers-snmp/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/hawkular-notifiers-snmp/src/main/webapp/WEB-INF/jboss-deployment-structure.xml new file mode 100644 index 000000000..885ba4008 --- /dev/null +++ b/hawkular-notifiers-snmp/src/main/webapp/WEB-INF/jboss-deployment-structure.xml @@ -0,0 +1,26 @@ + + + + + + + + + \ No newline at end of file diff --git a/hawkular-notifiers-snmp/src/main/webapp/WEB-INF/jboss-web.xml b/hawkular-notifiers-snmp/src/main/webapp/WEB-INF/jboss-web.xml new file mode 100644 index 000000000..e767507cf --- /dev/null +++ b/hawkular-notifiers-snmp/src/main/webapp/WEB-INF/jboss-web.xml @@ -0,0 +1,22 @@ + + + + hawkular-notifiers-snmp + diff --git a/hawkular-notifiers-snmp/src/main/webapp/WEB-INF/web.xml b/hawkular-notifiers-snmp/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..87653b40d --- /dev/null +++ b/hawkular-notifiers-snmp/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,24 @@ + + + + diff --git a/hawkular-notifiers-snmp/src/main/webapp/index.jsp b/hawkular-notifiers-snmp/src/main/webapp/index.jsp new file mode 100644 index 000000000..63e2a67cf --- /dev/null +++ b/hawkular-notifiers-snmp/src/main/webapp/index.jsp @@ -0,0 +1,26 @@ +<%-- + + Copyright 2015 Red Hat, Inc. and/or its affiliates + and other contributors as indicated by the @author tags. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--%> + + + Hawkular Notifiers Snmp + + +

Hawkular Notifiers Snmp

+ + diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..2d84f4895 --- /dev/null +++ b/pom.xml @@ -0,0 +1,260 @@ + + + + 4.0.0 + + org.hawkular.alerts + hawkular-alerts + 1.0.0.Alpha1-SNAPSHOT + pom + + Hawkular Alerts + Alerting subsystem for Hawkular + https://github.com/hawkular/hawkular-alerts + 2015 + + Red Hat, Inc. + http://redhat.com/ + + + + Apache License, Version 2.0 + repo + http://www.apache.org/licenses/LICENSE-2.0.html + + + + + + Hawkular Developer List + https://lists.jboss.org/mailman/listinfo/hawkular-dev + https://lists.jboss.org/mailman/listinfo/hawkular-dev + http://lists.jboss.org/pipermail/hawkular-dev + + + + + scm:git:git://github.com/hawkular/hawkular-alerts.git + scm:git:ssh://git@github.com/hawkular/hawkular-alerts.git + https://github.com/hawkular/hawkular-alerts + HEAD + + + https://issues.jboss.org/browse/HWKALERTS + jira + + + + jboss-releases-repository + JBoss Releases Repository + https://repository.jboss.org/nexus/service/local/staging/deploy/maven2/ + + + jboss-snapshots-repository + JBoss Snapshots Repository + https://repository.jboss.org/nexus/content/repositories/snapshots/ + + + + + hawkular-alerts-api + hawkular-notifiers-api + hawkular-alerts-engine + hawkular-alerts-bus + hawkular-alerts-rest + hawkular-alerts-ear + hawkular-notifiers-email + hawkular-notifiers-sms + hawkular-notifiers-snmp + examples/example-alerts-ui + + + + 1.6 + 1.6 + + true + true + hawkular-checkstyle/suppressions.xml + + ${project.basedir}/../../hawkular-bus/hawkular-nest/hawkular-nest-distro/target/wildfly-${version.org.wildfly} + ${org.hawkular.wildfly.home}/modules/system/layers/base/org/hawkular/nest/main/deployments + + 2.13 + 2.6 + + UTF-8 + UTF-8 + + 6.1.1 + 2.2.4 + 16.0.1 + 2.7 + 6.1.1 + 7.0 + 4.12 + 5.10.0 + 6.1.0.Final + 3.6.1.201501031845-r + 5 + 1.0.0.Alpha1-SNAPSHOT + 1.0.0.Final + 1.7.2 + 8.2.0.Final + + + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.5.1 + + @{project.version} + package + deploy + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${plugin.version.checkstyle} + + hawkular-checkstyle/checkstyle.xml + ${checkstyleConsoleOutput} + ${checkstyleFailOnError} + + ${basedir} + + + src/**/*.java, + *.xml, + src/**/*.xml, + src/**/*.js, + *.adoc, + src/**/*.adoc, + *.conf, + src/**/*.conf, + src/**/*.cql, + src/**/*.css, + Dockerfile, + src/**/Dockerfile, + src/**/*.groovy, + *.html, + src/**/*.html, + src/**/*.json, + src/**/*.js.map, + *.md, + src/**/*.md, + *.properties, + src/**/*.properties, + *.sh, + src/**/*.sh, + *.txt, + src/**/*.txt, + src/**/*.xsl, + *.yml, + src/**/*.yml, + + + ${checkstyle.suppressions.file} + + + + + com.puppycrawl.tools + checkstyle + ${version.checkstyle} + + + org.hawkular + hawkular-build-tools + ${version.org.hawkular.hawkular-build-tools} + + + + + check-style + compile + + checkstyle + + + + + + + com.mycila + license-maven-plugin + ${version.com.mycila.license-maven-plugin} + +
hawkular-license/jboss-apache-2-template.txt
+ + **/.bowerrc + **/.jshintrc + **/LICENSE + **/README.* + **/*.eot + **/*.otf + **/*.ttf + **/*.svg + **/*.woff + **/*.html + **/*.htm + + + SCRIPT_STYLE + DOUBLEDASHES_STYLE + SCRIPT_STYLE + SLASHSTAR_STYLE + DOUBLEDASHES_STYLE + SLASHSTAR_STYLE + SLASHSTAR_STYLE + SLASHSTAR_STYLE + +
+ + + org.hawkular + hawkular-build-tools + ${version.org.hawkular.hawkular-build-tools} + + + + + + check + + + +
+
+
+ +
\ No newline at end of file