Implementa un ESB personalizzabile con Java

Considera un'azienda in cui hai applicazioni eterogenee, possibilmente fornite da team diversi, che devono interagire tra loro ma hanno i seguenti vincoli:

  • Ogni applicazione non è necessariamente costruita utilizzando la stessa tecnologia e potrebbe non parlare con le altre utilizzando il suo meccanismo di invocazione nativo, ad esempio un'applicazione J2EE e un'applicazione .Net.
  • Preferibilmente, ogni applicazione non dovrebbe trasformare le sue richieste nel formato compreso dall'applicazione di destinazione. Inoltre, l'azienda dispone di molte applicazioni che utilizzano l'applicazione di destinazione.
  • I componenti del servizio dovrebbero utilizzare un meccanismo di chiamata o richiesta che sia naturale per loro. Ad esempio, un'applicazione J2EE esistente può accettare richieste solo tramite Java Message Service (JMS).
  • L'impresa si sta muovendo verso un'architettura in cui un'applicazione si occupa solo di uno, di ciò che sa e, due, di ciò che dovrebbe passare come parametri quando vuole ottenere i servizi di un'altra applicazione all'interno dell'azienda.

Altri vincoli potrebbero richiedere la presenza di un'infrastruttura che consenta ad applicazioni eterogenee di integrarsi perfettamente senza alterarne il design. Un Enterprise Service Bus (ESB) è un modo per realizzare una simile architettura di integrazione aziendale.

Sebbene ogni impresa creerà probabilmente il proprio ESB in un modo unico, è importante tenere a mente la flessibilità quando si considera la definizione di un ESB. Non esiste un approccio fisso per costruirne uno. L'idea è di disporre di un livello di connettività che ottimizzi le interazioni tra consumatori di servizi e fornitori di servizi, in grado di rispondere a contesti orientati a eventi, messaggi o servizi.

Questo articolo illustra un approccio per la creazione di un ESB estensibile basato su Java che supporta i requisiti funzionali ESB più comuni.

Requisiti ESB comuni

I requisiti comuni di un ESB sono anche le sue caratteristiche più comunemente utilizzate:

  1. Routing: L'ESB dovrebbe fornire un meccanismo di routing efficiente e flessibile.
  2. Trasformazione: un componente del servizio non dovrebbe aver bisogno di conoscere il formato della richiesta del servizio di destinazione che potrebbe richiamare. In base al richiedente e all'obiettivo, l'ESB dovrebbe essere in grado di applicare la trasformazione appropriata alla richiesta in modo che il destinatario possa comprenderla.
  3. Trasporto multiprotocollo: un'implementazione ESB che parla solo di JMS o solo di servizi Web non ha molto valore. Dovrebbe essere sufficientemente estensibile per supportare più protocolli di messaggi a seconda delle esigenze aziendali.
  4. Sicurezza: se necessario, l'ESB dovrebbe applicare l'autenticazione e l'autorizzazione per l'accesso a diversi componenti del servizio.

La Figura 1 mostra i principali componenti architetturali di un ESB. Ha tre ampi scomparti:

  1. Ricevitore: un ESB espone diverse interfacce per consentire alle applicazioni client di inviare messaggi all'ESB. Ad esempio, un servlet potrebbe ricevere le richieste HTTP per l'ESB. Allo stesso tempo, potresti avere un MDB (message-driven bean) in ascolto su una destinazione JMS dove le applicazioni client possono inviare messaggi.
  2. Core: questa è la parte principale dell'implementazione di ESB. Gestisce il routing e la trasformazione e applica la sicurezza. In genere, è composto da un MDB che riceve le richieste in ingresso e quindi, in base al contesto del messaggio, applica la trasformazione, il routing e la sicurezza appropriati. I dettagli su routing, trasporto, trasformazione e informazioni sulla sicurezza possono essere specificati in un documento XML (discusso a breve).
  3. Dispatcher: tutti i gestori di trasporto in uscita rientrano in questa parte dell'ESB. È possibile collegare qualsiasi gestore di trasporto arbitrario (e-mail, fax, FTP, ecc.) Nell'ESB.

Tutte queste parti ESB sono incollate insieme da un documento XML che elenca tutte le rotte su cui opera l'ESB. I diversi gestori di trasporto, trasformatori e criteri di ripetizione dei tentativi e la loro connessione a percorsi diversi sono tutti cablati tramite questo documento XML.

ESBConfiguration.xml

L'elenco XML ESBConfiguration.xml, che appare di seguito, ci dà un'idea del funzionamento di un ESB. I principali elementi di interesse ESBConfiguration.xmlsono i seguenti:

  1. Beans: Questo elemento contiene zero o più Beanelementi.
  2. Bean: Questo elemento definisce fondamentalmente il modo in cui creiamo e configuriamo una Beanclasse. Ha i seguenti attributi:
    • name: Nome univoco che può essere utilizzato per fare riferimento a questo bean.
    • className: Nome completo della classe bean.
    Ogni bean può avere zero o più Propertyelementi come figli. Ogni Propertyelemento ha un attributo nameche lo identifica e un elemento figlio di tipo Valueche contiene il valore della proprietà. Queste proprietà sono in realtà i membri in stile JavaBeans della classe che possono configurare la classe bean.
  3. RetryPolicies: Questo elemento contiene zero o più RetryPolicyfigli.
  4. RetryPolicy: Questo elemento definisce la politica di ripetizione per un determinato percorso. Ha un attributo nameche può essere utilizzato per fare riferimento ad esso. Ha due elementi figlio denominati MaxRetriese RetryInterval.
  5. Route: L' EsbConfigurationelemento radice può contenere zero o più elementi figlio di questo tipo. Fondamentalmente rappresenta un percorso per l'ESB. Ha i seguenti attributi:
    • name: Nome univoco che può essere utilizzato per fare riferimento a questo percorso.
    • retryPolicyRef: Riferimento alla politica di ripetizione dei tentativi. Dovrebbe corrispondere all'attributo RetryPolicydell'elemento name.
    • transformerRef: Riferimento a un fagiolo che rappresenta il trasformatore. Dovrebbe corrispondere all'attributo Beandell'elemento name.
    L' Routeelemento può avere uno o più elementi figlio di tipo TransportHandlerRef. Questo figlio fondamentalmente punta a un bean che rappresenta un gestore di trasporto appropriato che dovrebbe essere usato per questa rotta, e il nome del metodo pubblico di quel bean che dovrebbe essere invocato per inviare il messaggio. Facoltativamente, l' Routeelemento può avere un DeadLetterDestinationfiglio che punta a un altro percorso che rappresenta una destinazione lettera morta.

Di EsbConfiguration.xmlseguito viene visualizzato un documento XML di esempio,, :

                              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    

Comportamento ESB

Il ESBConfiguration.xmldocumento determina il comportamento del nostro ESB. L' EsbRouterMDB carica questo XML da una posizione specificata nel suo descrittore di distribuzione. Le informazioni in esso contenute vengono quindi organizzate in una struttura dati illustrata nella Figura 2 di seguito.

Il EsbRouterutilizza queste informazioni (via EsbConfigManager) per decifrare la rotta desiderata, la trasformazione, se del caso, da applicare, il controllo di autorizzazione di sicurezza, ecc Il punto importante da notare è il modo in cui la tecnica di iniezione di dipendenza, insieme con l'ereditarietà, è stata utilizzata per disaccoppiare varie funzioni (come il trasporto di messaggi multiprotocollo e la trasformazione dei messaggi) dell'ESB, consentendo così di essere altamente estensibile e personalizzabile.

Come mostra il diagramma delle classi, due importanti interfacce sono nel progetto ESB: TransformHandlere TransportHandler. Consentono di scrivere una trasformazione specifica e un'implementazione del trasporto per i messaggi instradati. Queste classi di implementazione possono quindi essere cablate con i percorsi tramite Beanelementi in EsbConfiguration. Ad esempio, nel EsbConfiguration.xmldocumento di esempio , la seguente definizione di bean specifica il gestore di trasporto:

   myQCF   myCreditQueue   

Questo gestore di trasporto può quindi essere indicato in un Routenodo inserendovi un TransportHandlerfiglio in questo modo:

Nota
L'approccio descritto in questo articolo utilizza le interfacce Java per definire i gestori di trasporto e trasformazione. Pertanto, qualsiasi nuovo gestore dovrebbe implementare l'interfaccia richiesta, che potrebbe sembrare invadente. È possibile modificare facilmente il EsbConfigManagerper utilizzare Dependency Injection per chiamare qualsiasi metodo arbitrario di una classe di implementazione, eliminando così la necessità di implementare un'interfaccia. Ma poiché EsbRouterpassa sempre javax.jms.Messageun'istanza, la classe di implementazione del gestore deve utilizzare javax.jms.Messagecomunque il tipo .