Thursday, July 28, 2011

Using JSONP in Datapower

For one of our clients we needed to create multiple JSONP services with SOAP-backends in Datapower. JSON is supported by default in het Multi-Protocol gateway, and with JSONx, Datapower can handle it quite well. This post describes the fixes we did to extend JSONx and make it easy to create a JSONP-response in the same way you would do for a JSON-response.

For those of you who never heard of JSONP (JSON with Padding): it’s JSON wrapped in round brackets, preceded with a prefix. This makes it possible for javascript to use it as if it where a javascript function. It is used to allow a web page to request data from a server in a different domain (our datapower device).

Back to our case: the strenght of Datapower is its ability to handle XML content. Since JSON is no xml, IBM provided us with a language called JSONx. It is an XML-model that represents JSON-content. The idea is to work as long as possible with JSONx and after all mappings and validations are done the conversion to a proper JSON response can be done using the provided ‘jsonx2json.xsl’ style sheet. This stylesheet is by default available in the ‘store://’ directory on the Datapower appliance.

Since we wanted to use JSONP instead of JSON, we complemented the JSONX-language with an extra element <jsonp:callback> that will serve as a root for the normal JSONX content. The new name we used for it is JSONPx. It has one property: ‘name’. The value of this property will be used as the prefix for our JSONP-response. If ‘name’ is empty, the output will be normal JSON.
Here you can see of a sample of a JSONPx-file:
<jsonp:callback
  xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx"
  xmlns:jsonp="http://www.i8c.be/xmlns/jsonpx" name="TestPrefix">
  <json:object>
     <json:number name="testValue">123</json:number>
     <json:string name="testName">Foo</json:string>
  </json:object>
</jsonp:callback>

Just like for a JSONx-file it is possible to validate this file against an XSD-schema. Instead of the default jsonx.xsd (located under ‘store://‘in Datapower), you now can use the XSD below and we called it jsonpx.xsd;
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:tns="http://www.i8c.be/xmlns/jsonpx"
  targetNamespace="http://www.i8c.be/xmlns/jsonpx" 
  elementFormDefault="qualified"   attributeFormDefault="unqualified">
<xs:import namespace="http://www.ibm.com/xmlns/prod/2009/jsonx"
           schemaLocation="store:///jsonx.xsd"/>
<xs:element name="callback" type="tns:callback"/>                       
   <xs:complexType name="callback">          
      <xs:sequence>
         <xs:any namespace="http://www.ibm.com/xmlns/prod/2009/jsonx"
            minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string"/>        
   </xs:complexType>
</xs:schema>

For the transformation we use the XSLT called ‘jsonpx2json.xsl’ which imports the transformations from the ‘jsonx2json.xsl’ file, but adds the transformation for the jsonp:calback element to it.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="1.0" 
     xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" 
     xmlns:jsonp="http://www.i8c.be/xmlns/jsonpx">
<xsl:output method="text" encoding="utf-8" 
  indent="no" media-type="application/javascript"/>          
  <xsl:import href="store:///jsonx2json.xsl"/>
  <xsl:template match="jsonp:callback">
     <xsl:if test="string-length(@name)>0">
        <xsl:value-of select="@name"/>
        <xsl:text>(</xsl:text>      
     </xsl:if>
     <xsl:apply-templates select="*"/>
     <xsl:if test="string-length(@name)>0">
        <xsl:text>)</xsl:text>
     </xsl:if>
  </xsl:template>
</xsl:stylesheet>



Author: Tim

Wednesday, July 20, 2011

Tracking JDBC calls with DataDirect driver

Out of the box the DataDirect driver comes with the Spy tool capability, allowing to trace calls in running programs.  In this blog entry, we will explain the configuration of this DataDirect JDBC driver in combination with the webMethods Integration Server.
  • Using the webMethods IntegrationServer’s Administrator UI go to Settings > JDBC Pools
 
  • In Pool Alias Definitions select the Pool Alias for which you want to enable DataDirect Spy tracing. Make sure the Associated Driver Alias is of type DataDirect Connect JDBC Oracle Driver
 
  • Take the selected JDBC Connection Pool Alias Definition in edit
 
  • Append string ;SpyAttributes=(log=(file)<location-spy-trace-output-file>;logTName=yes;timestamp=yes) to the Database URL.
o   Replace <location-spy-trace-output-file> with the location and filename of preference were the spy logging should be redirected to.            
o   DataDirect Spy Attributes
§  logTName={yes | no}
Specifies whether DataDirect Spy logs the name of the current thread.
When set to no (the initial default), DataDirect Spy does not log the name of the current thread.
§  timestamp={yes | no}
Specifies whether a timestamp should be included on each line of the DataDirect Spy log.
When set to no (the initial default), DataDirect Spy does not include a timestamp on each line.

More DataDirect Spy Attributes are available and can be found in the appropriate DataDirect reference documentation
  • Save your changes and restart the webMethods IntegrationServer before updated settings take effect.
Example Database URL:
jdbc:wm:oracle://oracle.integr8consulting.com:2849;SID=DVLUX001;LoginTimeout=120;wireprotocolmode=2;SpyAttributes=(log=(file)/opt/webMethods7/spylog/spy.log;logTName=yes;timestamp=yes)

Example Spy trace:

spy(Thread-112)(2011/07/15 12:59:10.413)>> Connection[3].prepareStatement(String sql)
spy(Thread-112)(2011/07/15 12:59:10.414)>> sql = SELECT EXCL_LOCK_ID, TARGET_ID, LOCK_HOLDER, LOCK_TYPE,
 LOCK_SHARE_COUNT, LOCK_TIMESTAMP FROM WM_EXCL_DIST_LOCK WHERE LOCK_TIMESTAMP<? AND LOCK_TYPE='E'
spy(Thread-112)(2011/07/15 12:59:10.414)>> OK (PreparedStatement[3])

spy(Thread-112)(2011/07/15 12:59:10.414)>> PreparedStatement[3].setLong(int


Author: Johan