2015-04-22 89 views
22

Ho diversi pacchetti (A, B e C) distribuiti in un contenitore OSGi, ciascuno contenente uno CamelContext e alcuni percorsi. Ho un altro pacchetto (M) con un CamelContext con un percorso (per la raccolta dei dati di monitoraggio) e un bean InterceptStrategy. Vorrei che il bean InterceptStrategy di M si applicasse automaticamente a tutti gli altri CamelContext s nel contenitore (ad esempio quelli in A, B e C), senza dover modificare gli altri pacchetti.Cammello nel contenitore OSGi: applica InterceptStrategy a tutti i contesti cammello

In definitiva, l'obiettivo è intercettare i dati da ogni CamelContext nel percorso in M, senza dover apportare modifiche a A, B o C per instradare esplicitamente lo Exchange. Questo approccio o un approccio simile è fattibile?

Tutti i CamelContext s sono configurati utilizzando Spring XML.


Aggiornamento: contesto aggiuntivo

Bundles A, B, e C contengono il prodotto principale responsabile del trattamento dei dati. Bundle M contiene uno strumento di monitoraggio opzionale, progettato per misurare determinati parametri dei dati che fluiscono attraverso A, B e C. Attualmente, l'aggiunta dello strumento opzionale richiede la modifica dei percorsi in A, B e C per aggiungere ulteriori Processor s per arricchire Exchange con i dati di monitoraggio e leggere i dati di monitoraggio prima degli endpoint <to />.

L'obiettivo è essere in grado di inserire il pacchetto M in un sistema già verificato-come-lavoro con A, B e C; e farlo applicare automaticamente alle rotte esistenti senza dover modificare la configurazione per i bundle esistenti e funzionanti. È è accettabile per apportare modifiche a A, B e C per supportare questo, a condizione che le modifiche non causino A, B e C per fare affidamento su M per l'esecuzione (vale a dire, ABC deve ancora funzionare senza M).

Se c'è un mezzo migliore per farlo rispetto all'utilizzo di intercettori, sono aperto a questo. Gli obiettivi principali sono:

  1. Tenere A, B, e C disaccoppiato da M (soprattutto durante lo sviluppo)
  2. Garantire integrare M con A, B, e C è il più semplice possibile
  3. Consentire M essere integrato senza dover modificare manualmente A, B o C

risposta

4

Non penso che questo sia possibile utilizzando InterceptorStrategy poiché si aspetta che sia in esecuzione nello stesso contesto di cammello. L'unico modo in cui sono consapevole di lavorare su più contesti è l'utilizzo dell'endpoint della VM (che è ovviamente limitato alla stessa JVM), tuttavia in questo caso probabilmente sarebbe meglio utilizzare JMS, JMX o qualcosa di simile.

JMS

Crea un InterceptorStrategy per ogni contesto cammello in A, B & C che pubblica i messaggi di M

intercept().bean(transformForMonitoring).to("jms:queue:monitoring"); 

from("whatever:endpoint") 
    .process(myProcessor) 
    .to("target:endpoint"); 

Si potrebbe anche utilizzare il componente vm sul intercept() se non volevi il sovraccarico di JMS, tuttavia limita il componente di monitoraggio a una singola JVM.

JMX

Questo è un po 'più complicato, ma l'idea di base è di informare il contesto cammello di pubblicare MBeans per A, B & C

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> 
    <jmxAgent id="agent" mbeanObjectDomainName="your.domain.name"/> 
    ... 
</camelContext> 

e poi M connettersi al server JVM MBean e utilizzare qualcosa come NotificationListener per reagire agli scambi.

+1

mi piacciono le idee che hai presentato qui, ma c'è un problema che non è chiaro dalla mia descrizione: alcuni dei passaggi del codice di monitoraggio necessitano per essere eseguito in modo sincrono nelle rotte in 'A',' B' e 'C' (dato che, ad esempio, impostano le proprietà su' Exchange'), quindi semplicemente dirigere i messaggi su una coda asincrona è insufficiente. Vedo che in Camel 2.16.0 la componente direct-vm sarà in grado di gestire una condizione di assenza di consumatori, che risolverebbe il problema. Conoscete qualche meccanismo analogo disponibile in Camel 2.12.0 che consentirebbe il routing sincrono ma facoltativo? – VeeArr

+0

No, non è uno che funziona attraverso i contesti in cammello, a meno che non si desidera utilizzare qualcosa di simile a una chiamata di servizio web nel intercettore e solo ingoiare qualsiasi eccezione se non c'è chi ascolta .. – stringy05

1

Utilizzare Spring-DM, o meglio trasformare tutti i percorsi basati su xml primaverili in quelli del modello. Questo è il modo migliore di usare Route basate su XML in Karaf/Osgi.

+0

Potete fornire un esempio di come Spring-DM può aiutare qui? È una delle cose che ho visto in origine, ma tutte le soluzioni che ho trovato in uso hanno riguardato la modifica dei bundle A, B e C (ad esempio per aggiungere un tag '). – VeeArr

+0

In questo caso spring-dm si assicura che tutti i contesti primaverili siano avviati correttamente e che il cablaggio degli Spring Beans sia gestito correttamente. Naturalmente è anche usato per fare riferimento ai servizi di osgi da iniettare nella vostra applicazione. –

+0

Ma ciò non aiuta ancora in questo caso specifico (facendo in modo che un bean sia disponibile in altri bundle senza modificare il bundle che lo contiene), per quanto ne so io. – VeeArr

2

Una delle possibilità è definire un custom Tracer in bundle 'M' ed esportarlo come servizio OSGi.

In fascio A, B, C definiscono osgi riferimento alle esportato Tracer fagiolo

Usa camel JMX abilitare traccia.

Ciò comporterà cambiamenti nel fascio A, B, C ma sarà minima e darà anche capacità di integrare e configurare l'analisi (intercettazione)

non hanno provato io stesso, ma hth

+0

abbiamo provato qualcosa di simile. Il problema con questo approccio è che i bundle A, B e C non partiranno senza M, poiché l'osgi: reference non sarà soddisfatto. C'è un modo per aggirare questo? – VeeArr

+1

Se si utilizza spring-dm ... è possibile impostare la cardinalità [0..1] sul riferimento, in caso contrario si può provare a impostare la risoluzione come opzionale per l'interfaccia di riferimento in manifest? – blob