De WSO2 Enterprise Integrator is een Enterprise Service Bus waarin berichtbemiddeling en -transformatie mogelijk is om systemen te kunnen verbinden. Een belangrijk onderdeel in de flow van berichten door de WSO2 EI is de zogenoemde message context, die ook wel Synapse Message Context wordt genoemd. Deze message context is de omgeving waarin het bericht zit, waardoor we bij het bericht kunnen komen om het te kunnen manipuleren. Die manipulatie kan op verschillende manieren gedaan worden. Daarvoor bekijken we de volgende manieren:
- Met regular mediation
- Vanuit een script mediator
- Vanuit Java
Regular Mediation
Regular mediation geeft ons de mogelijkheid om de message context aan te passen. In WSO2 kunnen we mediators zoals een ‘payload factory mediator’ gebruiken om de payload van de berichttekst te vervangen. Later zullen we ons richten op de properties en andere manieren om de message context te manipuleren.
Vanuit een script mediator
Een script mediator kan gezien worden als onderdeel van regular mediation, omdat het een van de standaard mediators is in de Enterprise Integrator. Het is echter flexibeler, omdat het verschillende soorten scripttalen, zoals JavaScript, Groovy en Ruby, ondersteund.
Synapse gebruikt het Apache Bean Scripting Framework als ondersteuning voor scripttalen. Met de Script Mediator kun je een functie aanroepen in het overeenkomstige script. Met deze functies is het mogelijk om toegang te krijgen tot de Synapse message context die voorgedefinieerd is in een scriptvariabele mc. De mc-variable is een ScriptMessageContext die beperkte toegang geeft tot de MessageContext. Deze variabele bevat de volgende methodes die binnen het script toegankelijk zijn met mc.[methodName], bijvoorbeeld getPayloadXML() die een XML representatie van een SOAP Body payload ophaalt.
Het werken met een script mediator is makkelijker dan een met Class mediator die in Java geschreven is. Dat is onze volgende mogelijkheid.
Vanuit Java
Natuurlijk hebben we ook vanuit Java controle over de message context from. WSO2-producten zijn in Java geschreven, dus via de juiste classes, bijv. org.apache.synapse.MessageContext, is de message context toegankelijk. Omdat een Custom mediator of Class mediator vereist dat er een .jar aan de Enterprise Integrator wordt toegevoegd en vaak om een reboot vraagt, is dit een lastigere aanpak. De voordelen zijn echter de flexibiliteit en de meer gedetailleerde manipulatie en verwerking van de berichten. Het is aan te raden om geen functies te implementeren die in toekomstige versies van het project niet ondersteund worden.
Focus op regular mediation
We richten ons daarom op regular mediation en beschrijven de mogelijkheden die we hebben als met de kant-en-klare beschikbare functies werken. We kijken naar het deel waar het bericht binnen de EI is en laten de in- en outflow van het bericht buiten beschouwing.
Sommige mediators zijn content aware. Dat houdt in dat ze toegang hebben tot de message context of die kunnen manipuleren. Ander mediators zijn content unaware, denk aan de send mediator die simpelweg het teken geeft om een bericht te verzenden. Weer andere zijn onder voorwaarden content aware/unaware. Een <log/> mediator is unaware, terwijl een <log level=”full”/> de inhoud van het bericht uitleest om in de console af te drukken en is daarom content aware. De meeste mediators zijn (voorwaardelijk) content aware, omdat bemiddeling en transformatie het doel zijn. Maar wat is nu het verschil tussen Message Content en Message Context? Vanwege het feit dat er maar één letter verschil in zit, kan het wat verwarrend zijn. De Message Context bevat de metadata die met het bericht meekomt. De context heeft de controle over hoe de transformation engine, Synapse, en het transport framework, Axis2, zich gedragen.
De berichttekst (Message content) is het daadwerkelijke bericht dat door het product ontvangen, getransformeerd en verzonden wordt. De berichttekst wordt ook wel message body genoemd.
Properties
We gaan nu kijken naar de instelling van properties en de manipulatie door xpath variabelen te gebruiken, zoals $body. Er zijn een aantal basisproperties die we in kunnen stellen. Dat zijn:
Synapse Message Context Properties: Hiermee kun je informatie krijgen over het bericht, zoals de datum/tijd waarop het verzonden werd, het formaat van het bericht en de message operation.
SOAP Headers: Biedt informatie over het bericht, zoals de To- en From-values. Deze waarden komen ook voor in de lijst met Synapse Message Context Properties.
Generic Properties: Geven je de mogelijkheid om berichten te configureren alsof ze verwerkt zijn door het ESB-profiel, zoals het markeren van een bericht als out-only (er wordt geen responsbericht verwacht). Dit gaat meer over het management van het bericht.
HTTP Transport Properties: Hiermee kun je instellen hoe het HTTP berichten verwerkt, zoals het afdwingen van een 202 HTTP-respons naar de client, zodat die stopt met wachten op een respons. Dit gaat opnieuw over het transport van het bericht.
Axis2 Properties: Hiermee kun je de web services engine in het ESB-profiel instellen, waaronder de specificatie van hoe JMS-objecten te cachen, het minimale en maximale aantal threads voor consuming messages, en het afdwingen van uitgaande HTTP/S-berichten om HTTP 1.0 te gebruiken. Deze properties hebben te maken met de web engine Axis2.
Get-property
De get-property() functie geeft de mogelijkheid om iedere XPath-expressie die in een configuratie gebruikt wordt om informatie van de huidige message context op te vragen. Door de Property mediator te gebruiken kun je properties van de message context, message content, message header, maar ook variabelen van de systeemomgeving en de registry uit te lezen.
Let op: het is aan te raden om de Synapse XPath Variabelen te gebruiken als ze in jouw scope beschikbaar zijn. Het gebruik van de Synapse XPath Variabelen is minder belastend op de systeembronnen. We zullen dit later bij de Shortcuts bespreken.
De syntax van de functie krijgt de volgende vorm:
- get-property(String propertyName)
- get-property(String scope, String propertyName)
Het instellen en uitlezen van een property (‘Test’) ziet er als volgt uit:
<property name="Test" scope="default" type="STRING" value="sample value"/>
<log level="custom">
<property expression="get-property('Test')" name="Value via get-property"/>
</log>
Op de console geeft dat deze output:
[2021-04-21 11:07:52,495] INFO {org.apache.synapse.mediators.builtin.LogMediator} – Value via get-property = sample valueScopes
De functie accepteert scope als een optionele parameter. Het haalt een message property op in de opgegeven scope. Dat kan één van de volgende zijn:
Synapse scope | Synapse of Default scope (wanneer weggelaten) |
axis2 | Wanneer de scope van een property axis2 is, dan is de waarde alleen beschikbaar binnen de sequentie waarvoor de property gedefinieerd is. |
axis2-client | Dit is vergelijkbaar met de synapse scope. Het verschil is dat het toegankelijk is binnen de mediate() methode van een mediator. |
transport | Als de scope van een property mediator transport is, zal het toegevoegd worden aan de transport header van het uitgaande bericht vanuit het ESB-profiel. |
registry | Je kunt properties uit de registry uitlezen. |
system | Je kunt Java Systeemproperties uitlezen. |
operation | Deze scope is beschikbaar zolang de operation actief is. Je kunt het ook gebruiken om informatie over te schrijven van en naar een iterate/aggregate mediator. |
default | Als er geen specifieke scope gedefinieerd is, dan wordt de default scope toegepast. Deze staat ook bekend als de Synapse scope. |
Als je alleen de naam van een property opgeeft zonder de scope, zal de default scope gebruikt worden.
Shortcuts
We hebben verschillende zogenoemde shortcuts, of XPath variabelen zoals WSO2 ze noemt, die ons de mogelijkheid geven om het Synapse command ‘get-property’ over te slaan. Er is een set voorgeprogrammeerde XPath-variabelen die je direct kunt gebruiken om access areas van de Message Context of Message Content te schrijven. Deze XPath variabelen hebben de volgende werking op properties van de verschillende scopes:
$body | De berichttekst. Bijvoorbeeld: de uitdrukking $body//getQuote verwijst naar het eerste getQuote-element in een SOAP body |
$header | Het SOAP 1.1 of 1.2 header-element. Bijvoorbeeld: de uitdrukking $header/wsa:To verwijst naar de adresserende To header |
$axis2 | Prefix voor Axis2 MessageContext properties. Dit wordt gebruikt om de waarde van de property in de axis2 scope op te vragen |
$ctx | Prefix voor Synapse MessageContext properties en haalt een property op in de default scope |
$trp | Prefix die gebruikt wordt om de transport headers uit te lezen. Bijvoorbeeld: om de transport header met de naam Content-Type van het huidige berichten te lezen, gebruik je de XPath uitdrukking: $trp:Content-Type |
$url | De prefix die gebruikt wordt voor het URI-element van een URL |
$func | De prefix die gebruikt wordt om te verwijzen naar een specifieke parameterwaarde die extern door een invoker, zoals de Call Template Mediator, doorgegeven wordt. |
$env | Prefix gebruikt voor een SOAP 1.1 of 1.2 envelope level element |
Een voorbeeld
Wat kunnen we met al deze informatie? Dat kunnen we het beste met een voorbeeld duidelijk maken.
We hebben een eenvoudige proxy die het volgende XML-bericht ophaalt:
<VatNumbers xmlns="http://yenlo.com/blog">
<VatNumber>
<country>AT</country>
<vat>U34275908</vat>
</VatNumber>
<VatNumber>
<country>BE</country>
<vat>98235273941</vat>
</VatNumber>
<VatNumber>
<country>DE</country>
<vat>432256432</vat>
</VatNumber>
</VatNumbers>
De broncode van de proxy spreekt voor zich en is simpel gehouden:
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="mcExample" startOnLoad="true" transports="http https"
xmlns="http://ws.apache.org/ns/synapse"
xmlns:ns="http://yenlo.com/blog">
<target>
<inSequence>
<log level="custom">
<property name="Value" expression="$body//ns:VatNumbers" /> <!-- #1 -->
</log>
<property name="Test" value="sample value"/>
<log level="custom">
<property name="Content Type via $trp" expression="$trp:Content-Type" /> <!-- #2 -->
<property name="Value via get-property" expression="get-property('Test')" /> <!-- #3 -->
</log>
<foreach expression="$body//ns:VatNumber">
<sequence>
<log level="custom">
<property name="Country" expression="$body//ns:country" />
</log>
</sequence>
</foreach>
<respond/>
</inSequence>
</target>
</proxy>
In regel #1 krijgen we toegang tot de berichttekst en verwijzen we naar alle elementen in VatNumbers in het bericht.
In regel #2 krijgen we toegang tot een transport-header, het HTTP Content-Type om precies te zijn en loggen die.
In regel #3 gebruiken we de functie get-property om bij de waardes van de Test property te komen.
In de foreach mediator wordt laten zien dat $body naar andere delen van de berichttekst verwijst, afhankelijk van de situatie waarin het gebruikt wordt.
Als we het bericht in de proxy verzenden en kijken naar wso2carbon.log, kunnen we deze Message Context voorbeelden in actie zien (opgeschoond voor betere leesbaarheid):
[2021-04-21 11:43:35,195] INFO {org.apache.synapse.mediators.builtin.LogMediator} –Value = <VatNumbers xmlns=”http://yenlo.com/blog”><VatNumber><country>AT</country><vat>U34275908</vat></VatNumber><VatNumber><country>BE</country><vat>98235273941</vat></VatNumber><VatNumber><country>DE</country><vat>432256432</vat></VatNumber></VatNumbers>, Content Type via $trp = text/xml; charset=UTF-8,
Value via get-property = sample value
[2021-04-21 11:43:35,196] INFO {org.apache.synapse.mediators.builtin.LogMediator} – Country = AT
[2021-04-21 11:43:35,196] INFO {org.apache.synapse.mediators.builtin.LogMediator} – Country = BE
[2021-04-21 11:43:35,197] INFO {org.apache.synapse.mediators.builtin.LogMediator} – Country = DE
In de laatste drie regels van de log zien we dat $body nu verwijst naar één element in VatNumber, omdat de foreach door al deze elementen heen loopt.
Conclusie
Deze blog legt uit op welke manieren de Message Context en de Message Content te manipuleren zijn. Er zijn mediators in de WSO2 Enterprise Integrator ingebouwd die gebruikt kunnen worden om zowel de message context als de message content te manipuleren, maar er kunnen ook speciale mediators ontwikkeld worden als de ingebouwde mediators niet voldoen.
Er zijn verschillende manieren om toegang te krijgen tot delen van de Message Context en Message content en er bestaan verschillende XPath variabelen om die toegang te krijgen. Enkele van deze worden getoond in een voorbeeld proxy.
Toegang krijgen tot de message context is makkelijk met de $-variabelen die gedefinieerd zijn in de Enterprise Integrator. We kunnen snel informatie opvragen, bijvoorbeeld uit de berichttekst.
Succes met integreren!