Monitoring activities in IIB

Usually, the admin guys use System Logs to see what is happening in remote node. Sometimes, the developer also wants to see but he/she doesn’t have access to System Logs. So, they have depend on the admin guys or go with what is available in Web UI like  activity logs or administrative logs or any custom audit logs.

Is there a way to see what is happening in the remote integration node ? How do I know if someone deletes or creates an integration server? Can I keep getting every activity from the remote node?

Yes. You can keep getting every activity from the remote node by using IBM Integration API Java Program. Here is a sample showing what has happened when an user tried to stop default integration node.

Thu Jan 24 00:54:55 EST 2019 : affectedObject = Log
Thu Jan 24 00:54:55 EST 2019 : new_subcomponent 2871<<Administration Request<<2019-01-24 00:54:55.287 EST<<user<<stop<<default<<ExecutionGroup<<IB10NODE<<Broker<<INITIATED
Thu Jan 24 00:54:55 EST 2019 : ----------------------------------------.processModify(...)
Thu Jan 24 00:55:15 EST 2019 : affectedObject = Log
Thu Jan 24 00:55:15 EST 2019 : new_subcomponent 2871<<Administration Request<<2019-01-24 00:55:15.317 EST<<user<<stop<<default<<ExecutionGroup<<IB10NODE<<Broker<<INITIATED
Thu Jan 24 00:55:15 EST 2019 : ----------------------------------------.processModify(...)
Thu Jan 24 00:55:26 EST 2019 : affectedObject = default
Thu Jan 24 00:55:26 EST 2019 : changed_attribute "ExecutionGroupRuntimeProperty/This/runMode" = "stopped"

Thu Jan 24 00:55:26 EST 2019 : changed_attribute "object.runstate" = "stopped"

Thu Jan 24 00:55:26 EST 2019 : ----------------------------------------.processModify(...)
Thu Jan 24 00:55:26 EST 2019 : affectedObject = Log
Thu Jan 24 00:55:26 EST 2019 : new_subcomponent 2880<<Change Notification<<2019-01-24 00:55:26.360 EST<<object.runstate<<running<<stopped<<default<<ExecutionGroup<<IB10NODE<<Broker
Thu Jan 24 00:55:26 EST 2019 : new_subcomponent 2871<<Administration Result<<2019-01-24 00:55:26.349 EST<<user<<stop<<default<<ExecutionGroup<<IB10NODE<<Broker<<COMPLETE
Thu Jan 24 00:55:26 EST 2019 : new_subcomponent 2871<<Administration Result<<2019-01-24 00:55:26.326 EST<<user<<stop<<default<<ExecutionGroup<<IB10NODE<<Broker<<COMPLETE
Thu Jan 24 00:55:26 EST 2019 : ----------------------------------------.processModify(...)
Thu Jan 24 00:55:26 EST 2019 : affectedObject = default
Thu Jan 24 00:55:26 EST 2019 : changed_attribute "ExecutionGroupRuntimeProperty/This/processId" = "0"

Thu Jan 24 00:55:26 EST 2019 : ----------------------------------------.processModify(...)
Thu Jan 24 00:55:26 EST 2019 : affectedObject = Log
Thu Jan 24 00:55:26 EST 2019 : new_subcomponent 2880<<Change Notification<<2019-01-24 00:55:26.396 EST<<processId<<14008<<0<<default<<ExecutionGroup<<IB10NODE<<Broker
Thu Jan 24 00:55:26 EST 2019 : ----------------------------------------.processModify(...)

 

If you are looking for the complete code or training on IBM Integration API, connect with us at support@vaithu.com/WhatsApp +1 6123058684. F0r more details, please visit www.vaithu.com

 

 

Exception Handler using Java Compute Node

Every project has its own way of implementing Error Handler and the subflows are the most common among them and in some cases the same is getting converted into an user defined node.

The problem with subflows are, “Every project should reference it and with UDN , the message flows and esql files become cmf file which hides information about what are all inside it. For any reason, if you need the code back again, it is difficult to get from CMF file so this is not a good solution.

Moving to Monitoring Profiles is another option but not sure why most of the projects did not explore the greatness of this. So, anyone who is looking for a pure java implementation for exception handling without any CMF issues, here is the code.

import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

import com.ibm.broker.javacompute.MbJavaComputeNode;
import com.ibm.broker.plugin.MbElement;
import com.ibm.broker.plugin.MbException;
import com.ibm.broker.plugin.MbJSON;
import com.ibm.broker.plugin.MbMessage;
import com.ibm.broker.plugin.MbMessageAssembly;
import com.ibm.broker.plugin.MbOutputTerminal;
import com.ibm.broker.plugin.MbUserException;
import com.ibm.broker.plugin.MbXMLNSC;
import com.iib.broker.utilities.MbUtils;


public class ExJCN extends MbJavaComputeNode {
  
  private String errorNumber;
  private String exceptionType;
  private String errorFunction;
  private String errorMsg;
  private String errorPath;
  private String errorLocation;
  private String transactionXPath;
  private String causeOfError;
  private String logLevel;
  private String sqlStatement;
  private boolean isValidInputMessage;
  
  
  private Pattern REGEX_PATTERN ;
  private Set<String> ignoreErrorTexts;
  
  public void onInitialize() throws MbException {
    REGEX_PATTERN = Pattern.compile("^\\p{XDigit}+$");
    ignoreErrorTexts = new HashSet<String>(Arrays.asList(
        new String[] {"Caught exception and rethrowing","Error detected, rethrowing","Node throwing exception"}));
    
  }
  
  public void evaluate(MbMessageAssembly inAssembly) throws MbException {
    MbOutputTerminal out = getOutputTerminal("out");
//		MbOutputTerminal alt = getOutputTerminal("alternate");

    MbMessage inMessage = inAssembly.getMessage();
    MbMessageAssembly outAssembly = null;
    try {
      MbMessage outMessage = new MbMessage();
      outAssembly = new MbMessageAssembly(inAssembly, inAssembly.getLocalEnvironment(),inAssembly.getExceptionList(),outMessage);
      // ----------------------------------------------------------
      // Add user code below
      MbElement exception = MbUtils.getExceptionList(inAssembly).getFirstChild();
      MbElement inputRoot = inMessage.getRootElement();
      String ipMsgStatus = MbUtils.isValidMessage(inputRoot);
      this.isValidInputMessage = ipMsgStatus == null ? true : false;
      
      if (exception != null && exception.getName().endsWith("Exception")) {
        getExceptionDetails(exception, inputRoot);
      }else if (null != inputRoot && !MbUtils.getValueAsString(inputRoot, "HTTPResponseHeader/X-Original-HTTP-Status-Code").isEmpty() 
        && !MbUtils.getValueAsString(inputRoot, "HTTPResponseHeader/X-Original-HTTP-Status-Code").equals("200")	) {
        
        MbElement httpResponse = inputRoot.getFirstElementByPath("HTTPResponseHeader");
        this.exceptionType = httpResponse.getFirstChild().getValueAsString();
        this.errorNumber = MbUtils.getValueAsString(httpResponse, "X-Original-HTTP-Status-Code");
        this.errorLocation = MbUtils.getValueAsString(httpResponse, "X-Original-HTTP-Status-Line") +":"+MbUtils.getValueAsString(httpResponse,"Server");
        
        if (inputRoot.getLastChild().getName().equals("BLOB")) {
          this.errorMsg = MbUtils.getStringFromBlob(inputRoot);
        }else{
          this.errorMsg = MbUtils.getPayloadAsString(inputRoot, inputRoot.getLastChild().getName());
        }
      }else if (MbUtils.getLocalEnvironment(inAssembly).getFirstElementByPath("/HTTP/Input/Timeout") != null) {
        this.exceptionType = "Timeout Exception";
        this.errorNumber = "504";
        this.errorMsg = "Request could not be completed with in the defined " 
        + MbUtils.getValueAsString(MbUtils.getLocalEnvironment(inAssembly).getFirstElementByPath("/HTTP/Input/Timeout"), "OriginalClientWaitTime") + " seconds.";
        this.errorLocation = getMessageFlow().getName();
      }else if (null != inputRoot && inputRoot.getLastChild().getName().equals("SOAP")) {
        
        exception = inputRoot.getFirstElementByPath("/Body/Fault");
        
        if (exception != null) {

          this.exceptionType = MbUtils.getValueAsString(exception, "faultcode");
          this.errorMsg = MbUtils.getValueAsString(exception, "faultstring") ;
          
          MbElement detail = exception.getFirstElementByPath("detail"); 
          detail = detail == null ? null : detail.getFirstChild();
          
          while (detail != null) {
            this.errorMsg = this.errorMsg +";" + detail.getName() +" = "+ detail.getValue();
            detail = detail.getNextSibling();
          }
          this.errorLocation = MbUtils.getValueAsString(exception, "faultactor");
        } 
      }else{
        String unknown = "Unknown";
        this.errorNumber = unknown;
        this.errorFunction = unknown;
        this.errorLocation = getMessageFlow().getName();
        this.errorMsg = "Unable to capture the error message as it is not having any exceptionlist, soap fault, http timeout, http error. Debug the flow and see what is happening";
        this.errorPath = unknown;
        this.exceptionType = unknown;
      }
      
      
      MbMessage errorMessage = new MbMessage();
      MbElement errorRoot = errorMessage.getRootElement();
      MbElement errorXML = null;
      
      switch (MbUtils.getDomainName(inputRoot).toUpperCase()) {
      case MbJSON.PARSER_NAME:
        errorXML = prepErrorMessageInJSON(errorRoot);
        break;
      case "SOAP":
        errorXML = MbUtils.prepSOAPFault(errorRoot, MbUtils.getValueAsString(inputRoot, "HTTPInputHeader/X-Original-HTTP-Command"));
        break;
      default:
        errorXML = prepErrorMessageInXML(errorRoot);
        break;
      }
      
      MbElement detail = errorXML.createElementAsLastChild(MbElement.TYPE_NAME, "Detail", null);
      getTransactionDetails(inputRoot, detail);
      
      if (!this.isValidInputMessage) {
        this.errorMsg += "\n"+ipMsgStatus;
      }
      
      prepErrorMessage(detail);
      MbUtils.copyLocalEnvironmentAsXML(inAssembly, errorXML);
      MbUtils.copyEnvironmentAsXML(inAssembly, errorXML);
      
      MbElement outputRoot = outMessage.getRootElement();
      MbUtils.copyProperties(inputRoot, outputRoot);
      MbUtils.copyMQMD(inputRoot, outputRoot);
      MbUtils.createMQRFH2(inputRoot, outputRoot);
      MbUtils.setPubTopic(outputRoot, "Excep");
      
      MbElement parts = MbUtils.createMIMEParser(outputRoot, "ExceptionHandler");
      MbUtils.addToMimePart(parts,  errorRoot);
      
      if (isValidInputMessage) {
        MbUtils.addToMimePart(parts,  inputRoot);
      }
      
      // End of user code
      // ----------------------------------------------------------
    } catch (MbException e) {
      // Re-throw to allow Broker handling of MbException
      throw e;
    } catch (RuntimeException e) {
      // Re-throw to allow Broker handling of RuntimeException
      throw e;
    } catch (Exception e) {
      // Consider replacing Exception with type(s) thrown by user code
      // Example handling ensures all exceptions are re-thrown to be handled in the flow
      throw new MbUserException(this, "evaluate()", "", "", e.toString(),
          null);
    }
    // The following should only be changed
    // if not propagating message to the 'out' terminal
    out.propagate(outAssembly);

  }
  
  
  public MbElement prepErrorMessageInJSON(MbElement outRoot) throws MbException {
    return
           outRoot.createElementAsLastChild(MbJSON.PARSER_NAME)
           .createElementAsLastChild(MbJSON.ARRAY, "Data", null)
           .createElementAsLastChild(MbElement.TYPE_NAME, "Error", null);
  }
  
  public MbElement prepErrorMessageInXML(MbElement outRoot) throws MbException {
    return
           outRoot.createElementAsLastChild(MbXMLNSC.PARSER_NAME).
          createElementAsLastChild(MbElement.TYPE_NAME, "Error", null);
  }
  
  
  
public void getExceptionDetails(MbElement exceptionRef, MbElement inputRoot) throws MbException {
    
    StringBuffer errorMessage = new StringBuffer("");
    StringBuffer errorPath = new StringBuffer("");
    String text,label,hexText,payload;
    byte[] bs = null;
    
    if (inputRoot.getLastChild().getName().equals("BLOB")) {
      bs = (byte[]) MbUtils.getBlob(inputRoot).getValue();
    } else if (isValidInputMessage) {
      bs = MbUtils.getPayloadAsBlob(inputRoot);
    }
//		MbElement blob;
    final int MSG_MAX_SIZE = 10240;
    final String FAILED_MSG_IGNORE = "Failed message is more than "+ MSG_MAX_SIZE +" bytes.So not capturing it";
    
    while ( exceptionRef != null && exceptionRef.getName().endsWith("Exception")) {
      
      text = MbUtils.getValueAsString(exceptionRef, "Text");
      
      if (!ignoreErrorTexts.contains(text)) {
        errorMessage.append(text);
        errorMessage.append("->");
      }
      
      label = MbUtils.getValueAsString(exceptionRef, "Label");
      if (!label.isEmpty()) {
        errorPath.append(label);
        errorPath.append("-->");
        
        if (!label.startsWith("Imb")) {
          this.errorLocation = label;
        }
      }
      
      for (MbElement errInsRef = exceptionRef.getFirstElementByPath("Insert"); errInsRef != null && errInsRef.getName().equals("Insert"); errInsRef = errInsRef.getNextSibling()) {
        
        text = MbUtils.getValueAsString(errInsRef, "Text");
        
        if (null != text && !text.isEmpty() ) {
          
            switch (Integer.parseInt(errInsRef.getFirstChild().getValueAsString())) {
            case 2:
              if (text.contains("SOCKET")) {
                errorMessage.append(text);
                errorMessage.append("->");
              }
              break;
            case 12:
              if (text.getBytes().length <= MSG_MAX_SIZE && isHex(text)) {
                
                payload = null != bs && bs.length <= MSG_MAX_SIZE ?  new String(bs) : FAILED_MSG_IGNORE;
                hexText = !payload.equals(FAILED_MSG_IGNORE) ? convertHexToString(text) : "";
                
                if (hexText.contentEquals(payload) ) {
                  errorMessage.append("Failed Input Message :\n");
                }
                errorMessage.append(hexText);
              }else{
                errorMessage.append(FAILED_MSG_IGNORE);
              }
              errorMessage.append("->");
              break;
            default:
              errorMessage.append(text);
              errorMessage.append("->");
            }
        } 
      }
      text = MbUtils.getValueAsString(exceptionRef, "Function");
      this.sqlStatement = text.isEmpty()  ? null : text;
      
      errorMessage.append("\n");
      exceptionRef = exceptionRef.getLastChild();
    }
    
    exceptionRef = exceptionRef.getParent();
    this.errorNumber = MbUtils.getValueAsString(exceptionRef, "Number");
    this.errorFunction = MbUtils.getValueAsString(exceptionRef, "Function");
    this.causeOfError = MbUtils.getValueAsString(exceptionRef, "Text");
    this.exceptionType = exceptionRef.getName();
    this.errorMsg = errorMessage.substring(0, errorMessage.length() - "->\n".length());
    this.errorPath = errorPath.substring(0, errorPath.length() - "-->".length());
    
  }


public void prepErrorMessage( MbElement output) throws MbException {
  
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "TimeStamp", new Date().toString());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ExceptionType", this.exceptionType);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ErrorNumber", this.errorNumber);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "CauseOfError", this.causeOfError);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ErrorMessage", this.errorMsg);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ErrorLocation", this.errorLocation);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ErrorFunction", this.errorFunction);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ErrorPath", this.errorPath);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "SqlStatement", this.sqlStatement);
  
}
public Boolean isHex(String str) {
    return REGEX_PATTERN.matcher(str).matches();
}


private String convertHexToString(String hex){

    StringBuilder sb = new StringBuilder();

    for( int i=0; i<hex.length()-1; i+=2 ){
      sb.append((char)Integer.parseInt(hex.substring(i, (i + 2)), 16));
    }
    return sb.toString();
  }

public void getBrokerDetails(MbElement output) throws MbException {
  
  output = output.createElementAsLastChild(MbElement.TYPE_NAME, "RuntimeDetail", null);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "MessageFlowLabel", getMessageFlow().getName());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Application", getMessageFlow().getApplicationName());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Library", getMessageFlow().getLibraryName());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ExecutionGroup", getExecutionGroup().getName());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "BrokerName", getBroker().getName());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Queue Manager", getBroker().getQueueManagerName());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "User", System.getProperty("user.home"));
}
}

If you are looking for complete implementation of the PI or any session with Java Compute Node, connect with us at support@vaithu.com/WhatsApp +1 6123058684. We offer complete solution in IIB for low cost.

Monthly Summary Report using DFDL

Recently we have been asked to design a message model which shows as a report like below. It was a nice report and they want the same intact.

Entry       Per         Post Date   GL Account  Description                                                                                                                                                                                                                                                     
--------------------------------------------------------------
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test

After playing with DFDL Fixed Length format couple of times, we were able to achieve the desired format and it was really interesting when you know the power and simplicity of DFDL. The message model created is

 

<?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ibmDfdlExtn="http://www.ibm.com/dfdl/extensions" xmlns:ibmSchExtn="http://www.ibm.com/schema/extensions" xmlns:recFixLengthFieldsFmt="http://www.ibm.com/dfdl/RecordFixLengthFieldFormat">

    <xsd:import namespace="http://www.ibm.com/dfdl/RecordFixLengthFieldFormat" schemaLocation="IBMdefined/RecordFixLengthFieldFormat.xsd"/>
        <xsd:simpleType dfdl:length="150" dfdl:terminator="" dfdl:textStringPadCharacter="-" name="border">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>
    <xsd:complexType name="Header">
    <xsd:sequence dfdl:separator="%SP;%SP;">
      <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="Entry" name="Entry" type="xsd:string"/>
      <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="Per" name="Per" type="xsd:string"/>
      <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="Post Date" name="PostDate" type="xsd:string"/>
      <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="GL Account" name="GLAccount" type="xsd:string"/>
      <xsd:element dfdl:length="256" ibmDfdlExtn:sampleValue="Description" name="Descrption" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
    <xsd:annotation>
    <xsd:appinfo source="http://www.ogf.org/dfdl/">
      <dfdl:format encoding="{$dfdl:encoding}" escapeSchemeRef="" occursCountKind="fixed" ref="recFixLengthFieldsFmt:RecordFixLengthFieldsFormat" textPadKind="padChar"/>
    </xsd:appinfo>
  </xsd:annotation>

  <xsd:element dfdl:lengthKind="delimited" ibmSchExtn:docRoot="true" name="FLength">
    <xsd:complexType>
      <xsd:sequence dfdl:separator="%CR;%LF;%WSP*;" dfdl:separatorSuppressionPolicy="anyEmpty">
                				<xsd:element dfdl:lengthKind="delimited" name="header" type="Header"/>
                <xsd:element ibmDfdlExtn:sampleValue="" name="border" type="border"/>
                <xsd:element dfdl:lengthKind="delimited" dfdl:occursCountKind="implicit" ibmDfdlExtn:sampleOccurs="10" maxOccurs="unbounded" name="body">
          <xsd:complexType>
            <xsd:sequence dfdl:separator="%SP;%SP;">
              <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="16524" name="Entry" type="xsd:string"/>
              <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="01" name="Per" type="xsd:string"/>
              <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="09/15/2018" name="PostDate" type="xsd:string"/>
                            <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="123456" name="GLAccount" type="xsd:string"/>
                            <xsd:element dfdl:length="50" dfdl:textPadKind="padChar" ibmDfdlExtn:sampleValue="Test" name="Description" type="xsd:string"/>
                                                                                                                                                                    </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
                			                        </xsd:sequence>
    </xsd:complexType>
  </xsd:element>


</xsd:schema>

If you have any requirements in DFDL Message modelling, connect with us at support@vaithu.com/+1 6123058684.

SOAP Nodes vs HTTP Nodes

HTTP and SOAP nodes can both be used to interact with Web services. Typically you use SOAP nodes when working with SOAP-based Web services.

For SOAP-based Web services, several advantages exist if you use the SOAP nodes and the SOAP message domain instead of the HTTP transport nodes and XMLNSC message domain.

  • Support for WS-Addressing, WS-Security and SOAP headers.
  • A common SOAP logical tree format, independent of the bitstream format.
  • Runtime checking against WSDL.
  • Automatic processing of SOAP with Attachments (SwA).
  • Automatic processing of Message Transmission Optimization Mechanism (MTOM).

Although the HTTP nodes can process SwA messages, you must use the MIME message domain and design your flow to handle the attachments explicitly, and use custom logic to extract and parse the SOAP.

Cases where it might be better to use HTTP nodes include:

  • Message flows that interact with Web services that use different standards, such as REST or XML-RPC.
  • Message flows that never use WS-Addressing, WS-Security, SwA, or MTOM.

IIB Useful Commands

BASIC COMMANDS:

Command for listing out all the Brokers created in the current installation

  • mqsilist

 

Command for creating the broker

  • mqsicreatebroker {BROKERNAME} -q {QMGRNAME} -i {USERNAME} -p {Password}

 

Command for Excecution group creation

  • mqsicreateexecutiongroup  {BROKERNAME} -e {EGName}

 

Command to start Execution group

  • mqsistartmsgflow {BROKERNAME} -e {EGName}

 

Command to stop Execution Group

  • mqsistopmsgflow {BROKERNAME} -e {EGName}

 

Command for deleting Execution Group

  • mqsideleteexecutiongroup -n {BROKERNAME} -e {EGName}

 

Command to specify Debug Port for EG

  • mqsichangeproperties {BROKERNAME} -e default -o ComIbmJVMManager -n jvmDebugPort -v 8117

 

Command for  Listing out all the deployed objects under Execution Group

  • mqsilist {BROKERNAME} -e default -k myApplication

 

Command for listing out all the deployed objects that are configured Library

  • mqsilist {BROKERNAME} -e default -k myApplication -y {myEGLibraryName}

 

Command to return detailed information about Application

  • mqsilist {BROKERNAME} -e default -k myApplication -d2

 

Command for listing all deployed objects that are configured in  myApplication

  • mqsilist {BROKERNAME} -e default -k myApplication -r

 

Command to list out a summary of the EG that are defined on a  broker

  • mqsilist {BROKERNAME}

 

Command for displaying detailed info about all resources for brokers on Local System

  • mqsilist -a -r -d2

 

NORMAL COMMANDS:

Command to start the Application

  • mqsistartmsgflow {BROKERNAME} -e {EGName} -k {ApplicationName}

 

Command to stop the Application

  • mqsistoptmsgflow {BROKERNAME} -e {EGName} -k {ApplicationName}

 

Command to delete the Application

  • mqsideploy {BROKERNAME} -e {EGName} -d {ApplicationName}

 

Command to know the Deployment Status

  • mqsilist {BROKERNAME} -e {EGName} -d 2

 

Command to deploy the BAR

  • mqsideploy {BROKERNAME} -e {EGName} -a {BARFileName}

 

Command to delete the BAR

  • mqsideploy {BROKERNAME} -e {EGName} -d {BARFileName}

 

Command to read the BAR

  • mqsireadbar -b {BARFileName} -r

 

BAR Override Command

  • mqsiapplybaroverride -b {BARFileName} -k {ApplicationName} -m {MessageFlowName}#{Property to change}

 

SECURITY IDENTITY COMMANDS:

Command to start the Broker

  • mqsistart {BROKERNAME};

 

Command to stop the Broker

  • mqsistop {BROKERNAME};

 

Command to register DSN with IIB

  • mqsisetdbparms {BROKERNAME} -n {DSName} -u {SchemaName} -p {Password};

 

Command to know whether Broker is associated with DSN or Not

  • mqsicvp {BROKERNAME} -n {DSName}

 

Command to give security for FTP

  • mqsisetdbparms {BROKERNAME} -n ftp::{SeuID} -u {SchemaName} -p {Password};

 

Command to give security for SMTP(Email Receiving)

  • mqsisetdbparms {BROKERNAME} -n smtp::{SeuID} -u {emailid} -p {Password};

 

Command to give security for Email Sending

  • mqsisetdbparms {BROKERNAME} -n email::{SeuID} -u {emailid} -p {Password};

 

Command to give security for JDBC Configurable Service

  • mqsisetdbparms {BROKERNAME} -n jdbc::{SeuID} -u {SchemaName} -p {Password};

 

 MONITORING COMMANDS:

Command to activate the Monitoring

  • mqsichangeflowmonitoring {BROKERNAME} -e default -k {ApplicationName} -f {FlowName} -c active

 

Command to report the Monitoring

  • mqsireportflowmonitoring {BROKERNAME} -e default -k {ApplicationName} -f {FlowName} -a

 

MQSICHANGE PROPERTY COMMANDS:

Command to report the HTTP Listener Property at Broker Level

  • mqsireportproperties {BROKERNAME} -b httplistener -o HTTPConnector -a

 

Command to report the HTTP Listener Property at EG Level

  • mqsireportproperties {BROKERNAME} -e default -o HTTPConnector -a

 

Command to Change the HTTP Listener Port Number(Broker Level)

  • mqsichangeproperties {BROKERNAME} -b httplistener -o HTTPConnector -n port -v 7800

 

Command to change the HTTP Listener Port Number at EG Level

  • mqsichangeproperties {BROKERNAME} -e default -o HTTPConnector -n port -v 7800

 

Command to Trace the HTTPListener

 

  • mqsireportbroker {BROKERNAME}

Picking files randomly for mock test

There are situations where we need mimic simulation for various scenario like  success, error, failure etc. We do the same by creating a mock test flow which drops files into the destination randomly and here is the ESQL code to pick those random files.

CREATE COMPUTE MODULE RandomFiles
  CREATE FUNCTION Main() RETURNS BOOLEAN
  BEGIN

    DECLARE R DECIMAL RAND(1);
    DECLARE fileName CHARACTER getRootElement(InputRoot);

    SET fileName = CASE

    WHEN R > 0.0 AND R < 0.3 THEN fileName ||'_success.txt'
    WHEN R > 0.3 AND R < 0.6 THEN fileName ||'_error.txt'
    ELSE fileName ||'_timeout.txt'
    END;

    CALL SetDestinationFileName(OutputLocalEnvironment, fileName);

    RETURN TRUE;
  END;

  CREATE PROCEDURE CopyMessageHeaders() BEGIN
    DECLARE I INTEGER 1;
    DECLARE J INTEGER;
    SET J = CARDINALITY(InputRoot.*[]);
    WHILE I < J DO
      SET OutputRoot.*[I] = InputRoot.*[I];
      SET I = I + 1;
    END WHILE;
  END;

  CREATE PROCEDURE CopyEntireMessage() BEGIN
    SET OutputRoot = InputRoot;
  END;
END MODULE;

CREATE PROCEDURE SetDestinationFileName(IN LocalEnvironment REFERENCE,IN Name CHARACTER)
BEGIN
  SET LocalEnvironment.Destination.File.Name = Name;
END;

CREATE FUNCTION getRootElement (In ipRef REFERENCE ) RETURNS CHARACTER
BEGIN
  RETURN FIELDNAME(ipRef.*:*[<].*:*[<]);
END;

If you are looking for IIB training, ESQL training and support, please connect with us at support@vaithu.com/WhatsApp +1 6123058684.

Say GoodBye to Log4jNode!!!

A developer spends lot of time not for development but for debugging. This is the most frustrating part when the issue could not be identified or diagnosed or no access to connect to the remote server or takes time to connect/disconnect. Usually every project has log4j or special custom node or subflow or use Flow exerciser but all these are not with flaws. Each has its own pros and cons. So we decided to create set of custom nodes which should give every detailed information a developer is interested and it must be controlled and configurable . It has to show him not only the message payload and headers but also what type of message, sender and receiver details, what protocol is it, time to complete and status of the transaction

  • Log files are written to a common directory as configured
  • Log files are written to physical file system where Node is installed
  • Can easily move to Database if needed to store audit messages
  • Dynamically change what level of log is required
  • Log files can be compressed and decompressed as configured
  • key business elements can also be captured
  • Additional information like Sender, Receiver, Interface Name, MessageId,Node details,Additional Instances,Message type and protocol can also be captured
  • Want to see Environment and LocalEnvironment too? Yes everything is availble as you confgured
  • Time of failure and Time of success are also captured
  • Elasped time for each message is also captured in log messages
  • Automatically rolling of files for every 10 minutes.
  • Every flow has its own unique log files
  • Works for all kinds of message types
  • Available both as subflow and node

A sample log file is shown below.

[
1. Metadata(Timestamp=2017-09-05T21:19:07.629|TransactionId=05bc1397-a8ab-4c47-b02f-539b8b697b56|MessageFlowName=SendToWarehouse|MessageType=XML|Sender=Maximo|Receiver=IIB|Protocol=Queue)

Header(<MQMD><SourceQueue>IN.Q</SourceQueue><Transactional>true</Transactional><Encoding>546</Encoding><CodedCharSetId>437</CodedCharSetId><Format>        </Format><Version>2</Version><Report>0</Report><MsgType>8</MsgType><Expiry>-1</Expiry><Feedback>0</Feedback><Priority>0</Priority><Persistence>0</Persistence><MsgId>414d5120494239514d47522020202020657ca5592041700e</MsgId><CorrelId>000000000000000000000000000000000000000000000000</CorrelId><BackoutCount>0</BackoutCount><ReplyToQ>                                                </ReplyToQ><ReplyToQMgr>IB9QMGR                                         </ReplyToQMgr><UserIdentifier>vaithu</UserIdentifier><AccountingToken>160105150000002d74cc5dfa721e73431607412b32030000000000000000000b</AccountingToken><ApplIdentityData>                                </ApplIdentityData><PutApplType>11</PutApplType><PutApplName>:\Softwares\ih03\rfhutil.exe</PutApplName><PutDate>2017-09-06</PutDate><PutTime>01:19:07.600</PutTime><ApplOriginData>    </ApplOriginData><GroupId>000000000000000000000000000000000000000000000000</GroupId><MsgSeqNumber>1</MsgSeqNumber><Offset>0</Offset><MsgFlags>0</MsgFlags><OriginalLength>-1</OriginalLength></MQMD>)

Input(<?xml version="1.0" encoding="UTF-8"?>
<Invoice>
 <InvoiceNo>7</InvoiceNo>
 <InvoiceDate>2000-12-07</InvoiceDate>
 <InvoiceTime>12:40:00</InvoiceTime>
 <TillNumber>3</TillNumber>
 <Cashier StaffNo='089'>Mary</Cashier>
 <Customer>
   <FirstName>Andrew</FirstName>
   <LastName>Smith</LastName>
   <Title>Mr</Title>
   <DOB>20-01-70</DOB>
   <PhoneHome>01962818000</PhoneHome>
   <PhoneWork />
   <Billing>
     <Address>14 High Street</Address>
     <Address>Hursley Village</Address>
     <Address>Hampshire</Address>
     <PostCode>SO213JR</PostCode>
   </Billing>
 </Customer>
 <Payment>
   <CardType>Visa</CardType>
   <CardNo>4921682832258418</CardNo>
   <CardName>Mr Andrew J. Smith</CardName>
   <Valid>1200</Valid>
   <Expires>1101</Expires>
 </Payment>
 <Purchases>
   <Item>
     <Title Category='Computer' Form='Paperback' Edition='2'>The XML Companion</Title>
     <ISBN>0201674866</ISBN>
     <Author>Neil Bradley</Author>
     <Publisher>Addison-Wesley</Publisher>
     <PublishDate>October 1999</PublishDate>
     <UnitPrice>27.95</UnitPrice>
     <Quantity>2</Quantity>
   </Item>
   <Item>
     <Title Category='Computer' Form='Paperback' Edition='2'>A Complete Guide to DB2 Universal Database</Title>
     <ISBN>0201674866</ISBN>
     <Author>Neil Bradley</Author>
     <Publisher>Morgan Kaufmann Publishers</Publisher>
     <PublishDate>April 1998</PublishDate>
     <UnitPrice>42.95</UnitPrice>
     <Quantity>1</Quantity>
   </Item>
   <Item>
     <Title Category='Computer' Form='Hardcover' Edition='0'>JAVA 2 Developers Handbook</Title>
     <ISBN>0782121799</ISBN>
     <Author>Philip Heller, Simon Roberts </Author>
     <Publisher>Sybex, Inc.</Publisher>
     <PublishDate>September 1998</PublishDate>
     <UnitPrice>59.99</UnitPrice>
     <Quantity>1</Quantity>
   </Item>
 </Purchases>
 <StoreRecords/>
 <DirectMail/>
 <Error/>
</Invoice>)

]
[
2. Metadata(Timestamp=2017-09-05T21:19:07.758|MessageType=XML|Protocol=Queue)

Header(<MQMD><SourceQueue>IN.Q</SourceQueue><Transactional>true</Transactional><Encoding>546</Encoding><CodedCharSetId>437</CodedCharSetId><Format>        </Format><Version>2</Version><Report>0</Report><MsgType>8</MsgType><Expiry>-1</Expiry><Feedback>0</Feedback><Priority>0</Priority><Persistence>0</Persistence><MsgId>414d5120494239514d47522020202020657ca5592041700e</MsgId><CorrelId>000000000000000000000000000000000000000000000000</CorrelId><BackoutCount>0</BackoutCount><ReplyToQ>                                                </ReplyToQ><ReplyToQMgr>IB9QMGR                                         </ReplyToQMgr><UserIdentifier>vaithu</UserIdentifier><AccountingToken>160105150000002d74cc5dfa721e73431607412b32030000000000000000000b</AccountingToken><ApplIdentityData>                                </ApplIdentityData><PutApplType>11</PutApplType><PutApplName>:\Softwares\ih03\rfhutil.exe</PutApplName><PutDate>2017-09-06</PutDate><PutTime>01:19:07.600</PutTime><ApplOriginData>    </ApplOriginData><GroupId>000000000000000000000000000000000000000000000000</GroupId><MsgSeqNumber>1</MsgSeqNumber><Offset>0</Offset><MsgFlags>0</MsgFlags><OriginalLength>-1</OriginalLength></MQMD>)

Output(<?xml version="1.0" encoding="UTF-8"?>
<Invoice>
 <InvoiceNo>7</InvoiceNo>
 <InvoiceDate>2000-12-07</InvoiceDate>
 <InvoiceTime>12:40:00</InvoiceTime>
 <TillNumber>3</TillNumber>
 <Cashier StaffNo='089'>Mary</Cashier>
 <Customer>
   <FirstName>Andrew</FirstName>
   <LastName>Smith</LastName>
   <Title>Mr</Title>
   <DOB>20-01-70</DOB>
   <PhoneHome>01962818000</PhoneHome>
   <PhoneWork />
   <Billing>
     <Address>14 High Street</Address>
     <Address>Hursley Village</Address>
     <Address>Hampshire</Address>
     <PostCode>SO213JR</PostCode>
   </Billing>
 </Customer>
 <Payment>
   <CardType>Visa</CardType>
   <CardNo>4921682832258418</CardNo>
   <CardName>Mr Andrew J. Smith</CardName>
   <Valid>1200</Valid>
   <Expires>1101</Expires>
 </Payment>
 <Purchases>
   <Item>
     <Title Category='Computer' Form='Paperback' Edition='2'>The XML Companion</Title>
     <ISBN>0201674866</ISBN>
     <Author>Neil Bradley</Author>
     <Publisher>Addison-Wesley</Publisher>
     <PublishDate>October 1999</PublishDate>
     <UnitPrice>27.95</UnitPrice>
     <Quantity>2</Quantity>
   </Item>
   <Item>
     <Title Category='Computer' Form='Paperback' Edition='2'>A Complete Guide to DB2 Universal Database</Title>
     <ISBN>0201674866</ISBN>
     <Author>Neil Bradley</Author>
     <Publisher>Morgan Kaufmann Publishers</Publisher>
     <PublishDate>April 1998</PublishDate>
     <UnitPrice>42.95</UnitPrice>
     <Quantity>1</Quantity>
   </Item>
   <Item>
     <Title Category='Computer' Form='Hardcover' Edition='0'>JAVA 2 Developers Handbook</Title>
     <ISBN>0782121799</ISBN>
     <Author>Philip Heller, Simon Roberts </Author>
     <Publisher>Sybex, Inc.</Publisher>
     <PublishDate>September 1998</PublishDate>
     <UnitPrice>59.99</UnitPrice>
     <Quantity>1</Quantity>
   </Item>
 </Purchases>
 <StoreRecords/>
 <DirectMail/>
 <Error/>
</Invoice>>)

LocalEnvironment(<WrittenDestination><MQ><DestinationData><queueName>OUT.Q</queueName><queueManagerName></queueManagerName><replyIdentifier>414d5120494239514d47522020202020657ca5592041700e</replyIdentifier><msgId>414d5120494239514d47522020202020657ca5592041700e</msgId><correlId>000000000000000000000000000000000000000000000000</correlId><GroupId>000000000000000000000000000000000000000000000000</GroupId></DestinationData></MQ></WrittenDestination>)

TransactionCompletedIn:00:00:00.142
Status:Success
]

Interested to buy these nodes, please connect with us at support@vaithu.com/WhatsApp +1 6123058684.

Local Environment Overriding Procedures in ESQL

Every time, we either Google or go to Help to find the statement to set dynamically destination queue name, file name, file directory and web service url etc and thought of creating a library which contains all these procedures so that it would be very handy and saves lot of time. Here is a list which you can use freely and save your precious time.

If you are looking for IIB training , support please connect with us at support@vaithu.com/ WhatsApp +1 6123058684.

-- COMPLETE ESQL TO Update
-- LocalEnvironment.Variables,
-- LocalEnvironment.Destination
-- LocalEnvironment.WrittenDestination
-- LocalEnvironment.Adapter
-- LocalEnvironment.Database
-- LocalEnvironment.CD and LocalEnvironment.CD.Transfer
-- LocalEnvironment.DecisionServices
-- LocalEnvironment.File
-- LocalEnvironment.FTE and LocalEnvironment.FTE.Transfer
-- LocalEnvironment.JMS
-- LocalEnvironment.Mapping
-- LocalEnvironment.ServiceRegistry
-- LocalEnvironment.SOAP
-- LocalEnvironment.TCPIP 
-- LocalEnvironment/Aggregation/Timeout'
-- MQ NODE OVVERRIDES STARTS---

CREATE PROCEDURE SetQManager (IN ref REFERENCE,IN myQManagerName CHARACTER)
BEGIN
  SET ref.Destination.MQ.DestinationData.queueManagerName = myQManagerName;
END;	 


CREATE PROCEDURE SetQName(IN ref REFERENCE,IN myQueueName CHARACTER)
BEGIN
  SET ref.Destination.MQ.DestinationData.queueName = myQueueName;
END;
---------------------------------------------------------------------------------------------
-- MQGet node - QueueName InitialBufferSize MQGMO.*

CREATE PROCEDURE SetMQGetQName (IN InputLocalEnvironment REFERENCE,IN MQGETQueue CHARACTER)
BEGIN
  SET InputLocalEnvironment.MQ.GET.QueueName = MQGETQueue;
END;

CREATE PROCEDURE SetMQGETWaitInter(IN InputLocalEnvironment REFERENCE,IN InterWaitTime CHARACTER)
BEGIN
  SET InputLocalEnvironment.MQ.GET.MQGMO.WaitInterval = InterWaitTime;
END;

CREATE PROCEDURE SetMQGETOptions(IN InputLocalEnvironment REFERENCE, IN MQGMO_ACCEPT_TRUNCATED_MSG CHARACTER)
BEGIN
  SET InputLocalEnvironment.MQ.GET.MQGMO.Options = MQGMO_ACCEPT_TRUNCATED_MSG;
END;

CREATE PROCEDURE SetMQGETBuffer(IN InputLocalEnvironment REFERENCE, IN BufferSize CHARACTER)
BEGIN
  SET InputLocalEnvironment.MQ.GET.InitialBufferSize = BufferSize;
END;
-- MQGet node Overrides ----ENDS-----
-- HTTPAsyncRequest node Ovverrides
-- Compression Overrides the Use compression property
CREATE PROCEDURE SetHTTPAsyReqeqCompression(IN OutputLocalEnvironment REFERENCE,IN gzip CHARACTER)
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.Compression = gzip;
END;
-- To set a minimum size (in bytes) at which compression is applied, use the following override:
CREATE PROCEDURE SetHTTPAsyReqeqMinCompressionSize(IN OutputLocalEnvironment REFERENCE,IN CompressionSize CHARACTER)
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.MinimumCompressionSize = CompressionSize;
END;
--RequestLine.RequestURI Overrides the RequestURI, which is the path after the URL and port
--SET OutputLocalEnvironment.Destination.HTTP.RequestLine.RequestURI = '/abc/def';

CREATE PROCEDURE SetHTTPAsyReqRequestURI(IN OutputLocalEnvironment REFERENCE ,IN URI CHARACTER)
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.RequestLine.RequestURI = URI;
END;
--RequestLine.HTTPVersion Overrides the HTTP version property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.RequestLine.HTTPVersion = 'HTTP/1.1';
CREATE PROCEDURE SetHTTPAsyReqHTTPVersion(IN OutputLocalEnvironment REFERENCE ,IN HTTPVersion CHARACTER)
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.RequestLine.HTTPVersion = HTTPVersion;
END;
--RequestLine.Method Overrides the HTTP method property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.RequestLine.Method = 'GET';

CREATE PROCEDURE SetHTTPAsyReqMethod(IN OutputLocalEnvironment REFERENCE ,IN GetorPost CHARACTER)
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.RequestLine.Method = GetorPost;
END;
--RequestURL Overrides the Web service URL property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.RequestURL = 'http://ibm.com/abc/';
CREATE PROCEDURE SetHTTPAsyReqRequestURL(IN OutputLocalEnvironment REFERENCE ,IN RequestURL CHARACTER)
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.RequestURL = RequestURL;
END;
--SSL authentication alias Overrides the SSL authentication alias for the client-side of an HTTP connection on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.KeyAlias = 'Key1Alias';
CREATE PROCEDURE SetHTTPAsyReqKeyAlias(IN OutputLocalEnvironment REFERENCE ,IN KeyAlias CHARACTER)
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.KeyAlias = KeyAlias;
END;
--SSLProtocol Overrides the SSLProtocol. For example:
--SET OutputLocalEnvironment.Destination.HTTP.SSLProtocol = 'TLS';
--Valid values are: SSL, SSLv3, and TLS.
CREATE PROCEDURE SetHTTPAsyReqSSLProtocol(IN OutputLocalEnvironment REFERENCE ,IN SSL0rSSLv3orTLS CHARACTER)
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.SSLProtocol = SSL0rSSLv3orTLS;
END;
--SSLCiphers Overrides the Allowed SSL Ciphers property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.SSLCiphers =
-- 'SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA';

CREATE PROCEDURE SetHTTPAsyReqSSLCiphers(IN OutputLocalEnvironment REFERENCE ,IN SSLCiphers CHARACTER)
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.SSLProtocol = SSLCiphers;
END;
--UserContext You can store BLOB context data in the following location in the local environment. The HTTPAsyncResponse node can later retrieve this data.
--SET OutputLocalEnvironment.Destination.HTTP.UserContext = x'aabbccddeeff11223344556677889900';
--Data stored in the UserContext must be in BLOB format.
CREATE PROCEDURE SetHTTPAsyReqUserContext(IN OutputLocalEnvironment REFERENCE ,IN UserContext BLOB)
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.SSLProtocol = UserContext;
END;
--Enable CRL checking Overrides the Enable Certificate Revocation List checking property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.EnableCRLCheck = 'true';
CREATE PROCEDURE SetHTTPAsyReqEnableCRLCheck(IN OutputLocalEnvironment REFERENCE ,IN EnableCRLCheck CHARACTER)
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.SSLProtocol = EnableCRLCheck;
END;

--ProxyConnectHeaders Specifies additional headers that are used if the outbound request is an SSL connection through a proxy. These additional headers are sent with the initial CONNECT request to the proxy. For example, you can send proxy authentication information to a proxy server when you are using SSL. You can send multiple headers but each one must be separated by a carriage return and a line feed (ASCII 0x0D 0x0A), in accordance with RFC2616; for example:
--DECLARE CRLF CHAR CAST(X'0D0A' AS CHAR CCSID 1208);
--SET OutputLocalEnvironment.Destination.HTTP.ProxyConnectHeaders =
--'Proxy-Authorization: Basic Zm5lcmJsZTpwYXNzd29yZA==' || CRLF ||
--'Proxy-Connection: Keep-Alive' || CRLF;
--This setting is used only if the request is an SSL request through a proxy server. To send proxy authentication information for a non-SSL request, specify the individual headers in the HTTPRequestHeader folder, as shown in the following example:
--SET OutputRoot.HTTPRequestHeader."Proxy-Authorization" =
-- 'Basic Zm5lcmJsZTpwYXNzd29yZA==';
--SET OutputRoot.HTTPRequestHeader."Proxy-Connection" = 'Keep-Alive';
--ProxyURL Overrides the HTTP(S) proxy location property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.ProxyURL = 'my.proxy';
--QueryString Allows the setting of outbound query string parameters. Each parameter must be set individually. For example:
--SET OutputLocalEnvironment.Destination.HTTP.QueryString.param1 = 'my"Value"1';
--SET OutputLocalEnvironment.Destination.HTTP.QueryString.param2 = 'my"Value"2';
--The above ESQL results in the following query string being encoded (according to http://tools.ietf.org/html/rfc3986) and sent with the outbound request:
--?param1=my%22Value%221&param2= my%22Value%222
--If the destination URL already has one or more query parameters, additional parameters specified here are appended to the existing list.
--QueryStringCCSID Specifies that, before encoding, the query string parameters must be converted into a character set other than the default, which is UTF-8. Any query string parameters are first converted into the specified CCSID before the resulting string is encoded, according to RFC3986. For example:
--SET OutputLocalEnvironment.Destination.HTTP.QueryStringCCSID = 943;
--The above ESQL results in any QueryString parameters being converted to the 943 code page before they are encoded. Note: Any query string parameters must contain the data in unicode.
-- HTTPAsyncRequest node Ovverrides ENDS ----------------------
-- HTTPAsyncResponse node Overrides
--You can retrieve context data that was stored by the HTTPAsyncRequest node from the following location in the local environment:
--SET myVar = InputLocalEnvironment.Destination.HTTP.UserContext;
--Context data is stored as a BLOB. To retrieve context data, assign the variable as a BLOB type or use a CAST. For example:
--DECLARE myVar BLOB;
--SET myVar = InputLocalEnvironment.Destination.HTTP.UserContext;
CREATE FUNCTION GETHTTPResUserContext(IN InputLocalEnvironment REFERENCE) RETURNS BLOB
BEGIN
  RETURN InputLocalEnvironment.Destination.HTTP.UserContext;
END;
-- HTTPAsyncResponse node Overrides ENDS ------------------------
-- HTTPRequest node Overrides
--RequestURL Overrides the Web service URL property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.RequestURL = 'http://ibm.com/abc/';
CREATE PROCEDURE SetHTTPReqRequestURL (IN OutputLocalEnvironment REFERENCE, IN RequestURL CHARACTER )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.RequestURL = RequestURL;
END;
--Timeout Overrides the Request timeout (sec) property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.Timeout = 42;
CREATE PROCEDURE SetHTTPReqTimeout (IN OutputLocalEnvironment REFERENCE, IN Timeout CHARACTER )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.Timeout = Timeout ;
END;
--TimeoutMillis Overrides the Request timeout (sec) property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.TimeoutMillis = 5000;
--This property defines the timeout in milliseconds. The value of TimeoutMillis overrides the value for Timeout if both values are set.
CREATE PROCEDURE SetHTTPReqTimeoutMillis (IN OutputLocalEnvironment REFERENCE, IN TimeoutMillis CHARACTER )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.TimeoutMillis = TimeoutMillis;
END;
--ProxyURL Overrides the HTTP(S) proxy location property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.ProxyURL = 'my.proxy';
CREATE PROCEDURE SetHTTPReqProxyURL (IN OutputLocalEnvironment REFERENCE, IN ProxyURL CHARACTER )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.ProxyURL = ProxyURL;
END;
--RequestLine.RequestURI Overrides the RequestURI, which is the path after the URL and port. For example:
--SET OutputLocalEnvironment.Destination.HTTP.RequestLine.RequestURI = '/abc/def';
CREATE PROCEDURE SetHTTPReqRequestURI (IN OutputLocalEnvironment REFERENCE, IN RequestURI CHARACTER )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTPRequestLine.RequestURI = RequestURL;
END;
--RequestLine.HTTPVersion Overrides the HTTP version property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.RequestLine.HTTPVersion = 'HTTP/1.1';
CREATE PROCEDURE SetHTTPReqHTTPVersion (IN OutputLocalEnvironment REFERENCE, IN HTTPVersion CHARACTER )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.RequestLine.HTTPVersion = HTTPVersion;
END;
--KeepAlive Overrides the Enable HTTP/1.1 keep-alive property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.KeepAlive = TRUE;
CREATE PROCEDURE SetHTTPReqKeepAlive (IN OutputLocalEnvironment REFERENCE, IN KeepAlive BOOLEAN )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.KeepAlive = KeepAlive;
END;
--RequestLine.Method Overrides the HTTP method property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.RequestLine.Method = 'GET';
CREATE PROCEDURE SetHTTPReqMethod (IN OutputLocalEnvironment REFERENCE, IN Method CHARACTER )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.RequestLine.Method = Method;
END;
--SSLProtocol Overrides the SSLProtocol. For example:
--SET OutputLocalEnvironment.Destination.HTTP.SSLProtocol = 'TLS';
--Valid values are: SSL, SSLv3, and TLS.
CREATE PROCEDURE SetHTTPReqSSLProtocol(IN OutputLocalEnvironment REFERENCE, IN SSLorSSLv3orTLS CHARACTER )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.SSLProtocol = SSLorSSLv3orTLS;
END;
--SSLCiphers Overrides the Allowed SSL Ciphers property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.SSLCiphers =
-- 'SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA';
CREATE PROCEDURE SetHTTPReqSSLCiphers (IN OutputLocalEnvironment REFERENCE, IN SSLCiphers CHARACTER )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.SSLCiphers = SSLCiphers;
END;
--ProxyConnectHeaders Specifies additional headers that are used if the outbound request is an SSL connection through a proxy. These additional headers are sent with the initial CONNECT request to the proxy. For example, you can send proxy authentication information to a proxy server when you are using SSL. You can send multiple headers but each one must be separated by a carriage return and a line feed (ASCII 0x0D 0x0A), in accordance with RFC2616; for example:
--DECLARE CRLF CHAR CAST(X'0D0A' AS CHAR CCSID 1208);
--SET OutputLocalEnvironment.Destination.HTTP.ProxyConnectHeaders =		
--'Proxy-Authorization: Basic Zm5lcmJsZTpwYXNzd29yZA==' || CRLF ||
--'Proxy-Connection: Keep-Alive' || CRLF;
--This setting is used only if the request is an SSL request through a proxy server. To send proxy authentication information for a non-SSL request, specify the individual headers in the HTTPRequestHeader folder, as shown in the following example:
--SET OutputRoot.HTTPRequestHeader."Proxy-Authorization" =
-- 'Basic Zm5lcmJsZTpwYXNzd29yZA==';
--SET OutputRoot.HTTPRequestHeader."Proxy-Connection" = 'Keep-Alive';
--UseFolderMode Sets the UseFolderMode. Use for bitstream generation; for certain parsers this changes the output bitstream. For example:
--SET OutputLocalEnvironment.Destination.HTTP.UseFolderMode = TRUE;
CREATE PROCEDURE SetHTTPReqUseFolderMode (IN OutputLocalEnvironment REFERENCE, IN UseFolderMode BOOLEAN )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.RequestURL = UseFolderMode;
END;
--QueryString Allows the setting of outbound query string parameters. Each parameter must be set individually. For example:
--SET OutputLocalEnvironment.Destination.HTTP.QueryString.param1 = 'my"Value"1';
--SET OutputLocalEnvironment.Destination.HTTP.QueryString.param2 = 'my"Value"2';
--The above ESQL results in the following query string being encoded (according to http://tools.ietf.org/html/rfc3986) and sent with the outbound request:
--?param1=my%22Value%221&param2= my%22Value%222
--If the destination URL already has one or more query parameters, additional parameters specified here are appended to the existing list.
--QueryStringCCSID Specifies that, before encoding, the query string parameters must be converted into a character set other than the default, which is UTF-8. Any query string parameters are first converted into the specified CCSID before the resulting string is encoded, according to RFC3986. For example:
--SET OutputLocalEnvironment.Destination.HTTP.QueryStringCCSID = 943;
--The above ESQL results in any QueryString parameters being converted to the 943 code page before they are encoded. Note: Any query string parameters must contain the data in unicode.
--Compression Overrides the Use compression property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.Compression =
-- 'gzip';
CREATE PROCEDURE SetHTTPReqCompression (IN OutputLocalEnvironment REFERENCE, IN Compression CHARACTER )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.Compression = Compression;
END;
--To set a minimum size (in bytes) at which compression is applied, use the following override:
--SET OutputLocalEnvironment.Destination.HTTP.MinimumCompressionSize = 1048576;
--SSL authentication alias Overrides the SSL authentication alias property for the client-side of an HTTP connection on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.KeyAlias = 'Key1Alias';
CREATE PROCEDURE SetHTTPReqKeyAlias(IN OutputLocalEnvironment REFERENCE, IN KeyAlias CHARACTER )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.KeyAlias = KeyAlias;
END;
--Enable CRL checking Overrides the Enable Certificate Revocation List checking property on the node. For example:
--SET OutputLocalEnvironment.Destination.HTTP.EnableCRLCheck = 'true';
CREATE PROCEDURE SetHTTPReqEnableCRLCheck (IN OutputLocalEnvironment REFERENCE, IN EnableCRLCheck BOOLEAN )
BEGIN
  SET OutputLocalEnvironment.Destination.HTTP.EnableCRLCheck = EnableCRLCheck ;
END;
-- HTTPRequest node Overrides ENDS -----------


--LocalEnvironment.File
--LocalEnvironment.File.Read
--LocalEnvironment.WrittenDestination.File
--LocalEnvironment.Destination.File
--LocalEnvironment.Destination.File.Remote
--LocalEnvironment.Wildcard.WildcardMatch
--LocalEnvironment.FTE
--LocalEnvironment.WrittenDestination.FTE
--LocalEnvironment.Destination.FTE
--LocalEnvironment.CD
--LocalEnvironment.CD.Transfer
--LocalEnvironment.Destination.CD
--LocalEnvironment.WrittenDestination.CD

 

ESQL Exercise -1

In a series of ESQL exercises which makes anyone to start writing ESQL very simple and efficient, here is a sample program to demonstrate the same.

The requirement is, you will get a message which will have multiple items inside a complex type called Purchases. Now you need to send the same message as output but Purchases should have only one item at a time. In other words, you need to split the items and each message will have one item.

The input message is

<?xml version="1.0" encoding="UTF-8"?>
<Invoice>
 <InvoiceNo>7</InvoiceNo>
 <InvoiceDate>2000-12-07</InvoiceDate>
 <InvoiceTime>12:40:00</InvoiceTime>
 <TillNumber>3</TillNumber>
 <Cashier StaffNo='089'>Mary</Cashier>
 <Customer>
   <FirstName>Andrew</FirstName>
   <LastName>Smith</LastName>
   <Title>Mr</Title>
   <DOB>20-01-70</DOB>
   <PhoneHome>01962818000</PhoneHome>
   <PhoneWork />
   <Billing>
     <Address>14 High Street</Address>
     <Address>Hursley Village</Address>
     <Address>Hampshire</Address>
     <PostCode>SO213JR</PostCode>
   </Billing>
 </Customer>
 <Payment>
   <CardType>Visa</CardType>
   <CardNo>4921682832258418</CardNo>
   <CardName>Mr Andrew J. Smith</CardName>
   <Valid>1200</Valid>
   <Expires>1101</Expires>
 </Payment>
 <Purchases>
   <Item>
     <Title Category='Computer' Form='Paperback' Edition='2'>The XML Companion</Title>
     <ISBN>0201674866</ISBN>
     <Author>Neil Bradley</Author>
     <Publisher>Addison-Wesley</Publisher>
     <PublishDate>October 1999</PublishDate>
     <UnitPrice>27.95</UnitPrice>
     <Quantity>2</Quantity>
   </Item>
   <Item>
     <Title Category='Computer' Form='Paperback' Edition='2'>A Complete Guide to DB2 Universal Database</Title>
     <ISBN>0201674866</ISBN>
     <Author>Neil Bradley</Author>
     <Publisher>Morgan Kaufmann Publishers</Publisher>
     <PublishDate>April 1998</PublishDate>
     <UnitPrice>42.95</UnitPrice>
     <Quantity>1</Quantity>
   </Item>
   <Item>
     <Title Category='Computer' Form='Hardcover' Edition='0'>JAVA 2 Developers Handbook</Title>
     <ISBN>0782121799</ISBN>
     <Author>Philip Heller, Simon Roberts </Author>
     <Publisher>Sybex, Inc.</Publisher>
     <PublishDate>September 1998</PublishDate>
     <UnitPrice>59.99</UnitPrice>
     <Quantity>1</Quantity>
   </Item>
 </Purchases>
 <StoreRecords/>
 <DirectMail/>
 <Error/>
</Invoice>

and the above message contains, three items under Purchases.

<Purchases>
   <Item>
     <Title Category='Computer' Form='Paperback' Edition='2'>The XML Companion</Title>
     <ISBN>0201674866</ISBN>
     <Author>Neil Bradley</Author>
     <Publisher>Addison-Wesley</Publisher>
     <PublishDate>October 1999</PublishDate>
     <UnitPrice>27.95</UnitPrice>
     <Quantity>2</Quantity>
   </Item>
   <Item>
     <Title Category='Computer' Form='Paperback' Edition='2'>A Complete Guide to DB2 Universal Database</Title>
     <ISBN>0201674866</ISBN>
     <Author>Neil Bradley</Author>
     <Publisher>Morgan Kaufmann Publishers</Publisher>
     <PublishDate>April 1998</PublishDate>
     <UnitPrice>42.95</UnitPrice>
     <Quantity>1</Quantity>
   </Item>
   <Item>
     <Title Category='Computer' Form='Hardcover' Edition='0'>JAVA 2 Developers Handbook</Title>
     <ISBN>0782121799</ISBN>
     <Author>Philip Heller, Simon Roberts </Author>
     <Publisher>Sybex, Inc.</Publisher>
     <PublishDate>September 1998</PublishDate>
     <UnitPrice>59.99</UnitPrice>
     <Quantity>1</Quantity>
   </Item>
 </Purchases>

So, there should be three output messages each containing one item and the message structure should be same as Input. Note the Purchases should be after Payment and the order should not be altered.

The below code ESQL does the splitting and sends the output in the desired format.

BROKER SCHEMA com.vaithu.iib
CREATE COMPUTE MODULE ESQLGuru_Compute
  CREATE FUNCTION Main() RETURNS BOOLEAN
  BEGIN
    
    DECLARE ipRef REFERENCE TO InputRoot.[<].[<];
    DECLARE opRef REFERENCE TO ipRef;
    
    FOR I AS ipRef.Purchases.[] DO
      
      CALL CopyEntireMessage();
      MOVE opRef TO OutputRoot.[<].[<].{'Purchases'};
      MOVE opRef PREVIOUSSIBLING;
      SET OutputRoot.[<].[<].{'Purchases'} = NULL;
      CREATE NEXTSIBLING OF opRef AS opRef NAME 'Purchases';
      SET opRef.{FIELDNAME(I)} = I;
      PROPAGATE;
      
    END FOR;
    
    RETURN FALSE;
  END;

  CREATE PROCEDURE CopyMessageHeaders() BEGIN
    DECLARE I INTEGER 1;
    DECLARE J INTEGER;
    SET J = CARDINALITY(InputRoot.*[]);
    WHILE I < J DO
      SET OutputRoot.*[I] = InputRoot.*[I];
      SET I = I + 1;
    END WHILE;
  END;

  CREATE PROCEDURE CopyEntireMessage() BEGIN
    SET OutputRoot = InputRoot;
  END;
END MODULE;

If you are looking for ESQL training, support and optimization tricks please connect with us at support@vaithu.com/WhatsApp @ +1 6123058684.