Canigó - Servei de Cues (JMS) 2.3.x
SERVEI DE CUES (JMS)
IntroduccióPropòsitAquest servei permet configurar i usar de forma senzilla la infraestructura de missatgeria estándard JMS (Java Messaging Service) de J2EE. Aquest estàndar defineix dues modalitats:
El consum de missatges assíncrons a l'estàndar J2EE es realitza mitjançant "Message-Driven Beans". Canigó no s'incorpora cap mecanisme específic pel consum de missatges asíncrons, i la seva disponibilitat dependrà de la plataforma (especificament del Servidor d'aplicacions). Així doncs, l'enfoc del servei és el de simplificar la publicació de missatges i la definició i configuració de destinataris. Context i Escenaris d'ÚsEl Servei d'Integració de Cues JMS es troba ubicat dins els serveis continguts a la capa de Dades/Integració de canigo.
Versions i DependènciesLes dependències descrites a la següent url són requerides per tal de compilar i fer funcionar el projecte: A qui va dirigitAquest document va dirigit als següents perfils:
Documents i Fonts de Referència
GlossariJMS ConnectionFactory Destination Descripció DetalladaMissatgeria Publicació/SubscripcióLa missatgeria de publicació/subscripció permet a una aplicació enviar missatges a una o múltiples aplicacions. Aquestes aplicacions envien i reben missatges subscrivint-se a un servidor de missatges a una cua o tòpic determinat. Hi ha dos tipus de missatge depenent de com es consumeixen:
Els consumidors d'un missatge poden ser síncrons o asíncrons. En general, els consumidors asíncrons escalen millor i tenen un rendiment superior. Per aplicacions que s'executen al costat servidor, gairebé sempre sempre s'utilitzaran consumidors asíncrons. Concretament per aplicacions J2ee es fa mitjançant Message-Driven Beans (MDB's) que són EJB's configurats per escoltar i subscriures a cues o tòpics del servidor d'aplicacions. A continuació es destaquen alguns paràmetres de configuració dels missatges JMS que cal tenir en compte en el desenvolupament d'aplicacions que publiquin o consumeixin aquests tipus de missatges. Persistència del missatgeEls missatges JMS poden ser especificats com a persistents o no-persistents.
Els missatges persistents tenen pitjor rendiment degut al pas addicional d'haver-se d'escriure en disc o a base de dades. Només es recomana utilitzar missatges persistents pels casos d'ús crítics, on no es pot permetre la pèrdua del missatge (p.ex. una trasacció bancària, ...). Destinacions distribuïdesUna destinació distribuïda és un conjunt de destinacions que són accessibles com a una única destinació lògica al client. Disposen d'una sola adreça JNDI, i els membres d'aquest conjunt normalment són distribuïts pels membres d'un cluster, on cada destinació pertany a un servidor JMS separat. Les aplicacions que usen destinacions distribuïdes tenen més disponibilitat respecte a les tradicionals, ja que els servidor (Weblogic) proporciona balanceig de càrrega i tolerància a fallades pels membres d'una destinació distribuïda en un cluster. Per tant, es recomana l'ús de destinacions distribuïdes sempre que les aplicacions publicadores/consumidores es desplegin en un cluster de Weblogic. Arquitectura i ComponentsEls components podem classificar-los en:
JavaDoc: http://canigo.ctti.gencat.net/confluence/canigodocs/site/canigo2_0/canigo-services-jms/xref/index.html Instal.lació i ConfiguracióInstal.lacióLa instal.lació del servei requereix de la utilització de la llibreria 'canigo-services-jms' i les dependències indicades a l'apartat 'Introducció-Versions i Dependències'. ConfiguracióLa configuració del servei implica els següents pasos:
Definició del Servei Ubicació proposada: <PROJECT_ROOT>/src/main/resources/spring En aquest apartat configurarem el bean de Servei de Cues, és a dir, la implementació que es farà servir en l'atribut 'class'. En l'actualitat s'ofereix la classe ' net.gencat.ctti.canigo.services.jms.impl.JmsServiceImpl'
<bean id="JmsService" class="net.gencat.ctti.canigo.services.jms.impl.JmsServiceImpl"> ... </bean> Podem definir les següents propietats:
Per les propietats es recomana que siguin definides de forma externa a un fitxer de propietats i referenciades aquí amb el format ${nom} (veure 'Definir les propietats del Servei'). En cas de que volguessim fer ús de diferents destins de publicació es farà ús de la propietat 'configurationMap', on la clau correspondrà al nom de la configuració (accessible després amb el mètode 'getJmsOperations(nom)') i podrem especificar les propietats indicades a dalt pel valor. Exemple:
<bean id="JmsService" class="net.gencat.ctti.canigo.services.jms.impl.JmsServiceImpl"> ... <property name="configurationMap"> <map> <entry key="otherConfig"> <bean parent="baseJmsConfigurator"> <property name="defaultDestinationName" value="topic2"/> <property name="namingContextFactory" value="org.exolab.jms.jndi.InitialContextFactory"/> <property name="namingProviderUrl" value="rmi://localhost:1099"/> <property name="namingPrincipal" value="admin"/> <property name="namingCredentials" value="openjms"/> <property name="connectionFactoryName" value="ConnectionFactory"/> </bean> </entry> </map> </bean> Definició de la Localització del Fitxer de Propietats del Servei ![]() Fitxer de configuració: canigo-services-configuration.xmlUbicació proposada: <PROJECT_ROOT>/src/main/resources/spring Seguint el propósit general del Servei de Configuració definirem a la propietat 'basePropertyFiles' una nova localització pel fitxer de propietats del servei. Exemple:
<bean id="configurationService" class="net.gencat.ctti.canigo.services.configuration. springframework.beans.factory.config.HostPropertyPlaceholderConfigurer"> <property name="basePropertyFiles"> <list> ... <value>classpath:jms/jms.properties</value> </list> </property> </bean> A l'exemple, s'ha definit la ubicació del fitxer a 'classpath:jms/jms.properties' (veure següent pas). Definició de les Propietats del Servei Fitxer de configuració: jms.properties Ubicació proposada: <PROJECT_ROOT>/src/main/resources/jms En aquest fitxer definirem les propietats que permet el servei (veure 'Definició del Servei') jmsService.namingProviderUrl=rmi://localhost:1099
jmsService.namingContextFactory=org.exolab.jms.jndi.InitialContextFactory
jmsService.connectionFactoryName=ConnectionFactory
jmsService.defaultDestinationName=topic1
jmsService.namingPrincipal=admin
jmsService.namingCredentials=openjms
En aquest cas, la referència en la definició del servei seria (només es mostra la referència a la primera propietat definida): <property name="namingProviderUrl" value="$\{jmsService.namingProviderUrl\}"/> ... Utilització del ServeiS'han de seguir els següents pasos:
El mètode "getDefaultJmsOperations" permet obtenir el destí JMS per defecte que es configura junt amb el servei, mentre que "getJmsOperations" permet obtenir una configuració diferent, identificada per un nom.
Eines de SuportOpenJMSEn cas de no disposar d'un Servidor de Cues per a realitzar les proves, es pot fer ús de OpenJMS. Accedir a http://openjms.sourceforge.net/ per a més referència. Integració amb Altres ServeisIntegració amb el Servei Multiidioma i ExcepcionsEl servei llença vàries excepcions amb codis per tal que el missatge pugui ser internacionalitzat. En el següent exemple es mostren els codis que s'han de definir:
canigo.services.jms.jndi_lookup_failed=Jndi lookup failed for \{0\}
ExemplesExemple d'Enviament a una DestinacióExemple de Prova UnitàriaObtenim el context Spring de test, això no cal fer-ho explícitament en una aplicació web
BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicationContext.xml"); //Obtenim el servei pròpiament dit JmsServiceImpl JmsService = (JmsServiceImpl)beanFactory.getBean("JmsService");
JmsServiceOperations operations = (JmsServiceOperations)
Ara es pot fer servir l'interface JmsServiceOperations ... operations.convertAndSend("A String message to the default destination")
Exemple des d'una classe Action
JmsServiceUtils.getOperations(request).convertAndSend("testMessage");
En aquest cas s'ha fet ús del mètode estàtic "getOperations" de la classe auxiliar "net.gencat.ctti.canigo.services.jms.JmsServiceUtils" Aquest mètode permet utilitzar el servei sense haver de localitzar-lo expressament. |