The example will show how
- to serialize a tree into BLOB using ESQL
- how to send a mail with attachment
- How to create/prepare the LocalEnvironment and Root for the EmailOutput node
- The usage of the business event capabilities provided by IIB
The principle is simple:
- Configure a flow to generate an IIB event
- Create a subscription to this event with a WMQ Queue as endpoint
- Create a flow that consumes these events and send an email with attachments
The example in this post shows how to create mail with attachments using ESQL but this could be easily made using Java as well.
Configure a flow to generate an IIB event
The event generated as a well defined structure and the schema can be imported into a library using new model -> IBM predefined model.
Any nodes in a flow can be configured to generate events (Generating events in WebSphere Message Broker) that may contain context information and payload.
It is for example possible to configure a node to include the localEnvironment, ExceptionList and Message tree structure (under Root). These information will be placed into the IIB events under the folder "complexContent".
Note that the LocalEnvironment is reset when an exception occurs, so the data that would have been stored in this tree would be wiped when the message is propagated to the catch terminal of the input node (will be covered in a future post).
Finally it is also possible to include the full payload (as it was received) by selecting in the monitoring node properties "include payload as bitstream". The payload will then be included into the IIB events under "BistreamData".
Create a subscription
The IIB runtime is publishing the IIB events on the WMQ topic "$SYS/Broker/IBMIBus/Monitoring/#".
Using the WMQ Explorer you create a subscription to these events and select a destination queue:
The flow that sends email
The flow is very simple: MQInput -> ComputeNode -> EmailOutput node
The compute node is used to create and configure the message that will be send using the emailoutput node.
The node it self is configured the minimum properties: server:port, email to, from and security.
The rest will be provided by the code in ESQL (subject, body content and attachments).
In this example the complexContent included in the incoming business event is serialized into bitstream and will be send by mail as attachment.
The payload if present is also send as attachment.
The body of the mail is made of event origin data and using a DFDL to have a text document separated with CRLF.
The code is provided here after:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CALL CopyMessageHeaders(); | |
-- CALL CopyEntireMessage(); | |
/* | |
emailoutput node requires the following (with attachments): | |
- LocalEnvironment->Destination->Email->Attachment | |
-- Attachment -> Content (BLOB)/ContentType (CHAR)/ContentName(CHAR)/ContentEncoding (CHAR) | |
- Root -> EmailOutput -> Subject (if you would like to be overriden at runtime | |
- Root -> BLOB (this is the actual body of the mail | |
*/ | |
-- Create the LocalEnvironment folders | |
DECLARE ptrMail REFERENCE TO OutputLocalEnvironment; | |
CREATE LASTCHILD OF ptrMail AS ptrMail TYPE Name NAME 'Destination'; | |
CREATE LASTCHILD OF ptrMail AS ptrMail TYPE Name NAME 'Email'; | |
DECLARE ptrAttachment REFERENCE TO ptrMail; | |
-- Get the information from the broker events | |
DECLARE ptrEvents REFERENCE TO InputRoot.XMLNSC.ns:event.ns:applicationData.ns:complexContent; | |
WHILE LASTMOVE(ptrEvents) DO | |
CREATE LASTCHILD OF ptrMail AS ptrAttachment TYPE Name NAME 'Attachment'; | |
SET OutputRoot.XMLNSC.Data = ptrEvents; | |
-- Content has to be BLOB to be taken as an attachment. | |
-- Serialize the broker event payload available as complexContent | |
SET ptrAttachment.Content = ASBITSTREAM(OutputRoot.XMLNSC.Data OPTIONS FolderBitStream); | |
SET ptrAttachment.ContentType = 'text/xml'; | |
-- Specify the attanchment name | |
SET ptrAttachment.ContentName = ptrEvents.ns:elementName; | |
-- Set as binary | |
SET ptrAttachment.ContentEncoding = 'binary'; | |
DELETE FIELD OutputRoot.XMLNSC; | |
-- move to the next complexContent | |
MOVE ptrEvents NEXTSIBLING REPEAT NAME; | |
END WHILE; | |
MOVE ptrEvents TO InputRoot.XMLNSC.ns:event.ns:bitstreamData.ns:bitstream; | |
IF LASTMOVE(ptrEvents) THEN | |
-- If there is the bitstream available, send it over as attachment | |
CREATE LASTCHILD OF ptrMail AS ptrAttachment TYPE Name NAME 'Attachment'; | |
--bitstream is base64 encoded, so first we need to decode it | |
-- ** the node allows to encode the data in Base64, it doesn't allows to provide a already base64 data though | |
SET ptrAttachment.Content = | |
BASE64DECODE(InputRoot.XMLNSC.ns:event.ns:bitstreamData.ns:bitstream); | |
SET ptrAttachment.ContentType = 'text/plain'; | |
SET ptrAttachment.ContentName = 'payload'; | |
-- ask the node to convert it into Base64 | |
SET ptrAttachment.ContentEncoding = 'Base64'; | |
END IF; | |
-- Set the subject | |
SET OutputRoot.EmailOutputHeader.Subject = 'Mail Service info'; | |
-- In order to have a pretty message layout, a DFDL is used with CRLF terminator. | |
SET OutputRoot.Properties.MessageFormat = 'DFDL'; | |
SET OutputRoot.Properties.MessageType = '{}:mailMessage'; | |
SET OutputRoot.DFDL.mailMessage.Header.MessageType = 'INFO'; | |
MOVE ptrEvents TO InputRoot.XMLNSC.ns:event.ns:eventPointData.ns:messageFlowData; | |
SET OutputRoot.DFDL.mailMessage.Header.Origin = ptrEvents.ns:node.ns:nodeLabel || ptrEvents.ns:node.ns:terminal; | |
SET OutputRoot.DFDL.mailMessage.Header.Server = ptrEvents.ns:messageFlow.ns:uniqueFlowName; | |
SET OutputRoot.DFDL.mailMessage.Header.MessageId = InputRoot.XMLNSC.ns:event.ns:eventPointData.ns:eventData.ns:eventCorrelation.ns:localTransactionId; | |
SET OutputRoot.DFDL.mailMessage.Messages.Message = 'simple content'; | |
-- Serialize the DFDL into BLOB for the OutputMail node. | |
-- This will be the mail body. | |
SET OutputRoot.BLOB.BLOB = ASBITSTREAM(OutputRoot.DFDL.mailMessage OPTIONS RootBitStream); | |
DELETE FIELD OutputRoot.DFDL; | |
RETURN TRUE; |