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).
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:
> 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!
Le scope en Javascript : définition et explications.
En Java, pour savoir ce qui peut avoir un impact sur les performances, il est nécessaire de comprendre ce qui se passe lorsqu’on lance un traitement en parallèle avec les streams. C’est l’objet de cet article.
Les tests E2E, c’est quoi ? Définition, implémentation et retour d’expériences des librairies de tests E2E !