JBOSS 7 et Message Driven Architecture (MDA)
Le 08/08/2012 Par Pierre Liseronjbossjeejboss 7jmsjndimessage drive
Configuration pour l’envoi et la réception et message JMS avec Jboss 7
Dans la configuration Full de Jboss 7, un broker de messagerie est intégré. (HornetQ)
Pour l’activer, il suffit de lancer son Jboss avec la configuration full (-c=standalone-full.xml).
Configuration de Jboss 7 messaging
La configuration des queues et topics se fait dans le subsystem urn:jboss:domain:messaging.
> <subsystem xmlns= »urn:jboss:domain:messaging:1.1″> > <hornetq-server> > <persistence-enabled>true</persistence-enabled> > <journal-file-size>102400</journal-file-size> > <journal-min-files>2</journal-min-files> > > <connectors> > <netty-connector name= »netty » socket-binding= »messaging »/> > <netty-connector name= »netty-throughput » socket-binding= »messaging-throughput »> > <param key= »batch-delay » value= »50″/> > </netty-connector> > <in-vm-connector name= »in-vm » server-id= »0″/> > </connectors> > > <acceptors> > <netty-acceptor name= »netty » socket-binding= »messaging »> > <param key= »host » value= »${hornetq.remoting.netty.host:XXX.XXX.XXX.XXX} »/> > <param key= »port » value= »${hornetq.remoting.netty.port:15445} »/> > </netty-acceptor> > <netty-acceptor name= »netty-throughput » socket-binding= »messaging-throughput »> > <param key= »batch-delay » value= »50″/> > <param key= »direct-deliver » value= »false »/> > </netty-acceptor> > <in-vm-acceptor name= »in-vm » server-id= »0″/> > </acceptors> > > <security-settings> > <security-setting match= »# »> > <permission type= »send » roles= »guest »/> > <permission type= »consume » roles= »guest »/> > <permission type= »createNonDurableQueue » roles= »guest »/> > <permission type= »deleteNonDurableQueue » roles= »guest »/> > </security-setting> > </security-settings> > > <address-settings> > <address-setting match= »# »> > <dead-letter-address>jms.queue.DLQ</dead-letter-address> > <expiry-address>jms.queue.ExpiryQueue</expiry-address> > <redelivery-delay>0</redelivery-delay> > <max-size-bytes>10485760</max-size-bytes> > <address-full-policy>BLOCK</address-full-policy> > <message-counter-history-day-limit>10</message-counter-history-day-limit> > </address-setting> > </address-settings> > > <jms-connection-factories> > <connection-factory name= »InVmConnectionFactory »> > <connectors> > <connector-ref connector-name= »in-vm »/> > </connectors> > <entries> > <entry name= »java:/ConnectionFactory »/> > </entries> > </connection-factory> > <connection-factory name= »RemoteConnectionFactory »> > <connectors> > <connector-ref connector-name= »netty »/> > </connectors> > <entries> > <entry name= »RemoteConnectionFactory »/> > <entry name= »java:jboss/exported/jms/RemoteConnectionFactory »/> > </entries> > <connection-ttl>6000000</connection-ttl> > </connection-factory> > <pooled-connection-factory name= »hornetq-ra »> > <transaction mode= »xa »/> > <connectors> > <connector-ref connector-name= »in-vm »/> > </connectors> > <entries> > <entry name= »java:/JmsXA »/> > </entries> > </pooled-connection-factory> > </jms-connection-factories> > > <jms-destinations> > <jms-queue name= »testQueue »> > <entry name= »queue/test »/> > <entry name= »java:jboss/exported/jms/queue/test »/> > </jms-queue> > <jms-topic name= »testTopic »> > <entry name= »topic/test »/> > <entry name= »java:jboss/exported/jms/topic/test »/> > </jms-topic> > </jms-destinations> > </hornetq-server> > </subsystem>
La partie la plus intéressante est la partie JMSJava Messaging Service-DESTINATIONS qui permet de créer des queue et des topic ainsi que de configurer leurs noms.
Deux types de noms sont présent: par exemple pour testQueue, vous avez le nom interne (depuis le serveur) et le nom externe depuis une autre application (si vous souhaitez exposer vos Queues).
Le nom interne est: queue/test tandis que le nom externe est : java:jboss/exported/jms/queue/test.
En remontant un peu dans le fichier, vous trouverez les factorys, de même deux factory sont présentes (remote et local) avec leurs noms JNDI. Ces factorys font références à des connecteur (ici netty). Pour chaque connecteur vous avez la possibilité de choisir les acceptors (flux entrants). Pensez bien à configurer:
avec la bonne adresse IP sinon vous ne pourrez pas vous connecter à votre QUEUE/TOPIC.Attention, il est aussi important de sécuriser l’accès à vos queues en créer une sécurité:
> <security-domain name= »messaging » cache-type= »default »> > <authentication> > <login-module code= »UsersRoles » flag= »required »> > <module-option name= »usersProperties » value= »${jboss.server.config.dir}/messaging-users.properties »/> > <module-option name= »rolesProperties » value= »${jboss.server.config.dir}/messaging-roles.properties »/> > </login-module> > </authentication> > </security-domain>
Les fichiers messaging-users.properties et messaging-roles.properties sont bien sur à créer.
Enfin il ne reste plus qu’à configurer les ports pour votre messagerie de la sorte:
Et voici un exemple de message bean qui se trouve sur le serveur:
> import javax.annotation.PostConstruct;
> import javax.annotation.PreDestroy;
> import javax.annotation.Resource;
> import javax.ejb.ActivationConfigProperty;
> import javax.ejb.EJBException;
> import javax.ejb.MessageDriven;
> import javax.ejb.MessageDrivenBean;
> import javax.ejb.MessageDrivenContext;
> import javax.inject.Inject;
> import javax.jms.Connection;
> import javax.jms.ConnectionFactory;
> import javax.jms.JMSException;
> import javax.jms.Message;
> import javax.jms.MessageListener;
> import javax.jms.ObjectMessage;
> import javax.jms.Session;
>
> import fr.axopen.logging.message.JmsMessage;
>
> @MessageDriven(activationConfig = {
> @ActivationConfigProperty(propertyName = « acknowledgeMode », propertyValue = « Auto-acknowledge »),
> @ActivationConfigProperty(propertyName = « destinationType », propertyValue = « javax.jms.Queue »),
> @ActivationConfigProperty(propertyName = « destination », propertyValue = « java:jboss/exported/jms/queue/test »),
>
> })
> public class ListingQueue implements MessageDrivenBean, MessageListener {
> /**
> *
> */
> private static final long serialVersionUID = 1L;
> @Resource(mappedName = « java:/JmsXA »)
> private ConnectionFactory factory;
>
> private Connection connection;
>
> private Session session;
>
> @SuppressWarnings(« unused »)
> private MessageDrivenContext messageDrivenContext;
>
> @PreDestroy
> protected void preDestroy() throws JMSException {
> session.close();
> connection.close();
> }
>
> @PostConstruct
> protected void postConstruct() throws JMSException {
> connection = factory.createConnection();
> session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
> }
>
> @Override
> public void setMessageDrivenContext(MessageDrivenContext ctx)
> throws EJBException {
> this.messageDrivenContext = ctx;
> }
>
> @Override
> public void ejbRemove() throws EJBException {
> }
>
> @Override
> public void onMessage(Message message) {
>
> try {
>
> } catch (JMSException jmse) {
> throw new RuntimeException(jmse);
> }
> }
>
> }
Enfin si vous souhaitez vous connecter à la file JMS à distance, voici un exemple:
## Exemple d’envoi d’un message JMS
import java.io.PrintWriter;
> import java.io.StringWriter;
> import java.util.Date;
> import java.util.HashMap;
> import java.util.List;
> import java.util.Map;
> import java.util.Properties;
>
> import javax.jms.Connection;
> import javax.jms.JMSException;
> import javax.jms.MessageProducer;
> import javax.jms.ObjectMessage;
> import javax.jms.Queue;
> import javax.jms.QueueConnectionFactory;
> import javax.jms.Session;
> import javax.naming.Context;
> import javax.naming.InitialContext;
> import javax.naming.NamingException;
> import javax.servlet.ServletRequest;
> import javax.servlet.http.HttpServletRequest;
>
> import org.apache.commons.lang.exception.ExceptionUtils;
> import org.hornetq.api.core.TransportConfiguration;
> import org.hornetq.api.jms.HornetQJMSClient;
> import org.hornetq.api.jms.JMSFactoryType;
> import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
> import org.hornetq.core.remoting.impl.netty.TransportConstants;
> import org.hornetq.jms.client.HornetQConnectionFactory;
>
> import com.workinlive.framework.Config;
>
> import fr.axopen.logging.message.JmsMessage;
> import fr.axopen.logging.message.TypeMessageEnum;
>
> public class JmsConnectionFactory {
> private static JmsConnectionFactory instance;
>
> private Context mContext;
> Connection mConnection = null;
>
> QueueConnectionFactory mConnectionFactory;
> Queue mQueue = null;
> HornetQConnectionFactory mHornetConnectionFactory;
> private boolean mIsOperationnel = false;
>
> private void connect() {
> try {
> System.out.println(« JMS Connection »);
> Properties props = new Properties();
> props.put(Context.INITIAL\_CONTEXT\_FACTORY,
> « org.jboss.naming.remote.client.InitialContextFactory »);
> props.put(Context.PROVIDER\_URL, Config.JMS\_PROVIDER_URL);
> props.put(Context.SECURITY\_PRINCIPAL, Config.JMS\_SECURITY_PRINCIPAL);
> props.put(Context.SECURITY_CREDENTIALS,
> Config.JMS\_SECURITY\_CREDENTIALS);
>
> mContext = new InitialContext(props);
>
> final Map<String, Object> p = new HashMap<String, Object>();
> TransportConfiguration tc;
>
> p.put(TransportConstants.HOST\_PROP\_NAME, Config.JMS\_HOST\_LOGGING);
> p.put(TransportConstants.PORT\_PROP\_NAME, Config.JMS\_HOST\_PORT);
>
> tc = new TransportConfiguration(
> NettyConnectorFactory.class.getName(), p);
>
> mHornetConnectionFactory = HornetQJMSClient
> .createConnectionFactoryWithoutHA(JMSFactoryType.QUEUE_CF,
> tc);
>
> mQueue = (Queue) mContext.lookup(Config.JMS\_JNDI\_QUEUE);
>
> mConnection = mHornetConnectionFactory.createConnection();
>
> mIsOperationnel = true;
> } catch (NamingException e) {
> e.printStackTrace();
> System.err.println(« Problème de connexion JMS »);
> } catch (JMSException e) {
> e.printStackTrace();
> System.err.println(« Erreur de connexion JMS »);
> }
>
> }
>
> private JmsConnectionFactory() {
> connect();
>
> }
>
> public static JmsConnectionFactory getInstance() {
> if (instance == null) // 1
> instance = new JmsConnectionFactory(); // 2
> return instance; // 3
> }
>
> public Connection getConnection() {
> if (mConnection == null || !mIsOperationnel) {
> closeSession();
> mIsOperationnel = true;
> connect();
> }
>
> return mConnection;
> }
>
> public Queue getQueue() {
> return mQueue;
> }
>
> public void closeSession() {
> try {
> if (mContext != null) {
> mContext.close();
> }
> } catch (NamingException e) {
> e.printStackTrace();
> }
> try {
> if (mHornetConnectionFactory != null)
> mHornetConnectionFactory.close();
> } catch (Exception e) {
> e.printStackTrace();
> }
> try {
> if (mConnection != null)
> mConnection.close();
> } catch (JMSException e) {
> e.printStackTrace();
> }
>
> }
>
> public boolean isOperationnel() {
> return mIsOperationnel;
> }
>
> public void setOperationnel(boolean pIsOperationnel) {
> mIsOperationnel = pIsOperationnel;
> }
N'hésitez pas si vous avez des questions!
Sommaire
Configuration de Jboss 7 messaging
Et voici un exemple de message bean qui se trouve sur le serveur: