Tuesday, August 28, 2012

What is the Endpoint of a Web Service Deployed on GlassFish Server ?

This evening, I was trying to play a little bit with GlassFish server to familiarize myself with it. I created a simple web service and deployed it to the server.

I followed the top-down approach by creating a wsdl, generating the stub code and writing my logic in the Impl class. I then deployed it to the server. When it came to testing the service, it took me some time to figure out what the endpoint of my web service was.

Here is where you can find the endpoint: Even though you have given a different address in the location element of the wsdl that you used to generate the stub, this address is overwritten in the wsdl file that is generated when you generate the stub code. Look under <Project Root Folder>/WebContent/WEB-INF/wsdl/<PortName in your WSDL>.wsdl for the new address as shown in the picture.

Web Service Endpoint - GlassFish Server 3.1

It looks like the endpoint for both top-down and bottom-up approaches will be in the following format
http://<Host>:<Port>/<Application Name>/services/<Port Name in your WSDL>

Tuesday, August 14, 2012

Free IPhone and IPad App development Course by Mr. Paul Hegarty (@ Stanford Univ.)

Absolutely love this course!! I should mention that i greatly admire Mr. Hegarty for his style of teaching. A must go thru for any one who is trying to learn development of iOS applications.




If you have access to iTunes, click "iTunes store" in the navigator > "iTunes U" (on the drop-down arrow) in the menu > select "Universities & Colleges" > select "Stanford" > In the "All Courses" section, click on "See All" and select "iPad and iPhone App Development (Fall 2011)" [Try and select the course that is latest].

You should be able to view all of the course material.

For more info and course material, visit Mr. Hegarty's blog

Good Luck with your "iDevelopment"!

Wednesday, May 16, 2012

DataPower: Flushing Stylesheet Cache.

Summary: Why aren’t my changes to the stylesheets being picked up by DataPower? Learn about the stylesheet cache in DataPower and what you should do to refresh the cache.

DataPower appliances maintain a cache of the stylesheets that are being used on the appliance for performance reasons. "Although the cache is configurable, disabling the cache might degrade performance. DataPower caches compiled stylesheets and if the cache is disabled the stylesheets will have to be compiled every time they are used." - [1]

Ever get into a situation where you have made a change on an imported/included stylesheet on DataPower and when the stylesheet was run, you did not see the changes you made being reflected in the results?

The reason is that DataPower fetches all the content from top level stylesheet with any imported and included stylesheets and after compilation stores it in the cache as one single compiled stylesheet. If you make changes to one of the imported/included stylesheets, DataPower does not detect the change and the recompilation and refreshing the same in the cache is not triggered.

In such scenarios, for the changes to be reflected, you could do two things

  1. You could flush the stylesheet cache. One way of doing this would be to use the WebGUI administrative interface. In the GUI select objects/XML Processing/XML Manager. Select the respective xml manager and to the top right corner you should see option called “Flush  Stylesheet Cache”.
  2. DataPower: Flush Stylesheet Cache
  3. You could introduce an empty line in the top level xslt and save it. This will trigger recompilation of that top level stylesheet effectively recompiling the imported/included stylesheets also.
 “At compile time all imported and included stylesheets are fetched and the complete compiled top level stylesheet is then cached. You can't see the imports and includes but they are all there under the top stylesheet.” – [2]

“Disabling the cache can be performance concern and might not be your goal. When style sheets are not cached, an XSLT compilation is run on every single transaction.

If you need to disable stylesheet caching, create a separate XML Manager for the particular service wherestylesheet caching is not required.

Do not disable stylesheet caching for a widely used XML Manager. For example, do not disable caching on the default XML Manager.” – [1]


References:

Sunday, April 15, 2012

WSRR Migration Best Practices

Summary:
Websphere Service Registry & Repository (WSRR) is useful to register reusable Business Services and serves as a centralized repository to capture all metadata related to Service Lifecycle, Configuration and Deployment.


Purpose
This document aims to shed light on some of the WSRR migration issues from version 6.x to v7 and v7.5. WSRR v7 offers major improvements compared to previous versions in different areas such as performance, enhanced governance lifecycle, ontology support etc. To quote an example, we have seen significant improvements related to import and export of documents from Web UI after migrating to WSRR v7. So there are a handful of very good reasons to migrate to the newer version.

Migration Path & Best Practices:
A medium-size or large enterprise typically will have separate environments for Development, Testing and Production activities. The challenge is to accomplish migration of all environments minimizing the repetition of same tasks for each environment, thereby reducing the overall time to complete migration.
We have also taken into account future needs of the WSRR, as the Enterprise’s SOA Adoption Strategy evolves. The chosen migration path should be reusable for any enhancements to be done in future on WSRR dataset.
 
Upgrade In-place vs. New Install & Copy Dataset

Given both options for a typical migration project, I would prefer new install & copy of dataset. This is lesser error-prone, risk-free approach and would allow leveraging all new features available with the newer version after migration. To eliminate the confusion, IBM does not offer a solution to upgrade “In-place” in the case of WSRR. Instead, recommends a 2-step process for a successful migration.

Migration Tasks

Profile Migration:
•    Capture profile in source repository using WSRR Web UI. Choose Configuration perspective, profile export option.
•    Load the exported profile into target WSRR. 

Note: If errors are encountered during the import, modify the profile using WSRR v7 Studio. Import the updated profile into WSRR v7.

Ontology Migration:
For this, ‘upgradetool.sh’ should be used. It involves the following 2 tasks.
i)  Export the dataset. This will create a cloudscape database dump file.
ii) Import the dataset. 

For a dataset with 200 documents and around 100 concepts, export took almost 40 hours. There were errors at the end of the long wait. We have to manually fix these errors using WSRR utility code developed in-house.

Why Cloudscape database is needed?
It might be useful if the database type of target WSRR v7 is different from source WSRR v6.x such as from SQL Server to Oracle or vice-versa. However, for most of the ESB Environments, it is unlikely to change the database type from one to another and breaks 80-20 rule. It adds unnecessary complexity to the overall migration process.

The following 2 approaches were considered for Migration.
 
Option A (Repeat Migration Tasks for each Environment):

•    Migration of WSRR v6.x DEV to WSRRv7 DEV.
•    Repeat this for 2 times to complete migration for QA and Production environments.

Option B (Migrate only once; leverage WSRR API features):
•    Migration of WSRR v6.x DEV to WSRR v7 DEV.
•    Reconcile dataset from QA and Production to WSRR v7 DEV using the WSRR client API. This will provide a good baseline dataset to setup Governance Repository in future.
•    Develop WSRR client code to modify / migrate metadata using WSRR API. It is fairly simple and should not take longer time to develop.
•    Build datasets for QA and Production from WSRR v7 DEV dataset using export utility available in WSRR v7 after classifying the dataset as DEV / QA / Production.
•    Import dataset into QA.
•    Import dataset into Production. 

Decision Taken: We have used Option B for migration instead of Option A and successfully completed the Migration ahead of time.


Monday, August 8, 2011

Creating MTOM Enabled JAX-WS Web Services Using RAD/WID/Integration Designer

Summary:
Learn how to develop MTOM enabled JAX-WS web services using Rational Application Developer (RAD) or WebSphere Integration Developer (WID) or IBM Integration Designer. A detailed development process for both Top-Down and Bottom-Up approaches is presented.


MTOM (Message Transmission Optimization Mechanism) is a W3C standard that uses XOP (XML Binary Optimized Packaging) to transmit binary data. For more information on MTOM or XOP, please refer to [1] and [2] in the references section.

Scenario: Create a web service using Java API for XML-Based Web Services (JAX-WS) with an operation called “getFileAsMTOM” that will accept a file name as input and will return a response message with the file content as attachment using MTOM/XOP. The operation will also return the file name provided in the input, as part of the output. The implementation of the operation could include logic to read the file in a particular folder on the local drive and return it as part of the response.

A detailed development process for both Top-Down and Bottom-Up approaches is presented.

Bottom-Up Approach

There are two different service endpoint implementation types that you could use to develop web services using JAX-WS. (Refer to [4] in the References section for more information.)
  1. JavaBeans Service Endpoint Interface and
  2. Provider Interface
This article follows the first method to creating the web service using the Bottom-Up approach.

Steps:

  • Create the Request JavaBean  ( SampleRequest.java - input object for the operation to be exposed on the web service interface). 
Input POJO - SampleRequest.java

  • Create the Response JavaBean (output object for the operation to be exposed on the web service interface).
Output POJO - SampleResponse.java

  • Create the Service Endpoint Interface.
TestMTOMIntf.java - Interface (SEI)

  • Create the Implementation class that implements the Service Endpoint Interface.
TestMTOM.java - Implementation Class

  • Add JAX-WS annotations as necessary. On both S.E.Interface and the Implementation classes add the annotations as necessary. In the above pictures named "TestMTOMIntf.java - Interface (SEI)" and "TestMTOM.java - Implementation Class", find the annotations that were added for this example. Refer to [3] in the References section for more information on JAX-WS annotations.

  • Add                                                                                                                "@javax.xml.ws.BindingType (value=javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING)"  or              "@javax.xml.ws.BindingType (value=javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING)" based on whether you are using SOAP 1.1 or SOAP 1.2 binding. Add the annotation on the Implementation class to enable MTOM as shown above in the picture named "TestMTOM.java - Implementation Class".

  • Generate the necessary artifacts.
Generate WSDL and Other artifacts

Generate Artifacts 2 (select JAX-WS)


Generate Artifacts 3 ("Enable MTOM Support" should show selected)


BottomUp - Web Project Showing Generated Artifacts

  • Deploy to WAS/WESB/WPS and Test. In this example i used soapUI to test the operation. You can see in the picture that <xop:Include> tag has been added and you can see an attachment. From the soapUI tool, you can download the attachment, name the file appropriate and view the same to make sure you got back what you were expecting.
soapUI - TestCase - BottomUp

Top-Down Approach

In the Top-Down approach, we start with creating a WSDL file. We then generate the necessary Java Beans and then code the logic in the generated implementation class.

Steps:
  • Create the WSDL file.
                                                    MTOMInterface.WSDL


<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions name="MTOMInterface" targetNamespace="http://Sample/MTOMInterface" xmlns:bons1="http://Sample" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://Sample/MTOMInterface" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <wsdl:types>
    <xsd:schema targetNamespace="http://Sample/MTOMInterface">
      <xsd:import namespace="http://Sample"/>
      <xsd:element name="getFileAsMTOM">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="input1" nillable="true" type="bons1:SampleRequest"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="getFileAsMTOMResponse">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="output1" nillable="true" type="bons1:SampleResponse"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:schema>
        <xsd:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://Sample">
      <xsd:complexType name="SampleResponse">
  <xsd:sequence>
   <xsd:element minOccurs="0" name="FileContent" type="xsd:base64Binary">
   </xsd:element>
   <xsd:element minOccurs="0" name="FileName" type="xsd:string">
   </xsd:element>
  </xsd:sequence>
 </xsd:complexType>
      <xsd:complexType name="SampleRequest">
  <xsd:sequence>
   <xsd:element minOccurs="0" name="FileName" type="xsd:string">
   </xsd:element>
  </xsd:sequence>
 </xsd:complexType>
    </xsd:schema>
    </wsdl:types>
    <wsdl:message name="getFileAsMTOMRequestMsg">
    <wsdl:part element="tns:getFileAsMTOM" name="getFileAsMTOMParameters"/>
  </wsdl:message>
    <wsdl:message name="getFileAsMTOMResponseMsg">
    <wsdl:part element="tns:getFileAsMTOMResponse" name="getFileAsMTOMResult"/>
  </wsdl:message>
    <wsdl:portType name="MTOMInterface">
    <wsdl:operation name="getFileAsMTOM">
      <wsdl:input message="tns:getFileAsMTOMRequestMsg" name="getFileAsMTOMRequest"/>
      <wsdl:output message="tns:getFileAsMTOMResponseMsg" name="getFileAsMTOMResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  
  <wsdl:binding name="MTOMInterfaceHttpBinding" type="tns:MTOMInterface">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getFileAsMTOM">
      <soap:operation soapAction=""/>
      <wsdl:input name="getFileAsMTOMRequest">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="getFileAsMTOMResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="FetchFileService">
    <wsdl:port binding="tns:MTOMInterfaceHttpBinding" name="MTOMInterfaceHttpPort">
      <soap:address location="http://localhost:9080/TEST/FetchFileService"/>
    </wsdl:port>
  </wsdl:service> 
</wsdl:definitions>

  • Generate the JavaBean Skeleton by enabling MTOM support.
Generate Java Bean Skeleton - TopDown

Generate Java Bean Skeleton (select JAX-WS) - TopDown

Generate Java Bean Skeleton (Enable MTOM) - TopDown
  • Implement the logic for the operation that is to be exposed.
MTOMInterfaceHttpBindingImpl - Implementation Class

MTOMInterfaceHttpBindingImpl - Implementation Class
  • Deploy to WAS/WESB/WPS and Test. In this example i used soapUI to test the operation. You can see in the picture that <xop:Include> tag has been added and you can see an attachment. From the soapUI tool, you can download the attachment, name the file appropriate and view the same to make sure you got back what you were expecting.
soapUI - Test MTOM - Top Down

For information on how to enable MTOM on Web Services in DataPower, Please Check my post – DataPower: Encoding base64Binary Inline Data into MTOM.

References:





Saturday, July 30, 2011

Unable to Create Profile: Installation Issue with IBM Integration Designer V 7.5

Summary:
Getting errors when you are trying to reinstall IBM Integration Designer V 7.5? See what you can do to resolve the issue.


IBM Integration Designer V 7.5 (previously called WebSphere Integration Developer) comes with IBM DB2 Express. Embedded Derby database was used with WebSphere Integration Developer.

DB2 Express Package with IBM Integration Designer V 7.5

IBM Infocenter has provided information for troubleshooting issues that you might face when installing or uninstalling IBM Integration Designer V 7.5. Check [1] in the references section.

Background: I was trying to reinstall IBM Integration Designer V 7.5 on a 64bit windows 7 system. I was able to successfully install and uninstall it for the first time. The reason for uninstalling it was to install DB2 Express with a different account which probably does not hold relevance here.

Issue: Re Installation of IBM Integration Designer V 7.5 with the test environment fails during the creation of a profile. As mentioned in [1] - “If you try to reinstall to the same location, or if you try to reinstall after a failed uninstall, the installation might fail because a new profile cannot be created.”

Resolution: IBM Infocenter [1] suggests that “If databases were created for the test environment, the databases must be dropped before you can create a new profile. If the databases are not automatically dropped during uninstall, you must drop them manually. “

Note that in my case, I had no prior DB2 installation on the system and the installation was done using the “typical installation” configuration from the Launchpad.

During the uninstallation process using the IBM Installation Manager, I had already uninstalled the DB2 Express also. How do I drop the databases manually when DB2 has already been uninstalled? Here is what I did.
  • Removed the “BPMINST” folder on c:\ drive.
BPMINST Folder

  • Removed the “DB2” folder under c:\ProgramData\IBM.
DB2 Folder

For Windows 32 bit systems, find the corresponding folders and try to delete them if you are facing similar issues.

NOTE: If you are having issues deleting the above two folders, try restarting the system and deleting them again. Also, make sure that you either disable the anti-virus software during the installation process or provide full access permission for this program in the anti-virus software.

Once I deleted the above two folders, I was able to install IBM Integration Designer V7.5 and the test environment without any issues.

References:

[1] IBM Integration Designer V 7.5: Troubleshooting the installation process.

Thursday, January 6, 2011

DataPower: Encoding base64Binary Inline Data into MTOM

Summary:
Learn how to encode base64Binary data as MTOM/XOP using an XSLT in DataPower.


MTOM (Message Transmission Optimization Mechanism) is a W3C standard that uses XOP (XML Binary Optimized Packaging) to transmit binary data. For more information on MTOM or XOP, please refer to [1] and [2] in the references section.

Scenario:
  1. Host service returning (images) base64Binary data inline.
  2. DataPower to encode the base64Binary data and send the response to the client as MTOM/XOP.
Scenario

In-order to achieve this, you will need to create a ‘MTOM Policy’ object. Find MTOM Policy object under Objects/XML Processing/MTOM Policy. MTOM policy object can be used for encoding or decoding by selecting the respective MTOM Mode on the Policy Object.

The name that I used for the MTOM Policy Object is ‘MTOM ‘ and for the scenario, we are trying to encode the base64Binary to MTOM so, I selected MTOM Mode as ‘encode’.

Under the MTOM Rules tab on the object, you will need to add a rule providing the XPath expression pointing to the element that has the base64Binary Data.

MTOM Policy Rule

Once the MTOM Policy object has been created, you can use it in any of your services in DataPower. You can do this in two ways.
  1. In your service response policy in DataPower, you can configure a Transform action and use the preshipped mtom.xsl with the MTOM Policy object that you have created as discussed in (References) [3].
  2. For scenarios where you have a generic DataPower service / processing rule for multiple back-end services and if you have a need to use different MTOM policy objects for different services, you could call the preshipped ‘mtom-implementation’ template in your own XSLT as follows.

You can use your own logic to pick the respective MTOM Policy name based on the backend service/operation being invoked.


<xsl:include href="store:///dp/mtom.xsl"/>
  <xsl:template match="/">
      <xsl:call-template>
            <xsl:with-param select="'MTOM'"/>
      </xsl:call-template>
  </xsl:template>


WSDL: Unlike SWA (SOAP With Attachments) definitions in the WSDL bindings, MTOM does not need any specific changes in the WSDL. In the above scenario, the element ‘image’ which holds the base64Binary data coming from the backend service  can be defined as

<xsd:element name="image" type="xsd:base64Binary" />

 The same definition for image element will also work for MTOM.

References:

[1] SOAP Message Transmission Optimization Mechanism

[2] XML-binary Optimized Packaging

[3]Processing Attachments in WebSphere DataPower SOA Appliances

Thursday, September 30, 2010

Developing Service Component Architecture (SCA) Applications Using Rational Application Developer (RAD) 7.5: Getting Started.

Summary:
Service Component Architecture (SCA), Installation of SCA development tools in RAD and feature pack for WAS runtime, Development and Learning Material Links


Service Component Architecture (SCA) is an Open Service Oriented Architecture Collaboration’s (OSOA) emerging standard programming model.

Service Component Architecture aims to provide a model for the creation of service components in a wide range of languages and a model for assembling service components into a business solution - activities which are at the heart of building applications using a service-oriented architecture.” – [1]

Rational Application Developer (RAD) Version 7.5.2 introduced a new installable feature – Service Component Architecture Development Tools.

“This feature provides a concise set of tools for developing Service Component Architecture service components implemented with annotated Java, for graphically wiring components together to form new composite services, for associating protocol bindings and quality of service intents to Service Component Architecture components, and for packaging Service Component Architecture assets and deploying them to the WebSphere Application Server.” – [2]

SCA Development Tools: Feature Pack Installation

The easiest way to install the SCA development tools for RAD is using the Installation Manager.

When you are doing an install/modify/update, make sure you select the feature “Service Component Architecture Development Tools”.

Installation Manager : SCA Feature Pack

If you have Test Environment, make sure you also select “feature pack for Service Component Architecture” for the runtime to support SCA applications.

Learning and Reference Material

You can find very good documentation on SCA and how to develop SCA applications using RAD on the IBM Info Center. Please use the following links to learn about the same.

IBM InfoCenter: Development Reference
OSOA: Development Reference
IBM InfoCenter: Tutorials
References:
  1. Open Service Oriented Architecture Collaboration (OSOA)
  2. Rational Application Developer (RAD) V 7.5 Releases: New Features And Enhancements

Wednesday, May 26, 2010

Serializing and Deserializing Business Objects From and To XML Documents in WebSphere Integration Developer

Summary:
Use BOXMLSerializer and BOXMLDocument interfaces to convert a Business Object to an XML string and vice versa in WebSphere Integration Developer.


Often times you will see a need to convert a given Business Object into an XML string and vice versa. You can serialize and deserialize a Business Object to and from a given XML string by using com.ibm.websphere.bo.BOXMLSerializer and com.ibm.websphere.bo.BOXMLDocument interfaces.

BOXMLSerializer serializer = (BOXMLSerializer)new ServiceManager().locateService(“com/ibm/websphere/bo/BOXMLSerializer”);

Sample Java code to convert a Business Object to an XML String:

Let’s say you have your Business Object stored in a variable ‘inputDataObject’ (of type commonj.sdo.DataObject)

ByteArrayOutputStream outputStream = newByteArrayOutputStream();
serializer.writeDataObject(inputDataObject,inputDataObject.getType().getURI(),inputDataObject.getType().getName(),outputStream);
String myXMLString = outputStream.toString(“UTF-8”);

“myXMLString” will hold the XML string corresponding to the Data Object “inputDataObject”.

Sample Java code to convert a given XML String to a Business Object:

Let’s say you have the XML string stored in a variable named ‘inputXMLString’ (of type java.lang.String)

BOXMLDocument document = serializer.readXMLDocument(new ByteArrayInputStream(inputXMLString.getBytes(“UTF-8”)));
commonj.sdo.DataObject myDataObject =document.getDataObject();

“myDataObject” will hold the Business Object corresponding to the XML string “inputXMLString”.

Note: The schema definition (xsd) corresponding to the Business Object that you are trying to convert the XML string into, should be available during runtime.

Wednesday, May 19, 2010

Fetching WSDL Properties From WebSphere Service Registry and Repository (WSRR) In WebSphere Integration Developer (WID) Using REST Calls

Summary:
Learn how to Query WSRR using REST calls to fetch content and parse this content. In particular, the scenario of fetching a property value on a particular WSDL without using the IBM WSRR (Java (EJB) or SOAP) API is discussed. We will use a regular Java class to make REST calls to WSRR and parse thorough the retrieved content.


WebSphere Integration Developer (WID) 6.2 offers Endpoint Lookup mediation primitive to be used in mediation modules to lookup the endpoint of a particular service from WebSphere Service Registry and Repository (WSRR), but for scenarios where you have the endpoint or any other service related information stored as a property on the WSDL in WSRR, fetching a property without using the IBM WSRR (Java (EJB) or SOAP) API is discussed. We will use a regular Java class to make REST calls to WSRR and parse thorough the retrieved content.

Querying WSRR for Content:

You could use XPath expressions to query content in WSRR. Two types of Queries

Graph Query
The URL format for a REST call using Graph Query is:

http://<host>:<port>/WSRR/6.1/Metadata/
XML/GraphQuery?query=<XPath expression>

Example:

http://<host>:<port>/WSRR/6.1/Metadata/
XML/GraphQuery?query=/WSRR/WSDLDocument
[@name=’MyWebService.wsdl’ and @version=’1.0’]

The above URL will fetch the metadata associated with a 1.0 version of the WSDL named “MyWebService.wsdl”.

Property Query
The URL format for a REST call using Graph Query is:

http://<host>:<port>/WSRR/6.1/Metadata/
XML/PropertyQuery?query=
<XPath expression>&p<#>=<property name>

# denotes a number starting from 1 and incremented by 1 for each additional property that you want to fetch.

You can use “&p<#>=<property name>” once for each property that you want to retrieve.The order of the #s can change.

Example:

http://<host>:<port>/WSRR/6.1/Metadata/
XML/PropertyQuery?query=/WSRR/WSDLDocument
[@name=’MyWebService.wsdl’ and @version=’1.0’]
&p1=name&p2=endpoint

Note: Make sure you use %27 for ‘, when you are using the URL from the browser to view the content.

Let us consider the scenario where I have a WSDL stored in WSRR with a property named ‘endpoint’. The value of the property will hold the endpoint URI for that service.

In-order to invoke a service from WID, we can create a utility class that hold the methods to fetch the information from WSRR and we can use this utility from any mediation. Once the endpoint is retrieved, you can save that information on the SMO to invoke your service dynamically with the fetched endpoint value.

The path on the SMO to store the endpoint for dynamic invocation is “smo/headers/SMOHeader/Target/address”.

Make sure you also select the “Use dynamic endpoint if set in the message header” option under “Details” section in the “Properties” view of either the “Callout” node or the “Service Invoke” primitive.

Fetching the property value involves two steps:

1. Fetch the content using REST call with a property query.
String resturl = "http://<host>:<port>/
WSRR/6.1/Metadata/XML/PropertyQuery?
query=/WSRR/WSDLDocument[@name=%27
MyWebService.wsdl%27%20and%20
@version=%271.0%27]&p2=name&p1=endpoint";
URL url = new URL(resturl);
URLConnection urlConnection = url.openConnection();
BufferedReader reader = new BufferedReader
(new InputStreamReader(urlConnection.getInputStream()));
StringBuffer stringBuffer = new StringBuffer();
String line = null;
while(null != (line = reader.readLine()))
            stringBuffer.append(line);
reader.close();

2. Parse the fetched content using an xml parser to read the value of the property.

String searchPath = "//*[local-name()='property'
 and @*[local-name()='name'='endpoint']]
/@*[local-name()='value']";
DocumentBuilder documentBuilder =
DocumentBuilderFactory.
newInstance().newDocumentBuilder();
Document contentDocument = documentBuilder.
parse(new InputSource(new StringReader
(stringBuffer.toString())));
XPath xPath = XPathFactory.
newInstance().newXPath();
XPathExpression xPathExpression = xPath.
compile(searchPath);
String  endpoint = (String)xPathExpression.
evaluate(contentDocument,XPathConstants.STRING);

The string endpoint will hold the value against the property named “endpoint” on the WSDL “MyService.wsdl” and version 1.0 that is in WSRR.

You could basically use the same method to fetch the value of any property on the WSDL. You can also fetch any other content from WSRR by creating appropriate queries using REST calls.

If you would like to use SOAP or Java (EJB) API for WSRR, you will need to use two jar files named
  • sdo-int.jar
  • ServiceRegistryClient.jar
You can find these jars in the installation directory of WSRR.

For more information on using the IBM API for WSRR use references below.

References:
  1. Using DataPower SOA Appliances to query WebSphere Service Registry and Repository.
  2. WebSphere Service Registry and Repository Handbook.
  3. Query Content in WSRR – (WSRR Information Center).
  4. SOAP API Guide – (WSRR Information Center)

Tuesday, May 11, 2010

Dynamic Invocation Using IBM Service Component Architecture (SCA) Addressing API

Summary:
This article highlights the steps involved in invoking imports with dynamic endpoints in WebSphere Integration Developer using Service Component Architecture (SCA) API. The static endpoints defined on the imports will be overridden by the dynamically selected endpoint value.


You have defined your imports with different bindings. You have defined your component which invokes these imports. Everything looks good….

What happens when you deploy the module in different environments? Will you change the endpoints on your imports with each deployment (e.g. for SOAP/HTTP web services)? How do you dynamically select endpoints for invoking the imports?

You can use the SCA Addressing API to dynamically invoke components using imports in WebSphere Integration Developer.

All wired/un-wired imports with any type of binding can be invoked with dynamic endpoints using SCA Addressing API. Shown below are some samples for some commonly used bindings.
  • Obtain the endpoint (for overriding the defaults on the import) based on a condition.
The endpoint can either be stored in a properties file or as a namespace binding on the WebSphere process server.

If you would like to store it in a properties file, you could use resource bundles to look-up the value.

You can define namespace binding using admin console @ Environment>Naming>Name space bindings. After defining the endpoint URL as a string, you can look it up by doing a JNDI look-up.

SCA endpoint URI format:

sca://<module_name>/<export_name>

Sample:

sca://DynamicInvocationModule/SCATestExport1

Web services (SOAP/HTTP) URI format:

http://<host:port>/<module_name>/<service_name>

Sample:

http://localhost:9080/DynamicInvocationModule/
WSTestExport1

If you have changed the context root and the URL mapping, then use the format that you have defined.

(SOAP/JMS) URI format: same as JMS URI format shown below.

Unless the binding type attribute on the EndpointReference object is set (sample shown below), the address is interpreted as a SOAP/JMS endpoint.

JMS endpoint URI format:

jms:jndi:<QueueName>?jndiConnectionFactoryName=
<ConnectionFactoryName>

Sample:

Jms:jndi:MyQueue?jndiConnectionFactoryName=
MyConnectionFactory

MQ endpoint URI format:

wmq://hostname:port/msq/queue/<queueName>
@<queueManager>? connectQueueManager=<qmgr>

Samples:

wmq:/msg/queue/MyQueue  
wmq:/msg/queue/MyQueue@MyQueueManager
  • Create new EndpointReference and set required attributes.
    // import com.ibm.websphere.sca.
    addressing.EndpointReference;
    // import com.ibm.websphere.sca.
    addressing.EndpointReferenceFactory;
    EndpointReference eRef = EndpointReferenceFactory.
    INSTANCE.createEndpointReference();
    eRef.setAddress(<Obtained String Endpoint Value(URI)>);
  • Selectively add attribute values to EndpointReference
If you are trying to use imports that are not wired to the component where you have this code, also add

eRef.setImport(<ImportName>);

If you are trying to invoke an import with JMS binding, you need to explicitly set the binding type by adding the following line of code.

eRef.setBindingType(<bindingType>);

For <bindingType>, you can use one of the following
    EndpointReference.BINDING_TYPE_NOT_SET
    EndpointReference.BINDING_TYPE_JMS
    EndpointReference.BINDING_TYPE_MQJMS
    EndpointReference.BINDING_TYPE_GENERIC_JMS
    EndpointReference.BINDING_TYPE_MQ
    EndpointReference.BINDING_TYPEWEB_SERVICE
    EndpointReference.BINDING_TYPE_HTTP
    EndpointReference.BINDING_TYPE_SCA
    EndpointReference.BINDING_TYPE_EIS
  • Lookup the Service with the new endpoint reference and invoke the service
Service service = (com.ibm.websphere.sca.Service)
ServiceManager.INSTANCE.
getService(<Reference Partner String Name>, eRef);
param_output = service.invoke(<method name>, param);

To find the <ReferencePartnerStringName>, select the component that you have wired to the imports and in the properties view and select the “Details” tab.

Please Refer to my previous post "Must-Have bookmarks for IBM WebSphere Integration Developers" for reference material.

Please use the references below for information on how to use dynamic endpoints with other bindings not mentioned above or for additional information on what is discussed here.

References:
  1. IBM WebSphere Business Process Management Version 7.0 Information Center
  2. IBM WebSphere Application Server, Release 6 API Specification

Monday, May 3, 2010

Updating XML Maps in WebSphere Integration Developer When Service Message Object (SMO) Context Changes

Summary:
Update XML maps when service context on Service Message Object (SMO) changes with out having to redo the existing mappings.


Consider the scenario in which you have created a mediation module where you used XSL Transformation primitive to transform messages and have chosen the Message Root for this primitive to be the root of the Service Message Object (SMO).

If you now try to set up the correlation, transient or shared context on the input node of the flow and want to do the mappings for the same in the XML maps that you originally created, the new object that was added to the context will not show up and you will see a warning message that the context type does not match as shown below.

Warning Message

How do I now update the XML map with out having to redo my mappings?

Right click on the XML map and select “Open With>XML Editor”. You will see all the mappings in an XML format. What you are looking for are the tags <mapping></mapping>.

XML Mappings
Now rename the current XML map to <name>_old and create a new one select the Message Root to be “/” and having the same input and output as the original map.

Once the map is created, right click and select “Open With>XML Editor”, and copy the mappings (all the <mapping> tags) from the old map to the new one.

Close the new XML map and reopen it using the Mapping Editor and you should see all your old mappings. You will also see the context of the SMO updated with your changes.

New Request Map With Correlation Context

When you have submaps in the original mappings, you can basically use them as-is. Any updates to the Business Objects will be reflected automatically on the XML maps.

Tuesday, April 27, 2010

Invoke Business Object Maps Using WebSphere Business Integration API

Summary:
Use “com.ibm.wbiserver.map.MapService” interface to invoke Business Object Maps from your Java Classes.


Using the MapService interface is pretty straight forward.
  1. Use com.ibm.websphere.sca.ServiceManager class to lookup the MapService.
  2. Use appropriate methods on the MapService to invoke the Business Object Maps.
Let’s see a small example of how this is done. I have created a sample interface with one operation, an input BO (Business Object) (FromBO) and an Output BO (ToBO). I have also created a business object map to map from FromBO to ToBO. The picture below shows the details.

In the code sample below, the input to the operation is an instance of FromBO. We create an instance of ToBO and use the ‘simpleTranformation’ method on the MapService to invoke the ‘FromBO_ToBO_Map’ business object map.

public DataObject mapInputtoOutput(DataObject input1) {
               //create an instance of the output data object.
              BOFactory boFactory = (BOFactory)ServiceManager.INSTANCE.
              locateService("com/ibm/websphere/bo/BOFactory");
              DataObject output1 = boFactory.create("http://SampleLib/com/test/bo", "ToBO");
              //locate the map service
             MapService serviceOne = (MapService)ServiceManager.INSTANCE.
             locateService("com/ibm/wbiserver/map/MapService");
             // invoke the business object map to do the transformation.
             try {
                      serviceOne.simpleTransform("http://SampleLib/com/test/maps", 
                                      "FromBO_ToBO_Map",input1, output1);
             } catch (WBIMapServiceException e) {
                      // TODO Auto-generated catch block
                     e.printStackTrace();
              } catch (WBIMapNotFoundException e) {
                     // TODO Auto-generated catch block
                    e.printStackTrace();
             } catch (WBIMapFailureException e) {
                   // TODO Auto-generated catch block
                  e.printStackTrace();
            }
         return output1;
}

You can also use ‘transform’ method on the MapService interface if you would like to invoke business object maps that deal with transformations from multiple BOs to multiple BOs

Please check Must-Have bookmarks for IBM WebSphere Integration Developers for WAS API and other useful references.

Wednesday, April 21, 2010

WebsiteBaker: Customizing Multiflex-5 theme to add new blocks

Summary:
Customize Multiflex-5 to add new blocks, display icons and add content.



Recently, I was looking for website themes for my personal website, to use with websitebaker and found Multiflex-5 which I really liked for its features and its simple looks.

You will get all the info that you need to customize your template @ Multiflex:5.0. All you need to do is to find something that you like on the above site, right click on the webpage and select “View Page Source / View Source”. You basically browse down to the section that you are looking for, and use that in your template.

I wanted to add a new block and add content to it as shown in the picture below

Thought it might be useful for others who want to do the same, if I post this information. So, here you go!

In-order to add new menus or new blocks, you need to modify “info.php” under <installation dir>/templates/Multiflex-5/

The default template comes with two blocks named “News” and “Sidebar”. If you want an additional block or want to change the name of the existing blocks, “info.php” is the place to do it.
Once you have added a new block to “info.php”, it will be reflected in your (websitebaker) admin screen (Manage sections of a page) as shown below.

Note that “MyBlock” was added to info and it shows up in the drop down box in the Manage Sections page.

To add content to a block:
  1. Add a section to your page and place it under one of the block names in the drop down box.
  2. Modify “index.php” under <installation dir>/templates/Multiflex-5/, to pull the content into that block. The picture below shows a sample of how the “index.php” was modified to show the blocks.
Add Block - index.php
Additionally you can use different classes with your headings to display cool icons as shown below.
NOTE: When you modify the template "index.php" to display the content of the blocks, this will be done on all pages. If you do not add sections to other pages to provide content, empty blocks will be displayed.

References:

[1] WebsiteBaker-Designer Guide

[2] Multiflex-5.0

Friday, April 16, 2010

Web Services: A HOWTO on SOAP headers using JAX-RPC and JAX-WS

Summary: 
This article tries to address the following questions
  • How to define SOAP headers in a WSDL?
  • How to deal with SOAP headers when following the top-down and bottom-up development approaches?
  • How to make the SOAP headers available to the implementation when the headers are defined using explicit or implicit styles using a top-down or a bottom-up approach?
Development Environment: WebSphere Integration Developer (WID) 6.2


Defining SOAP headers in WSDL (Implicit and Explicit Styles):

“An implicit SOAP header is a SOAP header that fits one of the following descriptions:
  1. A message part that is declared as a SOAP header in the binding in the Web Services Description Language (WSDL) file, but the message definition is not referenced by a portType element within a WSDL file.
  2. An element that is not contained in the WSDL file.” – [4]

The author of the wonderful article named “Implement implicit and explicit SOAP headers” has described both styles in great detail.

Two cases when using SOAP headers:
  1. The data in the SOAP header is either used or populated in the implementation of the operation.
  2. The data in the SOAP header is neither used nor populated in the implementation of the operation.
In particular, the rest of this article focuses on case 1 with both Implicit and Explicit styles.

Development Approach (Top-Down and Bottom-Up):

In a Top-Down development approach of a web service, the WSDL is first defined from which the java artifacts that are necessary to implement the service are generated.

For a top-down approach, you could use

  1. WSDL2Java command in case of JAX-RPC
  2. wsimport command in case of JAX-WS

In a Bottom-Up approach of a web service, the WSDL is generated from the java artifacts that are associated with the implementation of a particular service.

For a bottom-up approach, you could use
  1. Java2WSDL command in case of JAX-RPC
  2. wsgen command in case of JAX-WS

Combining the two options of the development approach with the two options of SOAP header definition styles, we end up with 4 combinations.
  1. Top-Down – Explicit
  2. Top-Down – Implicit
  3. Bottom-Up – Explicit
  4. Bottom-Up – Implicit

JAX-RPC

Top-Down – Explicit

If you have defined your SOAP header using the explicit style in the WSDL, JAX-RPC maps the explicit headers to the Service Endpoint Interface (SEI) of the web service. Both request and response headers if any will be available for the implementation code.

With an explicit header definition style, after the java artifacts are generated, the SEI looks like the following for one operation named “returnInput” that has both request and response headers defined

public interface TestTopDownHeaders extends java.rmi.Remote {
              public void returnInput(com.test.TestInput parameters, com.test.BaseRequest_Type    
                                            request_header, com.test.holders.TestOutputHolder parameters2, 
                                            com.test.holders.BaseResponse_TypeHolder response_header) throws  
                                            java.rmi.RemoteException;
}

Note that the headers are passed in as parameters.

Top-Down – Implicit

JAX-RPC does not provide any mapping for the implicit header definitions.

One could use JAX-RPC handlers to access the headers for cases where the implementation of the service does not deal with the header information.

For cases where the SOAP header is either used or populated in the implementation of the operation, you could use one of the two options
  1. Use the ServiceLifecycle interface as described in [2] in the references section.
  2. Use JAX-RPC handler and use ThreadLocal class to store/retrieve the header information. On the Server side, when the request comes in, the handler basically populates the values in the request header that the implementation needs on the thread-local variable. The information stored is available to the operation implementation. For the response headers, the operation implementation can pass the information along to the handler in a similar fashion. This is not an elegant approach but sure works!

Bottom-Up – Explicit

For the Bottom-Up – Explicit header approach, a lot of manual changes need to be made. This is particularly for cases where the operation implementation needs to have access to SOAP headers.

Here is what I have done.
  1. Create holder classes
  2. Modify the SEI to pass headers as parameters mimicking the generated classes in the top-down approach.
  3. Generate the WSDL
  4. Modify the WSDL
  5. Modify the mapping xml

Seems to work fine, but I would not recommend this approach since there is a lot of manual work involved.

Bottom-Up – Implicit

Some amount of manual changes to the WSDL is required (adding the SOAP header to the bindings sections). Also, in-order to generate the mappings for the header objects, they will have to be added to the interface and then removed at a later point, not to mention the changes to the mappings xml file.

One of the two approaches described in Top-Down – Implicit can be used to make the SOAP header information available to the implementation of the operation.

JAX-WS (2.1)



Using annotations in JAX-WS, you can mark a parameter as a header.

Eg:

@WebParam(name = "RequestHeader", targetNamespace = "http://www.test.com", header = true, partName = "request_header")

If you are looking for JAX-WS annotations reference, please use [5] in the references section.

Top-Down – Explicit

JAX-WS supports explicit headers and provides the header objects as parameters to the operation. It generates the annotations, marking the SOAP header parameters as headers.

Top-Down – Implicit

JAX-WS has no support for implicit headers but after generating the java artifacts. For cases where the implementation deals with the headers
  1. Simply add header parameters with annotations to the interface/implementation classes and the mapping is taken care of. Don’t forget to use the Holder class for OUT and IN/OUT parameters.
  2. The other approach would be to use JAX-WS handlers and MessageContext object to make the headers accessible to the implementation. Please refer [3] to see how you can work with JAX-WS handlers to do the same.

Bottom-Up – Explicit

JAX-WS supports explicit headers even in the bottom-up approach. Add the annotations marking the header parameters as headers.

E.g.:

@WebService(name = "TestBottomupHeaders", targetNamespace = "http://www.test.com")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface TestBottomupHeadersIntf extends java.rmi.Remote{
            @WebMethod(action = "returnInput")
            public void returnInput(
                @WebParam(name = "TestInput", targetNamespace = 
                            "http://www.test.com", partName = "input") TestInput input,
                @WebParam(name = "BaseRequest", targetNamespace = "http://www.test.com",  
                           header = true, partName = "request_header") BaseRequest_Type requestHeader,
                @WebParam(name = "TestOutput", targetNamespace = "http://www.test.com", mode 
                      = WebParam.Mode.OUT, partName = "output") Holder<TestOutput> output,
                @WebParam(name = "BaseResponse", targetNamespace = "http://www.test.com", 
                     header = true, mode = WebParam.Mode.OUT, partName = "response_header")
                     Holder<BaseResponse_Type> responseHeader);
}

NOTE: For OUT and IN/OUT parameters, you must use the Holder class as shown above.

Bottom-Up – Implicit

Two approaches here:

1.
  • Define the POJO interface passing the headers as parameters and with annotations marking header=”true” where appropriate
  • Generate the WSDL
  • Change the WSDL manually to have implicit headers definitions rather than explicit.
2.   Use JAX-WS handlers to make the headers available to the implementation. Please refer [3] to see how you can work with JAX-WS handlers and MessageContext to do the same.

References:

[1]        Implement implicit and explicit SOAP headers

[2]        Web services programming tips and tricks: Using SOAP headers with JAX-RPC

[3]        Get a handle on the JAX-WS API's handler framework

[4]        IBM WebSphere Application V 7.0 Information Center

[5]        JAX-WS annotations reference