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