Přeskočit na hlavní obsah

Posts

2013


Perforce best practices

·4 min
Po více jak dvou letech se končí moje soupoutničení s verzovacím systémem Perforce (P4). Z počátku nebylo naše soužití zcela harmonické. Ale poté, co jsem přijal pravidla hry (které P4 nastavuje) jsem si tento systém oblíbil. A nyní bych se chtěl o své zkušenosti podělit.

Počáteční rozčarování a zklidnění

Srážka nepřipraveného vývojáře s P4 může být dost nepříjemná a frustrující. Vývojáři mají dost často rutinní zkušenost s SVN a podobnými nástroji. P4 má v některých aspektech jinou filozofii, která (z hlediska třeba SVN) nemusí být intuitivní. Když člověk nepochopí principy, které se za tím skrývají, může dopadnout podobně, jako evropský řidič v Anglii (Irsku, Austrálii, ...) - nadává, jak to "ty pitomý Angláni blbě vymysleli".

Pokud se člověk rozhodne nepřijmout filozofii P4, tak může skončit jako někteří z mých kolegů, kteří pořád trousí hlášky o "debilním Perforsu". Holt rok je asi příliš krátká doba na to, naučit se to pořádně ;-)

Mě zkušenost naučila číst (v) dokumentaci. Rád totiž dělám věci správně a (dobrá či dokonce kvalitní) dokumentace mi přijde jako efektivní způsob jak zjistit, jak věci fungují. A navíc si člověk zbytečně nepřenáší zlozvyky odjinud. Takže než s P4 bojovat, přijde mi lepší přijmout jeho pravidla hry. On se vám za to odvděčí a rozkvete vám pod rukama :-)

Možná teď čekáte, že napíšu něco o té filozofii a o věcech, které jsou "jinak". Ale nenapíšu. Nechci se pouště do nějaké srovnávací studie, kterou by to asi skončilo. Prostě jen teď uvedu, jak P4 používám já.

Typický lifecycle

Následující lifecycle mi vykrystalizoval během těch dvou let používání a osvědčil se mi, jako účinný prostředek proti některým nástrahám P4.
  1. Check Out (Ctrl+E)    konkrétního projektu (nebo jeho části) do nového changelistu (Alt+N -> Alt+C).
  2. Editace zdrojových kódů.
  3. Na changelistu, který chci komitovat: Revert Unchanged Files   .
  4. Na adresáři, který jsem původně checkoutoval: Reconcile Offline Work a přidat eventuální soubory do changelistu.
  5. Kontrola souborů v changelistu. Pokud byly soubory modifikované, tak Diff Against Have Revision (Ctrl+D).
  6. Submit (Ctrl+S -> Alt+S)   .
Z tohoto seznamu bych vypíchnul body 3 a 4. Revert Unchanged Files je důležitý, aby se nekomitovaly nezměněné soubory. Reconcile Offline Work zajistí přidání (Mark for Add   ) nových souborů do changelistu.

Changelisty

Changelist je v P4 seskupením souborů, které chci komitovat. Já si vytvářím nový changelist pro každý kousek práce, typicky jedna položka v issue tracking systému. Novému changelistu pak nejčastěji dávám popis ve stylu: <issue ID>; <issue name>, <description>. Např.: SWS-12; Gradle tutorial, Jetty initial implementation.

Pending Changelists
Na záložku Pending Chagelists, která zobrazuje moje chagelisty, se přepnu klávesovou zkratkou Ctrl+1, nebo ikonou   .

P4 nabízí také tzv. default changelist, který ale používám pouze v jediném případě - pokud v changelistu potřebuju mít něco, co nechci komitovat a později to revertnu. Pokud bych to náhodou přesto potřeboval, vždy se to dá převést do jiného changelistu. Důvod, proč něco nekomitovat a mít to v changelistu je prostý - pokud si natáhnu do lokálního workspace nějakou revizi z depotu, P4 všechny soubory nastaví na read-only. A to může některým editorům vadit. Takže to šupnu do defaultu.

Shelved Files

Aneb soubory na poličce. Někdy mám něco rozpracovaného, ale nechci to ještě komitovat. Zároveň ale nechci, aby úpravy byly pouze u mne na lokálním počítači. Tak je přesunu z changelistu do poličky na serveru.

Shelved Files

Bookmarks

Souborová struktura v rámci daného depotu může být velmi rozsáhlá (na aktuálním projektu je to přes 10 000 souborů). Proto jsem si oblíbil záložky (Bookmarks) s nastavenými klávesovými zkratkami.

Bookmarks

Klávesové zkratky

P4 má výborného grafického klienta: P4V. A tak jako u každé grafiky, i zde se hodí (a efektivitě napomůžou) klávesové zkratky. Tyhle jsem si oblíbil:
  • Get Latest Revision: Ctrl+Shift+G
  • Check Out: Ctrl+E
  • Submit: Ctrl+S -> Alt+S
  • Revert Files: Ctrl+R
  • Diff Agains the Have Revision: Ctrl+D
  • Next Diff (P4Merge): Ctrl+2
  • Previous Diff (P4Merge): Ctrl+1
  • Close (P4Merge): Ctrl+W
  • Pending Changelists: Ctrl+1
  • Submitted Changelists: Ctrl+2
  • Skok na zazáložkovaný soubor/adresář: Ctrl+Shift+1 (až n)
  • Skok do file browseru z daného adresáře/souboru: Ctrl+Shift+S
K dokonalé spokojenosti mi chybí absence dvou zkratek: Revert Unchanged Files a Reconcile Offline Work.

Závěr

Myslím, že dobrá znalost (aktuálně používaného) verzovacího systému patří ke ctnostem každého vývojáře. Za ty dva roky jsme se s P4 docela skamarádili a pokud bych ho někdy v budoucnu zase potkal, tak se rozhodně nebudu zlobit.

A co vy, máte nějakou oblíbenou P4 vlastnost? Nebo vás naopak na něm něco rozčiluje? ;-)

Související články


Externí odkazy

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

Geek, který zapadne

·8 min
Jak se správně rozhodnout po úspěšném pracovním pohovoru? Překlad článku Being the Geek Who Fits od Andyho Lestera.

Oracle EDN, implementace EDA

·5 min
SOA Suite je zajímavou kompilací technologií, které, poskládány dohromady, stojí na architektonickém principu SCA (Service Component Architecture). Patří sem například implementace BPELu, business rules a human tasků. A jednou z těchto technologií je i Event Delivery Network (EDN), což je implementace paradigmatu Event Driven Architecture (EDA).

Event Driven Architecture

Even Driven Architecture (EDA) může být alternativou, nebo doplňkem k Servisně orientované architektuře (SOA). Ale EDN se netýká pouze SOA - tento architektonický princip najdeme i uvnitř GUI frameworků, jako je Java Swing, nebo Apache (dříve Adobe) Flex.

Jak už napovídá název, vše se v této architektuře motá kolem událostí. Událost je v EDA first-class citizen. Vlastně je to jediný citizen (obyvatel). Ale co to vlastně ta událost je? Událost je v podstatě zpráva, podobně jako zpráva má hlavičku a tělo. V hlavičce jsou samozřejmě meta-data, např. jméno a typ zprávy, timestamp apod. Zásadní rozdíl je v obsahu těla události (payload), ten bývá zpravidla velmi malý a měl by obsahovat pouze popis faktu, který událost instancoval. Někdy payload ani být nemusí - pokud je událost určitého typu, stačí pouze vědět, že nastala.

A jak taková událost zapadá do architektury? Dalším významem akronymu EDA by mohlo být: Extremely Decoupled Architecture. Události, které nejsou nijak svázány s konkrétním producentem, jsou publikovány do nějaké centrální generické infrastruktury. Producenti publikují události stylem fire-and-forget a vůbec se nestarají o to, kdo je jejich konzumentem.

Konzumentem je pak kdokoli, kdo se zajímá o výskyt určitého typu události. Pro konzumenty je původ události neznámý - neví kdo ji publikoval, oni se pouze dozvědí, že nastala. Na konzumentovi pak leží veškerá zodpovědnost za správné business zpracování události. S tím souvisí i to, že příjemce může konzumované události filtrovat.

Event Driven Architecture (barvy představují typy událostí)
Z předešlého komponentového diagramu vyplývá několik věcí. Jednak že v EDA existují v podstatě jen dva základní komponenty - Event Coordinator, který si můžeme představit jako jakýsi "event bus" (podle vzoru service bus) pro události, který se stará o publikování událostí, přihlášení (subscription) konzumentů apod.

A pak jednotlivé uzly (nody). Ty mohou fungovat buď jako producenti událostí (Node 3), nebo jejich konzumenti (Node 2, Node 5), anebo obojí (Node 1, Node 4). Každý node může publikovat nebo přijímat více typů událostí. Že jeden typ události může být konzumovaný více nody asi nikoho nepřekvapí (oranžová událost konzumovaná Nody 1 a 4). Daný typ události ale může taky být publikovaný více producenty (fialová událost publikovaná Nody 3 a 4).

To by, myslím, mohlo stačit, jako takový velmi lehoulilinký úvod do EDA a teď se podíváme na jednu její konkrétní implementaci.

Event Delivery Network

Event Delivery Network (EDN), která je součástí SOA Suite, je infrastruktura (postavená na JMS), která poskytuje deklarativní způsob definice událostí, jejich publikování a registraci jejich konzumace. Tři hlavní entity, se kterými pracuje jsou producent událostí, konzument událostí a události samotné.

Definice události

Události jsou v EDN definované názvem a typem a jsou uloženy v souboru s příponou edl. Tento soubor může být umístěný buď v rootu projektu, nebo v MDS (MetaData Services repository).
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions
xmlns="http://schemas.oracle.com/events/edl"
targetNamespace="http://sw-samuraj.blog/events/SimpleEvent-v1">
<schema-import
namespace="http://sw-samuraj.blog/events/simpleMessage-v1"
location="xsd/simpleMessage-v1.0.xsd"/>
<event-definition name="SimpleEvent">
<content
xmlns:sim="http://sw-samuraj.blog/events/simpleMessage-v1"
element="sim:simpleMessage"/>
</event-definition>
</definitions>
Definice události

Typ je popsán pomocí XSD:
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sim="http://sw-samuraj.blog/events/simpleMessage-v1"
targetNamespace="http://sw-samuraj.blog/events/simpleMessage-v1"
elementFormDefault="qualified">
<xsd:element name="simpleMessage">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="timestamp" type="xsd:dateTime"/>
<xsd:element name="status">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ON"/>
<xsd:enumeration value="OFF"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Typ události definovaný v XSD

Publishers

Producentem události může být buď BPEL proces, nebo Mediator. V případě Mediatoru je publikování události přímočaré - v definici akce se místo invoke zavolá raise s patřičnou události.

Publikování události v Mediatoru
Graficky pak vypadá kompozitní aplikace s publikujícím Mediatorem takto:

Mediator event publisher (kompozitní aplikace)

U BPEL procesu je situace maličko složitější. Vzhledem k tomu, že BPEL je otevřený standard, do kterého události nepatří, řeší to SOA Suita (standardním) BPEL extension. Událost se tak dá publikovat pomocí rozšíření z aktivity Invoke.

Publikování události v BPELu z aktivity Invoke

BPEL event publisher (kompozitní aplikace)
Všimněte si, že jak v případě Mediatoru, tak BPELu končí implementace publikování události na dané komponentě. Kdyby totéž bylo implementováno pomocí messagingu, musel by být v kompozitní aplikaci definován ještě JCA adaptér s pevně uvedenou destinací. Tohle u EDA/EDN není potřeba.

Subscribers

Konzumentem události může být opět buď Mediator nebo BPEL komponent.

Subskripce události v Mediatoru

Mediator event subscriber (kompozitní aplikace)

Podobně jako u publikování i u konzumace událostí si BPEL vypomáhá rozšířením, tentokrát v rámci aktivity Receive.
Subskripce události v BPELu v aktivitě Receive

BPEL event subscriber (kompozitní aplikace)

Monitorování událostí

Asi trochu překvapí, že již publikované, ale ještě nezkonzumované události nelze nikde vidět. Alespoň ne standardními nástroji. V podstatě lze vidět pouze "historický otisk" událostí. Něco jako: tudy kráčely dějiny :-)

Cestu události lze vidět v Enterprise Manageru:

Audit trace události (Enterprise Manager)
V uvedeném logu publikuje Mediator Publisher událost, která je konzumována dvěma konzumenty: Mediator Subscriber a BPEL komponent BpelSubscriber. Zároveň je vidět, že Enterprise Manager loguje celou cestu události - ačkoliv jsou producent a konzumenti události od sebe odděleni a vůbec o sobě nemají povědomí, v audit logu je to zaznamenáno jako jeden souvislý tok události.

BPEL nebo Mediator?

Na základě čeho se rozhodnout, kterou komponentu použít pro konzumaci/publikování události? Jednodušší a přímočařejší je použití Mediatoru. Koneckonců to doporučuje i sám Oracle. BPEL má jedinou výhodu - jako konzument může události korelovat. Čili pokud je reakcí na nějakou událost jiná událost a obě dvě jsou zpracovávány stejnou kompozitní aplikací, tak jejich korelace je možná pouze v BPEL procesu.

Závěr

Event Delivery Network (EDN) je standardní součástí SOA Suity a nabízí out-of-the-box implementaci Event Driven Architecture (EDA). Pokud nepotřebujeme robustní a konfigurovatelné messaging řešení, může být EDN vhodnou, rychle provozovatelnou alternativou.

Rozhodně bych ale EDN nedoporučoval použít pro kritické části systému. Byť je postavena na prověřené JMS platformě, její možnosti z hlediska konfigurace, provozování, monitoringu atd. jsou velmi omezené - berte jak to je, nebo nechejte být.

Související články

Oracle SOA certifikace

·3 min
Půlrok se sešel s půlrokem a já jsem si vystřihnul další certifikaci. Tentokrát jsem chtěl něco, čím bych zakončil své roční působení na projektu a důstojně :-) tak završil trnitý proces získávání znalostí o nové technologii: Oracle SOA Suite.

Okolnosti tomu chtěly, že jsem se zrovna trefil do přelomu, kdy Oracle jednu  SOA certifikaci nahrazuje jinou. Aktuální certifikace, která je k dispozici od letošního ledna, se jmenuje  Oracle SOA Suite 11g Certified Implementation Specialist. Já, protože jsem se ke zkoušce přihlásil již dříve, jsem nyní obdržel certifikaci Oracle Service Oriented Architecture Infrastructure Implementation Certified Expert. Uff! To je titul :-/

Každopádně, co je nám po jménu? Podstatné je, jestli se obě zkoušky od sebe nějak obsahově liší. Liší? Ano, ale pouze drobně - v nové certifikaci přibylo pouze něco málo o governance, deploymentu a monitoringu, ale gró zůstává stejné: jednotlivé komponentní technogie (viz Exam Topics).

Jak dlouho jsem se na certifikaci připravoval? Přípravě přímo na zkoušku jsem věnoval cca 3 týdny - přečetl jsem si guide (viz dále) a prošel testovací otázky. Ale obecně jsem k certifikaci studijně směřoval téměř celý rok. Za jeden z podstatných zdrojů vědomostí totiž považuji přímou zkušenost s technologií - 7 měsíců intenzivního "programování".

Kniha

Vývoj samotný z učedníka mistra neudělá. Primárním zdrojem informací jsou pro mne knihy, takže od nich jsem začal: hned z počátku práce na projektu jsem si koupil knihu Oracle SOA Suite 11g Handbook.

Jde o 800stránkový opus a pokud to někdo myslí se SOA Suitou vážně, tak rozhodně tuto knihu doporučuji - obsahuje vyčerpávající sumu témat (daleko přesahující rozsah zkoušky), které umožní pochopit principy, které za SOA Suitou stojí a provede návrhem, vývojem, testováním a provozem jednotlivých komponent a technologií. Ještě jednou: vysoce doporučuji!

Školení

Školení obvykle v portfoliu přípravných zdrojů nemám, tentokrát se mi ovšem naskytla příležitost, tak jsem ji využil a absolvoval školení hned tři:
  • Oracle SOA Suite 11g Implementation Bootcamp
  • Oracle Service Bus 11g
  • Oracle BPM Suite 11g Implementation Bootcamp
Školení nebyla špatná. Probíhala formou labů, takže si člověk mohl věci prakticky vyzkoušet. Tematicky školení zkoušku více méně pokrývala (s výjimkou BPM, který v certifikaci není) a umožnila mi trochu jiný pohled na věc, než byl třeba v knize, nebo jsem sám získal praxí. Z pohledu certifikace nejsou školení nutností, ale příjemným bonusem - stejné informace se dají získat i jinde a levněji :-)

Certifikační guide

Krátce před zkouškou jsem pořídil knihu Oracle SOA Infrastructure Implementation Certification Handbook, což je certifikační guide zaměřený na původní zkoušku (1Z0-451). Co se týká obsahu, kniha je slušným, velmi lehkým úvodem do SOA Suite. Jako studijní materiál je nedostačující. Co je na ní cenné, je sada testovacích otázek a odpovědí ke každému tématu, plus závěrečný test (také s řešením).

Závěr

Pokud vezmu v potaz svoji celoroční "přípravu", tak pro mne certifikace splnila (opět) svůj hlavní účel - motivační prostředek pro sebevzdělávání. Tak jako u jiných zkoušek i nyní mě certifikace přinutila podívat se do hloubky i na témata, která nutně (projektově) nepotřebuju a umožnila mi tak lépe pochopit celý kontext dané technologie.

Kecám, nepřinutila - já to dělám rád ;-)

Související články

Druhý rok s Kindlem

·4 min
Tak jsem strávil druhý rok s Kindlem. Jaké odborné knihy mojí čtečkou protekly? Bylo jich méně, než loni, ale to nevadí - důležité je nepřestávat číst.

Vytvoření JDBC datasource na WebLogicu pomocí WLST

·1 min

Dneska to bude jen taková variace na minulé téma (vytvoření JMS zdrojů pomocí WLST), aneb jak na WebLogicu vytvořit JDBC datasource pomocí skriptovacího nástroje WLST (WebLogic Scripting Tool).

Podstatné věci o WLST jsem zmínil v uvedeném postu, takže je tady už nebudu opakovat a eventuálně vás pro doplňující informace odkazuji tam.

#
# properties
#
user = ‘weblogic’
password = ’<password>’
server = ‘t3://<host>:7001’
dsName = ’<datasource>’
dsPath = ’/JDBCSystemResources/’ + dsName + ’/JDBCResource/’ + dsName
clusterName = ‘soa_cluster’

# connection
connect(user, password, server)

# edit mode
edit()
startEdit()

#
# delete an old JDBC resource
#
if cmo.lookupJDBCSystemResource(dsName):
delete(dsName, ‘JDBCSystemResource’)

#
# create JDBC resource
#
cmo.createJDBCSystemResource(dsName)
# set datasource name
cd(dsPath)
cmo.setName(dsName)
# set JNDI name
cd(dsPath + ’/JDBCDataSourceParams/’ + dsName)
cmo.setJNDINames([‘jdbc/’ + dsName])
# set driver
cd(dsPath + ’/JDBCDriverParams/’ + dsName)
cmo.setDriverName(‘oracle.jdbc.xa.client.OracleXADataSource’)
cmo.setPassword(’<password>’)
cmo.setUrl(‘jdbc:oracle:thin:@<host>:1521:<SID>’)
# set username
cd(dsPath + ’/JDBCDriverParams/’ + dsName + ’/Properties/’ + dsName)
cmo.createProperty(‘user’)
cd(dsPath + ’/JDBCDriverParams/’ + dsName + ’/Properties/’ + dsName + ’/Properties/user’)
cmo.setValue(’<user>’)
# set targets
cd(’/JDBCSystemResources/’ + dsName)
cmo.setTargets([getMBean(’/Clusters/’ + clusterName)])

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

Související články

Vytvoření WebLogic Distributed Queue pomocí WLST

·3 min

Pokud nějaká aplikace používá JMS zdroje, bývají  tyto zpravidla externí. (Výjimkou je JMS broker embeddovaný uvnitř aplikace.) Tyto externí zdroje bývají často vytvořeny na aplikačním serveru, ve kterém je většinou JMS server už obsažen. Pokud naše aplikace používá např. JMS fronty, musí je “někdo” na daném JMS serveru vytvořit. Ten někdo je na vývojovém a někdy i testovacím prostředí vývojář, na dalších prostředích už to bývá administrátor.

Podle daného aplikačního serveru se JMS zdroje dají buď naklikat v nějaké administrátorské konzoli, nebo je potřeba poeditovat/vytvořit nějaké konfigurační soubory. Třetí možností je tyto  zdroje nějakým nástrojem naskriptovat. V případě aplikačního serveru WebLogic je takovým nástrojem WebLogic Scripting Tool (WLST).

Jak už jsem psal v minlém zápisku o mazání dat z MDS, WLST je v Jythonu napsaný nástroj pro správu WebLogic serveru, který funguje ve dvou režimech - offline a online. V online režimu se WLST připojuje k běžícímu WebLogicu a operuje nad stromem jeho MBeans. Pro správu JMS zdrojů je potřeba používat WLST online.

Distributed Queue

Věc, kterou jsem potřeboval vyřešit, bylo vytvoření distribuované fronty ve WebLogicovém clusteru. Cluster byl velmi jednoduchý - admin server a dva nody (managed servery). Vzhledem ke clusteru bylo potřeba vytvořit logickou frontu, která by měla stejný JNDI (jako na vývojovém prostředí s jedním nodem) a zastřešovala by fronty na jednotlivých nodech. Na WebLogicu je toto řešeno distribuovanými destinacemi (queue/topic). Pokud si to neumíte představit, distribuovaná fronta funguje v podstatě jako klasický load balancer.

Distribuovaná fronta (WebLogic Administration Console)

Členové distribuované destinace (WebLogic Administration Console)

WLST a JMS

Použití WLST je po krátké praxi poměrně intuitivní a jednoduché. Zpočátku může dělat problém se orientovat ve struktuře (stromech) MBean. V tomto může napomoci celkem slušná dokumentace: navigace MBeans, Javadoc a MBean reference. Pak už stačí jenom lehké základy Pythonu.

V následujícím skriptu je několik věcí, které můžou trochu ztížit čtení/pochopení skriptu, takže ještě kratičká legenda:
  • Target. Cílové umístění zdroje, nebo aplikace, např. server, cluster, JMS server ad. V případě deploymentu (aplikace) tím říkám, na které nody/clustery chci aplikaci nasadit.
  • SubDeployment. Mechanismus pro seskupení a umístění JMS zdrojů. V rámci subdeploymentu říkám, na které cíle (targets) chci dané zdroje nasadit. Může to být libovolná kombinace, nebo podmnožina.
  • cmo. Proměnná, která reprezentuje “aktuálně spravovaný objekt” (current management object). Je to vlastně MBeana, která má momentálně “focus”. Tak, jak se prochází stromem MBean, tak se tato proměnná automaticky mění.

# properties
user = ‘weblogic’
password = ’<password>’
server = ‘t3://<host>:7001’
subDeploymentName = ‘EVMJMSServers’
queuePath = ‘JMSResource/SOAJMSModule/UniformDistributedQueues/’
queueName = ‘EVM_DLQ’
jndiPrefix = ‘jms/b2b/’
loadBalancing = ‘Round-Robin’

# connection
connect(user, password, server)

# edit mode
edit()
startEdit()

# get targets
s1 = getMBean(’/JMSServers/SOAJMSServer_auto_1’)
s2 = getMBean(’/JMSServers/SOAJMSServer_auto_2’)

#
# create a SubDeployment
#
cd(’/JMSSystemResources/SOAJMSModule’)
# delete an old SubDeployment
if cmo.lookupSubDeployment(subDeploymentName):
delete(subDeploymentName, ‘SubDeployment’)
# create a new SubDeployment
cmo.createSubDeployment(subDeploymentName)
subDeployment = cmo.lookupSubDeployment(subDeploymentName)
subDeployment.setTargets([s1, s2])

#
# create a ldistributed queue
#
resource = cmo.getJMSResource()
# delete an old queue
ref = getMBean(queuePath + queueName)
if ref != None:
cd(‘JMSResource/SOAJMSModule’)
delete(queueName, ‘UniformDistributedQueue’)
# create a new queue
resource.createUniformDistributedQueue(queueName)
distributedQueue = resource.lookupUniformDistributedQueue(queueName)
distributedQueue.setJNDIName(jndiPrefix + queueName)
distributedQueue.setLoadBalancingPolicy(loadBalancing)
distributedQueue.setSubDeploymentName(subDeploymentName)

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

Související články

Odstranění metadat z MDS

·2 min
Dneska to bude jedna praktická. Aneb jak v SOA Suite smazat z MDS (MetaData Store) nějaká metadata, soubory nebo adresář. Práce s MDS není z počátku úplně intuitivní, dokumentace není úplně jednoduše k nalezení a informace aby člověk vyškrabával z různých blogů a fór.

Tak, jak na to. Možnosti jsou dvě. Jednak použít WLST, nebo Ant skript, který je součástí SOA Suite (ten ale umožní pouze smazání adresáře).

WLST

WebLogic Scripting Tool (WLST) je zajímavý, v Jythonu napsaný, nástroj na administraci WebLogic serveru. Lze s ním pracovat dvěma způsoby: offline a online. Bohužel, s ohledem na MDS, je potřeba pro mazání souborů použít online způsob a pro smazání adresáře naopak offline (a také se používají dvě různé funkce). WLST zpravidla najdeme v adresáři <ORACLE_HOME>/oracle_common/common/bin.

Smazání souboru

Pro smazání jednoho a více souborů lze použít příkaz deleteMetadata. Vzhledem k tomu, že se tento příkaz používá online, je potřeba se prvně připojit k WebLogic administračnímu serveru. A po zadání mazacího příkazu se zase odpojit.
connect('weblogic', '<password>', 't3://<AdminServer>:7001')
deleteMetadata(
application='soa-infra',
server='soa_server1',
docs='/apps/<pathToFile>/DeadLetterQueue-v1.0.wsdl')
disconnect()
exit()


Smazání adresáře

Pro smazání adresáře slouží offline příkaz sca_removeSharedData. Problém s tímhle příkazem je, že není součástí standardních WLST modulů, ale je součástí instalace SOA Suite. Proto aby fungoval, je potřeba spustiti WLST z odpovídajícího adresáře: <ORACLE_HOME>/Oracle_SOA1/common/bin.

Dalším rozdílem je, že se nezadává cesta k administrativnímu serveru, ale ke spravovanému (managed) serveru, na kterém MDS běží.
sca_removeSharedData(
'http://<ManagedServer>:8001',
'public/evm/iface/DeadLetterQueue-v1',
'weblogic', '<password>')



Ant

Součástí instalace vývojového prostředí pro SOA Suite (JDeveloper) je i sada Ant skriptů mmj. pro buildování, (unit) testování a deployment. A také pro smazání adresáře z MDS. Tímto způsobem nejde mazat jednotlivé soubory.

Soubory se dají najít v adresáři <ORACLE_HOME>/jdeveloper/bin.
ant -f ant-sca-deploy.xml removeSharedData
-DserverURL=<ManagedServer>
-DfolderName=<pathToFolder>
-Duser=<user>
-Dpassword=<password>

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