Thursday, 14 August 2014

WTX INTEGRATION_ WITH_MB

WTX COMPILED MAP PROVIDED BY WTX TEAM:
BROWSE :

INPUT PROVIDED BY WTX TEAM AND BEFORE WTX TRANSFORMATION:




OUTPUT TREE STRUCTURE AFTER WTX TRANSFORMATION:


WTX MAP NODE INPUT PROPERTIES:


WTX MAP NODE OUTPUT PROPERTIES:




WTX MAP SETTINGS SPECIFIED:

Card Number To Wire

    This property specifies which input card of the map should be wired. The result of this property is that, specified map input card receives its data from the prior node in the message flow.

Outputs

On the Outputs tab of the WTX Map node, configure the properties to parse the output     from the map. Here you can specify Message set, Message type, Message format.

CacheMap:

At design time, set map caching to optimize runtime performance. Map caching optimizes the runtime performance because the process does not load the compiled map for every iteration of the running of the map. The compiled map is loaded only on the first invocation of the map. When map caching is set on, any changes that you make to the compiled map are used by the message after you stop and restart the execution group. When map caching is set off, any changes that you make to the compiled map are used by the next message that passes through the message flow. Set up map caching for each WTX Map node to enable individual control for each map node instance. Set map caching on in the Basic tab under Properties in the WebSphere Message Broker Toolkit.


Note: This caching should be enabled when you are sure that, map location will not be changed frequently.


Dynamically overriding the properties of next node using compute node:

* select the compute mode as local environment and message . This property enables us to propagate local environment to the next node

If InputRoot.XMLNSC.Employee_Details.employee.address = 'MI' THEN
        SET OutputLocalEnvironment.WTX.MapServerLocation = 'C:\WTX_MAPS\xml_to_fixed.mmc';
        ELSE
        SET OutputLocalEnvironment.WTX.MapServerLocation = 'C:\WTX_MAPS\xml_to_csv.mmc';
        END IF;

Wednesday, 18 June 2014

Accessing Configurable Service using Java

Configurable Services are typically run time properties. We can use them to define properties that are related to external services on which the broker relies. Instead of defining properties on the node or message flow, we can create configurable services so that nodes and message flows can refer to them to find properties at run time. If we use this method, we can change the values of attributes for a configurable service on the broker, which then affects the behavior of a node or message flow without the need for redeployment.

1. Userdefined Configurable Service
2. Java Method
3. ESQL

Create a user defined configurable service
Go to Websphere MQ > Configurable Service > New > Configurable Service
Select type as Userdefined configurable service.
Add property in the GUI.
Or
You can use command to create Configurable service with Key and Value
mqsicreateconfigurableservice IB9NODE -c UserDefined -o UD1 -n
BHANU -v "2032" 

Java Class
To retrieve the Value from the configurable service we use a simple java call.
We need a ConfigurationManagerProxy jar file in our project workspace.

Version 1 :
package com.get.configvalue;
import com.ibm.broker.config.proxy.*;
public class GET_CONFIG_VALUE
{
public static String getValue(String strKey)
{
String strValue = null;
try{
BrokerProxy b = BrokerProxy.getLocalInstance();

while(!b.hasBeenPopulatedByBroker())
 {
}

ConfigurableService[] CS_set =b.getConfigurableServices("UserDefined");

strValue =CS_set[0].getProperties().getProperty(strKey);
}
catch (Exception e)
{
e.printStackTrace();
}
return strValue;
}
}


Version 2 :
package com.external.java;
import com.ibm.broker.config.proxy.*;
public class GetConfigProperty
{
public static String getValue(String ConfigService,String KeyValue)
{
String ResultValue = null;
try{
BrokerProxy b = BrokerProxy.getLocalInstance();

while(!b.hasBeenPopulatedByBroker()) 
{
}

ConfigurableService CS_set =b.getConfigurableService("UserDefined",ConfigService);

ResultValue = CS_set.getProperties().getProperty(KeyValue);
}
catch (Exception e)
{
e.printStackTrace();
}
return ResultValue;
}
}

ESQL

Version 1 :
Calling Java method in ESQL

CREATE PROCEDURE getValueFromConfig (IN KeyChar CHAR)
RETURNS CHAR
LANGUAGE JAVA
EXTERNAL NAME "com.get.configvalue.GET_CONFIG_VALUE.getValue";

getValueFromConfig : Procedure Name
KeyChar : Input Parameter
com.get.configvalue : Package Name
GET_CONFIG_VALUE : Java Class Name
getValue : Java Method

Calling ESQL procedure

DECLARE strKey CHARACTER 'BHANU';
--result will be stored in strValue

DECLARE strValue CHARACTER;
--retrieves the Value from configurable service properties

CALL getValueFromConfig(strKey) INTO strValue;
 -- (Key:BHANU Value : 2032)

CALL getValueFromConfig('SampleKey') INTO strValue;
 --(Key:SampleKey Value:SampleValue)

Version 2 :
Calling Java method in ESQL

CREATE PROCEDURE getValueFromConfig
(IN ConfigService CHARACTER,IN KeyValue CHARACTER)
RETURNS CHAR
LANGUAGE JAVA
EXTERNAL NAME "com.external.java.GetConfigProperty.getValue";

getValueFromConfig : Procedure Name
ConfigService : ConfigService Name
KeyValue : Key Value in Properties file
GetConfigProperty : Java Class Name
getValue : Java Method

Calling ESQL procedure

DECLARE strKey CHARACTER 'BHANU';
--result will be stored in strValue

DECLARE strValue CHARACTER;
--retrieves the Value from configurable service properties

CALL getValueFromConfig('UD1','BHANU') INTO strValue; 
--(Key:BHANU Value : 2032)

CALL getValueFromConfig('UD2','UD2') INTO strValue;
CALL getValueFromConfig('AD1','AD1') INTO strValue;


Tuesday, 6 May 2014

Working with HTTPNodes

Create Consumer and Provider Flows like
Consumer Flow:-
Properties  On Each Node of Consumer flow are given below
CSV_IN
Passing_Dept_Salary

esql in ComputeNode:-
CREATE COMPUTE MODULE Consumer_flow_Compute
      CREATE FUNCTION Main() RETURNS BOOLEAN
      BEGIN

            DECLARE DEPT CHARACTER;
            DECLARE SAL INTEGER;
           
            SET DEPT=InputRoot.MRM.DEPT;
            SET SAL=InputRoot.MRM.SAL;
     
            SET OutputLocalEnvironment.Destination.HTTP.QueryString.key =DEPT;
            SET OutputLocalEnvironment.Destination.HTTP.QueryString.key1 =SAL;
           
            SET OutputLocalEnvironment.Destination.HTTP.RequestURL='http://localhost:7080/getQueryString?';
                 
            RETURN TRUE;
      END;

END MODULE;

Request_Details
Just give a sample url to supress error at node like http://test.com


Result_Details
Provider Flow:-

Properties  On Each Node of Provider  flow are given below

Take_Dept_Salary
Retrieve_Details

esql in ComputeNode:-

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

            DECLARE Dept_Sal_Location,SPLIT,DEPT CHARACTER;
            DECLARE SAL INTEGER;
            SET Dept_Sal_Location=InputRoot.HTTPInputHeader.[10];   
           
            SET SPLIT=SUBSTRING(Dept_Sal_Location AFTER '=');
            SET DEPT =SUBSTRING(SPLIT BEFORE '&');
            SET SAL  =SUBSTRING(SPLIT AFTER  '=');
           
      SET OutputRoot.XMLNSC.Employee.Details[]=PASSTHRU('SELECT * FROM mdeai.EMPLOYEE WHERE DEPT=? AND SALARY>?' TO Database.EmpTestDSN VALUES(DEPT,SAL));
                             
            RETURN TRUE;
      END;

END MODULE;


Provide_Respone

Input Message:-
EAI,10000

Create Message set for the Input Message with below details

DataBase records in the table

Tree Structure created with DataBase Details upon successful process

Message in Output Queue upon successful transaction is completed

Wednesday, 30 April 2014

Implementing Log4J on PCF related Java class

Step1:
Create a java project in Eclipse with name  GETCLUSQMGR.

Step2:
By default  we have a "src" folder  under  this folder  create a package by name com.logger.test and place the java classes with PCF,Logger  business logic.

Step3:
Create a source folder by name "resource" and add log4j2.xml file under it.

Step4:
Now the folder structure of the java project  will look like below


Step5:
Add the below code to ClusQmgr.java

package com.logger.test;
import java.io.IOException;
import org.apache.logging.log4j.Logger;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.constants.CMQCFC;
import com.ibm.mq.constants.MQConstants;
import com.ibm.mq.headers.pcf.PCFException;
import com.ibm.mq.headers.pcf.PCFMessage;
import com.ibm.mq.headers.pcf.PCFMessageAgent;
import com.ibm.mq.headers.MQDataException;


public class ClusQmgr
{     
static final Logger    logger      = CodeLogger.getLogger(ClusQmgr.class.getName());

public static void main (String [] args) throws MQDataException,PCFException, MQDataException,IOException
    {
              logger.debug("PCFMessageAgentCreation Start");
               PCFMessageAgent agent = new PCFMessageAgent("EB310000");

               logger.debug("Inquiring Cluster Queue Managers");
                PCFMessage pcfCmd = new PCFMessage(CMQCFC.MQCMD_INQUIRE_CLUSTER_Q_MGR);

                  pcfCmd.addParameter(CMQC.MQCA_CLUSTER_Q_MGR_NAME,"*");
      
                  logger.debug("Cluster Queue Managers Details");
                PCFMessage[] pcfResponse =agent.send(pcfCmd);

        System.out.println("**QueueManager**Host**Port**");
         String ClustQmgr=" ";
         String[] ConDetails;
         String Hostname=" ";
         String Port=" ";

 for (PCFMessage pcfMessage : pcfResponse)
{
     ClustQmgr=pcfMessage.getParameterValue(CMQC.MQCA_CLUSTER_Q_MGR_NAME).toString().trim();
      ConDetails=(pcfMessage.getParameterValue(MQConstants.MQCACH_CONNECTION_NAME).toString().trim()).split("\\(",2);
     Hostname=ConDetails[0];
     Port=ConDetails[1].substring(0,ConDetails[1].length()-1 );
      System.out.println("*****"+ClustQmgr+"*******"+Hostname+"*********"+Port+"**********");
      logger.debug("Values"+"**"+ClustQmgr+"**"+Hostname+"**"+Port+"**");
                    
       }
    logger.debug("End of PCF Details");

}
}

Step6:
Add the below code to CodeLogger.java

package com.logger.test;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.ConfigurationFactory.ConfigurationSource;
import org.apache.logging.log4j.core.config.Configurator;

public final class CodeLogger {
     
private static final String   LOG4J_CONFIG_FILE = "log4j2.xml";
     
static
{
ConfigurationSource source = new ConfigurationSource();
source.setInputStream(CodeLogger.class.getClassLoader().getResourceAsStream(LOG4J_CONFIG_FILE));
Configurator.initialize(CodeLogger.class.getClassLoader(), source);
}
     
public static Logger getLogger(String name)
{
return LogManager.getLogger(name);
}
}

Step7:
Add the below properties  to log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

<properties>
<property name="logFileDir">C:\\LOG4J\\</property>
<property name="logFileName">logger</property>
</properties>

<appenders>
             
<RollingFile name="RollingFile" fileName="${logFileDir}${logFileName}.log"
                     filePattern="${logFileDir}$${date:yyyy-MM}/${logFileName}-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="[%d{ISO8601}] [%t] %-5p %c{6} - %msg%n" />

<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB" />
</Policies>

</RollingFile>

</appenders>
<!-- Logging done on particular package bases "com.logger.test"-->
<loggers>
<logger name="com.logger.test" additivity="false" level="DEBUG">
<AppenderRef ref="RollingFile" />
</logger>
</loggers>

</configuration>

Step8:
Add the below jars to the Java Build Path of the project
log4j-api-2.0-rc1.jar, log4j-core-2.0-rc1.jar

Step9:
OutPut of the logger file will look like below

[2014-04-30 19:58:18,493] [main] DEBUG com.logger.test.ClusQmgr - PCFMessageAgentCreation Start
[2014-04-30 19:58:18,758] [main] DEBUG com.logger.test.ClusQmgr - Inquiring Cluster Queue Managers
[2014-04-30 19:58:18,758] [main] DEBUG com.logger.test.ClusQmgr - Cluster Queue Managers Details
[2014-04-30 19:58:18,774] [main] DEBUG com.logger.test.ClusQmgr - Values**EB310000**miracle-PC**1000**
[2014-04-30 19:58:18,774] [main] DEBUG com.logger.test.ClusQmgr - Values**EB310001**miracle-PC**1003**
[2014-04-30 19:58:18,774] [main] DEBUG com.logger.test.ClusQmgr - End of PCF Details








Tuesday, 15 April 2014

PCF Commands

 The purpose of WebSphere MQ programmable command format (PCF) commands is to allow administration tasks to be programmed into an administration program. In this way you can create queues, process definitions, channels, and namelists, and change queue managers, from a program.


     Each PCF command is a data structure that is embedded in the application data part of a WebSphere MQ message. Each command is sent to the target queue manager using the MQI function MQPUT in the same way as any other message. The command server on the queue manager receiving the message interprets it as a command message and runs the command. To get the replies, the application issues an MQGET call and the reply data is returned in another data structure. The application can then process the reply and act accordingly.

Briefly, these are some of the things the application programmer must specify to create a PCF command message:

Message descriptor

This is a standard IBM MQ message descriptor, in which:
·         Message type ( MsgType ) is MQMT_REQUEST.
·         Message format ( Format ) is MQFMT_ADMIN.
Application data

Contains the PCF message including the PCF header, in which:
·         The PCF message type ( Type ) specifies MQCFT_COMMAND.
·         The command identifier specifies the command, for example, Change Queue (MQCMD_CHANGE_Q).

Escape PCFs are PCF commands that contain MQSC commands within the message text. You can use PCFs to send commands to a remote queue manager.

Sample Java code to get cluster QueueManager Details

import java.io.IOException;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.constants.CMQCFC;
import com.ibm.mq.constants.MQConstants;
import com.ibm.mq.headers.pcf.PCFException;
import com.ibm.mq.headers.pcf.PCFMessage;
import com.ibm.mq.headers.pcf.PCFMessageAgent;
import com.ibm.mq.headers.MQDataException;


public class ClusQmgr {
     
public static void main (String [] args) throws MQDataException,PCFException, MQDataException,IOException
    {
//intializes a new PCFMessageAgent with a binding connection to a QueueManager
PCFMessageAgent agent = new PCFMessageAgent("EB310000");

//initializes PCFMessage as a PCF request
PCFMessage pcfCmd = new PCFMessage(CMQCFC.MQCMD_INQUIRE_CLUSTER_Q_MGR);

//add PCF parameters to PCFMessage
 pcfCmd.addParameter(CMQC.MQCA_CLUSTER_Q_MGR_NAME,"*");

//sends a PCF request to connect Queue Manager and return the responses
PCFMessage[] pcfResponse =agent.send(pcfCmd);
              
String ClustQmgr=" ";
String[] ConDetails;
String Hostname=" ";
String Port=" ";

System.out.println("*****QueueManager*******Host*********Port**********");

for (PCFMessage pcfMessage : pcfResponse)
{

//get cluster Queue Manager Name      ClustQmgr=pcfMessage.getParameterValue(CMQC.MQCA_CLUSTER_Q_MGR_NAME).toString().trim();

//get connection Details      ConDetails=(pcfMessage.getParameterValue(MQConstants.MQCACH_CONNECTION_NAME).toString().trim()).split("\\(",2);

//get Host name
Hostname=ConDetails[0];

//get port name
Port=ConDetails[1].substring(0,ConDetails[1].length()-1 );
      System.out.println("*****"+ClustQmgr+"*******"+Hostname+"*********"+Port+"**********");
                 
            }
           
            }