Skip to content

Instantly share code, notes, and snippets.

@pmuir
Created September 12, 2011 19:52
Show Gist options
  • Save pmuir/1212202 to your computer and use it in GitHub Desktop.
Save pmuir/1212202 to your computer and use it in GitHub Desktop.
Resource Producer proposal for JMS 2.0
/**
* PLM: ApplicationConsumer is a class provided by the application, and injects and
* uses the resources defined in the central Resources class. An application would
* typically have multiple ApplicationConsumer-style classes - this is just an
* example
*/
public class ApplicationConsumer {
// temporary reply queue
@Inject @Foo
TemporaryQueue temporaryReplyQueue;
// connection used to receive replies
@Inject @Foo
Connection connection;
// session used to receive replies
@Inject @Foo
Session session;
@Inject @Foo
MessageConsumer consumer;
/**
* Send a request to requestQueue and receive the reply using a temporary queue
* @param request
* @throws JMSException
*/
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public String sendRequestAndReceiveReply2(String request) throws JMSException {
// PLM: Note that I have not injected the request message, as it seems simpler to create it through the JMS as defined today.
// Potentially this is an area where the JMS API could be made more CDI friendly. In order to comment I would need to understand the use cases better.
TextMessage requestMessage = session.createTextMessage(request);
textMessage.setJMSReplyTo(temporaryReplyQueue);
// send request in a separate transaction
sendRequest(request,temporaryReplyQueue);
// now receive the reply,
// using the same connection as was used to create the temporary reply queue
connection.start();
TextMessage reply = (TextMessage) consumer.receive();
String replyString=reply.getText();
connection.close();
return replyString;
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private void sendRequest(String request) throws JMSException {
TextMessage requestMessage = session.createTextMessage(request);
requestMessage.setJMSReplyTo(temporaryReplyQueue);
producer.send(requestMessage);
connection.close();
}
}
/**
* PLM: Foo is a user defined qualifier. An application would have one qualifier per "group" JMS resources defined.
*/
@Target({ TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
@Documented
@Qualifier
public @interface Foo {
}
/**
* PLM: This is version 1 of the Resources class - an app would only need one
* version. Typically an app would define one Resources class per logical grouping
* of resources (e.g. a simple app might choose to declare one, a complex app might
* decide to split it up). There is no structure imposed by this proposal on how
* this file is split up.
*
* PLM: V1 represents the way this is logically wired up, and makes no assumptions
* about convention.
*/
public class Resources {
@Produces @Foo
@Resource(lookup = "jms/connFactory")
ConnectionFactory connFact;
@Produces @Foo
public Connection createConnection(ConnectionFactory cf) {
return cf.createConnection();
}
@Produces @Foo
public Session createSession(@Foo Connection c) {
return c.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
@Produces @Foo
public TemporaryQueue createTemporaryQueue(@Foo Session s) {
return c.createTemporaryQueue();
}
@Produces @Foo
MessageConsumer createMessageConsumer(@Foo Session s, TemporaryQueue q) {
return s.createConsumer(q);
}
}
/**
* PLM: This is version 2 of the Resources class (see notes above).
*
* PLM: V2 introduces some conventions that provide sensible defaults. Should the
* user not wish to change this is all the configuration of resources they require,
* and all injections shown above (and indeed as this proposal is extended beyond
* this example, all types of injections currently defined) will work.
*/
public class Resources {
@Produces @Foo
@Resource(lookup = "jms/connFactory")
ConnectionFactory connFact;
}
/**
* PLM: This is version 3 of the Resources class (see notes above).
*
* PLM: V3 shows how we can override a default at any point, without needing to
* define the intermediate producers.
* PLM Here we change the convention that sessions are auto-acknowledge for all
* types of JMS resource injection annotated with @Foo
*/
public class Resources {
@Produces @Foo
@Resource(lookup = "jms/connFactory")
ConnectionFactory connFact;
@Produces @Foo
public Session createSession(@Foo Connection c) {
return c.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment