IFBO as a webservice supporting ws-* ("WS-Star")

Very interested in hearing of anyone working on getting IFBO to support ws-star capabilities.

Current client (October 2009) would like webservice interfacing with Asset Suite business objects. Plan is to implement IFBO with HTTP POST (multipart as delivered from Ventyx) first and then work towards supporting ws-star.

The client is MicroSoft oriented and what they asked for is WCF (MicroSoft Windows Communications Foundation) compliant webservices for Asset Suite. Through speaking with a systems architect acting as an interpreter it was agreed with the client that what would be acceptable is ws-star compliant webservices for Asset Suite. It is hoped to accomplish this via the use of Sun's jaxws-ri.

Fortunately the client is also a heavy Oracle PeopleSoft user and it appears that Oracle does not deliver a webservice solution conforming to ws-star. Therefore the PeopleSoft developers are in a similar situation and it's led to the serious investigation of jaxws-ri.

As of October 2009, jaxws-ri has been implemented on Apache / Tomcat (version 5) on Solaris with almost all of the jaxws-ri/samples functioning. It's hoped that the samples can serve as a guide for wrapping IFBO in jaxws-ri with using ant for deployment.

Experiment of IFBO as a webservice

Experiment of Asset Suite Integration Framework Business Objects (IFBO) secure web service hosted on Tomcat 5.
 WSDL 1.1
 SOAP 1.2
 JAX-WS 2.1.7
 IFBO 6.0.1
 Java 1.5
 Synchronous



The goal is having IFBO as a secure web service (implemented as a servlet) supporting WSDL and SOAP. Secure web service means TLS/SSL to web service endpoint.



This does not address IFBO publishing as a web service.



Start with with implementing Jax 2.1.7 sample fromwsdl_secure.



Here's what fromwsdl_secure/src/fromwsdl_secure/server/AddNumbersImpl.java
looks like after being used for IFBO at
ifbo-wsdl-xml-secure/src/ifbo_wsdl_xml_secure/server/ifboServiceImpl.java


/*
  Experiment of Asset Suite Integration Framework Business Objects (IFBO) secure web service
  WSDL 1.1
  SOAP 1.2
  JAX-WS 2.1.7
  Java 1.5 Must match version JAX-WS was built with.
  Synchronous

  Note that this is an experimental implemenation of a jaxws web service.
  APIFWAdapterServlet.java was implemented as extending HttpServlet
  and had access to things like:
  getServletConfig().getInitParameter("configDir").
  Could not find the equivalent of this for a web service.
  Any logging necessary should go to System.out and will end up in the
  Tomcat catalina.out log.

PassPortGeek.com Winter 2009
*/

package ifbo_wsdl_xml_secure.server;

import com.indus.apifw.adapter.*;
import com.indus.apifw.inbound.InboundAPIReply;

import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import java.io.*;

@javax.jws.WebService (endpointInterface="ifbo_wsdl_xml_secure.server.IfboServicePortType")
public class ifboServiceImpl {

  public String ifboService (String IFBOxml) throws IfboServiceFault_Exception {

    System.out.println ("ifboService xml=" + IFBOxml);

    InboundAPIReply reply = null;
    String replyS = "";
    String configdir = "dir_path/if_ws/config";

    try {

      NativeJavaAdapter adapter = new NativeJavaAdapter(IFBOxml, "UTF8&");

      adapter.setConfigDir(configdir);

      reply = adapter.invokeInboundServices();

    } catch(Throwable theException) {
      theException.printStackTrace();
    }

    return reply.getXMLReplyString();

  }

}

Experiment of IFBO as a webservice (client)

/*
 Asset Suite IFBO (Integration Framework Business Objects)

  WSDL 1.1 Ref: Entry in wsdl: http://schemas.xmlsoap.org/wsdl/soap12/ (paste into browser)
  SOAP 1.2 Ref: Entries in the wsdl
  JAX-WS 2.1.7 Ref: /jaxws-ri/docs/ReleaseNotes.html
  Java 1.5 Ref: Must match version JAX-WS was built with.
  Synchronous Ref:
  Certificate length and Signature Algorithm are defined in the etc/deploy-targets.xml.
    Verify certificate by accessing wsdl via browser and looking at certificate.
  Define TLS/SSL for web service endpoint within Tomcat:
    /tomcat/webapps/jaxws-ifbo-wsdl-xml-secure/WEB-INF/web.xml
    Transport Layer Security (TLS)/Secure Sockets Layer (SSL) with no Mutual Authentication (server authentification). Ref: http://java.sun.com/developer/EJTechTips/2006/tt0527.html#1
    <security-constraint>
        <web-resource-collection>
          <web-resource-name>ifboService</web-resource-name>
          <url-pattern>/ifboService</url-pattern>
          <http-method>GET</http-method>
          <http-method>POST</http-method>
        </web-resource-collection>
        <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

 PassPortGeek.com Winter 2009

*/

// Unix commands for defining certificate location, creating web service stubs, and creating jar file of web service stubs.
//
// Define shell variable WSIMPORT_OPTS to let the Java environment know where to find SSL certificates.
// export WSIMPORT_OPTS="-Djavax.net.ssl.trustStore=.../jaxws-ri/samples/ifbo-wsdl-xml-secure/etc/certs/client.truststore"
//
// Use wsimport to create stubs:
// .../jaxws-ri/bin/wsimport.sh -keep -extension -verbose https://server:port/jaxws-ifbo-wsdl
-xml-secure/ifboService?wsdl
//
//Create a zip file and rename it to jar and put in the classpath.
// find ./assetsuite/ifbo_wsdl_xml_secure -name "*.class" -print | zip ./ifboWsdlXmlSec -@
//
// Windows commands for same.
//
// Verify Java version 1.5 with: java -version
//
// Define shell variable WSIMPORT_OPTS to let the Java environment know where to find SSL certificates.
// set WSIMPORT_OPTS="-Djavax.net.ssl.trustStore=.\tomcat.keystore"
// Note that tomcat.keystore and client.truststore depend on how you created the certificates.
//
// Use wsimport to create stubs:
// wsimport.bat -keep -extension -verbose https://server:port/jaxws-ifbo-wsdl-xml-secure/ifboService?wsdl
//
// If the above setting of WSIMPORT_OPTS and execution of wsimport.bat doesn't work, try:
// java -Djavax.net.ssl.trustStore=.\tomcat.keystore -jar w:\temp\java\jaxws-ri\
lib\jaxws-tools.jar -keep -extension -verbose https://server:port/jaxws-ifbo-wsdl-xml-secure/ifboService?wsdl
//
//Create a zip file and rename it to jar and put in the classpath.
// Not sure how to do this in Windows.
//

import assetsuite.ifbo_wsdl_xml_secure.*;
import java.io.*;

public class ifboWsdlXmlSecure {

  private static String program = "ifboWsdlXmlSecure";

  public static void main (String[] args) {

    String currentMethod = "main";

    String fileXML = "fileXML";

    fileXML = args[0];

    /* Read file */

    // Get the size of the file
    File input = new File(fileXML);
    long filelength = input.length();

    // Create the byte array to hold the data.
    // The array size matches the file size.

    byte fileByteArray[] = new byte[(int)filelength];

    try {

      FileInputStream fis = new FileInputStream(input);
      filelength = fis.read(fileByteArray);
      fis.close();

    } catch (UnsupportedEncodingException ee) {
      System.out.println("IOException error" + ee.getMessage());
    } catch (IOException e) {
      System.out.println("IOException error" + e.getMessage());
    }

    System.out.println("filelength = " + filelength);

    /* end Read file */

    try {

      IfboServicePortType port = new IfboService_Service().getIfboServicePort();

      String IFBOxml = new String(fileByteArray);
      String resultS = "";

      System.out.printf (program + " " + currentMethod + " invoking ifboService(%s)\n", IFBOxml);
      resultS = port.ifboService(IFBOxml);
      System.out.printf ("The result of ifboService is %s.\n", resultS);

    } catch (IfboServiceFault_Exception ex) {
      System.out.printf ("Caught IfboServiceFault_Exception: %s\n", ex.getFaultInfo().getFaultInfo ());
    }
  }
}

Experiment of IFBO as a web service client (.Net C#)

//Visual Studio 2008 C# console application
//
//Create the web service stubs using IFBO's WSDL:
// Solution Explorer, right click, select Add Service Reference
// Address: https://server:port/jaxws-ifbo-wsdl-xml-secure/ifboService?wsdl
// NameSpace: ifbo_wsdl_xml_secure
// Click Go.
//
//Define the IFBO's certificate to the Windows machine running this program:
// Start, Run, MMC (your Microsoft Management Console might vary from the below instructions)
// File/Add-Remove Snap-In
// Click Add
// Select Certificates and click Add
// Click Close, Click OK
// Select Certificates under Trusted Root Certification Authorities and right click on it and chose All Tasks->Import
// Specify the file name as the certificate copied from server. "server.certificate"
// Chose all the default options and click finish
// MMC is giving access to Windows settings. Once the certificate is added under Trusted Root Certification Authorities, you're done.
// Ref for MMC: http://cwiki.apache.org/ETCH/howto-tls.html
//
// PassPortGeek.com Winter 2009

using System;
using System.Web;
using System.Collections.Generic;
using System.Text;
using assetsuite.ifbo_wsdl_xml_secure;

namespace BPA {

  public class ifboWsdlXmlSec {

    public ifboWsdlXmlSec() {
    }

    public void Run() {

      String hello = "Hello World";
      Console.WriteLine(hello);

      }

    static void Main() {

      // create an instance
      ifboWsdlXmlSec ifbo = new ifboWsdlXmlSec();

      // invoke the instance method
      ifbo.Run();

      IfboServicePortType port = new IfboServicePortTypeClient();

      ifboServiceRequest hs = new ifboServiceRequest();
      hs.ifboService = new ifboService();
      //IFBO XML for Work Order create. This program is not pretty, just a proof.
      string IFBOXML = String.Format("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE InboundRequest [ <!ELEMENT InboundRequest (APIHeader, BusinessObject)< >!ENTITY % APIHeader SYSTEM \"http://apifw//xml/APIHeader.Inbound.Request.V060000.dtd\"> %APIHeader; <!ENTITY % BusinessObject SYSTEM \"http://apifw//xml/WorkOrder.Create.Request.V060000.dtd\"> %BusinessObject; ]><InboundRequest><APIHeader ReplyTypeOK=\"A\" ReplyTypeError=\"N\"><apiAPIVersion>V060000</apiAPIVersion><apiBusinessObject>WorkOrder</apiBusinessObject><apiBusObjectMethod>Create</apiBusObjectMethod><apiBusObjectVersion>V060000</apiBusObjectVersion><apiUserID>PASSPORTID</apiUserID><apiExtSystemID></apiExtSystemID><apiExtRequestID></apiExtRequestID><apiRoutingInfo></apiRoutingInfo></APIHeader><BusinessObject><WoHeader><Facility>TIG</Facility><WorkOrderType>CA</WorkOrderType><WoDescription>Test123 IFBO</WoDescription><Planner>PASSPORTID</Planner><WoPriority>99</WoPriority><ProjectNbr>0001066</ProjectNbr></WoHeader></BusinessObject></InboundRequest>");

      char[] myChar = IFBOXML.ToCharArray();

      try {
        hs.ifboService.ifboXml = new string(myChar).ToString();
      } catch(NullReferenceException nre) {
        Console.WriteLine("Exception occured" + nre.ToString());
      }

      ifboServiceResponse1 iSR = new ifboServiceResponse1();
      iSR = port.ifboService(hs);
      Console.WriteLine(iSR.ifboServiceResponse.@return);

    }

  }
}

ifbo-wsdl-xml-secure/build.xml

build.xml

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

<!--
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.

Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.

The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
and Distribution License("CDDL") (collectively, the "License"). You
may not use this file except in compliance with the License. You can obtain
a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
language governing permissions and limitations under the License.

When distributing the software, include this License Header Notice in each
file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
Sun designates this particular file as subject to the "Classpath" exception
as provided by Sun in the GPL Version 2 section of the License file that
accompanied this code. If applicable, add the following below the License
Header, with the fields enclosed by brackets [] replaced by your own
identifying information: "Portions Copyrighted [year]
[name of copyright owner]"

Contributor(s):

If you wish your version of this file to be governed by only the CDDL or
only the GPL Version 2, indicate your decision by adding "[Contributor]
elects to include this software in this distribution under the [CDDL or GPL
Version 2] license." If you don't indicate a single choice of license, a
recipient has the option to distribute your version of this file under
either the CDDL, the GPL Version 2 or to extend the choice of license to
its licensees as provided above. However, if you add GPL Version 2 code
and therefore, elected the GPL Version 2 license, then the option applies
only if the new code is made subject to such option by the copyright
holder.
-->

<project basedir="." default="help" name="ifbo-wsdl-xml-secure">

  <import file="etc/deploy-targets.xml"/>
  <property name="service.wsdl.location" value="https://${domain.name}:${https.port}/jaxws-ifbo-wsdl-xml-secure/if
boService?wsdl"/>
  <path id="jaxws.classpath">
   <pathelement location="${java.home}/../lib/tools.jar"/>
   <pathelement location="${ifbo.home}/WEB-INF/lib/apifw.jar"/>
   <pathelement location="${ifbo.home}/WEB-INF/lib/log4j-1.2.jar"/>
   <pathelement location="${javax.home}/servlet-api.jar"/>
   <fileset dir="${lib.home}">
    <include name="*.jar"/>
    <exclude name="j2ee.jar"/>
   </fileset>
  </path>

  <taskdef name="wsimport" classname="com.sun.tools.ws.ant.WsImport">
   <classpath refid="jaxws.classpath"/>
  </taskdef>

  <target name="setup">
   <mkdir dir="${build.home}"/>
   <mkdir dir="${build.classes.home}"/>
   <mkdir dir="${build.war.home}"/>
  </target>

  <target name="clean">
   <delete dir="${build.home}" includeEmptyDirs="true"/>
  </target>

  <target name="build-server-wsdl" depends="setup">
   <wsimport
    debug="true"
    verbose="${verbose}"
    keep="true"
    extension="true"
    destdir="${build.classes.home}"
    package="ifbo_wsdl_xml_secure.server"
    wsdl="${basedir}/etc/ifboService.wsdl">
   </wsimport>
   <javac
    fork="true"
    srcdir="${basedir}/src"
    destdir="${build.classes.home}"
    includes="**/server/**,**/common/**">
    <classpath refid="jaxws.classpath"/>
   </javac>
  </target>

  <target name="create-war">
   <war warfile="${build.war.home}/jaxws-${ant.project.name}.war" webxml="etc/web.xml">
    <webinf dir="${basedir}/etc" includes="sun-jaxws.xml"/>
    <zipfileset
    dir="${basedir}/etc"
    includes="*.wsdl, *.xsd"
    prefix="WEB-INF/wsdl"/>
    <classes dir="${build.classes.home}"/>
   </war>
  </target>

  <target name="generate-client" depends="setup, setup-client-truststore">
   <echo message="Importing wsdl: ${service.wsdl.location}"/>
   <wsimport
    fork="true"
    debug="true"
    verbose="${verbose}"
    keep="true"
    extension="true"
    destdir="${build.classes.home}"
    package="ifbo_wsdl_xml_secure.client"
    wsdl="${service.wsdl.location}">

<!-- http://today.java.net/pub/a/today/2006/09/19/asynchronous-jax-ws-web-services.html#client-for-synchronous-invocation
-->
<!-- Synchronous -->
<!--
<binding dir="${basedir}/etc" includes="${schema.binding}"/>
<binding dir="${basedir}/etc" includes="${client.binding}"/>
-->

    <jvmarg value="-Djavax.net.ssl.trustStore=${client.truststore.file}"/>
    <jvmarg value="-Djavax.net.ssl.trustStorePassword=${client.truststore.pass}" />
   </wsimport>
  </target>

  <target name="client" depends="generate-client">
   <javac
    fork="true"
    srcdir="${basedir}/src"
    destdir="${build.classes.home}"
    includes="**/client/**,**/common/**">
    <classpath refid="jaxws.classpath"/>
   </javac>
  </target>

  <target name="run" depends="setup-certs-props">
   <java fork="true" classname="ifbo_wsdl_xml_secure.client.AddNumbersClient">
    <classpath>
    <path refid="jaxws.classpath"/>
    <pathelement location="${build.classes.home}"/>
    <pathelement location="${basedir}/etc"/>
    </classpath>
    <jvmarg value="-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=${log}"/>
    <jvmarg value="-Djavax.net.ssl.trustStore=${client.truststore.file}"/>
    <jvmarg value="-Djavax.net.ssl.trustStorePassword=${client.truststore.pass}" />
   </java>
  </target>

  <target name="help">
   <echo message="server: Builds and deploy the service endpoint WAR"/>
   <echo message="client: Builds the client"/>
   <echo message="run: Runs the client"/>
  </target>

  <target name="server" depends="setup">

   <antcall target="clean"/>

   <antcall target="build-server-wsdl"/>

   <antcall target="create-war"/>

   <antcall target="deploy"/>
  </target>

</project>

ifbo-wsdl-xml-secure/etc

deploy-targets.xml
ifboService.wsdl
sun-jaxws.xml
web.xml