Zdravím,

  Topic bylo to první, co mě napadlo použít, bohužel  Topic a Dynamic Recipient List Pattern (DRLP)  není to samé.  Pomocí DRLP lze realizovat Topic, ale obráceně to neplatí.
Klíčový požadavek je ve větě "Dynamic Recipient List Router by podle typu zprávy, která mu přijde na vstupu, poslal kopii do všech registrovaných kanálů, které mají o tento typ zprávy zájem." Tedy na vstupu jsou zprávy s různým obsahem a ne všichni chtějí všechno.

Topic udělá to, že "nakopíruje" příchozí message do všech výstupních Subscriptions.
Důležité je právě to, že ten Router má nakopírovat zprávy jen do Subscription, které mají o daný typ zprávy zájem.  Toto se dá řešit také tak, že klient dostává všechny zprávy a použije MessageFilter a ty, co ho nezajímají, zahodí (sice neefektivní, ale funguje to).

Moje úloha je však ještě komplikovanější - nezmínil jsem bezpečnost - klient se registruje k odběru, ale provider musí nejdříve schválit, že zprávy splňující jím definovaná pravidla se mu mohou posílat. Tedy do jeho Subscripce musí jít pouze zprávy, které smí dostávat. Tedy zde nejde použít Topic+MessageFilter - filtrovaní musím řešit na straně poskytovatele, nikoliv klienta.

Toto by šlo asi řešit tak, že bych měl tolik Topiců, kolik je typů zpráv, ale to mi nepřipadá moudré, protože bych se mohl dostat na prudký nárůst počtu Topiců s počtem různých kombinací pravidel.

A tak jsem stále přesvědčen, že ten Dynamic Recipient List Pattern (DRLP) je nejlepší řešení mého problému, jen je komplikované ho realizovat.

Nakonec jsem se rozhodl ohnout Spring Integration, uvidíme, zda se mi to podaří,bohužel ten jejich kód není moc připraven na úpravy a rozšiřování, jako ve zbytku Springu.
Píšu si vlastní  org.springframework.integration.support.channel.ChannelResolver, který jde plugnout do org.springframework.integration.router.AbstractMessageRouter, který podědím a rozšířím o aplikování pravidel (načítaných asi z databáze, kam je bude zapisovat ta registrace). A pak ještě ohýbám org.springframework.integration.jms.config.JmsChannelFactoryBean, která se bohužel tváří tak, že umí vytvořit jen 1 Channel.  Já ji teď domlouvám Eclipsem, abych ji mohl žádat opakovaně o vytvoření nového kanálu a tím tak získal možnost dynamicky zakládat kanály. ChannelResolver s Routerem se pak už postarají o zbytek.

V dnešním světě plném Cloudu bych tak nějak řekl, že jde o řešení   "Message Router as a Service"  :)) 

Ale děkuji moc za tip, vážím si každé reakce.

Přeji hezký víkend

Petr


Dne 25.3.2011 8:59, Vlastimil Elias napsal(a):
Dobrý den,

podle mě si na toto úplně vystačíte s JMS serverem, nic navíc nepotřebujete. Podívejte se k čemu jsou určeny JMS destinace typu Topic. To je podle mě přesně to co potřebujete.
Topic je vlastně kanál, odběratelé se mohou dynamicky sami přihlašovat k odběru zpráv z tohoto kanálu.
Navíc mohou odebírat zprávy jen v době kdy jsou aktivně připojeni, nebo využít tzv. "Durable subscription" a poté dostanou i zprávy které byly na Topic odeslány v době kdy nebyly zrovna připojeni.
JMS servery mívají navíc management rozhraní, kde mimo jiné vidíte kdo má na Topic registrované durable subscription atp.

BTW tady se skrývá jedno "provozní nebezpečí" které není na první pohled úplně patrné. Pokud se totiž nějaký klient, který má durable subscription, přestane k JMS serveru připojovat ale nezruší to subscription,
tak vám časem přeplní persistentní úložiště JMS serveru. Samozřejmě toto nebezpečí je hlavně u systémů kde těch zpráv je opravdu hodně nebo jsou velké.

Vlastik

Dne 18.3.2011 11:41, Petr Novak napsal(a):
Zdravím všechny,

zkouším vytvořit komponentu, která by umožňovala dynamicky propojovat různé systémy. Prakticky se mi jedná o realizaci integračního patternu "Dynamic Recipient List".


Principiálně by to mělo fungovat tak, že není dopředu znám seznam příjemců, různé systémy se mohou zaregistrovat prostřednictvím nějakého API k odběru určitých typů zpráv. V rámci registrace jsem chtěl vytvořit dynamicky jejich odběrný kanál (frontu) a ten Dynamic Recipient List Router by podle typu zprávy, která mu přijde na vstupu, poslal kopii do všech registrovaných kanálů, které mají o tento typ zprávy zájem (tedy na základě té registrace).

Chtěl jsem použít řešení založené na Spring Integration + nějaké JMS, asi ActiveMQ.  Ale narážím na tu dynamičnost řešení - jak vytvořit Spring Channel podle nějakého seznamu registrovaných (třeba z databáze). Připadá mi, že Spring má všechno staticky - vše nakonfigurovat a propojit  v XML a pak nastartovat aplikaci. Ano mohl bych zkusit zavádět beany (Channel, Router, ...) do Spring Contextu za chodu, ale to se mi moc nezdá - nevím, jak pak Spring rozdýchá procesy jako injection, postprocesing, AOP a ostatní zpracování koleminicializace bean, které probíhá při jeho startování. Nebo myslíte, že Springu nebude vadit,když mu za chodu aplikace zadefinuji nějaké další beany ? Ani nevím, jestli na to má nějaké API,něco ve smyslu  ApplicationContext.createBean(bean.class,"beanID",properties);

Ještě jsem zvažoval omrknout Apache Camel, nemám s ním zkušenost. Našel jsem, že lze psát pomocí jeho DSL kódy jako

from("jms:xmlOrders").recipientList(header("recipients"));

Ale nejsem si jistý, zda toto lze dělat i za chodu aplikace a nebo to je jen jiný zápis statické XML configurace, která se provede při startu, navytváří se fronty a pospojují se těmi transformatory a routery. To bych pak na tom byl stejně jako s tím Springem.

Co byste použili vy na řešení takové úlohy ? Rád bych se vyhnul objevování kola - tedy že bych si na to musel napsat vlastní integrační framework.  Zároveň si myslím, že jde v principu o relativně jednoduchou úlohu a tak řešení typu použít ESB mi připadne jako kanón na vrabce.

Google mi zatím moc nepomohl, nebo jen nevím, jak se ho správně zeptat :o).
V této oblasti nemám moc zkušeností, začínám se s tím seznamovat, tak budu rád za každý váš tip, radu nebo zkušenost.

Přeji úspěšný den

Petr



-- 
Vlastimil Elias
Senior Software Engineer
JBoss.org community team


Odpovedet emailem