Vaadin + Holon UI Components

Button

Components.configure(this)
                .add(Components.button().text("Hello")
                        .icon(VaadinIcon.TRASH)
                        .iconAfterText(true)
                        .withThemeVariants(ButtonVariant.LUMO_ERROR)
                        .withClickListener(event ->
                        {
                            Notification.show("Clicked");
                        })
                        .build());

Calendar

Components.configure(this)
                .add(Components.input.localDate()
                        .label("Calendar")
                        .required()
                        .withValueChangeListener(event -> {
                            Notification.show(event.getValue().toString());
                        })
                        .build());
Components.configure(this)
                .add(Components.input
                        .localDate()
                        .min(LocalDate.now().withDayOfMonth(5))
                        .max(LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth()))
                        .build());

For some reason, the below validation is not working. I’ll look into this again once I learned a bit about Holon Validation.

Components.configure(this)
                .add(Components.input.localDate()
                        .label("Calendar")
                        .required()
                        .validatable()
                        .validateOnValueChange(true)
                        .withValueChangeListener(event -> {
                            Notification.show(event.getValue().toString());
                        })
                        .withValidator(value -> {
                            Validator.greaterOrEqual(value).validate(LocalDate.now());
                        })
                        .build());

CheckBox

Components.configure(this)
                .add(Components.input.boolean_()
                        .label("Check Box")
                        .onClick(event -> {
                            event.toString();
                            Notification.show("Selected");
                        })
                        .build());

Combo Box

Components.configure(this)
                .add(Components.input
                        .singleSelect(String.class)
                        .label("Combo Box")
                        .items("A","B","C")
                        .withValueChangeListener(event -> {
                            Components.dialog.showMessage(event.getValue());
                        })
                        .build());

Email

Components.configure(this)
                .add(Components.input.string()
                        .label("Email")
                        .validatable()
                        .valueChangeMode(ValueChangeMode.EAGER)
                        .validateOnValueChange(true)
                        .withValidator(Validator.email())
                        .withValidator(Validator.min(5))
                        .build());

Textfield

Components.configure(this)
                .add(Components.input
                        .string()
                        .label("Text Field")
                        .placeholder("type here")
                        .withValueChangeListener(event -> {
                            Notification.show(event.getValue());
                        })
                        .build());
Components.configure(this)
                .add(Components.input
                        .string()
                        .label("Text Field")
                        .placeholder("type here")
                        .clearButtonVisible(true)
                        .autoselect()
                        .withValueChangeListener(event -> {
                            Notification.show(event.getValue());
                        })
                        .build());
Components.configure(this)
                .add(Components.input
                        .number(Integer.class)
                        .prefixComponent(new Span("$"))
                        .withValue(100)
                        .validatable()
                        .withValidator(Validator.min(100))
                        .withValidator(Validator.max(105))
                        .preventInvalidInput()
                        .validateOnValueChange(true)
                        .label("Text Field")
                        .withValueChangeListener(event -> {
                            Notification.show(String.valueOf(event.getValue()));
                        })
                        .build());

Password

Components.configure(this)
                .add(Components.input
                        .secretString()
                        .autoselect()
                        .clearButtonVisible(true)
                        .emptyValuesAsNull(true)
                        .required()
                        .validatable()
                        .withValidator(Validator.min(6))
                        .label("Password Field")
                        .withThemeVariants(TextFieldVariant.LUMO_SMALL)
                        .withValueChangeListener(event -> {
                            Notification.show(String.valueOf(event.getValue()));
                        })
                        .build());

 

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

 

 

Creating Queue Manager

What happens when you create a queue manager from MQ Explorer ? Here are the commands that gets executed in the background.

****************************************
* Command: “C:\Program Files (x86)\IBM\WebSphere MQ\bin\crtmqm” -sa ACEQMGR
****************************************
WebSphere MQ queue manager created.
Directory ‘C:\Program Files (x86)\IBM\WebSphere MQ\qmgrs\ACEQMGR’ created.
The queue manager is associated with installation ‘Installation1’.
Creating or replacing default objects for queue manager ‘ACEQMGR’.
Default objects statistics : 77 created. 0 replaced. 0 failed.
Completing setup.
Setup completed.
exitvalue = 0
****************************************
* Command: “C:\Program Files (x86)\IBM\WebSphere MQ\bin\strmqm” ACEQMGR
****************************************
WebSphere MQ queue manager ‘ACEQMGR’ starting.
The queue manager is associated with installation ‘Installation1’.
5 log records accessed on queue manager ‘ACEQMGR’ during the log replay phase.
Log replay for queue manager ‘ACEQMGR’ complete.
Transaction manager state recovered for queue manager ‘ACEQMGR’.
WebSphere MQ queue manager ‘ACEQMGR’ started using V7.5.0.1.
exitvalue = 0
****************************************
* Command: “C:\Program Files (x86)\IBM\WebSphere MQ\bin\runmqsc” ACEQMGR
* Input: DEFINE LISTENER(‘LISTENER.TCP’) TRPTYPE(TCP) PORT(1416) CONTROL(QMGR)
****************************************
5724-H72 (C) Copyright IBM Corp. 1994, 2011. ALL RIGHTS RESERVED.
Starting MQSC for queue manager ACEQMGR.
1 : DEFINE LISTENER(‘LISTENER.TCP’) TRPTYPE(TCP) PORT(1416) CONTROL(QMGR)
AMQ8626: WebSphere MQ listener created.
One MQSC command read.
No commands have a syntax error.
All valid MQSC commands were processed.
exitvalue = 0
****************************************
* Command: “C:\Program Files (x86)\IBM\WebSphere MQ\bin\runmqsc” ACEQMGR
* Input: START LISTENER(‘LISTENER.TCP’)
****************************************
5724-H72 (C) Copyright IBM Corp. 1994, 2011. ALL RIGHTS RESERVED.
Starting MQSC for queue manager ACEQMGR.
1 : START LISTENER(‘LISTENER.TCP’)
AMQ8021: Request to start WebSphere MQ listener accepted.
One MQSC command read.
No commands have a syntax error.
All valid MQSC commands were processed.
exitvalue = 0

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.