Follow Us on Twitter

Gegevensverrijking in Oracle SOA Suite

Gepubliceerd in

November 2010 - Gegevensverrijking behoort tot één van de verantwoordelijkheden van een adapter (verbindingscomponent): Validatie - Gegevensverrijking - Transformatie. Verrijken heeft betrekking op het toevoegen van gegevens aan een bericht zodat deze betekenisvoller is voor een service of doelapplicatie. In de praktijk blijkt het lastig om gegevensverrijking op de juiste manier toe te passen. Dit komt omdat het aanmaken en vullen van mapping tabellen als omslachtig wordt ervaren en de noodzaak ervan niet direct aanwezig is. Dit is met name het geval als de interface is ontworpen met één afnemer in gedachte (rechtstreekse koppeling). Vaak ook is het een kwestie van gemakzucht. Het op de juiste manier toepassen van verrijking is niet moeilijk. Deze Whitebook gaat over gegevensverrijking in Oracle SOA Suite, het nut ervan en hoe het gebruikt dient te worden.

Volgens de SOA-gedachte zijn de service objecten in de integratie laag losgekoppeld van applicaties. Dit betekent onder andere dat deze objecten geen waarden mogen bevatten die specifiek zijn voor een bepaalde applicatie. Deze loskoppeling zorgt ervoor dat een leverende applicatie te vervangen is door een andere applicatie. Alle applicaties dienen hun informatie naar dezelfde objecten te vertalen. Een manier om applicatie-specifieke waarden om te zetten naar applicatie-onafhankelijke waarden is door middel van gegevensverrijking.

Lang niet altijd is het direct duidelijk of een element een waarde bevat die specifiek is voor een bepaalde applicatie. Daar komt men pas naderhand achter. Statussen en sleutels die voor identificatie worden gebruikt zijn vaak overduidelijk applicatie specifiek. Maar ook er zijn ook andere eigenschappen waarvoor gegevensverrijking moet worden toegepast: alle informatie die nodig is om een bericht compleet te maken maar die niet (in eerste instantie) worden geleverd door de bronapplicatie.

Er zijn verschillende technieken om gegevensverrijking te bewerkstelligen:

  • Domain Value Maps - statische mapping
  • Cross Reference Tables - dynamische mapping
  • Services - functies die objecten terug geven aan de hand van invoer parameters

 

Domain Value Maps

Als in een interface twee applicaties voor een bepaald element dezelfde waarden worden gebruikt lijkt het omslachtig om deze eerst naar een applicatie-onafhankelijke waarde te vertalen. Doordat men bij het ontwerp van een interface al weet welke applicatie afnemer is van de informatie wordt vaak voor de eenvoudige weg gekozen. Het is namelijk veel eenvoudiger om de waarde te kopiëren:

<xsl:value-of select="/serviceObject/value"/>
App_A App_B
Y Y
N N

In dit geval gebruiken beide applicaties toevallig dezelfde waarde voor een bepaald element. Dit blijft goed gaan zolang deze koppeling beperkt blijft tot deze twee applicaties en er niets wijzigt in de applicaties. Echter, een probleem ontstaat op het moment er een derde applicatie bij komt die een andere code nodig heeft.

App_A App_B App_C
Y Y 1
N N 0

Welke waarde moet er nu in het service object worden gebruikt? Meestal wordt er gekozen voor een <choose> constructie:

<xsl:choose>
   <xsl:when test="/inp1:Person/isCustomer = 'Y'">1</xsl:when>
   <xsl:when test="/inp1:Person/isCustomer = 'N'">0</xsl:when>
</xsl:choose>

Dit kan acceptabel zijn zolang het aantal verschillende waarden te overzien is. Als er echter meerdere waarden bijkomen wordt deze constructie onoverzichtelijk en wordt de kans op fouten groter. Een ander bezwaar aan deze constructie is dat de waarden ‘hard’ gecodeerd zijn. Dus als er iets wijzigt, dan moet deze wijziging in alle transformaties worden aangebracht.

Een betere oplossing is om de mapping van deze waarden in een tabel te stoppen. In Oracle SOA Suite is functionaliteit toegevoegd genaamd Domain Value Maps. Middels een web-interface is een dergelijke DVM tabel te creëren en te vullen.

App_A App_B App_C Common
Y Y 1 true
N N 0 false

De kolom Common bevat de waarde zoals deze in het service object terecht komt. Voor de transformatie bestaan er XPath functies. Het ophalen van een waarde ziet er als volgt uit:

<xsl:value-of select="orcl:lookup-dvm ('Status_Code','App_B',/inp1:Person/Status,'Common','')"/>

Een DVM is voornamelijk geschikt voor element- en attribuutwaarden waarop nauwelijks mutaties plaatvinden, zoals statussen, landcodes, afkortingen voor eenheden. Hieronder een voorbeeld van een mapping van status codes:

App_A App_B App_C Common
A Active 1 status_open
I Inactive 3 status_inactive
R Deleted 2 status_removed
T Discontinued 4 status_terminated

Bij een DVM is niet mogelijk om vanuit een BPEL process of ander component nieuwe waarden toe te voegen aan een mapping. Het is wel mogelijk om via de beheer console waarden toe te voegen aan een tabel. Deze wijzigingen zijn dan direct beschikbaar. Als er voortdurend objecten bijkomen en verdwijnen zijn Cross Reference Tables beter geschikt.

Cross Reference Tables

Cross Reference Tables (XRef) worden voornamelijk gebruikt voor het vertalen van primaire sleutels. Primaire sleutels zijn vaak nodig om een object is te uniek te identificeren. Deze identificatie geldt vaak alleen voor één applicatie; de sleutel van bijvoorbeeld een klant heeft in applicatie A een andere sleutel als in applicatie B.

App_A App_B Common
213 4235 9b946206-f2f8-45e0-9b2b-c0fb63a7c599
214 4567 51eb8a09-d95f-4875-94ad-a0db86cd4e73

Net als DVM is XRef geen standaard Java EE functionaliteit, maar een feature die door Oracle is toegevoegd aan SOA Suite. Voor XRef bestaan ook een aantal XPath functies waarmee waarden kunnen worden toegevoegd, opgehaald en verwijderd. Hieronder een fragment voorbeeld code om een waarde op te halen:

<xsl:value-of select="xref:lookupXRef('Customer_ID','App_A',/inp1:Person/Status, 'Common', true())"/>

De common waarde wordt meestal gevuld met een gegenereerde GUID die in geen van de applicaties een betekenis heeft en is daarmee applicatie-onafhankelijk. Deze GUID wordt alleen gebruikt om een relatie tussen de verschillende sleutels aan te geven.

In principe hoeft er voor XRef geen onderhoud plaats te vinden. Een XRef tabel wordt door de componenten in de integratielaag actueel gehouden. In Create-adapters worden rijen in een XRef tabel aangemaakt en in Delete-adapters worden rijen verwijderd. Onderstaand voorbeeld illustreert het gebruik van XRef aan de hand van een aantal Application Integration Architecture (AIA) scenario's:

XRef populate scenario
Vullen van XRef (populate):
1. Bronapplicatie verstuurt details van nieuw aangemaakt object.
2. Primaire sleutel van bronapplicatie wordt opgeslagen in XRef tabel m.b.v. populate functie. De Common waarde wordt gegenereerd. Deze Common waarde wordt doorgegeven aan de business of entitity service.
3. Object wordt aangemaakt in de doelapplicatie.
4. De synchrone service retourneert de primaire sleutel van het object in de doelapplicatie.
5. De primaire sleutel van doelapplicatie wordt toegevoegd aan de XRef tabel en gekoppeld aan de Common waarde.

XRef lookup scenario
Verrijken met behulp van XRef (lookup):
6. Bronapplicatie verstuurt de details van een gewijzigd object.
7. Met behulp van de XRef lookup functie wordt de Common waarde opgehaald uit de XRef tabel.
8. In de adapter van de doelapplicatie wordt de primaire sleutel opgehaald van het object in de doelapplicatie.
9. De primaire sleutel van de doelapplicatie wordt meegestuurd naar de doelapplicatie.

XRef mark for delete scenario
Verwijderen uit XRef (mark for delete):
10. Bronapplicatie verstuurt de primaire sleutel van een te verwijderen object.
11. De Common waarde wordt opgehaald en de primaire sleutel van doelapplicatie wordt uit de XRef tabel verwijderd.
12. De primaire sleutel van doelapplicatie wordt uit de XRef tabel opgehaald.
13. Het object wordt uit de doelapplicatie verwijderd.
14. De primaire sleutel van de doelapplicatie wordt uit de XRef tabel verwijderd.

XRef ondersteunt het gebruik van één-op-meer relaties: een waarde in 1 applicatie wordt vertaald naar meerdere waarden in een andere applicatie. De mapping hiervan levert dus in één richting één waarde op maar kan in de andere richting een array met meerdere waarden opleveren. Een waarschuwing bij het toepassen van één-op-meer relaties is hier wel op zijn plaats. In de praktijk levert deze vorm van XRef complexe situaties op. Welke waarde moet je kiezen als er meerdere mogelijkheden zijn? Daarom is het is beter om één-op-meer relaties te vermijden. Hou de vertaling zo simpel en eenduidig mogelijk.

Services

Sommige integratie architecten vinden dat een ESB geen data mag bevatten. Als men dit principe volgt dan moeten gegevens voor verrijking uit een externe bron komen. Aangezien zowel XRef en DVM gegevens opslaan op de ESB server (althans op de database van de ESB server), moet een andere manier gebruikt worden om deze gegevens op te halen en op te slaan. Dit kan middels services. Services zijn componenten die functies aanbieden die gegevens retourneren voor invoer parameters. Een component die een services levert kan uitgevoerd zijn als een BPEL proces, database adapter, etc.

Het nadeel van services is dat ze niet in een (XSL) transformatie gebruikt kunnen worden. Ze moeten als in aparte (BPEL) stappen uitgevoerd worden en de retourwaarde moet in afzonderlijke stappen aan de XML worden toevoegd. Het gevolg is dat de BPEL processen vaak behoorlijk complex kunnen worden. While - Assign - Invoke - Assign. Het zou veel gemakkelijker is om gebruik te maken van specifieke XPath functies (zoals dit het geval is bij XRef en DVM). Hiermee kunnen alle vertalingen in de XSL transformatie plaatsvinden.

Een service kan een wrapper om een SQL query of stored procedure aanroep zijn. Bijvoorbeeld om een straatnaam en/of plaatsnaam te bepalen voor een bepaalde postcode / huisnummer combinatie:

Postcode Straat Huisnummer vanaf Huisnummer tot Even Plaatsnaam
3543GT Miles Davisstraat 151 295 false Utrecht
3439NE Fultonbaan 2 84 true Nieuwegein

Het contract van de service die gebruik maakt van bovenstaande tabel kan er als volgt uitzien:

<definitions ... >
  <types>
    <schema ... >

      <element name="QueryPostcode">
        <complexType>
          <sequence>
            <element name="postcode" type="string"/>
            <element name="huisnummer" type="int"/>
          </sequence>

        </complexType>
      </element>
      <element name="QueryPostcodeResponse">
        <complexType>
          <sequence>
            <element name="straat" type="string"/>

            <element name="plaatsnaam" type="string"/>
          </sequence>
        </complexType>
      </element>
    </schema>
  </types>

  <message name="QueryPostcodeRequestMsg">
    <part name="payload" element="tns:QueryPostcode"/>
  </message>
  <message name="QueryPostcodeResponseMsg">
    <part name="payload" element="tns:QueryPostcodeResponse"/>
  </message>

  <portType ... >
    <operation name="query">
      <input message="tns:QueryPostcodeRequestMsg"/>
      <output message="tns:QueryPostcodeResponseMsg"/>
    </operation>
  </portType>

  ... 
</definitions>

Anders dan in BPEL kan in Oracle Service Bus (OSB) wel verrijking met behulp van een service in 1 stap plaatsvinden. OSB biedt verschillende manieren om gegevens te op te halen: middels web services, databases of Java code. Omdat OSB geen tijdelijke variabelen kent is het niet zo geschikt als de gegevens uit verschillende bronnen komen of wanneer er complexe logica nodig is. In deze gevallen biedt BPEL meer mogelijkheden.

Beslissingstabel

Wanneer gebruik je wat? In onderstaande tabel laat zien wanneer welke technologie gebruikt kan worden.

  DVM XRef Service
Vertaling van statische waarden (codes, afkortingen)? Ja Nee Nee
Vertaling van dynamische waarden (primaire sleutels)? Nee Ja Ja
Is het toevoegen van een waarde aan de mapping mogelijk vanuit een BPEL proces? Nee Ja Ja
Verrijking van gegevens die afhankelijk zijn van meerdere parameters? Nee Nee Ja
Te gebruiken in een SCA Mediator? Ja Ja Nee
Te gebruiken in een BPEL proces? Ja Ja Ja
Te gebruiken in AIA? Ja Ja Ja
Te gebruiken in OSB? Nee(*) Nee(*) Ja

(*) Volgens de blog van Chris Tomkins komen DVM en XRef beschikbaar in OSB 11gR2, zie referenties.

Conclusie

DVMs en XRefs zijn zeer nuttig voor het verrijken van gegevens en zijn bovendien eenvoudig in gebruik. De broncode blijft netjes. Als er principiële bezwaren bestaan om mapping-gegevens op te slaan op de ESB kan er gebruik worden gemaakt van services. Bij services worden de gegevens in een applicatie ondergebracht. Services dienen ook te worden toegepast wanneer XRefs en DVMs niet toereikend zijn.

Bedenk goed wanneer je welke manier toepast. Misbruik deze technieken niet voor dingen waar ze niet voor bedoeld zijn. Persoonlijk ben ik geen voorstander van het samenvoegen (concateneren) van verschillende waarden om op deze manier een lookup mogelijk te maken. Als een waarde afhankelijk is van meerdere parameters gebruik dan een service en geen DVM of XRef. Het is goed om principieel te zijn bij de keuze van verrijkkingsmethode.

Tenslotte wil ik benadrukken dat DVM en XRef functionaliteit alleen bestaan in Oracle SOA Suite. Als je geen gebruik kunt of wil maken van Oracle SOA Suite en toch DVM en/of XRef functionaliteit zou willen, kun je nog altijd zelf proberen om XPath functie extensies te programmeren (bijvoorbeeld met behulp van de Saxon XSLT libraries). Persoonlijk vind ik het wel zo prettig als deze functionaliteit ’out-of-the-box’ beschikbaar is.

Referenties

Waardering:
 

Reacties

Nieuwe reactie inzenden

De inhoud van dit veld is privé en zal niet openbaar worden gemaakt.

Meer informatie over formaatmogelijkheden

CAPTCHA
Deze vraag is om te testen of u een persoon bent en om spam te voorkomen
Image CAPTCHA
Enter the characters shown in the image.