Přeskočit na hlavní obsah
  1. Tags/

Patterns

2013


Vytvoření JMS Bridge na WebLogicu

Messaging bridge je šikovné řešení, pokud potřebujeme distribuovat zprávy mezi několika messaging systémy. Potřeboval jsem vytvořit JMS bridge na WebLogicu a protože jsem si oblíbil WebLogic Scripting Tool (WLST), tak jsem si napsal skript.

Nicméně dnes, vás milí čtenáři, nechci odfláknout pouhým WLST skriptem, ale podíváme se na téma trochu zeširoka. Prvně si zasadíme JMS bridge do kontextu Enterprise Integration Patterns (EIP), pak se podíváme, jak jde bridge naklikat ve WebLogic konzoli. A samozřejmě vás neochudím o to WLST :-)

Messaging Bridge

Nebyl bych to já, kdybych se nevytasil s nějakým patternem. Tak tady je - Messaging Bridge, jak je definován v EIP. (Věty kurzivou jsou citacemi z knihy Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions.)

Messaging Bridge řeší následující problém: "How can multiple messaging systems be connected so that messages available on one are also available on the others?" Integrační vzory řeší problémy obecně. V tomto případě jde o to, jak dostat zprávy z jednoho systému na jiný. Např. jak dostat zprávy z WebSphere MQ na MSMQ. Nebo JMS. Nebo TIBCO Randevouz. Nebo... Jasný, ne? Odkudkoliv kamkoliv.

Messaging Bridge tedy je "a way for messages on one messaging system that are of interest to applications on another messaging system to be made available on the second messaging system as well."

Protože většinou neexistuje způsob, jak propojit dva různé messaging systémy, propojují se jednotlivé, odpovídající kanály na daných systémech. "The Messaging Bridge is a set of Channel Adapters ... where each pair of adapters connects a pair of corresponding channels. The bridge acts as a map from one set of channels to the other and transforms the message format of one system to the other."

Vzor Messaging Bridge (zdroj EIP)

JMS Bridge

JMS bridge je speciální variantou Messaging bridge, který má několik omezení, nebo spíše možná zjednodušení. Tři hlavní jsou:
  • Propojuje pouze JMS systémy (různých dodavatelů).
  • Zprávy netransformuje (protože pracuje pouze s JMS zprávami).
  • Zprávy z jednoho (zdrojového) systému přeposílá na jiný (cílový). Čili nečiní je pouze dostupnými, ale provádí routing/forwarding.

JMS bridge běžně poskytují všichni dodavatelé JMS systémů, např.:

Zajímavým atributem u JMS bridge je Quality of Service (QoS), který říká, v jakém modu budou zprávy přeposílány:
  • At most once - nanejvýš jednou. Toto je nejbenevolentnější mod. Zpráva buď dorazí (maximálně jednou), anebo taky ne. A nám to tak vyhovuje.
  • Duplicates OK - duplicity jsou v pořádku. V tomto modu jsou zprávy potvrzeny, že dorazily na cílový systém. Může se stát, že stejná zpráva nám dorazí ve více instancích, ale to je v pořádku - řekli jsme přece, duplicity jsou OK. Výhodou je, že se žádná zpráva neztratí.
  • Exactly once - přesně jednou. Toto je nejvíc striktní mod, který nám nejen zaručuje, že každá zpráva dorazí na cílový systém, ale taky že tam dorazí právě jednou. Takový závazek není jen tak a zajistí nám ho JTA, čili distribuovaná transakce.

WebLogic JMS Bridge

Vytvoření JMS bridge na WebLogicu je otázkou chvilky, stačí mít připraveny správné ingredience. Co budeme potřebovat?
  • URL (a credentials) zdrojového serveru,
  • URL (a credentials) cílového serveru,
  • JNDI JMS adapteru (transakční, nebo netransakční)
    • eis.jms.WLSConnectionFactoryJNDIXA
    • eis.jms.WSLConnectionFactoryJNDINoTX
  • JNDI Connection Factory,
  • JNDI JMS destinace (fronty),
  • Quality of Service
    • Exactly-once
    • Duplicate-okay
    • Atmost-once

Pak už stačí jen naházet to do hrnce, zamíchat, podusit... a proklikat se průvodcem. Protože těch obrazovek ve wizardu je zbytečně moc, ukážu jenom screenshoty konečného stavu.

Pokud chceme použít transakční mod Exactly once, je dobré ještě před vytvářením bridge deployovat transakční adaptér jms-xa-adp.rar - vyhneme se tak zbytečným restartům (adapteru či WebLogicu). Adapter najdeme mezi knihovnami WebLogicu a nasazujeme ho jako aplikaci.

Nasazený resource adapter jms-xa-adp.rar (ve struktuře Deployments)

Bridge se sestává ze dvou destinací (zdrojové a cílové):

Definice JMS (source) destination

a samotného bridge:

Definice JMS bridge

Že nám bridge funguje, poznáme podle jeho stavu (záložka Monitoring) a taky doporučuju si nějakou zprávu cvičně přeposlat. Světe div se, ale transakce můžou zlobit.

Stavy JMS bridgů (záložka Monitoring)

WLST

No a máme tady velké finále, ke kterému jsem nenápadně, ale cílevědomě směřoval. Takže tady je: WLST v celé své pythoní kráse :-)
#
# properties
#
user = 'weblogic'
password = 'welcome1'
server = 't3://sandman:7001'
# source credentials
sourceJmsUser = 'weblogic'
sourceJmsPassword = 'welcome1'
sourceURL = 't3://sandman:7003'
# target credentials
targetJmsUser = 'weblogic'
targetJmsPassword = 'welcome1'
targetURL = 't3://sandman:7004'
# JMS servers
servers = ['SourceServer']
targets = []
# queues
queues = [
'EVM_EVE_CMS',
'EVM_EVE_FC',
'EVM_EVE_GEN',
'EVM_EVE_PTS',
'NTF_PARTY',
'NTF_PRODUCT']
adapterJNDI = 'eis.jms.WLSConnectionFactoryJNDIXA'
connectionFactory = 'jms/sws/SWSConnectionFactory'
qualityOfService = 'Exactly-once'
jndiPrefix = 'jms/sws/'

# connection
connect(user, password, server)

# edit mode
edit()
startEdit()

# get targets
for server in servers:
targets.append(getMBean('/Servers/' + server))
print '\nTargets:', targets, '\n'

#
# create bridges
#
print '\n### Create bridges:\n'
for queue in queues:
bridgeName = queue + '_bridge'
sourceName = queue + '_source'
targetName = queue + '_target'
# delete an old bridge
ref = getMBean('/MessagingBridges/' + bridgeName)
if ref != None:
cd('/MessagingBridges')
delete(bridgeName, 'MessagingBridge')
# delete an old source destination
ref = getMBean('/JMSBridgeDestinations/' + sourceName)
if ref != None:
cd('/JMSBridgeDestinations')
delete(sourceName, 'JMSBridgeDestination')
# delete an old target destination
ref = getMBean('/JMSBridgeDestinations/' + targetName)
if ref != None:
cd('/JMSBridgeDestinations')
delete(targetName, 'JMSBridgeDestination')
# create a new source destination
cd('/')
cmo.createJMSBridgeDestination(sourceName)
cd('/JMSBridgeDestinations/' + sourceName)
cmo.setAdapterJNDIName(adapterJNDI)
cmo.setConnectionFactoryJNDIName(connectionFactory)
cmo.setConnectionURL(sourceURL)
cmo.setDestinationJNDIName(jndiPrefix + queue)
cmo.setUserName(sourceJmsUser)
cmo.setUserPassword(sourceJmsPassword)
print 'Source:', cmo
# create a new target destination
cd('/')
cmo.createJMSBridgeDestination(targetName)
cd('/JMSBridgeDestinations/' + targetName)
cmo.setAdapterJNDIName(adapterJNDI)
cmo.setConnectionFactoryJNDIName(connectionFactory)
cmo.setConnectionURL(targetURL)
cmo.setDestinationJNDIName(jndiPrefix + queue)
cmo.setUserName(targetJmsUser)
cmo.setUserPassword(targetJmsPassword)
print 'Target:', cmo
# create a new bridge
cd('/')
cmo.createMessagingBridge(bridgeName)
cd('/MessagingBridges/' + bridgeName)
cmo.setSourceDestination(getMBean('/JMSBridgeDestinations/' + sourceName))
cmo.setTargetDestination(getMBean('/JMSBridgeDestinations/' + targetName))
cmo.setStarted(true)
cmo.setQualityOfService(qualityOfService)
cmo.setTargets(targets)
print 'Bridge:', cmo, '\n'

# save and finish
save()
activate()
disconnect()
exit()

Související články

Dead Letter Channel nebo Invalid Message Channel? Toť otázka

·3 min
Řešil jsem teď zajímavou filozofickou otázku. Potřeboval jsem v rámci integrace někam odkládat JMS zprávy, které se nepodařilo aplikačně zpracovat. Rozhodl jsem se je odkládat do speciální fronty, kterou jsem nazval Dead Letter Queue. Což je termín, který se používá na platformě WebSphere MQ. Naopak moje platforma je SOA Suite, která žádný podobný termín nemá (a řekl bych, že nejen termín, ale ani koncept).

Své řešení jsem hrdě (a úspěšně) představil v týmu a argumentačně ho podpořil tvrzením, že jde o vzor z Enterprise Integration Patterns (EIP). Tyto patterny jsou shrnuty v knížce, kterou vřele doporučuji - zcela jednoznačně jde o bibli messagingu.

Už je to nějaký čas, co jsem knížku četl a jelikož jsem si matně pamatoval, že ve skutečnosti jsou tam dva takové podobné vzory, znovu jsem si dané kapitoly pročetl. Co kdyby se vynořila nějaká zvídavá otázka :-) Po (znovu)přečtení jsem uvažoval, kterému vzoru se moje řešení více podobá - Dead Letter Channel nebo Invalid Message Channel? Ještě než se k těmto vzorům dostanu, předestřu, jak vypadá moje řešení.


Aniž bych zabíhal do přílišných podrobností. JMS listener vyčte zprávu z JMS fronty Input Queue a pošle ji ke zpracování do orchestrační/business logiky. Zde proběhnou validace zprávy, plus nějaká omáčka a pak jsou v rámci orchestrace volaný 3-4 externí služby (z diagramu vypuštěno). Pokud je během orchestrace vyhozena SOAP fault, zapíše se iniciální zpráva do JMS fronty Dead Letter Queue. Zároveň se do hlavičky zprávy přidá "uživatelská hlavičková vlastnost" (custom header property), kam se zapíše, ze které fronty byla zpráva původně vyčtena.

Nyní k oběma vzorům. První odstavec je definice vzoru a následuje signifikantní text, který jsem si podtrhl na  Kindlu. A obrázek :-)

Dead Letter Channel


"When a messaging system determines that it cannot or should not deliver a message, it may elect to move the message to a Dead Letter Channel."

"Typically, each machine the messaging system is installed on has its own local Dead Letter Channel so that whatever machine a message dies on, it can be moved from one local queue to another without any networking uncertainties. ... When the messaging system moves the message, it may also record the original channel on which the message was supposed to be delivered."

"Determining if a message should be moved to the Dead Letter Channel is an evaluation of the messages's header performed by the messaging system."

Vzor Dead Letter Channel (zdroj EIP)

Invalid Message Channel

"The receiver should move the improper message to an Invalid Message Channel, a special channel for messages that could not be processed by their receivers."

"An Invalid Message Channel is like an error log for messaging. When Something goes wrong in an application, it's a good idea to log the error. When something goes wrong processing a message, it's a good idea to put the message on the channel for invalid messages."

"If an error occurs while processing the message, the message is invalid and should be moved to the Invalid Message Channel. If it occurs while the application processes the data from the message, that is an application error that has nothing to do with messaging."

Vzor Invalid Message Channel (zdroj EIP)

Co to teda je?

Moje řešení má znaky obou výše uvedených vzorů, ale zároveň se jim i vymyká. Což není nic divného - moje platforma není messagingová, JMS fronty používá pouze jako rozhraní kvůli decouplingu.

Co si o tom myslíte vy? Jak byste nazvali takovou "odkládací" frontu? Nebo existuje nějaký vzor, který toto řešení/problém pokrývá lépe? Budu rád, když se v diskuzi podělíte.

Související články

2012


SOA Patterns, kniha

·2 min
SOA je široké téma a kde kdo si do něj schová kde jakou webovou službičku. Určitě proto není na škodu se občas trochu ochytřit a zjistit, "jak se to správně dělá". Jednou z knižních alternativ, po které se dá sáhnout je počin mého oblíbeného vydavatelství Manning, které čersvě vydalo knihu SOA Patterns jejímž autorem je Arnon Rotem-Gal-Oz.

Hned na úvod je potřeba říct, že titul knihy je zavádějící. Daleko přesnější by byl název "Distributed Systems Patterns" s podtitulem "Taking SOA into Account". Nicméně kniha rozhnodně stojí za přečtení a je vhodným doplňkem k jiným "patternovým" knihám. Pokud byste chtěli opravdu SOA patterny, je pravděpodobně jediným dostupným titulem na trhu SOA Design Patterns od Thomase Erla.

Co v knize najdeme? Kniha sleduje klasické schéma návrhových vzorů, takže každý vzor je popsání pomocí sekcí: problém, řešení, technologické mapování a atributy kvality. Vzory (celkem jich je 26) jsou pak seskupeny do jednotlivých kapitol:
  • Foundation structural patterns
  • Patterns for performance, scalability and availability
  • Security and manageability patterns
  • Message exchange patterns
  • Service consumer patterns
  • Service integration patterns

Následují kapitoly s anti-patterny, case study a úplným závěrem je zajímavá kapitola, kde se SOA srovnává s jinými architekturními styly: REST, Cloud computing a Big data.

Jak už jsem psal, SOA je široké téma, takže kniha jej pokrývá pouze z části. Vzhledem k tomu, že titul vyšel u Manningu, tak nepřekvapí, že většina vzorů je "nízkoúrovňových" tzn., že je využijete, pokud bude servisní architekturu implementova from-the-scratch. Tomu odpovídají i příklady uváděné z autorovy praxe - systém pro námořní hlídkování, vyhledávač videí apod., čili dosti specifické systémy, které vyžadují dobrou performance a těžko by se na ně aplikovalo nějaké krabicové řešení.

Pokud ovšem sáhnete po nějaké hotovém/předpřipraveném řešení (a nemusí to být zrovna nějaké dělo od Oracle nebo IBM, ale klidně třeba Apache Camel nebo ServiceMix), tak už tam většina vzorů bude naimplementovaná "pod kapotou". Ovšem samozřejmě, že neškodí vědět, jak to tam sviští.