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
|