Skip to content

Commit

Permalink
Work supporting HK-484 (deployment failure event alerting)
Browse files Browse the repository at this point in the history
- add CommandEventListener to grab Events off the bus and
  forward to alerts.  Currently generates events for application
  deployments.
- Fix bug in event expression eval when RHQ has spaces
- Fix classloader issue in Metric/AvailDataListener
  - This can be updated if/when metrics makes its bus classes public

TODO:
- Snapshot deps should be replaced with srcdep/final deps
- The whole CommandEventListener should probably be moved into
  an independent hawkular war deployment. And that war should
  be able to filter the events that actually get forwarded to alerts
  for storage/eval.
  • Loading branch information
jshaughn committed Nov 19, 2015
1 parent ea44bd2 commit 7d08a87
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,18 @@ private boolean processExpression(String expression, Event value) {
return false;
}
String[] tokens = expression.split(" ");
if (tokens.length != 3) {
if (tokens.length < 3) {
return false;
}
String eventField = tokens[0];
String sEventValue = null;
Long lEventValue = null;
String operator = tokens[1];
String constant = tokens[2];
for (int i = 3; i < tokens.length; ++i) {
constant += " ";
constant += tokens[i];
}
String sEventValue = null;
Long lEventValue = null;
String sConstantValue = null;
Double dConstantValue = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,29 @@ public void testTenantIdExpression() {
assertTrue(condition.match(event2));
}

@Test
public void testCategoryExpressionWithSpaces() {

EventCondition condition = new EventCondition("trigger-1", "app.war", "category == 'my category'");
Event event1 = new Event();
event1.setCategory("my category");

assertTrue(condition.match(event1));

Event event2 = new Event();
event2.setCategory("my category 2");

assertFalse(condition.match(event2));

condition.setExpression("category starts 'my category '");

assertTrue(condition.match(event2));

condition.setExpression("category ends '2'");

assertTrue(condition.match(event2));
}

@Test
public void testCtimeExpression() {
EventCondition condition = new EventCondition("trigger-1", "app.war", "ctime > 10");
Expand Down
14 changes: 14 additions & 0 deletions hawkular-alerts-bus/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@

<dependencies>

<!-- Hawkular Command Gateway dependencies -->
<dependency>
<groupId>org.hawkular.cmdgw</groupId>
<artifactId>hawkular-command-gateway-api</artifactId>
<version>${version.org.hawkular.command-gateway}</version>
</dependency>

<!-- Hawkular Alerts dependencies -->
<dependency>
<groupId>org.hawkular.alerts</groupId>
Expand All @@ -52,6 +59,13 @@
<version>${project.version}</version>
</dependency>

<!-- Hawkular dependencies -->
<dependency>
<groupId>org.hawkular.inventory</groupId>
<artifactId>hawkular-inventory-api</artifactId>
<version>${version.org.hawkular.inventory}</version>
</dependency>

<!-- Hawkular Nest dependencies -->
<dependency>
<groupId>org.hawkular.bus</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,18 @@ protected void onBasicMessage(AvailDataMessage msg) {
}
}
}

// Metrics is not currently exposing the class it uses for the message. So we needed to
// implement a compatible class that we can use to deserialize the JSON. If the class becomes
// something we can get as a dependency, then import that and this can be removed.
@Override
protected String convertReceivedMessageClassNameToDesiredMessageClassName(String className) {

if (className.equals("org.hawkular.metrics.component.publish.AvailDataMessage")) {
return "org.hawkular.alerts.bus.messages.AvailDataMessage";
}

return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* 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 java.util.Collections;
import java.util.UUID;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.jms.MessageListener;

import org.hawkular.alerts.api.model.event.Event;
import org.hawkular.alerts.api.services.AlertsService;
import org.hawkular.bus.common.BasicMessage;
import org.hawkular.bus.common.consumer.BasicMessageListener;
import org.hawkular.cmdgw.api.DeployApplicationResponse;
import org.hawkular.inventory.api.model.CanonicalPath;
import org.jboss.logging.Logger;

/**
* <p><b>
* NOTE: This listener should likely move to a dedicated deployment, in Hawkular, not Hawkular Alerts. Hawkular
* Alerts should not really have knowledge about Hawkular-level decisions, like which possible Events to filter out or
* various special handling that needs to be performed.
* </b></p>
* <p>
* Consume Command Gateway Events, convert to Hawkular Events and forward to the engine for persistence/evaluation.
* </p>
* This is useful only when deploying into the Hawkular Bus with Hawkular Command Gateway. The expected message
* payload should a command pojo.
*
* @author Jay Shaughnessy
* @author Lucas Ponce
*/
@MessageDriven(messageListenerInterface = MessageListener.class, activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "HawkularCommandEvent") })
@TransactionAttribute(value = TransactionAttributeType.NOT_SUPPORTED)
public class CommandEventListener extends BasicMessageListener<BasicMessage> {
private final Logger log = Logger.getLogger(CommandEventListener.class);

@EJB
AlertsService alerts;

@Override
protected void onBasicMessage(BasicMessage msg) {

if (msg instanceof DeployApplicationResponse) {
DeployApplicationResponse dar = (DeployApplicationResponse) msg;

String canonicalPathString = dar.getResourcePath();
CanonicalPath canonicalPath = CanonicalPath.fromString(canonicalPathString);
String tenantId = canonicalPath.ids().getTenantId();
String resourceId = canonicalPath.ids().getResourcePath().getSegment().getElementId();
resourceId = resourceId.substring(0, resourceId.length() - 2); // trim trailing '~~'
String eventId = UUID.randomUUID().toString();
String dataId = resourceId + "_DeployApplicationResponse";
String category = "Hawkular Deployment";
String text = dar.getStatus().name();
Event event = new Event(tenantId, eventId, dataId, category, text);
event.addContext("CanonicalPath", canonicalPathString);
event.addContext("Message", dar.getMessage());

log.debugf("EVENT! %s", event.toString());

try {
alerts.addEvents(Collections.singleton(event));
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
log.errorf("Unexpected Event Message! %s", msg.toJSON());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,18 @@ protected void onBasicMessage(MetricDataMessage msg) {
}
}
}

// Metrics is not currently exposing the class it uses for the message. So we needed to
// implement a compatible class that we can use to deserialize the JSON. If the class becomes
// something we can get as a dependency, then import that and this can be removed.
@Override
protected String convertReceivedMessageClassNameToDesiredMessageClassName(String className) {

if (className.equals("org.hawkular.metrics.component.publish.MetricDataMessage")) {
return "org.hawkular.alerts.bus.messages.MetricDataMessage";
}

return null;
}

}
6 changes: 4 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,12 @@
<version.org.freemarker>2.3.17</version.org.freemarker>
<version.org.hawkular>1.0.0.Alpha6</version.org.hawkular>
<version.org.hawkular.accounts>1.1.1.Final</version.org.hawkular.accounts>
<version.org.hawkular.bus>0.7.1.Final</version.org.hawkular.bus>
<version.org.hawkular.bus>0.7.3.Final-SNAPSHOT</version.org.hawkular.bus>
<version.org.hawkular.command-gateway>0.10.4.Final-SNAPSHOT</version.org.hawkular.command-gateway>
<version.org.hawkular.commons>0.2.2.Final</version.org.hawkular.commons>
<version.org.hawkular.nest>${version.org.hawkular.bus}</version.org.hawkular.nest>
<version.org.hawkular.inventory>0.8.0-Final</version.org.hawkular.inventory>
<version.org.hawkular.metrics>0.6.0.Final</version.org.hawkular.metrics>
<version.org.hawkular.nest>${version.org.hawkular.bus}</version.org.hawkular.nest>
<version.org.jboss.jboss-vfs>3.2.10.Final</version.org.jboss.jboss-vfs>
<version.org.schwering>2.0.0.Alpha3</version.org.schwering>
<version.org.slf4j>1.7.2</version.org.slf4j>
Expand Down

0 comments on commit 7d08a87

Please sign in to comment.