Skip to content

Commit

Permalink
Implementations for various test cases and refactoring of code to pro…
Browse files Browse the repository at this point in the history
…vide both api and impl for API classes.
  • Loading branch information
johnament committed Mar 23, 2011
1 parent dee4a80 commit 6a2bb15
Show file tree
Hide file tree
Showing 17 changed files with 514 additions and 163 deletions.
68 changes: 41 additions & 27 deletions api/pom.xml
@@ -1,34 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>
<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.jboss.seam.jms</groupId>
<artifactId>seam-jms-parent</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<parent>
<groupId>org.jboss.seam.jms</groupId>
<artifactId>seam-jms-parent</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>seam-jms-api</artifactId>
<packaging>jar</packaging>
<artifactId>seam-jms-api</artifactId>
<packaging>jar</packaging>

<name>Seam JMS API</name>
<description>Client View of the Seam JMS Module</description>
<!-- url required for JAR Manifest -->
<url>${project.parent.url}</url>
<name>Seam JMS API</name>
<description>Client View of the Seam JMS Module</description>
<!-- url required for JAR Manifest -->
<url>${project.parent.url}</url>

<dependencies>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<scope>provided</scope>
</dependency>
<dependencies>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.jboss.spec.javax.jms</groupId>
<artifactId>jboss-jms-api_1.1_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.0.0.Beta4</version>
<scope>provided</scope>
</dependency>

<dependency>
<!-- Required until the Servlet 3.0 API can be resolved in Central -->
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

<dependency>
<groupId>org.jboss.spec.javax.jms</groupId>
<artifactId>jboss-jms-api_1.1_spec</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

</project>
58 changes: 58 additions & 0 deletions api/src/main/java/org/jboss/seam/jms/AbstractMessageListener.java
@@ -0,0 +1,58 @@
package org.jboss.seam.jms;

import javax.enterprise.inject.spi.BeanManager;
import javax.jms.JMSException;
import javax.jms.Message;

import org.jboss.logging.Logger;

/**
* Supporting base MessageListener for working in CDI enabled environments.
* This is useful for having a MessageListener
*
* @author johnament
*
*/
public abstract class AbstractMessageListener implements javax.jms.MessageListener {
private Logger logger;

protected BeanManager beanManager;
protected ClassLoader classLoader;

protected AbstractMessageListener(BeanManager beanManager, ClassLoader classLoader) {
this.logger = Logger.getLogger(AbstractMessageListener.class);
this.beanManager = beanManager;
this.classLoader = classLoader;
logger.debug("Creating new AbstractMessageListener.");
}

/**
* AbstractMessageListener implements the basic on message functionality to
* handle classloader behavior for working in CDI environments.
*
* @param message The JMS Message that is being received.
*/
public final void onMessage(Message message) {
logger.info("Received a message");
ClassLoader prevCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
try{
handleMessage(message);
} catch (JMSException e) {
logger.warn("A JMS Exception occurred during processing.",e);
} finally {
Thread.currentThread().setContextClassLoader(prevCl);
}
}

/**
* Implementations should override this method and
* perform necessary business logic in here.
*
* A BeanManager reference is available, for looking up beans.
*
* @param message The message to be handled.
* @throws JMSException The method can throw this exception if an error occurred.
*/
protected abstract void handleMessage(Message message) throws JMSException;
}
76 changes: 72 additions & 4 deletions api/src/main/java/org/jboss/seam/jms/MessageBuilder.java
Expand Up @@ -7,10 +7,15 @@
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.QueueReceiver;
import javax.jms.QueueSender;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.TopicPublisher;
import javax.jms.TopicSubscriber;

/**
* The MessageBuilder interface defines an abstraction layer over the JMS APIs
Expand Down Expand Up @@ -140,19 +145,82 @@ public interface MessageBuilder {
*/
public Session getSession();

/**
* Creates a new MessageProducer that will be managed by the used session
*
* @param destination JNDI Location of Destination in use
* @return a new MessageProducer that is ready to work.
*/
public MessageProducer createMessageProducer(String destination);

/**
* Creates a TopicPublisher for the given topic.
*
* @param destination JNDI Location of Destination in use
* @return a new TopicPublisher that is ready to work.
*/
public TopicPublisher createTopicPublisher(String destination);

/**
* Creates a QueueSender for the given queue.
*
* @param destination JNDI Location of Destination in use
* @return a new QueueSender that is ready to work.
*/
public QueueSender createQueueSender(String destination);

/**
* Creates a new MessageConsumer that will be managed by the used session
*
* @param destination JNDI Location of Destination in use
* @param listeners optional list of MessageListeners that will be bound to the consumer.
* @return a new MessageConsumer that is ready to work.
*/
public MessageConsumer createMessageConsumer(String destination);
public MessageConsumer createMessageConsumer(String destination, MessageListener... listeners);

/**
* Creates a new MessageProducer that will be managed by the used session
* Creates a new MessageConsumer that will be managed by the used session
*
* @param destination JNDI Location of Destination in use
* @return a new MessageProducer that is ready to work.
* @param listeners optional list of MessageListeners that will be bound to the consumer.
* @return a new MessageConsumer that is ready to work.
*/
public MessageProducer createMessageProducer(String destination);
public MessageConsumer createMessageConsumer(Destination destination, MessageListener... listeners);

/**
* Creates a new TopicSubscriber that will be managed by the used session
*
* @param destination JNDI Location of Topic in use
* @param listeners optional list of MessageListeners that will be bound to the subscriber.
* @return a new TopicSubscriber that is ready to work.
*/
public TopicSubscriber createTopicSubscriber(String destination, MessageListener... listeners);

/**
* Creates a new QueueReceiver that will be managed by the used session
*
* @param destination JNDI Location of Queue in use
* @param listeners optional list of MessageListeners that will be bound to the receiver.
* @return a new QueueReceiver that is ready to work.
*/
public QueueReceiver createQueueReceiver(String destination, MessageListener... listeners);

/**
* Creates a topic subscriber with the given ID and binds a message listener to it, if valid.
*
* {@see MessageBuilder.createDurableSubscriber}
*
* @param destination JNDI Location of the topic to subscribe to.
* @param id the client id for the subscriber. This ID should be unique, and should be used to shutdown the listener.
* @param listener The Message Listeners to be bound, if any.
* @return the resulting TopicSubscriber or null if an error occurred.
*/
public TopicSubscriber createDurableSubscriber(String destination, String id, MessageListener... listeners);

/**
* Unsubscribes a durable subscriber from the topic, with the given id.
*
* @param id the id of the subscriber.
*/
public void unsubscribe(String id);
}
25 changes: 25 additions & 0 deletions api/src/main/java/org/jboss/seam/jms/bridge/RouteBuilder.java
@@ -0,0 +1,25 @@
package org.jboss.seam.jms.bridge;

import javax.annotation.PostConstruct;
import javax.enterprise.event.Observes;
import javax.jms.JMSException;
import javax.servlet.ServletContext;

/**
* RouteBuilder is a start up component responsible for loading the finalized
* BeanManager into the Seam3JmsExtension and then loading all destinations
* that will be used by the ingress routes.
*
* Loading the BeanManager into the Seam3JmsExtension has the result of doing
* the same thing to the egress routes.
*
* Implementations of RouteBuilder should be singleton, and defines start up
* capabilities in handleStartup (servlet containers) and init.
*
* @author johnament
*/
public interface RouteBuilder {
public void handleStartup(@Observes ServletContext servletContext);
@PostConstruct
public void init() throws JMSException;
}
3 changes: 1 addition & 2 deletions docs/reference/src/main/docbook/en-US/mapping-interfaces.xml
Expand Up @@ -23,8 +23,7 @@

<para>
This chapter is meant to describe the behavior of mapping interfaces, where event mapping to data flowing through
JMS Queues and Topics are handled via events. Currently, the mapping interfaces only support single direction
mappings, a route defined can only be one of egress or ingress, never both.
JMS Queues and Topics are handled via events.
</para>
<tip>
You should never create a bi-directional route via the API. The results will not be what you expect.
Expand Down
33 changes: 33 additions & 0 deletions docs/reference/src/main/docbook/en-US/messaging.xml
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
JBoss, Home of Professional Open Source
Copyright 2011, Red Hat, Inc. and/or its affiliates, and individual
contributors by the @authors tag. See the copyright.txt in the
distribution for a full listing of individual contributors.
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.
-->

<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []>
<chapter id="messaging-api">
<title>Messaging API</title>
<para>
The Seam JMS Messaging API is a higher level abstraction of the JMS API to provide a number of convenience methods for creating consumers, producers, etc.
</para>

<section id="messaging-api-jms-local">
<title>MessageBuilder</title>
<para>
The MessageBuilder interface (org.jboss.seam.jms.MessageBuilder) is the main consolidated API for Seam JMS. It provides almost all of the background functionality for Seam JMS's features (Observer Interfaces, Routing API). In later releases there will be multiple implementations of this interface. The default implementation works against javax.naming.Context assuming running within the same local application server.
</para>
</section>
</chapter>
1 change: 1 addition & 0 deletions impl/pom.xml
Expand Up @@ -125,6 +125,7 @@
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-jbossas-managed-6</artifactId>
<version>1.0.0.Alpha4</version>
</dependency>
<dependency>
<groupId>org.jboss.jbossas</groupId>
Expand Down

0 comments on commit 6a2bb15

Please sign in to comment.