Skip to content

Commit

Permalink
Merge pull request #17 from objectiser/HAWKULAR-175
Browse files Browse the repository at this point in the history
HAWKULAR-175 Provide virtual topic MDB sample
  • Loading branch information
jmazzitelli committed May 11, 2015
2 parents 674322e + 43bcd9e commit 4d834ef
Show file tree
Hide file tree
Showing 10 changed files with 412 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
A sample MDB inside a war for Hawkular Bus that publishes messages to a topic, which are then consumed by two sample applications (A and B) via queues. This leverages the _virtual topic_ concept within ActiveMQ (http://activemq.apache.org/virtual-destinations.html).

The motivation for using _virtual topics_ is to support multiple instances of a particular consumer, for load balancing and failover support, without consuming (and processing) the message more than one. This is possible using plain queues, except this then only allows a single consuming application. If more than one application is interested in processing the events, and we don't want the producer to have to send that event to multiple queues, then using _virtual topics_ provides the ideal solution. From the producer's perspective they are sending messages to a topic and therefore multiple consumers, while from the consumer perspective they are receiving messages from a load balanced queue, enabling the application to be load balanced across a cluster of servers.

Here's how to set this up:

1. Build hawkular-bus (the messaging framework and wildfly modules)
(cd <hawkular-bus> ; mvn clean install -Pdev)
2. Build this sample war and deploy it:
(cd <hawkular-bus>/hawkular-bus-samples/hawkular-bus-sample-virtual-topic-mdb; mvn clean install -Pdev)
3. Run the Wildfly server:
<hawkular-bus>/hawkular-nest/hawkular-nest-distro/target/wildfly-8.2.0/bin/standalone.sh
4. Point browser to http://localhost:8080/sample-vt-mdb/
5. Enter some text and click submit (this will send a message on "java:/topic/VirtualTopic.ExampleName")
6. See the Wildfly server logs for a message that the MDB prints out showing both AppA and AppB received the message.
126 changes: 126 additions & 0 deletions hawkular-bus-samples/hawkular-bus-sample-virtual-topic-mdb/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.hawkular.bus</groupId>
<artifactId>hawkular-bus-samples-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>

<artifactId>hawkular-bus-sample-vt-mdb</artifactId>
<packaging>war</packaging>
<name>Hawkular Bus Sample Virtual Topics MDB Web Application</name>

<dependencies>
<!-- The hawkular platform will provide these -->
<dependency>
<groupId>org.hawkular.bus</groupId>
<artifactId>hawkular-bus-mdb</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>

<!-- The hawkular platform will provide these transitive deps from common -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging-processor</artifactId>
<scope>provided</scope>
</dependency>

<!-- these will be provided by our RA - the MDB itself will never need ActiveMQ specific classes -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jaas</artifactId>
<scope>provided</scope>
</dependency>

<!-- The EJB API is provided by the container -->
<dependency>
<groupId>org.jboss.spec.javax.ejb</groupId>
<artifactId>jboss-ejb-api_3.2_spec</artifactId>
<scope>provided</scope>
</dependency>

<!-- The Servlet API is provided by the container -->
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.1_spec</artifactId>
<scope>provided</scope>
</dependency>

</dependencies>

<profiles>
<profile>
<id>dev</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>deploy</id>
<phase>install</phase>
<configuration>
<target>
<property name="org.hawkular.wildfly.home"
value="${basedir}/../../../hawkular-bus/hawkular-nest/hawkular-nest-distro/target/wildfly-${version.org.wildfly}" />
<property name="org.hawkular.wildfly.deployments" value="modules/system/layers/base/org/hawkular/nest/main/deployments" />
<copy file="${project.build.directory}/${project.build.finalName}.war" todir="${org.hawkular.wildfly.home}/${org.hawkular.wildfly.deployments}" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
@@ -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.bus.sample.mdb;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.MessageListener;

import org.hawkular.bus.common.SimpleBasicMessage;
import org.hawkular.bus.common.consumer.BasicMessageListener;
import org.jboss.logging.Logger;

@MessageDriven(messageListenerInterface = MessageListener.class, activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination",
propertyValue = "Consumer.AppA.VirtualTopic.ExampleName"),
@ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "MyFilter = 'fnf'") })
public class AppAMDB extends BasicMessageListener<SimpleBasicMessage> {
private final Logger log = Logger.getLogger(AppAMDB.class);

protected void onBasicMessage(SimpleBasicMessage msg) {
log.infof("===> MDB {AppA} received message [%s]", msg);
};
}
Original file line number Diff line number Diff line change
@@ -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.bus.sample.mdb;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.MessageListener;

import org.hawkular.bus.common.SimpleBasicMessage;
import org.hawkular.bus.common.consumer.BasicMessageListener;
import org.jboss.logging.Logger;

@MessageDriven(messageListenerInterface = MessageListener.class, activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination",
propertyValue = "Consumer.AppB.VirtualTopic.ExampleName"),
@ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "MyFilter = 'fnf'") })
public class AppBMDB extends BasicMessageListener<SimpleBasicMessage> {
private final Logger log = Logger.getLogger(AppBMDB.class);

protected void onBasicMessage(SimpleBasicMessage msg) {
log.infof("===> MDB {AppB} received message [%s]", msg);
};
}
Original file line number Diff line number Diff line change
@@ -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.bus.sample.mdb;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.jms.TopicConnectionFactory;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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.SimpleBasicMessage;
import org.hawkular.bus.common.producer.ProducerConnectionContext;

public class VirtualTopicSendServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String CONN_FACTORY = "/HawkularBusConnectionFactory";

// the full name is "java:/topic/VirtualTopic.ExampleName"
private static final String TOPIC_NAME = "VirtualTopic.ExampleName";

private static final Map<String, String> FNF_HEADER = createMyFilterHeader("fnf");

public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userMessage = request.getParameter("jmsMessageFNF");
if (userMessage != null) {
fireAndForget(request, response, userMessage);
} else {
throw new ServletException("Don't know what to send!");
}
}

protected void fireAndForget(HttpServletRequest request, HttpServletResponse response, String userMessage) {
try {
InitialContext ctx = new InitialContext();
TopicConnectionFactory qconFactory = (TopicConnectionFactory) ctx.lookup(CONN_FACTORY);

ConnectionContextFactory ccf = new ConnectionContextFactory(qconFactory);
ProducerConnectionContext pcc = ccf.createProducerConnectionContext(new Endpoint(Endpoint.Type.TOPIC,
TOPIC_NAME));

SimpleBasicMessage msg = new SimpleBasicMessage(userMessage);
MessageId mid = new MessageProcessor().send(pcc, msg, FNF_HEADER);

PrintWriter out = response.getWriter();
out.println("<h1>Fire and Forget</h1>");
out.println("<p>Message Sent [" + msg + "]</p>");
out.println("<p>(messageId=" + mid + ")</p>");
} catch (Exception e) {
e.printStackTrace();
}
}

// return the header that our sample MDBs' selectors will look at
private static Map<String, String> createMyFilterHeader(String value) {
Map<String, String> map = new HashMap<String, String>(1);
map.put("MyFilter", value);
return map;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!--
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.
-->
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
<deployment>
<dependencies>
<module name="org.hawkular.nest" />
</dependencies>
</deployment>
</jboss-deployment-structure>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0"?>
<!--
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.
-->

<jboss-web>
<context-root>sample-vt-mdb</context-root>
</jboss-web>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!--
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.
-->
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">

<servlet>
<servlet-name>VirtualTopicSendServlet</servlet-name>
<servlet-class>org.hawkular.bus.sample.mdb.VirtualTopicSendServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>VirtualTopicSendServlet</servlet-name>
<url-pattern>/VirtualTopicSendServlet</url-pattern>
</servlet-mapping>
</web-app>

0 comments on commit 4d834ef

Please sign in to comment.