Copyrights @ Journal 2014 - Designed By Templateism - SEO Plugin by MyBloggerLab

Friday, April 17, 2009

CICS Web Services Assistant for Windows

Share

As we know, web services are reached to mainframes also. The best way to enable any CICS program (except assembler) via web services is to use Rational Application Developer for System Z. I would say that is the best and also the most expensive way to create WS on mainframe. You can use CICS Web Services Assistant to do that. Usually the license of RAD4Z is very expensive, so if you only need to create webservices artifacts, use CICS WS assistant.

You need to first download the CICS WS A from here, importantly check the documentation that it comes with. Apart from that you need to download Java Record I/O for OS/390. You can both these from your CICS/USS installation on mainframe. Later I found out that, DFHLWS2WS batch program invokes the java classes one after the other to create Web services. Using JRIO, you can read the VSAM datasets (KSDS), system catalogs, I am still not sure why do we need this for running the Windows assistant. I would suggest reading this overview for more details.

Using the assistant you can create both approaches

  1. Top down approach - WSDL to CICS program - WS2LS
  2. Bottom up approach - CICS program to WSDL - LS2WS

First things first

  1. I created a utility class which will read from a properties file with the string/constant values that are needed.
  2. I downloaded the copybook for the CICS program that needs to be enabled via Web services.
  3. You may want to separate the input and output as two different copybooks.
  4. Read thru the sample code for more documentation.
Initialize
  1:     // Decide your defaults.
  2:     // Here is the target program name
  3:     public final String PARAM_PROGRAM_NAME = Utility.getProperty("PARAM_PROGRAM_NAME", "FIRSTCICS");
  4:     // Is the target program looking for perticular container name in
  5:     // default channel? Default container name is "DFHWS-DATA"
  6:     public final String PARAM_CONTAINER_NAME = Utility.getProperty("PARAM_CONTAINER_NAME", "DFHWS-DATA");
  7:     /*
  8:          * You need to provide Cobol mapping level that is used in copybooks.
  9:          * This is important because some mappings are not supported by certain
 10:          * version of CICS WS.
 11:          */
 12:     public final String PARAM_MAPPING_LEVEL = Utility.getProperty("PARAM_MAPPING_LEVEL", "2.0");
 13:     /*
 14:          * If you have preference for namespaces for the WSDL, you can specify
 15:          * that here. Usually, the auto generated Java/C# classes has reveresed
 16:          * package/namespace hierarchy. Like when you say com.test.myCo the
 17:          * namespace in Java will look like myCo.test.com. This is the reason I
 18:          * wrote it reversed. This helps if you plan to import the generated
 19:          * WSDL into JAX-WS or Axis based tool. Specify namespaces for request
 20:          * and response.
 21:          * 
 22:          */
 23:     public String PARAM_REQUEST_NAMESPACE_MF = Utility.getProperty("PARAM_REQUEST_NAMESPACE_MF", "myCo.test.com");
 24:     public String PARAM_RESPONSE_NAMESPACE_MF = Utility.getProperty("PARAM_RESPONSE_NAMESPACE_MF", "myCo.test.com");
 25:     // You must specify the programmming language for target program.
 26:     // 0 = COBOL.
 27:     public final int PARAM_LANGUAGE = Integer.parseInt(Utility.getProperty("PARAM_LANGUAGE", "0"));
 28:     // What is the target program need COMMAREA or CHANNELS/Containers.
 29:     public final int PARAM_PROGRAM_INTERFACE = Integer.parseInt(Utility.getProperty("PARAM_PROGRAM_INTERFACE", "1"));
 30:     // Name of default channel?
 31:     public final String PARAM_CHANNEL_NAME = Utility.getProperty("PARAM_CHANNEL_NAME", "CHANNEL");
 32:     // Define codepage for the PDS that will be used as input or output.
 33:     // I used default as IBM-037
 34:     public final String PARAM_PDS_CODEPAGE = Utility.getProperty("PARAM_PDS_CODEPAGE", "IBM-037");
 35:   
 36:     public String PARAM_SERVICE_INTERFACE = "";
 37:     //Location of generated WSDL (LS2WS) or WSDL to be used to generate (WS2LS)
 38:     public String WSDL_LOCATION = "";
 39:     
 40:     //Name of the PDS file names on local machine.
 41:     public String PARAM_REQUEST_CBMEMBER_MF = "";
 42:     public String PARAM_RESPONSE_CBMEMBER_MF = "";
 43:     /*
 44:      * This is the name of interface that wsbind file will use to create a web service.
 45:      * This will also be used at http://server:port/PARAM_SERVICE_INTERFACE
 46:      */ 
 47:     public String PARAM_INTERFACE_ID = "";
 48:     public String PARAM_DIRECTORY_PDS_LIB = "";
 49:     public String PARAM_DIRECTORY_ARTIFACTS_WSDL = "";
 50:     public String PARAM_DIRECTORY_ARTIFACTS_WSBIND = "";
 51:     public String PARAM_DIRECTORY_ARTIFACTS_LOG = "";
 52:     public final String PARAM_EXTENTION_WSBIND = Utility.getProperty("PARAM_EXTENTION_WSBIND", ".wsbind");
 53:     public final String PARAM_EXTENTION_WSDL = Utility.getProperty("PARAM_EXTENTION_WSDL", ".wsdl");
 54:     public final String PARAM_EXTENTION_LOG = Utility.getProperty("PARAM_EXTENTION_LOG", ".log");

Setup the parameters:

  1: private IAssistantParameters setParams(String type) {
  2:  IAssistantParameters params = Factory.createAssistantParameters();
  3:  /*
  4:          * You can create both LS2WS and WS2LS from CICS WS Assistant. Both use
  5:          * different parameters. this program is written to handle both
  6:          * scenarios.
  7:          */
  8:  if (type.equals("LS2WS")) {
  9:      //Copybook to web services approach
 10:      params.setParamLANG(PARAM_LANGUAGE);
 11:      params.setParamPDSCP(PARAM_PDS_CODEPAGE);
 12:      params.setParamMAPPING_LEVEL(PARAM_MAPPING_LEVEL);
 13:      params.setParamPGMNAME(PARAM_PROGRAM_NAME);
 14:      params.setParamREQMEM(PARAM_REQUEST_CBMEMBER_MF);
 15:      params.setParamRESPMEM(PARAM_RESPONSE_CBMEMBER_MF);
 16:      params.setParamPGMINT(PARAM_PROGRAM_INTERFACE);
 17:      params.setParamPGMINT(PARAM_CHANNEL_NAME);
 18:      params.setParamCONTID(PARAM_CONTAINER_NAME);
 19:      params.setParamPDSLIB(PARAM_DIRECTORY_PDS_LIB);
 20:      params.setParamURI(PARAM_INTERFACE_ID);
 21:      params.setParamREQUEST_NAMESPACE(PARAM_REQUEST_NAMESPACE_MF);
 22:      params.setParamRESPONSE_NAMESPACE(PARAM_RESPONSE_NAMESPACE_MF);
 23:      params.setParamWSBIND(PARAM_DIRECTORY_ARTIFACTS_WSBIND + PARAM_INTERFACE_ID + PARAM_EXTENTION_WSBIND);
 24:      params.setParamLOGFILE(PARAM_DIRECTORY_ARTIFACTS_LOG + PARAM_INTERFACE_ID + PARAM_EXTENTION_LOG);
 25:      params.setParamWSDL(WSDL_LOCATION);
 26:  } else {
 27:      //WSDL to Cobol copybook/program approach
 28:      params.setParamLANG(PARAM_LANGUAGE);
 29:      params.setParamPDSCP(PARAM_PDS_CODEPAGE);
 30:      params.setParamMAPPING_LEVEL(PARAM_MAPPING_LEVEL);
 31:      params.setParamPGMNAME(PARAM_PROGRAM_NAME);
 32:      params.setParamREQMEM(PARAM_REQUEST_CBMEMBER_MF);
 33:      params.setParamRESPMEM(PARAM_RESPONSE_CBMEMBER_MF);
 34:      params.setParamPGMINT(PARAM_PROGRAM_INTERFACE);
 35:      params.setParamPGMINT(PARAM_CHANNEL_NAME);
 36:      params.setParamCONTID(PARAM_CONTAINER_NAME);
 37:      params.setParamPDSLIB(PARAM_DIRECTORY_PDS_LIB);
 38:      params.setParamURI(PARAM_INTERFACE_ID);
 39:      params.setParamCHAR_VARYING("NO");
 40:      /*
 41:       * No need to specify namespaces here, because they come from specified WSDL.
 42:       */
 43:      // params.setParamREQUEST_NAMESPACE(PARAM_REQUEST_NAMESPACE_MF);
 44:      // params.setParamRESPONSE_NAMESPACE(PARAM_RESPONSE_NAMESPACE_MF);
 45:      params.setParamWSBIND(PARAM_DIRECTORY_ARTIFACTS_WSBIND + PARAM_INTERFACE_ID + PARAM_EXTENTION_WSBIND);
 46:      params.setParamLOGFILE(PARAM_DIRECTORY_ARTIFACTS_LOG + PARAM_INTERFACE_ID + PARAM_EXTENTION_LOG);
 47:      params.setParamWSDL(WSDL_LOCATION);
 48:  }
 49:  return params;
 50:     }

Part I: Create Copybook to Web service (LS2WS)


  1:  public String CreateWSArtifactsLS2WS() {
  2:  try {
  3:      /*
  4:       * Create the paths where you want your WS artifacts will be crated.
  5:       */
  6:      PARAM_REQUEST_NAMESPACE_MF = this.PARAM_SERVICE_INTERFACE + "." + PARAM_REQUEST_NAMESPACE_MF;
  7:      PARAM_RESPONSE_NAMESPACE_MF = this.PARAM_SERVICE_INTERFACE + "." + PARAM_RESPONSE_NAMESPACE_MF;
  8:      WSDL_LOCATION = PARAM_DIRECTORY_ARTIFACTS_WSDL + PARAM_INTERFACE_ID + PARAM_EXTENTION_WSDL;
  9:      
 10:      /*
 11:       * Setup parameters
 12:       */
 13:      IAssistantParameters params = this.setParams("LS2WS");
 14:      /*
 15:       * Create assistant
 16:       */
 17:      ICICSWebServicesAssistant cwsa = Factory.createCICSWebServicesAssistant();
 18:      /*
 19:       * Make the run
 20:       */
 21:      IAssistantResponse ar = cwsa.DFHLS2WS(params);
 22:      /*
 23:       * Check the output.
 24:       */
 25:      int retCode = ar.getReturnCode();
 26:      String retMessages = "";
 27:      /*
 28:       * There are list of messages.
 29:       */
 30:      String[] msgs = ar.getAllMessages();
 31:      for (int i = 0; i < msgs.length; i++) {
 32:   retMessages += msgs[i] + "\n";
 33:   Utility.PrintLine(msgs[i]);
 34:      }
 35:      Utility.PrintLine("DFHLS2WS:AssistantResponse.getReturnCode():" + retCode);
 36:      if (retCode == IAssistantResponse.RC_ERROR) {
 37:   Utility.PrintLine("Error while creating the WSDL\n" + retMessages);
 38:   throw new Exception("WSDL Creation Error : " + retMessages);
 39:      }
 40:  } catch (Exception e) {
 41:      Utility.PrintError(e);
 42:  }
 43:  
 44:  return WSDL_LOCATION;
 45:     }
 46: 

 

Part II: Create Web service to Cobol(WS2LS)

  1:     public String CreateWSArtifactsWS2LS() {
  2:  try {
  3:      /*
  4:       * Create the paths where you want your WS artifacts will be crated.
  5:       */
  6:      PARAM_REQUEST_NAMESPACE_MF = this.PARAM_SERVICE_INTERFACE + "." + PARAM_REQUEST_NAMESPACE_MF;
  7:      PARAM_RESPONSE_NAMESPACE_MF = this.PARAM_SERVICE_INTERFACE + "." + PARAM_RESPONSE_NAMESPACE_MF;
  8:      WSDL_LOCATION = PARAM_DIRECTORY_ARTIFACTS_WSDL + PARAM_INTERFACE_ID + PARAM_EXTENTION_WSDL;
  9:      /*
 10:       * You have to provide the names of the PDS which it will generate the the Copybooks.
 11:       */
 12:      PARAM_REQUEST_CBMEMBER_MF = "WBSXI";
 13:      PARAM_RESPONSE_CBMEMBER_MF = "WBSXO";
 14:      IAssistantParameters params = this.setParams("WS2LS");
 15:      ICICSWebServicesAssistant cwsa = Factory.createCICSWebServicesAssistant();
 16:      IAssistantResponse ar = cwsa.DFHWS2LS(params);
 17:      int retCode = ar.getReturnCode();
 18:      String retMessages = "";
 19:      String[] msgs = ar.getAllMessages();
 20:      for (int i = 0; i < msgs.length; i++) {
 21:   retMessages += msgs[i] + "\n";
 22:   Utility.PrintLine(msgs[i]);
 23:      }
 24:      Utility.PrintLine("DFHLS2WS:AssistantResponse.getReturnCode():" + retCode);
 25:      if (retCode == IAssistantResponse.RC_ERROR) {
 26:   Utility.PrintLine("Error while creating the WSDL\n" + retMessages);
 27:   throw new Exception("WSDL Creation Error : " + retMessages);
 28:      }
 29:  } catch (Exception e) {
 30:      Utility.PrintError(e);
 31:  }
 32:  return WSDL_LOCATION;
 33:     }

Glue it togather:

  1: String WSDL_LOCATION ="";
  2: CICSCreateWSDL createWSDL = new CICSCreateWSDL();
  3: 
  4: createWSDL.PARAM_INTERFACE_ID="GetCustomerAddress";
  5: createWSDL.PARAM_REQUEST_CBMEMBER_MF = "CUSTADDR.cpy";
  6: createWSDL.PARAM_RESPONSE_CBMEMBER_MF = "CUSTADDR.cpy";
  7: createWSDL.PARAM_DIRECTORY_PDS_LIB = Utility.BASE_ARTIFACT_FOLDER + "1.Interfaces\\";
  8: createWSDL.PARAM_DIRECTORY_ARTIFACTS_WSDL = Utility.BASE_ARTIFACT_FOLDER + "2.WSDLs\\";
  9: createWSDL.PARAM_DIRECTORY_ARTIFACTS_WSBIND = Utility.BASE_ARTIFACT_FOLDER +  "3.WSBINDs\\";
 10: createWSDL.PARAM_DIRECTORY_ARTIFACTS_LOG = Utility.BASE_ARTIFACT_FOLDER + "4.LOGs\\";
 11: createWSDL.PARAM_SERVICE_INTERFACE=PARAM_NAMESPACE;
 12: WSDL_LOCATION= createWSDL.CreateWSArtifactsLS2WS();

1 comments:

Art Valdivia said...

Hi,

Nice blog sir, you have done a great content

Thanks
Indiska kläder