PEtALS Binding Component BC-SOAP WS-Notification Extensions Thierry DÉJEAN July 27, 2010 Abstract Note explicative sur le pourquoi du comment du code spécifique ajouté au binding component BC-SOAP, pour modifié le contenu des messages correspondant à des requêtes ou des réponses de requêtes de type WS-Notification. 1 Le besoin 1.1 Constat Un endpoint JBI se compose d un triplette ServiceQname/InterfaceQname/EndpointName et permet l identification unique d un service donné, au sein du bus PEtALS. En fait le couple ServiceQname/EndpointName suffit à cette identification. Dans le paradigme des Web Services, un service est identifiable de façon unique via une URI. En pratique, lorsque les échanges sont de type SOAP over http, cette valeur apparaît dans le wsdl associé, dans le champs soapaddress. Cette différence de représentation, dès lors que la valeur d un endpoint apparaît dans les parties metiers des messages échangés, vaconduire à des problèmes si l on ne réalise lorsque ces échanges de message vont être réalisé entre un Service Engine PEtALS et un Web Service, via le Binding Component SOAP. Or c est justement à cette situation que l on est confronté lorsque veut utilisé les notifications, puisque les payload des requêtes de notification 1
et leurs réponses contiennent pour la plupart EndpointReference WS- ADDRESSING. Pour bien fixer les idées, voici le payload d un requête Subscribe correspondant d abord à un échange interne entre deux Service Engines (par exemple entre le se-wsnconsumer et le se-notification) 1 : <?xml version= 1. 0 encoding= UTF 8?> <w s n t : S u b s c r i b e xmlns:wsnt= h t t p : // docs. o a s i s open. org /wsn/b 2 xmlns:wsa= h t t p : //www. w3. org /2005/08/ a d d r e s s i n g targetnamespace = h t t p : // docs. o a s i s open. org /wsn/b 2 > <wsa:address> </ wsa:address> <wsa: ReferenceParameters> <ebm:servicename xmlns:ns8= h t t p : // p e t a l s. ow2. org / p e t a l s se wsnconsumer > n s 8 : N o t i f i c a t i o n C o n s u m e r S e r v i c e </ ebm:servicename> <ebm:interfacename xmlns:ns8= h t t p : // docs. o a s i s open. org /wsn/bw 2 > n s 8 : N o t i f i c a t i o n C o n s u m e r </ ebm:interfacename> <ebm:endpoint>notificationconsumerendpoint</ ebm:endpoint> </ ebm:soaparameter> </ wsa: ReferenceParameters> <w s n t : F i l t e r> <wsnt:topicexpression D i a l e c t= h t t p : // docs. o a s i s open. org /wsn/ t 1/TopicExpression / F u l l x m l n s : t n s 1= h t t p : // p e t a l s. ow2. org / topicnamespace /MyOtherTopicNamespaceSample > t n s 1 : r o o t T o p i c 2 / / c h i l d C h i l d T o p i c 2 [ @wstop:topic= t r u e ] </ wsnt: TopicExpression> </ w s n t : F i l t e r> <w s n t : I n i t i a l T e r m i n a t i o n T i m e>pt1h</ w s n t : I n i t i a l T e r m i n a t i o n T i m e> </ w s n t : S u b s c r i b e> Et la même requête échangé cette fois-ci entre deux Web Service (typiquement un web service implémentant l interface NotificationConsumer et un autre implémentant l interface NotificationProducer ) 2 : <?xml version= 1. 0 encoding= UTF 8?> <w s n t : S u b s c r i b e xmlns:wsnt= h t t p : // docs. o a s i s open. org /wsn/b 2 xmlns:wsa= h t t p : //www. w3. org /2005/08/ a d d r e s s i n g targetnamespace = h t t p : // docs. o a s i s open. org /wsn/b 2 > <wsa: Address>h t t p : //www. SOAUPUI. com/mock/wsn/consumer</ wsa: Address> <w s n t : F i l t e r> <wsnt:topicexpression D i a l e c t= h t t p : // docs. o a s i s open. org /wsn/ t 1/TopicExpression / F u l l x m l n s : t n s 1= h t t p : // p e t a l s. ow2. org / topicnamespace /MyOtherTopicNamespaceSample > t n s 1 : r o o t T o p i c 2 / / c h i l d C h i l d T o p i c 2 [ @wstop:topic= t r u e ] </ wsnt: TopicExpression> </ w s n t : F i l t e r> <w s n t : I n i t i a l T e r m i n a t i o n T i m e>pt1h</ w s n t : I n i t i a l T e r m i n a t i o n T i m e> </ w s n t : S u b s c r i b e> 1 Ce payload n est autre que le normalize message du message exchange JBI 2 Ce payload est cette fois-ci la autre que le body du message SOAP 2
Ce que l on doit retenir c est que dans le premier cas, pour les echanges interne au bus Petals, les valeurs correspondant à la description d un endpoint JBI - le fragment SOAPArameter - sont localisées dans le champ optionnel wsa:referenceparameters du EndpointReference ws-addressing, le contenu du champs wsa:address n étant pas utilisé, bien que celui-ci soit obligatoire. Alors que dans le second cas, le endpoint ws-addressing est utilisé de façon parfaitement standard, l adresse du endpoint identifiant le Web Service correspondant à la valeur - l URI - du champ wsa:address 1.2 Le problème à résoudre De ce qui précède, on voit tout de suite qu il va y avoir une difficulté à résoudre lorsque, par exemple, le consommateur des évènements, celui qui émettra la requête Subscribe, sera un web service, donc externe au bus, et que le producteur des évenements sera un service interne au bus, tel que le service engine se-notification, qui devra traiter cette requête puis renvoyé une réponse, réponse contenant elle aussi un EndpointReference wsaddressing. En effet, le se-notification ne comprenant que les SOAParameter contenus dans le champ wsa:referenceparameters comme adresse d un servicealors que le web-service externe ne prend en compte que les URI contenu dans le champ wsa:address, on comprend tout de suite qu à linterface il va falloir déplacer et reformatter cette information. Et c est au bc-soap de réalisé cette tâche lors de la transformation du message exchange JBI et message SOAP, ainsi que lors de la transformation inverse, pour les messages entrants. Danc en résumé le travail consiste, en se basant sur les informations contenues dans les fichier jbi.xml des SU du BC-SOAP, de tranformé à la volée, les fragments xml correspondant à des endpoints ws-addressing afin de passer suivant si le message est entrant ou sortant du bus, du formalisme de représentation interne d un endpoint basé sur le type interne SOAParameter : <wsa:address> </ wsa:address> <wsa: ReferenceParameters> <ebm:servicename xmlns:ns8= h t t p : // p e t a l s. ow2. org / p e t a l s se wsnconsumer > n s 8 : N o t i f i c a t i o n C o n s u m e r S e r v i c e </ ebm:servicename> <ebm:interfacename xmlns:ns8= h t t p : // docs. o a s i s open. org /wsn/bw 2 > n s 8 : N o t i f i c a t i o n C o n s u m e r </ ebm:interfacename> <ebm:endpoint>notificationconsumerendpoint</ ebm:endpoint> </ ebm:soaparameter> </ wsa: ReferenceParameters> 3
au formalisme standard de représentation basé sur les URI : <wsa: Address>h t t p : //www. sopaui. com/wsn/mock/ EventConsumer</ wsa: Address> <wsa: ReferenceParameters /> Tout en sachant que cette correspondance, ce mapping, est complètement défini dans les SU et leur fichier de configuration, lorsque l on definit les consumes et provide jbi, comme le montre l extrait du fichier jbi.xml d une SU du BC-SOAP suivant : <! Import a S e r v i c e i n t o P e t a l s => p r o v i d e s a S e r v i c e. > <j b i : p r o v i d e s i n t e r f a c e name= wsntw:notificationconsumer s e r v i c e name= g e n e s i s s e s : s e s N o t i f i c a t i o n C o n s u m e r S e r v i c e endpoint name= sesnotificationconsumerendpoint > <! CDK s p e c i f i c f i e l d s > <! <petalscdk:mep x s i : n i l= t r u e /> > <! WSDL f i l e > <! <petalscdk:wsdl>h t t p : //192.168.1.101 :8088 /SOAPUI/ N o t i f i c a t i o n C onsumerservice? wsdl</ p <petalscdk:wsdl>ses NotificationConsumer. wsdl</ petalscdk:wsdl> <petalscdk:timeout>30000</ petalscdk:timeout> <petalscdk: validate wsdl> f a l s e</ petalscdk: validate wsdl> <petalscdk:forward s e c u r i t y s u b j e c t> f a l s e</ petalscdk:forward s e c u r i t y s u b j <petalscdk:forward message p r o p e r t i e s> f a l s e</ petalscdk:forward message p r o <petalscdk:forward attachments> f a l s e</ petalscdk:forward attachments> <! SOAP s p e c i f i c f i e l d s > <s o a p : a d d r e s s>h t t p : // giv s e s. uni muenster. de:8080 /GENESIS s e s / s e r v i c e s / SesPortType</ s o a p <soap: soap version>1. 2</ soap: soap version> <soap:add r o o t> f a l s e</ soap:add r o o t> <soap:chunked mode> f a l s e</ soap:chunked mode> <soap:cleanup t r a n s p o r t>t r u e</ s oap:cleanup t r a n s p o r t> <soap:mode>soap</ soap:mode> </ j b i : p r o v i d e s> Le mapping correspondant étant dans ce cas : <ebm:servicename x m l n s : g e n e s i s s e s= h t t p : //www. g e n e s i s. org /SES/ W S N o t i f i c a t i o n S e r v i c e > g e n e s i s s e s : s e s N o t i f i c a t i o n C o n s u m e r S e r v i c e </ebm:servicename> <ebm:interfacename xmlns:wsntw= h t t p : // docs. o a s i s open. org /wsn/bw 2 > wsntw: NotificationConsumer </ebm:interfacename> <ebm:endpoint>sesnotificationconsumerendpoint </ebm:endpoint> </ebm:soaparameter> à associer à l URI : h t t p : // giv s e s. uni muenster. de:8080 /GENESIS s e s / s e r v i c e s / SesPortType 4
2 La solution mise en oeuvre 2.1 Les différentes étapes (pseudo algorithme) 1. Créer la table de Mapping à partir des SU installées et en rapport avec des services de type WS-Notification. Pour chaque consume/provide, créer un couple (soapaddress,soaparameter) à partir des information du fichier jbi.xml de la SU et stocker dans la table de mapping. Récupérer également les address SOAP des services internes SubscriptionManagerService et PublisherRegistrationManagerService, adresses qui seront utilisé pour les reponses des requètes de type Subscribe et RegisterPublisher. 2. Pour chaque requète/reponse entrant dans le bus et reçue par le bc- SOAP, qui est de type WS-Notification (Subscribe, RegisterPublisher, SubscribeResponse,... voir specification WS-Notification et son wsdl), ajouter dans les referenceparameter des EndpointReference le fragment SOAParameter à partir de la table de mapping et de la valeur contenue dans le champs address. 3. Pour chaque requète/reponse sortant du bus et reçue par le bc-soap, qui est de type WS-Notification (SubscribeResponse,...... voir specification WS-Notification et son wsdl), supprimer dans les referenceparameter des EndpointReference le fragment SOAParameter et positionner éventuellement dans le champs address l adresse externe du service SubscriptionManagerService ou PublisherRegistration- ManagerService suivant que le message sortant soit respectivement de type SubscrbeRresponse ou RegisterPublisherResponse. 2.2 Le code L ensemble des fonctionnalités sont regroupés dans la classe ExternalNotificationRequestTransformer.java dans le package util. Ces methodes sont ensuite appelées à divers endroits du code signalé par : // TDEJEAN WS NOTIFICATION IMPL // // r e s t o r a t i o n date : 2010 07 26 // // // 5