Using Ant to inspect Connection Properties in WSDL Files that are generated by Oracle SOA Suite Adapters 13422386 1019544571447648 7687716130941590224 o1

Using Ant to inspect Connection Properties in WSDL Files that are generated by Oracle SOA Suite Adapters

 

Oracle SOA Suite comes with a collection of adapters that allow you to easily tap into a number of technologies from BPEL Processes or from ESB Services. Want to connect to a database, hook up to a queue or access your E-Business Suite: create an adapter for it with a WSDL interface from within JDeveloper by simply running a wizard.

Logical Connection Names

All adapters, whether these are used to connect to an FTP server or access an MQ-Series queue, use logical connection names or JNDI names that must be specified at design time. At runtime, the adapter framework uses these JNDI names for looking up the physical connection data from configuration files. This mechanism works well. It ensures that the software remains unchanged when dragging it through the various stages of the software development life-cycle process: from QA to SIT, to UAT and finally Production only the environment-specific configuration files have different data. Obviously, developers are required to stick to the naming conventions for the logical connection names.

Risky business

Unfortunately, for ‘convenience’ Oracle decided to place physical connection data in the generated WSDL files at design time. When the system is not able to obtain the connection details from the configuration files using the JNDI name, it will use the so called ManagedConnectionFactory or MCF properties from the WSDL instead. Risky business that may cause undesirable behavior: if there is a misconfiguration the service may connect to an instance that was specified at design time without you knowing that. I prefer a clear error on which a system administrator can act appropriately by fixing the connection details in the proper configuration file. Hence, as a rule, the MCF properties need to be removed from the generated WSDL files afterwards. For inspection of the connection properties in the WSDL files I created a simple Ant script. 

Requirements

My initial requirement is simple: I want an overview of the connection data for all WSDL files in the project. Typically, these are listed in the WSDL files in the following format:

    <!-- Your runtime connection is declared in
        J2EE_HOME/application-deployments/default/DbAdapter/oc4j-ra.xml
        These 'mcf' properties here are from your design time connection and 
        save you from having to edit that file and restart the application server
        if eis/DB/HR is missing.
        These 'mcf' properties are safe to remove.
    -->
    <service name="ReadDptData">
        <port name="ReadDptData_pt" binding="tns:ReadDptData_binding">
            <jca:address location="eis/DB/HR"
                UIConnectionName="HR"
                ManagedConnectionFactory="oracle.tip.adapter.db.DBManagedConnectionFactory"
                mcf.DriverClassName="oracle.jdbc.OracleDriver"
                mcf.PlatformClassName="oracle.toplink.platform.database.oracle.OraclePlatform"
                mcf.ConnectionString="jdbc:oracle:thin:@//localhost:1521/XE"
                mcf.UserName="hr"
                mcf.Password="62C32F70E98297522AD97E15439FAC0E"
            />
        </port>
    </service>

Now, I want to check the contents of the <jca:address> element for each file. In a project I am currently working on that literally means plowing through hundreds of files. Hence, I need a utility that automates that tedious task for me. Since we already use Ant extensively, e.g. for deploying BPEL Processes and ESB Services, the utility is implemented as an Ant build script.

Loop Constructs and XML Tasks in Ant

Out of the Apache box, Ant does not come with looping constructs. Luckily the Ant-Contrib project provides very useful extensions to Ant among which is a foreach task that allows looping over a set of files. Subsequently, for each file I want to display the contents of of the <jca:address> element. Applying a simple XPath expression should do the trick. That is possible using the yet another Ant extension, XMLTask. Putting it all together results in the following script:

<?xml version="1.0" encoding="UTF-8"?>
<project name="QA" default="list-connection-data-in-wsdl-files" basedir=".">
<!--  QA Utilities for SOA components -->
    <property environment="env"/>
    <property name="server-src" value="${env.SOA_PROJECT_HOME}/work"/>

    <taskdef resource="net/sf/antcontrib/antcontrib.properties">
      <classpath>
        <pathelement location="${env.SOA_DA_HOME}/lib/ant-contrib-1.0b3.jar"/>
      </classpath>
    </taskdef>

    <taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask">
      <classpath>
        <pathelement location="${env.SOA_DA_HOME}/lib/xmltask-v1.15.1.jar"/>
      </classpath>
    </taskdef>

    <target name="list-connection-data-in-wsdl-files">
      <foreach target="list-connection-data-in-wsdl-file"
               param="source-file"
      >
        <path id="src.path">
          <fileset dir="${server-src}">
            <include name="**/*.wsdl"/>
          </fileset>
        </path>
      </foreach>
    </target>    

    <target name="list-connection-data-in-wsdl-file">
      <echo message="File name: ${source-file}" />
      <xmltask source="${source-file}">
        <copy path="descendant::*/:service/:port" buffer="connect-data-buffer"/>
        <print buffer="connect-data-buffer"/>
      </xmltask>
    </target>

</project>

When using XPath expressions in XMLTask Ant targets, like descendant::*/:service/:port in this case, the colon character is used by XMLTask to deal with local namespaces in the WSDL file. As far as I know, there is no way to pass on namespaces data to XMLTask (I confess that I did not spent a lot of time investigating). XPath expressions /:service/:port/:address and /:service/:port/jca:address do not return the required results.

Room for improvements

The script that is provided here suits my needs. But as always there is room for improvements. For one, when it does not find a <jca:address> element it reports that whereas in that case we could opt for not even mentioning the file. Furthermore, the script could be extended to automatically remove all but the location attribute from the <jca:address> element. For that purpose, XMLTask provides options for manipulation of XML documents.