How to generate clean properties file from a Bar file?

The standard procedure to generate properties file from a Bar file is to use mqsireadbar command. The problem with this command is, it generates lot of stuffs which we really don’t need.

The ACE developer usually removes the clumsy stuffs from the generated properties to keeps only the required stuffs. Is it something simple to do? NO

If the bar file contains many messages flows/nodes, it is a tedious job to clean up and if any mandatory property is accidentally lost, the impact would be huge and also difficult to identify what is going on in Production.

To solve this problem, we’ve found an automated solution which takes care of

  • Removing unnecessary stuffs
  • Keeping only those that valid
  • Prettyprint the property values
  • Work with latest ACEv12 version
  • Simplifying the process

First, let us see how the properties file looks like when using mqsireadbar command

mqsireadbar -b "C:\Test\RESTRequest_Clientproject.generated.bar" -r > "C:\Test\RESTRequest_Clientproject.generated1.properties"

and the properties file generated is

BIP1052I: Reading Bar file using runtime mqsireadbar...
C:\Test\RESTRequest_Clientproject.generated.bar:
  RESTRequest_Client.appzip (10/11/20 1:05 AM):
    application.descriptor (10/11/20 1:05 AM):
    RESTRequest_Client_inputMessage.xml (10/11/20 1:05 AM):
    RESTRequest_Client.msgflow (10/11/20 1:05 AM):
    Deployment descriptor:
      startMode
      javaIsolation
      RESTRequest_Client#additionalInstances
      RESTRequest_Client#notificationThresholdMsgsPerSec
      RESTRequest_Client#maximumRateMsgsPerSec
      RESTRequest_Client#processingTimeoutSec
      RESTRequest_Client#processingTimeoutAction
      RESTRequest_Client#wlmPolicy
      RESTRequest_Client#commitCount
      RESTRequest_Client#commitInterval
      RESTRequest_Client#coordinatedTransaction
      RESTRequest_Client#consumerPolicySet
      RESTRequest_Client#providerPolicySet
      RESTRequest_Client#consumerPolicySetBindings
      RESTRequest_Client#providerPolicySetBindings
      RESTRequest_Client#securityProfileName
      RESTRequest_Client#monitoringProfile
      RESTRequest_Client#startMode
      RESTRequest_Client#startInstancesWhenFlowStarts
      RESTRequest_Client#HTTP Input.URLSpecifier = /REST/getUser
      RESTRequest_Client#HTTP Input.useHTTPS
      RESTRequest_Client#HTTP Input.decompressInputMessage
      RESTRequest_Client#HTTP Input.timeoutForClient
      RESTRequest_Client#HTTP Input.faultFormat
      RESTRequest_Client#HTTP Input.validateMaster
      RESTRequest_Client#HTTP Input.securityProfileName
      RESTRequest_Client#HTTP Reply.validateMaster
      RESTRequest_Client#getUser.securityIdentity
      RESTRequest_Client#getUser.timeoutForServer
      RESTRequest_Client#getUser.baseURL
      RESTRequest_Client#getUser.httpProxyLocation = http://localhost:7800
      RESTRequest_Client#getUser.enableKeepAlive
      RESTRequest_Client#getUser.requestCompressionType
      RESTRequest_Client#getUser.protocol
      RESTRequest_Client#getUser.allowedCiphers
      RESTRequest_Client#getUser.hostnameChecking
      RESTRequest_Client#getUser.keyAlias
      RESTRequest_Client#getUser.enableCRLCheck
      RESTRequest_Client#getUser.acceptCompressedResponses = true
      RESTRequest_Client#getUser.validateMaster
      RESTRequest_Client#getUser.securityProfileName

BIP8071I: Successful command completion.

Now After using the solution we’ve developed, the output looks like this

RESTRequest_Client#HTTP Input.URLSpecifier = /REST/getUser
RESTRequest_Client#getUser.httpProxyLocation = http://localhost:7800
RESTRequest_Client#getUser.acceptCompressedResponses = true

As you can see, those clutters are removed and provides you really what you want.

How this solution works? Here is the java code which does the magic

import com.ibm.integration.admin.proxy.BarFile;
import com.ibm.integration.admin.proxy.DeploymentDescriptor;

import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

public class GeneratePropertiesFile {

    public static String fileChooser(String ext) {

        String file = null;

        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        fileChooser.setAcceptAllFileFilterUsed(false);
        fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("*."
                + ext, ext));
        if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION
                && fileChooser.getSelectedFile().getAbsolutePath()
                .endsWith(ext)) {
            file = fileChooser.getSelectedFile().getAbsolutePath();
        }

        return file;

    }

    public static void savePropFile(String propFileName, List<String> propLines) throws IOException {
        JFileChooser jfc = new JFileChooser();
        File file = new File(propFileName);
        jfc.setSelectedFile(file);

        jfc.setCurrentDirectory(file.getParentFile());

        jfc.setDialogTitle("Save As ");
        jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
        jfc.setAcceptAllFileFilterUsed(false);
        jfc.addChoosableFileFilter(new FileNameExtensionFilter("*.properties", "properties"));

        if (jfc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
            file = jfc.getSelectedFile();
            if (file == null) {
                System.out.println("Not a valid file");
            } else {

                if (!file.getName().toLowerCase().endsWith(".properties")) {
                    file = new File(file.getParentFile(), file.getName()
                            + ".properties");
                }
                System.out.println(file);
                Files.write(Paths.get(file.getAbsolutePath()), propLines);
                JOptionPane.showMessageDialog(null,"Properties file successfully generated");
            }

        }
    }

        public static void main (String[]args){

            String outBar = fileChooser("bar");

            List<String> lines = new ArrayList<>();

            try {
                Collections.list(BarFile.loadBarFile(outBar).getBarEntries())
                        .stream()
                        .filter(barEntry -> barEntry.isApplication() || barEntry.isLibrary()
                                || barEntry.isSharedLibrary())
                        .forEach(barEntry -> {

                            try {
                              ..............................................
                            } catch (IOException e) {
                                e.printStackTrace();
                                JOptionPane.showMessageDialog(null,
                                        "Error occurred, check the stacktrace for more details");
                            }
                        });

                if (lines.isEmpty()) {
                    JOptionPane.showMessageDialog(null,
                            "No overridable properties found");
                } else {
                    savePropFile(outBar.substring(0,outBar.lastIndexOf(".")), lines);
                }

            } catch (IOException e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(null,
                        "Error occurred, check the stacktrace for more details");
            }
        }
    }

Once you run this java program, it will ask you the bar file location

Select the bar file

Next, it will ask you to choose the properties file location with pre-populated name

Once the properties file is generated, it shows an acknowledgement message

The properties file generated was

RESTRequest_Client#HTTP Input.URLSpecifier = /REST/getUser
RESTRequest_Client#getUser.httpProxyLocation = http://localhost:7800
RESTRequest_Client#getUser.acceptCompressedResponses = true

To buy this solution, please contact us at support@vaithu.com.

We’ve more than 15+ years of experience in ACE(formerly WMB/IIB). If you’re looking for consultation or any assistance, please contact us at support@vaithu.com.

ACE Explorer

If you’re like us working on WMB since v6.1, we all know how much the product has changed so far. We’re working on the latest version ACEv12 for a migration project which is to migrate from IIBv10 to ACEv12. The client is using a custom application for all administrative tasks and is completely built using IBM Integration JAVA API.

As the product architecture has changed dramatically in ACE, IIB v10 APIs are deprecated so the current custom application won’t work AS IS. So, it has be re-written from scratch and today we’re able to get the ActivityLog working.

Here is the screenprint showing all message flows and one of the flow’s activity log.

ACE Explorer

Activity Log

The current version ACE12.0.3 doesn’t support deploying a bar file with a overriding property file. But, we added this feature to simplify the life of both developers/administrators. All, you’ve to do is, choose the Integration server in which you’d like to deploy, drag the bar file and properties file then click the Deploy Bar button located at the bottom.

image.png

If you’re using IIBv10 Integration API and looking for any assistance, please contact us at support@vaithu.com.

Also, we’d like to know the features you’re expecting in the Web UI. You can put them in the comments section. We’ll try our best to get them into ACE Buddy. Those who provide good suggestions would get ACE Buddy free license for ONE year.

Mastering ESQL In One Day

Can someone master ESQL in just one day? YES, ESQL is not like any other programming language which has lot of statements and libraries to know. It is the most simplest language that I’ve ever seen.

The statements are limited, syntax is simple and learning is super easy. As an ACE/IIB developer, what do you do most of the time? Writing ESQL code right? Then, are you harvesting the real power of ESQL?

This one day training program is going to show you the real power of ESQL. It is going to explain you from the basics to advanced statements with examples

Here is what we’re going to cover in the course.

  1. Introduction
  2. Data Types
    1. Boolean
      1. TRUE
      2. FALSE
      3. UNKNOWN
    2. DateTime
    3. NULL
    4. Numeric
      1. DECIMAL
      2. FLOAT
      3. INTEGER
    5. Reference
    6. String
      1. BIT
      2. BLOB
      3. CHARACTER
  3. Correlation Names
    1. Root
    2. FirstChild
    3. LastChild
    4. FirstSibling
    5. NextSibling
    6. PreviousSibling
    7. LastSibling
  4. Message Components
    1. Properties
    2. Message Domain
    3. Environment
    4. Local Environment
    5. Exception List
  5. Variables
    1. Declaration
    2. Normal
    3. External
    4. Shared
    5. Scope
  6. Operators
    1. Simple Comparison 
      1. >, >=, <, <=, <> & =
    2. Complex Comparison
      1. BETWEEN
      2. EXISTS
      3. IN
      4. IS
      5. LIKE
      6. SINGULAR
    3. Logical
      1. AND
      2. OR
      3. NOT
    4. Numeric
    5. String
  7. Field References
  8. Field Types
    1. NAME
    2. TYPE
    3. NAMEVALUE
  9. Conditional Statements
    1. IF….ELSEIF…..ELSE
    2. CASE
      1. Simple
      2. Searched
  10. Looping Statements
    1. REPEAT UNTIL
    2. WHILE
    3. FOR
    4. LABELED LOOP
    5. ITERATE
    6. LEAVE
    7. RETURN
  11. Error Handling
    1. THROW
    2. DECLARE HANDLER
  12. Modules
    1. Procedures
    2. Functions
    3. CALL
    4. MOVE
    5. LASTMOVE
  13. Handling NULL values
  14. Propagating Multiple Messages
  15. List Functions
    1. CARDINALITY
    2. EXISTS
    3. SINGULAR
    4. THE
    5. ITEM
  16. Complex Functions
    1. CAST
    2. FORMAT
    3. SELECT
      1. Simple
      2. Complex
    4. ROW
    5. LIST
    6. ROW & LIST Combined
  17. Working with Database
    1. INSERT
    2. SELECT
    3. UPDATE
    4. DELETE
    5. PASSTHRU
    6. Stored Procedures
  18. Manipulating repeating fields
  19. Calling Java methods
  20. String Functions
    1. CONTAINS
    2. ENDSWITH
    3. LEFT
    4. LENGTH
    5. LOWER
    6. LTRIM
    7. OVERLAY
    8. POSITION
    9. REPLACE
    10. REPLICATE
    11. RIGHT
    12. RTRIM
    13. SPACE
    14. STARTSWITH
    15. SUBSTRING
    16. TRANSLATE
    17. TRIM
    18. UPPER
  21. Miscellaneous
    1. ATTACH
    2. DETACH
    3. PATH
    4. BROKER SCHEMA
    5. DECLARE
    6. CREATE FIELD
    7. DELETE FIELD
    8. COALESCE 
    9. SLEEP
    10. UUIDASCHAR
    11. ASBITSTREAM
    12. EXTRACT

As the trainer has more than 15+ years of experience in ESQL, you can ask him any questions related to ESQL. If you’ve complex requirement, ask him how to resolve it during the training. So, why wait ?

Enroll into the training program and become a Master in ESQL in One Day.

Event Address: Online
Contact us at (612) 305-8684 or support@vaithu.com

Course Fee: USD : 75$/ INR 5000

To register the training, click here : shorturl.at/bpuLO

Alternative Link : https://docs.google.com/forms/d/e/1FAIpQLSd9GuiYIV7Kh18MwLUjqbwqFHL-n4RGl68Goaxm3LShMvV03A/viewform?entry.2109138769=Yes

ACE Buddy

One tool for all your ACE needs like MQ testing, Kafka Testing, String manipulations, Proprty file generator and KafKa Editor.

If you’ve any suggestions or questions, feel free to ask in the comments. We’ll try to include those as well in our next release.

Message Set to DFDL Automatic Conversion

Daffodils

Recently we’ve started working on migrating stuffs from WMBv7 to ACEv12. The biggest challenge we’ve encountered is so far is, converting the message sets to DFDLs. Please note I’m talking about Custom Wire Formats not Cobol copy books.

I’d say it is one of the most difficult task I’ve encountered so far because the messages sets are all EDIFACT ( IBM 500 ) messages with different initiators, separators and terminators along with various padding characters and justification configuration.

So, thought of finding some automatic solution in Google but no luck. There are 100+ models need to be converted in next couple of months. All I can do so far is, write a java program to read the MXSD files and clean up the unnecessary stuffs. Also, tried to have the group indicators/terminators and delimiters converted into DFDL annotations.

This is not a 100% working solution but definitely helping a lot to quickly have the DFDL created. If you’ve any better solution, please feel free to add in the comments.

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileSystemView;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;


public class TDSCleaner {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		JFileChooser jfc = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());

        int returnValue = jfc.showOpenDialog(null);

        if (returnValue == JFileChooser.APPROVE_OPTION) {
            File selectedFile = jfc.getSelectedFile();
            System.out.println(selectedFile.getAbsolutePath());
            
            Path path = Paths.get(selectedFile.getAbsolutePath());
            
            List&lt;String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
            List&lt;String> newLine = new ArrayList&lt;>();
            /*String rootElm = JOptionPane.showInputDialog("Enter the root element name");
            
            
            if (rootElm != null) {
				rootElm = "       01  "+FilenameUtils.getBaseName(selectedFile.getAbsolutePath())+".";
				newLine.add(rootElm);
			}
            
            String rootElm =  "       01  "+FilenameUtils.getBaseName(selectedFile.getAbsolutePath())+".";
            newLine.add(rootElm);*/
            String delimiter,groupTerminator,groupIndicator;
            delimiter = null;
    		groupTerminator = null;
    		groupIndicator = null;
            
            for (String line : lines) {
				
            	if (!StringUtils.containsAny(line, "annotation","appinfo",
            			"MRMessage","MRMessage","MRComplexType","tdsElemRep"))  {
					
            		if (line.contains("tdsStructRep")) {
            			
            			line = StringUtils.replace(line, "&amp;lt;U+001D&amp;gt;", "%GS;");
            			line = StringUtils.replace(line, "&amp;lt;U+001C&amp;gt;", "%FS;");
            			
            			if (line.contains("groupIndicator")) {
							groupIndicator = "dfdl:initiator="+StringUtils.substringBetween(line, "groupIndicator=", " ");
						}
            			
            			if (line.contains("groupTerminator")) {
            				groupTerminator = "dfdl:terminator="+StringUtils.substringBetween(line, "groupTerminator=", " ");
						}
            			
            			if (line.contains("delimiter")) {
            				delimiter = "dfdl:separator="+StringUtils.substringBetween(line, "delimiter=", " ");
						}
            			
            			continue;
            			
					}
            		
            		if (line.contains("&lt;xsd:sequence")) {
            			
            			if (delimiter != null) {
            				line = StringUtils.replace(line, ">", " ")+delimiter+">";
						}
            			
            			if (groupIndicator != null) {
            				line = StringUtils.replace(line, ">", " ")+groupIndicator+">";
						}
            			
            			if (groupTerminator != null) {
            				line = StringUtils.replace(line, ">", " ")+groupTerminator+">";
						}
            			
            		}
            		
            		
            		delimiter = null;
            		groupTerminator = null;
            		groupIndicator = null;
            		
            		newLine.add(line);
            		System.out.println(line);
				}
            	
			}
            
            if (!lines.isEmpty()) {
            	
            	String cpyFileName = FilenameUtils.getFullPath(selectedFile.getAbsolutePath())
            			+"Modified_"+FilenameUtils.getBaseName(selectedFile.getName())+".xsd";
            	System.out.println(cpyFileName);
            	
            	FileUtils.writeLines(new File(cpyFileName), newLine);
            	
            	JOptionPane.showMessageDialog(null, "File created successfully");
				
			} else {
				JOptionPane.showMessageDialog(null, "Lines are empty check your source file");
			}
        }

	}

}

IIB to ACE

Some of the notes we’ve taken while working on a migration project from IIB to ACE. If you see anything has changed or provided incorrectly, feel free put those in the comments and we’d update this post with your comments.

  1. App Connect Enterprise v11 (first released 2018):
    1. Onpremise + Cloud
    1. IIB + App Connect Professional
    1. Local -> Toolkit ; Cloud -> Designer
  2. Integration Node is optional
  3. Integration Servers can run independently
  4. Configurable services are replaced with Policy files
  5. Local queue manager is required if Collector, Timer and Aggregate nodes are used.
  6. One Web UI can show any number of Integration Servers & Nodes
  7. Not all features available in v10 Web UI are available in ACE V11 but soon they will be available
  8. Flow and Resource Statistics are turned on by default
  9. Some mqsi commands are not available like mqsiformatlog, mqsireadlog, mqsimigratecomponents, mqsideleteconfigurableservice
  10. IIB End of Support is announced as Apr 2022
  11. ACE can run in on-premise and cloud
  12. Use TransformationAdvisor for the migration plan and impact
  13. App Connect Standard is effectively IIB standard with the addition of the Salesforce Request node whereas App Connect Enterprise is the official successor to IIB and includes the ACE V11 software, App Connect Professional V7.5.2 as well as the IBM App Connect on Cloud Service.
  14. A new administrative REST APIv2 for configuring App Connect Enterprise servers
  15. All Runtime node properties can be modified using server.conf.yml file
  16. IBM App Connect professional has 100+ connectors
  17. If there is any project created in older versions like WMB v6/v7 or anything as integration project, those would be deployed into a default Application project.
  18. Integration projects are no longer encouraged. Any attempt to subsequent redeploy independent resources will replace the entire content of the default application of an integration server with the new BAR file’s independent resources.
  19. New REST API testing utility in admin Web UI
  20. Migration
    1. Parallel Migration
      1. Install your ACEv11 environment,
      1. Configure the environment manually from scratch or reuse command scripts from IIBv10
      1. Take a branch in version control and then deploy your BAR files to the new environment
    1. Parallel Migration using extraction to help
      1. Install your ACEv11 environment
      1. Use mqsiextractcomponents to configure the v11 environment (this will help to create policies for you from config services for example) to help ensure you don’t forget configuration from your v10 system. Discard the run directory contents, because instead you are going to deploy items to the new system one by one as the next action
      1. Take a branch in version control and then deploy your BAR files to the new environment.
    1. Big Bang using extraction
      1. Install your ACEv11 environment
      1. Use mqsiextractcomponents to configure the v11 environment (this will help to create policies for you from config services for example) to help ensure you don’t forget configuration from your v10 system. Don’t discard the run directory contents
      1. Restart the integration node.
  21. There is no change in the project types. It is same as v10.
    1. Application (same as v10)
    1. Library (same as v10)
    1. Shared Library (same as v10)

How do I capture the messages on the fly in IIB?

IBM has provided lot of ways to capture the messages flowing through our message flows. In this post, we are going to discuss about one of them and it is also one of the most unnoticed.

IIB allows you to capture the messages by enabling monitoring profile or by writing custom subflows or using trace nodes.

The most frequently used one is subflows and now a days people use monitoring profile too a lot. There are companies which do not have logs at all ( don’t know how they survive).

Have you ever used Record & Replay? If not, just google to get some basic idea on how that works.

This post is also utilizing the same Record & Replay concept but it does on the fly. I do not have any database setup to store the messages permanently. Just going with built-in capacity of the Integration node.

Let me put here the sequence of steps to achieve this

  1. Enable recording
  2. Enable Injection
  3. Retrieve Recorded Message

Let me put here the Java APIs used here

public void enableRecording(ExecutionGroupProxy proxy, boolean status) throws ConfigManagerProxyLoggedException, ConfigManagerProxyPropertyNotInitializedException {
		
		if (status) {
			proxy.setTestRecordMode(AttributeConstants.MODE_ENABLED);
		}else {
			// clear recorded data and reset server to turn off recording and injection
			proxy.clearRecordedTestData();
			proxy.setTestRecordMode(AttributeConstants.MODE_DISABLED);
		}
		
		enableInjection(proxy, status);
	}
	
	public void enableInjection(ExecutionGroupProxy proxy, boolean status) throws ConfigManagerProxyLoggedException, ConfigManagerProxyPropertyNotInitializedException {
		
		if (status) {
			proxy.setInjectionMode(AttributeConstants.MODE_ENABLED);
		}else {
			// clear recorded data and reset server to turn off recording and injection
			proxy.setInjectionMode(AttributeConstants.MODE_DISABLED);
		}
	}
public List<RecordedTestData> retreiveRecordedMessage(MessageFlowProxy mf) throws ConfigManagerProxyPropertyNotInitializedException, ConfigManagerProxyLoggedException {
		
		Properties filterProps = new Properties();
		String name = getApplication(mf).getName();
//		System.out.println(name);
		if (name != null) {
			filterProps.setProperty(Checkpoint.PROPERTY_APPLICATION_NAME,name);
		}else {
			name = getLibraryProxy(mf).getName();
			if (name != null) {
				filterProps.setProperty(Checkpoint.PROPERTY_LIBRARY_NAME,name);
			}
		}
//		System.out.println(mf.getName());
		filterProps.setProperty(Checkpoint.PROPERTY_MESSAGE_FLOW_NAME,mf.getName());
		
//		ExecutionGroupProxy egProxy = mf.getExecutionGroup();
//		List<RecordedTestData> dataList = egProxy.getRecordedTestData(filterProps);
		
		return mf.getExecutionGroup().getRecordedTestData(filterProps);
	}

That’s it. Once you enable recording, the message flow automatically turns into like this

The recorded message is here (I’ve a UI to make this easier to read)

Here is the local environment message

<localEnvironment xmlns:iib="http://com.ibm.iib/lt/1.0" iib:parser="MQROOT" iib:injectable="true">
   <MQTT>
      <Input>
         <Retained iib:valueType="BOOLEAN">FALSE</Retained>
         <QualityOfService iib:valueType="INTEGER">0</QualityOfService>
         <Topic iib:valueType="CHARACTER">IBM/IntegrationBus/default/Monitoring/Hello</Topic>
         <Duplicate iib:valueType="BOOLEAN">FALSE</Duplicate>
      </Input>
   </MQTT>
</localEnvironment>

And here is the payload

<message xmlns:iib="http://com.ibm.iib/lt/1.0" iib:parser="GENERICROOT" iib:injectable="true">
   <Properties iib:parser="GENERICPROPERTYPARSER">
      <MessageSet iib:valueType="CHARACTER" iib:elementType="0x03000000"></MessageSet>
      <MessageType iib:valueType="CHARACTER" iib:elementType="0x03000000"></MessageType>
      <MessageFormat iib:valueType="CHARACTER" iib:elementType="0x03000000"></MessageFormat>
      <Encoding iib:valueType="INTEGER">546</Encoding>
      <CodedCharSetId iib:valueType="INTEGER">5348</CodedCharSetId>
      <Transactional iib:valueType="BOOLEAN">TRUE</Transactional>
      <Persistence iib:valueType="BOOLEAN">FALSE</Persistence>
      <CreationTime iib:valueType="GMTTIMESTAMP">2021-04-13 16:54:58.451</CreationTime>
      <ExpirationTime iib:valueType="INTEGER">-1</ExpirationTime>
      <Priority iib:valueType="INTEGER">0</Priority>
      <ReplyIdentifier iib:valueType="BLOB"></ReplyIdentifier>
      <ReplyProtocol iib:valueType="CHARACTER">UNKNOWN</ReplyProtocol>
      <Topic iib:elementType="0x03000000"/>
      <ContentType iib:valueType="CHARACTER" iib:elementType="0x03000000"></ContentType>
      <IdentitySourceType iib:valueType="CHARACTER" iib:elementType="0x03000000"></IdentitySourceType>
      <IdentitySourceToken iib:valueType="CHARACTER" iib:elementType="0x03000000"></IdentitySourceToken>
      <IdentitySourcePassword iib:valueType="CHARACTER" iib:elementType="0x03000000"></IdentitySourcePassword>
      <IdentitySourceIssuedBy iib:valueType="CHARACTER" iib:elementType="0x03000000"></IdentitySourceIssuedBy>
      <IdentityMappedType iib:valueType="CHARACTER" iib:elementType="0x03000000"></IdentityMappedType>
      <IdentityMappedToken iib:valueType="CHARACTER" iib:elementType="0x03000000"></IdentityMappedToken>
      <IdentityMappedPassword iib:valueType="CHARACTER" iib:elementType="0x03000000"></IdentityMappedPassword>
      <IdentityMappedIssuedBy iib:valueType="CHARACTER" iib:elementType="0x03000000"></IdentityMappedIssuedBy>
   </Properties>
   <XMLNSC iib:parser="xmlnsc">
      <wmb:event xmlns:wmb="http://www.ibm.com/xmlns/prod/websphere/messagebroker/6.1.0/monitoring/event">
         <wmb:eventPointData>
            <wmb:eventData>
               <wmb:productVersion iib:valueType="CHARACTER" iib:elementType="0x03000100">100011</wmb:productVersion>
               <wmb:eventSchemaVersion iib:valueType="CHARACTER" iib:elementType="0x03000100">6.1.0.3</wmb:eventSchemaVersion>
               <wmb:eventSourceAddress iib:valueType="CHARACTER" iib:elementType="0x03000100">MQ Input.transaction.Start</wmb:eventSourceAddress>
               <wmb:eventIdentity>
                  <wmb:eventName iib:valueType="CHARACTER" iib:elementType="0x03000100">OrderReceived</wmb:eventName>
               </wmb:eventIdentity>
               <wmb:eventSequence>
                  <wmb:creationTime iib:valueType="CHARACTER" iib:elementType="0x03000100">2020-06-01T02:02:32.402892Z</wmb:creationTime>
                  <wmb:counter iib:valueType="CHARACTER" iib:elementType="0x03000100">1</wmb:counter>
               </wmb:eventSequence>
               <wmb:eventCorrelation>
                  <wmb:localTransactionId iib:valueType="CHARACTER" iib:elementType="0x03000100">f8a1af6d-013b-4420-9c1b-baf23d5e10a4-5</wmb:localTransactionId>
                  <wmb:parentTransactionId iib:valueType="CHARACTER" iib:elementType="0x03000100"></wmb:parentTransactionId>
                  <wmb:globalTransactionId iib:valueType="CHARACTER" iib:elementType="0x03000100"></wmb:globalTransactionId>
               </wmb:eventCorrelation>
            </wmb:eventData>
            <wmb:messageFlowData>
               <wmb:broker>
                  <wmb:name iib:valueType="CHARACTER" iib:elementType="0x03000100">IB10NODE</wmb:name>
                  <wmb:UUID iib:valueType="CHARACTER" iib:elementType="0x03000100">b7d2e6dd-0b36-4728-9015-818133dbeb14</wmb:UUID>
               </wmb:broker>
               <wmb:executionGroup>
                  <wmb:name iib:valueType="CHARACTER" iib:elementType="0x03000100">default</wmb:name>
                  <wmb:UUID iib:valueType="CHARACTER" iib:elementType="0x03000100">61704de3-b47c-4b23-b95f-0ffd934fdcb1</wmb:UUID>
               </wmb:executionGroup>
               <wmb:messageFlow>
                  <wmb:uniqueFlowName iib:valueType="CHARACTER" iib:elementType="0x03000100">IB10NODE.default.TestMon.TestMon</wmb:uniqueFlowName>
                  <wmb:name iib:valueType="CHARACTER" iib:elementType="0x03000100">TestMon</wmb:name>
                  <wmb:UUID iib:valueType="CHARACTER" iib:elementType="0x03000100">429ff9ef-1c8d-48c1-bf42-99ac3bd247fb</wmb:UUID>
                  <wmb:threadId iib:valueType="CHARACTER" iib:elementType="0x03000100">21980</wmb:threadId>
               </wmb:messageFlow>
               <wmb:node>
                  <wmb:nodeLabel iib:valueType="CHARACTER" iib:elementType="0x03000100">MQ Input</wmb:nodeLabel>
                  <wmb:nodeType iib:valueType="CHARACTER" iib:elementType="0x03000100">ComIbmMQInputNode</wmb:nodeType>
                  <wmb:detail iib:valueType="CHARACTER" iib:elementType="0x03000100">IN.Q</wmb:detail>
               </wmb:node>
            </wmb:messageFlowData>
         </wmb:eventPointData>
         <wmb:applicationData xmlns="">
            <wmb:complexContent>
               <wmb:elementName iib:valueType="CHARACTER" iib:elementType="0x03000100">MQMD</wmb:elementName>
               <MQMD>
                  <SourceQueue iib:valueType="CHARACTER">IN.Q</SourceQueue>
                  <Transactional iib:valueType="CHARACTER">true</Transactional>
                  <Encoding iib:valueType="CHARACTER">273</Encoding>
                  <CodedCharSetId iib:valueType="CHARACTER">1208</CodedCharSetId>
                  <Format iib:valueType="CHARACTER">MQSTR   </Format>
                  <Version iib:valueType="CHARACTER">2</Version>
                  <Report iib:valueType="CHARACTER">0</Report>
                  <MsgType iib:valueType="CHARACTER">8</MsgType>
                  <Expiry iib:valueType="CHARACTER">-1</Expiry>
                  <Feedback iib:valueType="CHARACTER">0</Feedback>
                  <Priority iib:valueType="CHARACTER">0</Priority>
                  <Persistence iib:valueType="CHARACTER">0</Persistence>
                  <MsgId iib:valueType="CHARACTER">414d5120494942763130514d475220204064d15e10000105</MsgId>
                  <CorrelId iib:valueType="CHARACTER">000000000000000000000000000000000000000000000000</CorrelId>
                  <BackoutCount iib:valueType="CHARACTER">0</BackoutCount>
                  <ReplyToQ iib:valueType="CHARACTER">                                                </ReplyToQ>
                  <ReplyToQMgr iib:valueType="CHARACTER">IIBv10QMGR                                      </ReplyToQMgr>
                  <UserIdentifier iib:valueType="CHARACTER">vaithu      </UserIdentifier>
                  <AccountingToken iib:valueType="CHARACTER">160105150000002d74cc5dfa721e73431607412b32030000000000000000000b</AccountingToken>
                  <ApplIdentityData iib:valueType="CHARACTER">                                </ApplIdentityData>
                  <PutApplType iib:valueType="CHARACTER">28</PutApplType>
                  <PutApplName iib:valueType="CHARACTER">vaithu</PutApplName>
                  <PutDate iib:valueType="CHARACTER">2020-06-01</PutDate>
                  <PutTime iib:valueType="CHARACTER">02:02:32.480</PutTime>
                  <ApplOriginData iib:valueType="CHARACTER">    </ApplOriginData>
                  <GroupId iib:valueType="CHARACTER">000000000000000000000000000000000000000000000000</GroupId>
                  <MsgSeqNumber iib:valueType="CHARACTER">1</MsgSeqNumber>
                  <Offset iib:valueType="CHARACTER">0</Offset>
                  <MsgFlags iib:valueType="CHARACTER">0</MsgFlags>
                  <OriginalLength iib:valueType="CHARACTER">-1</OriginalLength>
               </MQMD>
            </wmb:complexContent>
         </wmb:applicationData>
         <wmb:bitstreamData>
            <wmb:bitstream iib:valueType="CHARACTER">TUQgIAIAAAAAAAAACAAAAP////8AAAAAEQEAALgEAABNUVNUUiAgIAAAAAAAAAAAQU1RIElJQnYxMFFNR1IgIEBk0V4QAAEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElJQnYxMFFNR1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN4cDI2NyAgICAgIBYBBRUAAAAtdMxd+nIec0MWB0ErMgMAAAAAAAAAAAALICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAcAAAAZ21haWwuc3Jpbml2YXNhLkFwcGxpY2F0aW9uIDIwMjAwNjAxMDIwMjMyNDggICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAA/////zxPcmRlcnM+CiAgIDxPcmRlcj4KICAgICAgPEN1c3RvbWVySUQ+R1JFQUw8L0N1c3RvbWVySUQ+CiAgICAgIDxFbXBsb3llZUlEPjY8L0VtcGxveWVlSUQ+CiAgICAgIDxPcmRlckRhdGU+MTk5Ny0wNS0wNlQwMDowMDowMDwvT3JkZXJEYXRlPgogICAgICA8UmVxdWlyZWREYXRlPjE5OTctMDUtMjBUMDA6MDA6MDA8L1JlcXVpcmVkRGF0ZT4KICAgICAgPFNoaXBJbmZvIFNoaXBwZWREYXRlPSIxOTk3LTA1LTA5VDAwOjAwOjAwIj4KICAgICAgICAgPFNoaXBWaWE+MjwvU2hpcFZpYT4KICAgICAgICAgPEZyZWlnaHQ+My4zNTwvRnJlaWdodD4KICAgICAgICAgPFNoaXBOYW1lPkdyZWF0IExha2VzIEZvb2QgTWFya2V0PC9TaGlwTmFtZT4KICAgICAgICAgPFNoaXBBZGRyZXNzPjI3MzIgQmFrZXIgQmx2ZC48L1NoaXBBZGRyZXNzPgogICAgICAgICA8U2hpcENpdHk+RXVnZW5lPC9TaGlwQ2l0eT4KICAgICAgICAgPFNoaXBSZWdpb24+T1I8L1NoaXBSZWdpb24+CiAgICAgICAgIDxTaGlwUG9zdGFsQ29kZT45NzQwMzwvU2hpcFBvc3RhbENvZGU+CiAgICAgICAgIDxTaGlwQ291bnRyeT5VU0E8L1NoaXBDb3VudHJ5PgogICAgICA8L1NoaXBJbmZvPgogICA8L09yZGVyPgo8L09yZGVycz4=<wmb:encoding iib:valueType="CHARACTER" iib:elementType="0x03000100">base64Binary</wmb:encoding>
            </wmb:bitstream>
         </wmb:bitstreamData>
      </wmb:event>
   </XMLNSC>
</message>

By this way, if you’ve a need to immediately see what is flowing through your messages, simply implement this solution and see the messages on the fly. Once done, clear up the recordings.

If you’re interested to know more about this solution, feel free to contact us at support@vaithu.com. WhatsApp +1 6123058684.

Setup IIB Logging in 10 minutes

Are you using log4j or any custom subflow to capture the IN and OUT messages but looking for a simple solution which can

  • captures all messages, not just IN & OUT but also exception message
  • captures the header values, environment values etc
  • does not need you to add subflows or log4j node
  • works with simple configuration like enabling monitoring profile and that’s it
  • automatically creates the log based on Node/ServerName/FlowName

A simple flow like this does all the magic for you.

IIB Transaction Monitor Flow
MQTT properties
UDP to specify Log4j config file location
2021-04-11 19:05:14.889 [Thread-30] INFO  - ----------------------------------------Transaction Starts---------------------------------------------------------
2021-04-11 19:05:14.889 [Thread-30] INFO  - Event Number :1
2021-04-11 19:05:14.889 [Thread-30] INFO  - Data Element Name :MQMD
2021-04-11 19:05:14.889 [Thread-30] INFO  - ***********************************************************************
2021-04-11 19:05:14.889 [Thread-30] INFO  - SourceQueue : IN.Q
2021-04-11 19:05:14.889 [Thread-30] INFO  - Transactional : true
2021-04-11 19:05:14.889 [Thread-30] INFO  - Encoding : 273
2021-04-11 19:05:14.889 [Thread-30] INFO  - CodedCharSetId : 1208
2021-04-11 19:05:14.889 [Thread-30] INFO  - Format : MQSTR   
2021-04-11 19:05:14.889 [Thread-30] INFO  - Version : 2
2021-04-11 19:05:14.905 [Thread-30] INFO  - Report : 0
2021-04-11 19:05:14.905 [Thread-30] INFO  - MsgType : 8
2021-04-11 19:05:14.905 [Thread-30] INFO  - Expiry : -1
2021-04-11 19:05:14.905 [Thread-30] INFO  - Feedback : 0
2021-04-11 19:05:14.905 [Thread-30] INFO  - Priority : 0
2021-04-11 19:05:14.905 [Thread-30] INFO  - Persistence : 0
2021-04-11 19:05:14.905 [Thread-30] INFO  - MsgId : 414d5120494942763130514d475220204064d15e10000105
2021-04-11 19:05:14.905 [Thread-30] INFO  - CorrelId : 000000000000000000000000000000000000000000000000
2021-04-11 19:05:14.905 [Thread-30] INFO  - BackoutCount : 0
2021-04-11 19:05:14.905 [Thread-30] INFO  - ReplyToQ :                                                 
2021-04-11 19:05:14.905 [Thread-30] INFO  - ReplyToQMgr : IIBv10QMGR                                      
2021-04-11 19:05:14.905 [Thread-30] INFO  - UserIdentifier : vaithu      
2021-04-11 19:05:14.905 [Thread-30] INFO  - AccountingToken : 160105150000002d74cc5dfa721e73431607412b32030000000000000000000b
2021-04-11 19:05:14.905 [Thread-30] INFO  - ApplIdentityData :                                 
2021-04-11 19:05:14.905 [Thread-30] INFO  - PutApplType : 28
2021-04-11 19:05:14.905 [Thread-30] INFO  - PutApplName : vaithu
2021-04-11 19:05:14.905 [Thread-30] INFO  - PutDate : 2020-06-01
2021-04-11 19:05:14.905 [Thread-30] INFO  - PutTime : 02:02:32.480
2021-04-11 19:05:14.905 [Thread-30] INFO  - ApplOriginData :     
2021-04-11 19:05:14.905 [Thread-30] INFO  - GroupId : 000000000000000000000000000000000000000000000000
2021-04-11 19:05:14.905 [Thread-30] INFO  - MsgSeqNumber : 1
2021-04-11 19:05:14.905 [Thread-30] INFO  - Offset : 0
2021-04-11 19:05:14.905 [Thread-30] INFO  - MsgFlags : 0
2021-04-11 19:05:14.905 [Thread-30] INFO  - OriginalLength : -1
2021-04-11 19:05:14.905 [Thread-30] INFO  - ***********************************************************************
2021-04-11 19:05:14.905 [Thread-30] INFO  - OrderReceived Payload :
<Orders>
   <Order>
      <CustomerID>GREAL</CustomerID>
      <EmployeeID>6</EmployeeID>
      <OrderDate>1997-05-06T00:00:00</OrderDate>
      <RequiredDate>1997-05-20T00:00:00</RequiredDate>
      <ShipInfo ShippedDate="1997-05-09T00:00:00">
         <ShipVia>2</ShipVia>
         <Freight>3.35</Freight>
         <ShipName>Great Lakes Food Market</ShipName>
         <ShipAddress>2732 Baker Blvd.</ShipAddress>
         <ShipCity>Eugene</ShipCity>
         <ShipRegion>OR</ShipRegion>
         <ShipPostalCode>97403</ShipPostalCode>
         <ShipCountry>USA</ShipCountry>
      </ShipInfo>
   </Order>
</Orders>
2021-04-11 19:05:14.905 [Thread-30] INFO  - ----------------------------------------Transaction Ends---------------------------------------------------------

There is much more. For more info, contact us at support@vaithu.com/ WhatsApp +1 6123058684

How to read excel files using Java Compute Node

Sometimes, we need to read excel files and there is no native connector in IBM Integration Bus. So, the obvious solution is to read them using Java. The most commonly used library is Apache POI.

Here I’ve written a simple program which reads the sheets ( assuming it has a header and multiple rows) and attach them to Environment tree. The java code is

public class ReadExcel_JCN extends MbJavaComputeNode {

	public void evaluate(MbMessageAssembly inAssembly) throws MbException {
		MbOutputTerminal out = getOutputTerminal("out");

		MbMessage inMessage = inAssembly.getMessage();
		MbMessageAssembly outAssembly = null;
		try {
			// create new message as a copy of the input
			MbMessage outMessage = new MbMessage(inMessage);
			outAssembly = new MbMessageAssembly(inAssembly, outMessage);
			// ----------------------------------------------------------
			// Add user code below
			
			MbElement environment = inAssembly.getGlobalEnvironment().getRootElement();
			
			File excelFiles = new File((String) getUserDefinedAttribute("ExcelDir"));
			
			Workbook workbook = null;
			
			DataFormatter dataFormatter = new DataFormatter();
			
			List<String> headerNames = null;
			String cellValue = null;
			MbElement cellElm = null;
			
			for (File excel : excelFiles.listFiles()) {
				
				workbook = WorkbookFactory.create(excel); 
				
				for (Sheet sheet : workbook) {
					
						MbElement sheetElm = environment.createElementAsLastChild(MbElement.TYPE_NAME, sheet.getSheetName(), null);
						headerNames = new ArrayList<>();
						for (Row row : sheet) {
							
							if (row.getRowNum() != 0) {
								cellElm = sheetElm.createElementAsLastChild(MbElement.TYPE_NAME, "rows", null);
							}
							for (Cell cell : row) {
								
								cellValue = dataFormatter.formatCellValue(cell);
								if (row.getRowNum() == 0) {
									headerNames.add(cellValue);
								} else {
									
									cellElm.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, headerNames.get(cell.getColumnIndex()), cellValue);
								}
							}
						}
						
						if (sheetElm.getLastChild() == null) {
							sheetElm.detach();
						}
						
				}
				
				workbook.close();
			}
			

			// 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);

	}

}

If you’re looking for any support in IIB, please contact us support@vaithu.com.

About the Author

He has worked for various clients and developed more than 800+ message flows. He is an expert in ESQL, Java Compute Node and DFDL. If you’ve any complex code to be written in ESQL, feel free to contact him at +1 6123058684.