There are several new features in IBM Integration Bus (IIB) v10 which make it easier to create tests for your message flows. This post outlines the features and details one way to create regression tests for message flows.

Message recording and retrieval

IIB v10 adds the ability to record messages as they are processed by a flow. A snapshot of the message is recorded as it passes between nodes and the recorded messages can be displayed in the toolkit so that the route through the flow can be easily visualised.
phil1

The recorded snapshot includes the message, local environment, environment and the exception list as well as several other properties such as a sequence number which give more context to the recorded message.

A new toolbar has been added to the flow canvas which allows message recording and display with only a couple of clicks. The toolbar is activated when the user selects the button to put the flow into record mode. This will deploy the message flow, along with any dependent resources, and enable recording. Once the message flow has been invoked, either by using an external client or injecting a message, the recorded messages can be displayed with one more button click.

Message injection

IIB v10 also includes the ability to inject recorded messages back into a flow bypassing their normal transport method. For example, messages can be injected in the MQTT subscribe node even when an MQTT server is unavailable.

When recorded messages are displayed in the toolkit, those which are valid for injection include a save icon in the top-right corner. Messages are saved to the same project as the message flow and can be shared with a project interchange file or backed up to a repository for use in a test environment.

Message injection is supported on the following nodes:
– MQ Input
– MQTT Subscribe
– SOAP Input
– HTTP Input
– File Input

The supported input nodes will only process an injected message if they have no incoming data via their regular transport. The matching output nodes are also aware that a message has been injected and will deal with it differently to a normal message. The SOAP and HTTP output nodes will not attempt to output an injected message because there is no client in the scenario. The message will simply pass downstream to the next node in the flow. The MQ, MQTT and File nodes will attempt to output an injected message to their normal transport but if the transport is not available then they will still pass the message downstream.

Using the unit test features via API

Along with the toolkit, the new unit test features can be exercised via Java and REST API.

The Java API are included in the ConfigManagerProxy.jar and integrate with existing Java API. The following is an example of how the Java API can be used:

BrokerProxy bproxy = BrokerProxy.getLocalInstance("myBroker");
ExecutionGroupProxy egproxy = bproxy.getExecutionGroupByName("myEG");
    
// Enable recording for execution group
egproxy.setTestRecordMode(AttributeConstants.MODE_ENABLED);
    
// Enable injection for execution group
egproxy.setInjectionMode(AttributeConstants.MODE_ENABLED);
    
// Run code to invoke message flow
    
// Setup filter properties to restrict the amount of recorded messages retrieved    
Properties filterProps = new Properties();
filterProps.setProperty(Checkpoint.PROPERTY_APPLICATION_NAME, "myApplication");
filterProps.setProperty(Checkpoint.PROPERTY_MESSAGE_FLOW_NAME, "myFlow");
// Only request the first 25 messages that are recorded
filterProps.setProperty(AttributeConstants.TESTRECORD_COUNT, "25");   
    
// Retrieve the recorded messages
List recordedMessages = egproxy.getRecordedTestData(filterProps);
    
for (RecordedTestData recordedMessage : recordedMessages) {
    // Check the sequence number and source node of the recorded message
    String sequence = recordedMessage.getPropertyValue(Checkpoint.PROPERTY_SEQUENCE_NUMBER);
    String sourceNodeName = recordedMessage.getPropertyValue(Checkpoint.PROPERTY_SOURCE_NODE_NAME);

    // Only inject the first message that was recorded after the input node 
    if (sequence.equals("1") && sourceNodeName.equals("myFlow#FCMComposite_1_1")) {
      // Set up injection properties
      Properties injectionProps = new Properties();
        
      // Set injection location
      String appName = recordedMessage.getPropertyValue(Checkpoint.PROPERTY_APPLICATION_NAME);
      injectionProps.setProperty(AttributeConstants.DATA_INJECTION_APPLICATION_LABEL, appName);
      
      String flowName = recordedMessage.getPropertyValue(Checkpoint.PROPERTY_MESSAGE_FLOW_NAME);
      injectionProps.setProperty(AttributeConstants.DATA_INJECTION_MESSAGEFLOW_LABEL, flowName);
     
      String nodeUUID = recordedMessage.getPropertyValue(Checkpoint.PROPERTY_SOURCE_NODE_NAME);
      injectionProps.setProperty(AttributeConstants.DATA_INJECTION_NODE_UUID, nodeUUID);
      
      // Set message sections to inject
      TestData messageData = recordedMessage.getTestData();
      String messageSection = messageData.getMessage();
      injectionProps.setProperty(AttributeConstants.DATA_INJECTION_MESSAGE_SECTION, messageSection);
      
      String localEnvSection = messageData.getLocalEnvironment();
      injectionProps.setProperty(AttributeConstants.DATA_INJECTION_LOCALENVIRONMENT_SECTION, localEnvSection);
        
      // Inject message synchronously. Returns true when the injection is complete so that tests know when they can continue.
      boolean injectionComplete = egproxy.injectTestData(injectionProps, true);
      System.out.println("Injection complete: " + injectionComplete);
    }
  }

Java API calls

ExecutionGroupProxy.setTestRecordMode() and getTestRecordMode()
– Turn on/off record mode and check it’s status

ExecutionGroupProxy.setInjectionMode() and getInjectionMode()
– Turn on/off injection mode and check it’s current status

ExecutionGroupProxy.getRecordedTestData(Properties filterProperties)
– Retrieves recorded messages that match the filters supplied e.g app, lib, flow

ExecutionGroupProxy.clearRecordedTestData(Properties filterProperties)
– Clears recorded messages that match the filters supplied e.g. app, lib, flow
– Clears all recorded messages if no filters are supplied

ExecutionGroupProxy.getRecordedTestDataCount(Properties filterProperties)
– Returns a count of the recorded messages that match the filters supplied

ExecutionGroupProxy.injectTestData(Properties injectionProperties, boolean waitForResponse)
– Injects a message using the supplied properties e.g. location, message sections
– Injection is synchronous is waitForResponse equals true

REST API calls

PUT to apiv1/executiongroups/{egName}?action=
– Change record mode with action = enableTestRecordMode or disableTestRecordMode
– Change injection mode with action = enableInjectionMode or disableInjectionMode

POST to apiv1/test?action=inject
– Inject a message into a flow
– Specify location and message sections via extra query parameters

GET to apiv1/test/recordedTestData
– Retrieve recorded messages
– Specify filters as query parameters

PUT to apiv1/test/recordedTestData?action=
– Performs actions on recorded messages
– Valid actions are clear & count
– Specify filters as extra query parameters

Further reading

These pages in the knowledge center give more information on how to use these features:

Using the flow exerciser: https://www-304.ibm.com/support/knowledgecenter/SSMKHH_10.0.0/com.ibm.etools.mft.doc/rt26110_.htm

Injecting recorded messages: https://www-304.ibm.com/support/knowledgecenter/SSMKHH_10.0.0/com.ibm.etools.mft.doc/rt26140_.htm

2 comments on"Using the flow exerciser in IBM Integration Bus (IIB) v10"

  1. Thanks for the informative article,

    I’d like to know one thing, how can i know the IP and port of the REST API calls to perform actions on the messages ?

    Thanks in advance.

  2. Does this support Publication Node?

Join The Discussion

Your email address will not be published. Required fields are marked *