Nevado JMS

a Skyscreamer project


Quickstart

0. If you haven't already, Sign up for Amazon Web Services. Enable SQS and SNS. View pricing

Remember Amazon charges for every call made to the server. Nevado polls the server regularly when a listener is configured, even when no messages are coming through. (Although by default it will "back off" pretty quickly when it's not receiving messages.) The pricing is fairly cheap, but it can add up in extreme cases.

1. Get the library. You can download it, ...

build it:

% git clone git@github.com:skyscreamer/nevado.git
% cd nevado ; mvn clean install

or put it as a dependency in your application's pom.xml:

<dependency>
  <groupId>org.skyscreamer</groupId>
  <artifactId>nevado-jms</artifactId>
  <version>1.0.0-Beta2</version>
</dependency>

2. Configure your AWS credentials for Spring.

Create aws.properties in the root of your classpath. Store your access key and secret in there. You can look them up on AWS.

aws.accessKey=[YOUR ACCESS KEY]
aws.secretKey=[YOUR SECRET KEY]

If you don't have a PropertyPlaceholderConfigurer already in your project, create one. Otherwise, just add aws.properties to your existing bean configuration:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
    <list>
      <value>classpath:aws.properties</value>
    </list>
  </property>
</bean>

Make sure you have spring-jms in your project. If you are using maven, simply add the following to your pom.xml:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jms</artifactId>
  <version>3.0.5.RELEASE</version>
</dependency>

3. Set up Nevado JMS in your Spring configuration:

Define your connector. We recommend Amazon's SDK. We also provide a mock connector (org.skyscreamer.nevado.jms.connector.mock.MockSQSConnectorFactory) that allows you to develop offline.):

<bean id="sqsConnectorFactory" class="org.skyscreamer.nevado.jms.connector.amazonaws.AmazonAwsSQSConnectorFactory" />

The connection factory:

<bean id="connectionFactory" class="org.skyscreamer.nevado.jms.NevadoConnectionFactory">
  <property name="sqsConnectorFactory" ref="sqsConnectorFactory" />
  <property name="awsAccessKey" value="${aws.accessKey}" />
  <property name="awsSecretKey" value="${aws.secretKey}" />
</bean>

A queue. (A topic is similar. Just use NevadoTopic instead.):

<bean id="helloWorldQueue" class="org.skyscreamer.nevado.jms.destination.NevadoQueue">
  <constructor-arg value="helloWorldQueue" />
</bean>

A client connector:

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
  <property name="defaultDestinationName" value="helloWorldQueue"/>
  <property name="connectionFactory" ref="connectionFactory"/>
</bean>

A listener and a MDP container:

<bean id="helloService" class="demo.HelloService"/>

<bean id="listener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
  <property name="delegate" ref="helloService"/>
  <property name="defaultListenerMethod" value="hello"/>
  <property name="defaultResponseDestination" ref="helloWorldQueue"/>
</bean>

<bean id="container" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
  <property name="connectionFactory" ref="connectionFactory"/>
  <property name="messageListener" ref="listener"/>
  <property name="destination" ref="helloWorldQueue"/>
</bean>

4. Write your Java code. Following is a simple example using Spring MDP's, but any JMS client code should work:

A listener delegate to receive the messages:

package demo;

public class HelloService {
  public void hello(String name) {
    System.out.println("Hello " + name + "!");
  }
}

A simple daemon to do the listening:

package demo;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloRunner {
  public static void main(String[] args) throws Exception {
    new ClassPathXmlApplicationContext("/applicationContext.xml");
    System.in.read();
  }
}

A client to publish the messages:

package demo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HelloWorld {
  public static void main(String[] args) throws Exception {
    ApplicationContext context = new ClassPathXmlApplicationContext("/applicationContext.xml");
    JmsTemplate jmsTemplate = (JmsTemplate) context.getBean("jmsTemplate");

    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

    while(true) {
      System.out.print("Enter Name: ");
      String name = reader.readLine();
      jmsTemplate.convertAndSend(name);
      Thread.sleep(5000);
    }
  }
}

5. And run it...

Start the program and enter some names:

Enter Name: Juergen Hoeller
Hello Juergen Hoeller!
Enter Name: Mark Hapner
Hello Mark Hapner!
Enter Name:

This just barely taps into what you can do with JMS, but it should be a start. If you need to learn more about how to write JMS client code, check out Oracle's JMS Tutorial. Good luck!