Implémentez un ESB personnalisable avec Java

Prenons l'exemple d'une entreprise où vous disposez d'applications hétérogènes, éventuellement fournies par différentes équipes, qui doivent interagir les unes avec les autres mais qui présentent les contraintes suivantes:

  • Chaque application n'est pas nécessairement construite à l'aide de la même technologie et peut ne pas parler aux autres en utilisant son mécanisme d'appel natif, par exemple une application J2EE et une application .Net.
  • De préférence, chaque application ne doit pas transformer ses requêtes dans le format compris par l'application cible. De plus, l'entreprise dispose de nombreuses applications qui utilisent l'application cible.
  • Les composants de service doivent utiliser un mécanisme d'appel ou de demande qui leur est naturel. Par exemple, une application J2EE existante ne peut accepter des demandes que via Java Message Service (JMS).
  • L'entreprise s'oriente vers une architecture où une application ne s'occupe que de, un, ce qu'elle sait et, deuxièmement, ce qu'elle doit passer en paramètres lorsqu'elle souhaite obtenir les services d'une autre application au sein de l'entreprise.

D'autres contraintes peuvent vous obliger à disposer d'une infrastructure permettant aux applications hétérogènes de s'intégrer de manière transparente sans modifier leur conception. Un bus de services d'entreprise (ESB) est un moyen de réaliser une telle architecture d'intégration d'entreprise.

Bien que chaque entreprise créera probablement son ESB à sa manière, il est important de garder à l'esprit la flexibilité lors de l'examen de la définition d'un ESB. Il n'y a pas d'approche fixe pour en construire un. L'idée est d'avoir une couche de connectivité qui optimise les interactions entre les consommateurs de services et les fournisseurs de services, une couche capable de répondre à des contextes orientés événement, message ou service.

Cet article décrit une approche pour créer un ESB Java extensible prenant en charge les exigences fonctionnelles ESB les plus courantes.

Exigences ESB communes

Les exigences communes d'un ESB sont également ses fonctionnalités les plus couramment utilisées:

  1. Routage: l'ESB doit fournir un mécanisme de routage efficace et flexible.
  2. Transformation: un composant de service ne devrait pas avoir besoin de connaître le format de demande du service cible qu'il pourrait appeler. En fonction du demandeur et de la cible, l'ESB devrait être en mesure d'appliquer la transformation appropriée à la demande afin que la cible puisse la comprendre.
  3. Transport multiprotocole: une implémentation ESB qui ne parle que de JMS ou uniquement de services Web n'a pas beaucoup de valeur. Il doit être suffisamment extensible pour prendre en charge plusieurs protocoles de messages en fonction des besoins de l'entreprise.
  4. Sécurité: si nécessaire, l'ESB doit appliquer l'authentification et l'autorisation d'accès aux différents composants de service.

La figure 1 montre les principaux composants architecturaux d'un ESB. Il comporte trois larges compartiments:

  1. Récepteur: un ESB expose différentes interfaces pour permettre aux applications client d'envoyer des messages à l'ESB. Par exemple, un servlet peut recevoir les requêtes HTTP pour l'ESB. En même temps, vous pouvez avoir un MDB (bean géré par message) à l'écoute sur une destination JMS où les applications clientes peuvent envoyer des messages.
  2. Core: Il s'agit de la partie principale de la mise en œuvre ESB. Il gère le routage et la transformation et applique la sécurité. En règle générale, il est composé d'un MDB qui reçoit les demandes entrantes puis, en fonction du contexte du message, applique la transformation, le routage et la sécurité appropriés. Les détails sur le routage, le transport, la transformation et les informations de sécurité peuvent être spécifiés dans un document XML (discuté brièvement).
  3. Dispatcher: tous les gestionnaires de transport sortant relèvent de cette partie de l'ESB. Vous pouvez brancher n'importe quel gestionnaire de transport arbitraire (e-mail, fax, FTP, etc.) dans l'ESB.

Toutes ces parties ESB sont collées ensemble par un document XML qui répertorie toutes les routes sur lesquelles l'ESB opère. Les différents gestionnaires de transport, transformateurs et stratégies de relance et leur connexion à différentes routes sont tous câblés via ce document XML.

ESBConfiguration.xml

La liste XML - ESBConfiguration.xmlqui apparaît ci-dessous - nous donne une idée du fonctionnement d'un ESB. Les principaux éléments d'intérêt ESBConfiguration.xmlsont les suivants:

  1. Beans: Cet élément contient zéro ou plusieurs Beanéléments.
  2. Bean: Cet élément définit fondamentalement la façon dont nous créons et configurons une Beanclasse. Il a les attributs suivants:
    • name: Nom unique pouvant être utilisé pour faire référence à ce bean.
    • className: Nom complet de la classe de bean.
    Chaque bean peut avoir zéro ou plusieurs Propertyéléments comme enfants. Chaque Propertyélément a un attribut namequi l'identifie et un élément enfant de type Valuequi contient la valeur de la propriété. Ces propriétés sont en fait les membres de style JavaBeans de la classe qui peuvent configurer la classe bean.
  3. RetryPolicies: Cet élément contient zéro ou plusieurs RetryPolicyenfants.
  4. RetryPolicy: Cet élément définit la stratégie de nouvelle tentative pour une route donnée. Il a un attribut namequi peut être utilisé pour s'y référer. Il a deux éléments enfants nommés MaxRetrieset RetryInterval.
  5. Route: L' EsbConfigurationélément racine peut contenir zéro ou plusieurs éléments enfants de ce type. Il représente essentiellement une route pour l'ESB. Il a les attributs suivants:
    • name: Nom unique pouvant être utilisé pour faire référence à cette route.
    • retryPolicyRef: Référence à la stratégie de nouvelle tentative. Il doit correspondre à l' attribut de l' RetryPolicyélément name.
    • transformerRef: Référence à un bean qui représente le transformateur. Il doit correspondre à l' attribut de l' Beanélément name.
    L' Routeélément peut avoir un ou plusieurs éléments enfants de type TransportHandlerRef. Cet enfant pointe essentiellement vers un bean qui représente un gestionnaire de transport approprié qui doit être utilisé pour cette route, et le nom de la méthode publique de ce bean qui doit être appelé pour envoyer le message. Facultativement, l' Routeélément peut avoir un DeadLetterDestinationenfant qui pointe vers un autre itinéraire représentant une destination lettre morte.

Un exemple de document XML,, EsbConfiguration.xmlapparaît ci-dessous:

                              qcf-1   myCreditQueue     //www.tax.com/calc      file:///C:/temp/esb/transform/xsl/credit.xsl     file:///C:/temp/esb/transform/custom/configManager.properties      qcf-1   Redelivery.Queue     qcf-1   System.DL.Queue     qcf-1   System.Error.Queue     qcf-1   Redelivery.Request.Topic       10 100   10 500    

Comportement ESB

Le ESBConfiguration.xmldocument dicte le comportement de notre ESB. La EsbRouterMDB charge ce XML à partir d'un emplacement spécifié dans son descripteur de déploiement. Les informations qu'il contient sont ensuite organisées en une structure de données représentée sur la figure 2 ci-dessous.

Le EsbRouterutilise ces informations (via EsbConfigManager) pour déchiffrer l'itinéraire approprié, la transformation, le cas échéant, à appliquer, le contrôle d'autorisation de sécurité, etc. Le point important à noter est la façon dont la technique d'injection de dépendance, avec l'héritage, a été utilisée pour découpler diverses fonctions (telles que le transport de messages multiprotocole et la transformation de messages) de l'ESB, lui permettant ainsi d'être hautement extensible et personnalisable.

Comme le montre le diagramme de classes, deux interfaces importantes se trouvent dans la conception ESB: TransformHandleret TransportHandler. Ils vous permettent d'écrire une transformation spécifique et une implémentation de transport pour les messages routés. Ces classes d'implémentation peuvent ensuite être câblées avec les routes via des Beanéléments dans EsbConfiguration. Par exemple, dans l'exemple de EsbConfiguration.xmldocument, la définition de bean suivante spécifie le gestionnaire de transport:

   myQCF   myCreditQueue   

Ce gestionnaire de transport peut ensuite être référencé dans un Routenœud en y insérant un TransportHandlerenfant comme ceci:

Remarque
L'approche décrite dans cet article utilise des interfaces Java pour définir les gestionnaires de transport et de transformation. Ainsi, tout nouveau gestionnaire devrait implémenter l'interface requise, ce qui peut sembler intrusif. Vous pouvez facilement modifier le EsbConfigManagerpour utiliser l'injection de dépendances pour appeler toute méthode arbitraire d'une classe d'implémentation, éliminant ainsi le besoin d'implémenter une interface. Mais comme le EsbRouterpasse toujours une javax.jms.Messageinstance, la classe d'implémentation de votre gestionnaire doit javax.jms.Messagequand même utiliser le type .