OpenVMS Notes: AXIS2, SOAP, gSOAP

(OpenVMS) Product Name Confusion

Product Description/Notes
ANT Another Neat Tool (an Apache script interpreter)
Apache HTTPd Hyper Text Transport Protocol daemon is a standalone product which operates on TCP/IP port 80 (http) and 443 (https) by default. When OpenVMS was owned by Compaq, this product was called CSWS (Compaq Secure Web Sever) pronounced "C-Swiss". Since HP bought (err, merged with) Compaq, I have heard HP engineers refer to this product as "Swiss" but the downloadable modules still have a "CSWS" prefix.
CSWS_JAVA HPE's name for Apache Tomcat (requires Java which is not included)
CSWS_PERL HPE's name for a module which enables Apache HTTPd to access Perl (requires Perl)
CSWS_PHP HPE's name of a module which provides Apache HTTPd with a PHP Interpreter
Apache Tomcat A standalone Java-based web server product which operates on TCP/IP port 8080 by default
(configure the connector kit to facilitate server back channels between HTTPd and Tomcat)
Confusingly, the Compaq/HP Tomcat product for OpenVMS is named CSWS_JAVA
Jakarta Apache's umbrella name for Java projects
Catalina Name of Tomcat's Servlet Container Technology
Coyote Tomcat's Java-based HTTPd server
Jasper Tomcat's JSP technology
GNV GNU Not VMS (Unix command interpreter for OpenVMS which includes BASH)
Java Standalone product is required by Tomcat. You need the development kit (has a JIT compiler), not the run-time kit.
1.5 and higher 1.4 and lower
JDK java development kit SDK standard development kit
JRE java runtime edition RTE run time edition
JAVA 5 comes up as version 1.5
JAVA 6 comes up as version 1.6
JAVA 8 comes up as version 1.8
OpenSSL Open Secure Sockets Layer "standalone product" (not used by Apache HTTPd which has its own built-in OpenSSL routines) Question: So why would you ever use it? Answer: to support encryption in client apps or standalone server apps Required by OpenVMS 8.x (used to validate HP patch kits)
Perl Standalone product (required by CSWS_PERL)
SOAP Toolkit 1.1 SOAP 1.0 - based upon Apache SOAP 2.31 - Apache's proof of concept SOAP offering (now obsolete)
SOAP Toolkit 2.0 SOAP 1.1 - based upon Apache AXIS/Java - Apache's first production SOAP engine (now obsolete)
AXIS2 SOAP 1.2 - based upon Apache AXIS2/Java - Apache's second production SOAP engine (served up by Tomcat)
WSIT Web Services Integration Toolkit (technology for accessing high level language routines from Java-based web services)
UDDI Universal Description Discovery and Integration is another Web Services component (this technology has not lived up to original expectations)
gSOAP generated SOAP. Third-party SOAP engine supporting SOAP code based upon C/C++
(this looks like a very promising alternative to AXIS2/c which is not available on OpenVMS unless you are willing to do your own build from Apache sources)

Installing "Apache SOAP" on OpenVMS Alpha (2010)

SOAP (Simple Object Access Protocol) is an XML extension for sending messages to other systems on the internet. It is platform neutral as well a language neutral.
AXIS (Apache eXtensible Interaction System)
SOAP
Technology
Original
Product
Name
Official
VMS
Name
Requires
Tomcat?
Document Links Language
SOAP 1.0 Apache SOAP SOAP Toolkit 1.x Y http://www.w3.org/TR/soap/ Java
SOAP 1.1 Apache AXIS SOAP Toolkit 2.x Y https://en.wikipedia.org/wiki/Apache_Axis Java
SOAP 1.1 and 1.2 Apache AXIS2 Axis2 Y https://en.wikipedia.org/wiki/Apache_Axis2 Java
SOAP 1.1 and 1.2 gSOAP   N http://www.cs.fsu.edu/~engelen/soap.html C or C++

Notes:

  • You do not need a SOAP engine like AXIS or AXIS2 to support SOAP technology on your platform, but SOAP engines do things for you which you would normally need to write into your stand-alone application. I recently stumbled across two Java demos: one was a 5-line AXIS2 service while the other was a 100 line stand-alone service if you also counted "included boilerplate". A 100-to-5 reduction is welcome in anyone's world
  • gSOAP is a lightening fast product which doesn't use Tomcat. It can been used as a stand-alone application or under Apache via a plugin module
  • On OpenVMS you will be tempted to begin learning with the SOAP Toolkit (AXIS) then migrate to AXIS2. Be aware that AXIS doesn't play nicely with newer Java versions. To properly use AXIS you should consider an older version of Java so I suggest you start with AXIS2.
  • Most SOAP books (with SOAP in the title) were written in the early 2000s but now seem only worthwhile to bootstrap your brain. Why? The technology has changed dramatically over the past 10 years (Web 1.0 -> Web 2.0, Apache SOAP -> Apache AXIS -> Apache AXIS2, etc). Newer books may contain the phrase "Web Services", "SOA", or "Service Oriented Architecture". The most recent O'Reilly books seem to have a pretty good signal-to-noise ratio. Before buying books you might want to preboot your brain with these links:

Installing AXIS2 on Tomcat for OpenVMS Alpha (2010)

  • Now execute this DCL command (notice that the source filename is uppercase while the destination is lowercase):
    $!
    $! change your DCL session to case-sensitive $!
    $ SET PROC/CASE=SENS/PARSE=EXTENDED
    $!
    $! copy with rename
    $! $ COPY AXIS2$ROOT:[openvms]AXIS2.WAR APACHE$COMMON:[JAKARTA.TOMCAT.webapps]axis2.war
    $!
    $! revert your DCL session back to case-insensitive $! $ SET PROC/CASE=SENS/PARSE=TRADITIONAL
  • use a browser to test axis2
  • click the VERIFY link to make sure everything is in place and working
  • click the SERVICES link to make sure everything is in place and working
    • notice the Version service lists a method named getVersion
  • click the ADMINISTRATION link (default settings: User="admin" Password="axis2")
  • use a browser to see what services are currently offered:
  • use a browser to test the Version service:

Installing AXIS on Tomcat for OpenVMS Alpha (2010)

  • not recommended because AXIS is officially obsolete
  • AXIS and AXIS2 can coexist on the same Tomcat but I wouldn't bother except during a migration from AXIS to AXIS2
  • AXIS doesn't play well with newer software and AXIS2 doesn't play well with older software.
  • After installing AXIS (a.k.a. SOAP Toolkit 2.0) you must execute this DCL command:
    $backup/log/ignore=interlock				-
    AXIS$ROOT:[AXIS-1_1.webapps.axis...]*.* - apache$common:[jakarta.tomcat.webapps.axis...]*.*
  • How did I know to do this? If you inspect the contents of script:
    AXIS$ROOT:[AXIS-1_1.openvms.com]soap_toolkit-2_0_util.com
    you will notice a fourth menu command which is disabled in a couple of places. If it was enabled, it would execute an unfinished sub-routine which would perform the backup command which I have just documented. 
  • use a browser to test AXIS like so: http://yada.net:8080/axis
  • click the VERIFY link to make sure everything is in place and working properly (you may have problems using AXIS with Java-1.5 so be prepared to do some web-based research. One problem involves Java discovery of the XML parser)
  • test the Version service: http://yada.net:8080/axis/services/Version?method=getVersion (caveat: this syntax will not work with AXIS2)

AXIS/AXIS2 Tutorials etc.

Miscellaneous notes

  • According to the W3C, SOAP no longer means Simple Object Access Protocol since objects are not mandatory and the spec is no longer simple. Nevertheless, the "SOAP" name stuck and no one is willing to change it. Since the first 3-letters of SOAP are also the only letters of Service Oriented Architecture (SOA), perhaps SOAP now means Service Oriented Architecture Protocol
  • Java files with these extensions: AAR, EAR, JAR, WAR are zip files which have been created with Java. On OpenVMS you can do a quick peek inside them like so:
            $ unzip  -l  axis2.war
  • (some) Java File Extensions
    • AAR - AXIS Archive - can hold AXIS and AXIS2 service class files as well as services.xml in a folder called META-INF
    • EAR - Enterprise Archive - can hold Enterprise Java Beans (EJB), etc.
    • JAR - Java Archive - can hold libraries, etc.
    • WAR - Web Archive - holds at least one Servlet or JSP
  • Creating an AXIS2 Service (Army Instructions)
  • Hacking with GNV (GNU not VMS)
  • Invoking WSDL2Java
  • When using OpenVMS SOAP Toolkit (Apache AXIS) or AXIS2 for OpenVMS, you will be working entirely in Java. While I have done Java development for AXIS2 on the VMS platform (click: AXIS2 - Army Instructions), it is much easier to do it on a Windows PC using the free NetBeans IDE. Your AXIS2 service will have a name like yada.aar (so an axis archive) which you need to copy under your AXIS2 deployment directory:
            APACHE$COMMON:[JAKARTA.TOMCAT.webapps.axis2.WEB-INF.services]

"Army Instructions" for creating an AXIS2 Service on OpenVMS

========================================================================================
title	   : axis2_service_demo_axp.txt
author	   : Neil Rieck
created	   : 2010.07.21
purpose    : A "Simple Service" demo for Apache Axis2 on OpenVMS-8.3
reference 1: Book "Quickstart Apache Axis2" by Deepal Jayasinghe
reference 2: http://people.apache.org/~ruchithf/hw-axis2/
notes      :
1. case is important for files as well as directories (folders) 2. AXIS2 will not deploy a service unless the extension is ".aar" (axis archive) 3. SET PROC/CASE=SENS/PARSE=EXTENDED ! change VMS session to case-sensitive SET PROC/CASE=BLIND/PARSE=TRADITIONAL ! restore VMS sessions to default 4. here, the "ss" prefix means "simple service" ======================================================================================== $ SET PROC/CASE=SENS/PARSE=EXTENDED ! change your DCL session case-sensitive $ create SimpleService.java ! create a new file with this name /* * The service implementation class */ public class SimpleService { /* * method: ssAdd */ public int ssAdd(int ssValue1, ssValue2) { return ssValue1 + ssValue2; } /* * method: ssSubtract */ public int ssSubtract(int ssValue1, ssValue2) { return ssValue1 - ssValue2; } /* * method: ssEcho */ public String ssEcho(String ssValue3) { return "You sent: "+ ssValue3; } } <<<---- hit CTRL-Z here to close the "create" command $ cre/dir [.TEMP] $ cre/dir [.TEMP.META-INF] $ create [.TEMP.META-INF]services.xml <service name="SimpleService"> <description> Simple Service Hack </description> <parameter name="ServiceClass" locked="false">SimpleService</parameter> <operation name="ssAdd"> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> <operation name="ssSubtract"> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> <operation name="ssEcho"> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> </service> <<<---- hit CTRL-Z here to close the "create" command $ javac "SimpleService.java" -d TEMP/ $ jar cvf SimpleService.aar -C TEMP/ META-INF/services.xml $ jar uvf SimpleService.aar -C TEMP/ SimpleService.class $ unzip -l SimpleService.aar ! test the archive like so Archive: AXIS2$ROOT:[000000.NEIL.SS]SimpleService.aar;21 Length Date Time Name -------- ---- ---- ---- 0 08-10-10 13:41 META-INF/ 70 08-10-10 13:41 META-INF/MANIFEST.MF 572 08-10-10 13:40 META-INF/services.xml 585 08-10-10 13:41 SimpleService.class -------- ------- 1227 4 files $ copy SimpleService.aar - APACHE$COMMON:[JAKARTA.TOMCAT.webapps.axis2.WEB-INF.services] $! step 7 ------------------------------------------------------------------------- Probe the service with IE8: http://yada.net:8080/axis2/services/listServices view the available services http://yada.net:8080/axis2/services/SimpleService?xsd view the associated xsd http://yada.net:8080/axis2/services/SimpleService?wsdl view the associated wsdl http://yada.net:8080/axis2/services/SimpleService?wsdl2 view the associated wsdl2 Test the service methods with IE8: http://yada.net:8080/axis2/services/SimpleService/ssEcho?param0=This is a test http://yada.net:8080/axis2/services/SimpleService/ssAdd?param0=34&param1=12 http://yada.net:8080/axis2/services/SimpleService/ssSubtract?param0=34&param1=12 Caveat: this kind of testing only works if you have include support for the HTTP GET
method (usually there with AXIS2; optional with gSOAP; not supported on OpenVMS where
the Apache module 'mod_gsoap.exe' blocks all HTTP GET operations except for '?wsdl')

(using AXIS/AXIS2 to) Generate a WSDL Document

  • If a service was deployed without a user-supplied WSDL, AXIS2 will dynamically create one for internal use
  • See the third link in step-7 above to see how to view it.
  • Caveat: what you see will depend upon your browser:
    IE 8 displays the full XML page
    Firefox 3.6 only displays a small fraction. Do a "view page source" to see more.
    Google Chrome 5.0 display almost nothing until you issue "view page source"
    Common if you do not see this first line: <?xml version="1.0" encoding="UTF-8" ?> ...then you must issue a "view page source" command
  • Inspect the WSDL below which I have highlighted for your hacking pleasure:
    1. Even though I used Java variable names like "ssValue1", "ssValue2", and "ssValue3", the dynamic WSDL created names like "param0" and "param1". These latter names must be used when calling methods in the service unless we modify this WSDL then redeploy the service (more on this later)
    2. Notice that there are three bindings:
      • HTTP (for testing with a browser)
      • SOAP11 (for SOAP 1.1)
      • SOAP12 (for SOAP 1.2)
    <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                      xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
                      xmlns:ns0="http://ws.apache.org/axis2"
                      xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
                      xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
                      xmlns:ns1="http://org.apache.axis2/xsd"
                      xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
                      xmlns:xs="http://www.w3.org/2001/XMLSchema"
                      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                      targetNamespace="http://ws.apache.org/axis2">
        <wsdl:documentation>SimpleService</wsdl:documentation>
        <wsdl:types>
            <xs:schema xmlns:ns="http://ws.apache.org/axis2"
                       attributeFormDefault="qualified"
                       elementFormDefault="qualified"
                       targetNamespace="http://ws.apache.org/axis2">
                <xs:element name="ssAdd">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element minOccurs="0" name="param0" type="xs:int"/>
                            <xs:element minOccurs="0" name="param1" type="xs:int"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="ssAddResponse">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element minOccurs="0" name="return" type="xs:int"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="ssSubtract">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element minOccurs="0" name="param0" type="xs:int"/>
                            <xs:element minOccurs="0" name="param1" type="xs:int"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="ssSubtractResponse">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element minOccurs="0" name="return" type="xs:int"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="ssEcho">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element minOccurs="0" name="param0" nillable="true" type="xs:string"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="ssEchoResponse">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:schema>
        </wsdl:types>
        <wsdl:message name="ssSubtractRequest">
            <wsdl:part name="parameters" element="ns0:ssSubtract"/>
        </wsdl:message>
        <wsdl:message name="ssSubtractResponse">
            <wsdl:part name="parameters" element="ns0:ssSubtractResponse"/>
        </wsdl:message>
        <wsdl:message name="ssEchoRequest">
            <wsdl:part name="parameters" element="ns0:ssEcho"/>
        </wsdl:message>
        <wsdl:message name="ssEchoResponse">
            <wsdl:part name="parameters" element="ns0:ssEchoResponse"/>
        </wsdl:message>
        <wsdl:message name="ssAddRequest">
            <wsdl:part name="parameters" element="ns0:ssAdd"/>
        </wsdl:message>
        <wsdl:message name="ssAddResponse">
            <wsdl:part name="parameters" element="ns0:ssAddResponse"/>
        </wsdl:message>
        <wsdl:portType name="SimpleServicePortType">
            <wsdl:operation name="ssSubtract">
                <wsdl:input message="ns0:ssSubtractRequest" wsaw:Action="urn:ssSubtract"/>
                <wsdl:output message="ns0:ssSubtractResponse" wsaw:Action="urn:ssSubtractResponse"/>
            </wsdl:operation>
            <wsdl:operation name="ssEcho">
                <wsdl:input message="ns0:ssEchoRequest" wsaw:Action="urn:ssEcho"/>
                <wsdl:output message="ns0:ssEchoResponse" wsaw:Action="urn:ssEchoResponse"/>
            </wsdl:operation>
            <wsdl:operation name="ssAdd">
                <wsdl:input message="ns0:ssAddRequest" wsaw:Action="urn:ssAdd"/>
                <wsdl:output message="ns0:ssAddResponse" wsaw:Action="urn:ssAddResponse"/>
            </wsdl:operation>
        </wsdl:portType>
        <wsdl:binding name="SimpleServiceSOAP11Binding" type="ns0:SimpleServicePortType">
            <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
            <wsdl:operation name="ssSubtract">
                <soap:operation soapAction="urn:ssSubtract" style="document"/>
                <wsdl:input>
                    <soap:body use="literal"/>
                </wsdl:input>
                <wsdl:output>
                    <soap:body use="literal"/>
                </wsdl:output>
            </wsdl:operation>
            <wsdl:operation name="ssEcho">
                <soap:operation soapAction="urn:ssEcho" style="document"/>
                <wsdl:input>
                    <soap:body use="literal"/>
                </wsdl:input>
                <wsdl:output>
                    <soap:body use="literal"/>
                </wsdl:output>
            </wsdl:operation>
            <wsdl:operation name="ssAdd">
                <soap:operation soapAction="urn:ssAdd" style="document"/>
                <wsdl:input>
                    <soap:body use="literal"/>
                </wsdl:input>
                <wsdl:output>
                    <soap:body use="literal"/>
                </wsdl:output>
            </wsdl:operation>
        </wsdl:binding>
        <wsdl:binding name="SimpleServiceSOAP12Binding" type="ns0:SimpleServicePortType">
            <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
            <wsdl:operation name="ssSubtract">
                <soap12:operation soapAction="urn:ssSubtract" style="document"/>
                <wsdl:input>
                    <soap12:body use="literal"/>
                </wsdl:input>
                <wsdl:output>
                    <soap12:body use="literal"/>
                </wsdl:output>
            </wsdl:operation>
            <wsdl:operation name="ssEcho">
                <soap12:operation soapAction="urn:ssEcho" style="document"/>
                <wsdl:input>
                    <soap12:body use="literal"/>
                </wsdl:input>
                <wsdl:output>
                    <soap12:body use="literal"/>
                </wsdl:output>
            </wsdl:operation>
            <wsdl:operation name="ssAdd">
                <soap12:operation soapAction="urn:ssAdd" style="document"/>
                <wsdl:input>
                    <soap12:body use="literal"/>
                </wsdl:input>
                <wsdl:output>
                    <soap12:body use="literal"/>
                </wsdl:output>
            </wsdl:operation>
        </wsdl:binding>
        <wsdl:binding name="SimpleServiceHttpBinding" type="ns0:SimpleServicePortType">
            <http:binding verb="POST"/>
            <wsdl:operation name="ssSubtract">
                <http:operation location="SimpleService/ssSubtract"/>
                <wsdl:input>
                    <mime:content type="text/xml" part="ssSubtract"/>
                </wsdl:input>
                <wsdl:output>
                    <mime:content type="text/xml" part="ssSubtract"/>
                </wsdl:output>
            </wsdl:operation>
            <wsdl:operation name="ssEcho">
                <http:operation location="SimpleService/ssEcho"/>
                <wsdl:input>
                    <mime:content type="text/xml" part="ssEcho"/>
                </wsdl:input>
                <wsdl:output>
                    <mime:content type="text/xml" part="ssEcho"/>
                </wsdl:output>
            </wsdl:operation>
            <wsdl:operation name="ssAdd">
                <http:operation location="SimpleService/ssAdd"/>
                <wsdl:input>
                    <mime:content type="text/xml" part="ssAdd"/>
                </wsdl:input>
                <wsdl:output>
                    <mime:content type="text/xml" part="ssAdd"/>
                </wsdl:output>
            </wsdl:operation>
        </wsdl:binding>
        <wsdl:service name="SimpleService">
            <wsdl:port name="SimpleServiceSOAP11port_http" binding="ns0:SimpleServiceSOAP11Binding">
                <soap:address location="http://kawc09.on.bell.ca:8080/axis2/services/SimpleService"/>
            </wsdl:port>
            <wsdl:port name="SimpleServiceSOAP12port_http" binding="ns0:SimpleServiceSOAP12Binding">
                <soap12:address location="http://kawc09.on.bell.ca:8080/axis2/services/SimpleService"/>
            </wsdl:port>
    
            <wsdl:port name="SimpleServiceHttpport" binding="ns0:SimpleServiceHttpBinding">
                <http:address location="http://kawc09.on.bell.ca:8080/axis2/services/SimpleService"/>
            </wsdl:port>
        </wsdl:service>
    </wsdl:definitions>

gSOAP (very, very fast)

gSOAP (all platforms)

  • http://www.cs.fsu.edu/~engelen/soap.html
  • This SOAP engine supports user programs written in C or C++
  • It is very very fast since it avoids "dynamic-binding" to a WSDL -and- doesn't rely upon Java
  • server apps can work with Apache (via the mod_gsoap plugin) or "stand-alone"
  • client apps are only "stand-alone" (obviously)
  • IEEE Article
  • Dr. Dobbs
    • http://drdobbs.com/184401909 gSOAP & Web Services - 2005 article from at Dr. Dobbs
      Quote: Immediately after the public release of SOAP 1.0 in 1999, I designed and implemented (with the help of one of my students) the first prototype of a compiler to generate C/C++ language bindings for SOAP/XML. We dubbed the system "gSOAP" (short for "SOAP generators" a.k.a. "generated SOAP"). Like many SOAP toolkits at the time, gSOAP only supported the SOAP RPC (remote procedure call) request/response message exchange pattern with the SOAP encoding style for serializing primitive types, structs/classes, arrays, and pointer-based structures in XML. Since then, advances in web services standards have required frequent updates to the system to generate code that meets the requirements for compliance with SOAP 1.1/1.2, SOAP RPC and document/literal style, SOAP with attachments, WSDL 1.1, XML schemas and namespaces, and WS best practices.

gSOAP Toolkit for OpenVMS

gSOAP on OpenVMS

Home page of Brett Cameron & John Apps

Tips for using gSOAP on OpenVMS

Two Flavors (client and server)

  • gSOAP server applications:
    • a standalone application run directly from DCL (great for learning as well as developer testing)
    • also hosted by Apache via plugin mod_gsoap
  • gSOAP client applications:
    • a stand-alone program used to send a SOAP packet to a SOAP service (usually hosted by a web server)
      • can also be run from DCL in order to test the DCL-based server
    • if SSL encryption is required, it must be linked with the client (most server apps rely upon the web server for SSL support)
  • Brett's gSOAP distribution for OpenVMS has a SAMPLE folder which contains example code for various languages (COBOL, FORTRAN, C).
    • Every OpenVMS programmer wishing to climb "mount soap" should first inspect the CALC demo (written in C).
    • If you have access to either a C or C++ compiler then get both client and server demos working only from DCL in standalone mode.
    • Next, move the server piece into Apache (accessed via the mod_gsoap plugin) to ensure your standalone-DCL-client now will work with the server on port 80 (or whatever port you specified in file "httpd.conf")
  • Here's a link to some of my gSOAP demos

One tiny little problem with the plugin

  • 2011-09-27: I just stumbled across a minor problem with the mod_gsoap plugin which seems to have been around since 2001 and affects all platforms. Our end-user (a remote company in Montreal) expects to start Level-one connectivity tests to our gSOAP platform by first performing "a wsdl retrieval".
    • This is usually done by issuing an HTTP GET from telnet like so:
      legend: <sr> = system response
              <ur> = user response
      -------------------------------------------------------------------------
      <sr> $									<--- my DCL prompt
      <ur> telnet www.bellics.com 80						<--- use telnet to connect to port 80
      <sr> %TCPWARE_TELNET-I-TRYING, trying bellics.com,http (207.35.137.66,80) ...
           %TCPWARE_TELNET-I-ESCCHR, escape (attention) character is "^\"
      <ur> GET /bsttv10?wsdl HTTP/1.0						<--- HTTP-GET (request WSDL from service "bsttv10")
      									<--- blank line signifies end of HTTP header
      <sr> HTTP/1.1 200 OK							<--- start of HTTP Response
           Date: Sat, 28 Jul 2012 13:29:37 GMT
           Server: Apache/2.0.63 (OpenVMS) mod_ssl/2.0.52 OpenSSL/0.9.8o
           Connection: close
           Content-Type: text/xml
      									<--- blank line signifies end of HTTP header
           <?xml version="1.0" encoding="UTF-8"?>				<--- start of WSDL (an XML document)
           <wsdl:definitions xmlns:tns="http://yada.com/bl"
      ...
    • The official gSOAP documentation is complete so I copied the code directly from chapter 19.10 HTTP GET Support then tested my gSOAP application in standalone application mode (run from DCL and listening on port 5000). It worked perfectly.
    • Next, I tested the server app by accessing it via Apache then was presented with a "no body received" message from mod_gsoap saying the transaction was aborted (nothing was logged by my program). Inspection of the mod_gsoap.c at http://sourceforge.net/projects/mod-gsoap/ shows that mod_gsoap is expecting an HTML body from the client during "all HTTP methods" when it should only be doing this test for method POST (comment: the GET method does not have a body so the "no body received" message now makes sense). I don't think this will be too difficult to fix but wonder why no one has fixed mod_gsoap.c in 10 years (this is the one area where open-source sometimes fails; people fix problems on their own systems but never fix the public code)
    • On a related note, when you get any error messages from mod_gsoap you are directed to this link: http://www.webware.at/SOAP which is discouraging because it is dead. A little detective work via the WayBackMachine returned these archived pages (2001-2009):
      • http://web.archive.org/web/20011005033738/http://mx.aberger.at/SOAP/
      • http://web.archive.org/web/20090224053554/http://mx.aberger.at/SOAP/apache_index.html
        where you can read the original instructions from Christian Aberger. Maybe someone should paste these notes into the docs area at sourceforge.net
  • 2011-10-04: A patched version of mod_gsoap.exe (only for gSOAP v.11 on OpenVMS) is available upon request from Brett Cameron. He will include it with gSOAP v.12 on OpenVMS. Brett's code does not use the method described in the gSOAP manual. Instead, you need to create a static wsdl file then drop it into the same directory as your executable. It must have the same name as the executable but must have an extension of ".wsdl". This solution is entirely satisfactory for our needs but you must remember to update this file if the wsdl ever changes. No big deal.

Case Sensitivity

gSOAP sample apps were originally written for use in a case-sensitive environment (UNIX/Linux). So now you've got several options:

  1. Keep your DCL session in case insensitive mode but double-quote every parameter (to preserve case) like so:
    $ soapcpp2 "-c" "-S" -1 yada.h		! only generate "c" code
    $					! only generate Server code
    $					! only support soap1.1
  2. Switch to case-sensitive mode, execute your case-sensitive command, then switch back to case-insensitive mode:
    $ SET PROC/CASE=SENS/PARSE=EXTENDED	! switch your DCL session to case-sensitive
    $ soapcpp2 -c -S -1 yada.h ! only generate "c" code $ ! only generate Server code $ ! only support soap1.1
    $ SET PROC/CASE=BLIND/PARSE=TRADITION ! revert your DCL session back to case-insensitive
  3. Permanently switch your process to case sensitive and leave it there
    caveat: if you previously used mixed-case symbols and/or logical names in your scripts, then you might have trouble doing anything including "logging out" 

Overview of gSOAP code development in C

  • wsdl-first
    • if someone sent you a WSDL then you will be using the "wdsl first" method
    • use tool wsdl2h to read whatever.wsdl which will generate whatever.h and a bunch of other support files
  • code-first (a.k.a. wsdl-last)
    • create a file titled whatever.h then use soapcpp2 to generate lots of stuff including whatever.wsdl
  • common steps
    • write whatever_server.c
    • write whatever_client.c
    • see the script "build" to see how to compile and link
    • test both programs from your scripting environment (DCL in the case of OpenVMS); I used port 8123
    • modify Apache to serve up your service on port 80
    • use your client from the scripting environment to test to Apache on port 80
    • view: my simple gSOAP example code in C
    • view: my simple gSOAP example code in C++

Sample Apache configuration for plugin mod_gsoap

file: [.conf]httpd.conf
#=======================================================================
# experimental stuff for gSOAP (root)
# required so I can use a browser to look at docs specific to this stack
#=======================================================================
# DCL: $define/sys/trans=conc "gsoap$root" "DISK$USER1:[gsoap.]" Alias /gsoap/ "/gsoap$root/000000/" Alias /GSOAP/ "/gsoap$root/000000/" <Directory "/gsoap$root/000000/"> Options Indexes MultiViews IndexOptions NameWidth=* AllowOverride None Order allow,deny Allow from all </Directory> # # this plugin module is required for gSOAP to work # LoadModule gsoap_module modules/mod_gsoap.exe # # enabled gSOAP services # 1. only enable the stuff we need because more stuff seems to take a toll) # 2. SOAPLibrary must point to a valid gSOAP executable (or Apache won't start) #=============================== # service: calc demo # logical: $def/sys gsoap_calc_server CSMIS$ROOT3:[DVLP._GSOAP_SAMPLES.CALC-NSR]calcserver.EXE # <Location /gsoap_calc_server> # lowercase name (also enable in SSL.CONF if HTTPS support is desired) SetHandler gsoap-handler SOAPLibrary GSOAP_CALC_SERVER # this system-level logical name points to the executable </Location> #=============================== # service: current-time demo # logical: $def/sys gsoap_current_time CSMIS$ROOT3:[DVLP._GSOAP_CURRENT_TIME]GSOAP_CURRENT_TIME.EXE # <Location /gsoap_current_time> # lowercase name (also enable in SSL.CONF if HTTPS support is desired) SetHandler gsoap-handler SOAPLibrary GSOAP_CURRENT_TIME # this system-level logical name points to the executable </Location> #===============================
file: [.conf]ssl.conf
<VirtualHost 142.180.39.16:443>
#===============================
#	service: calc service demo
#	logical: $def/sys gsoap_calc_server CSMIS$ROOT3:[DVLP._GSOAP_SAMPLES.CALC-NSR]calcserver.EXE 
#
<Location /gsoap_calc_server>		# lowercase name (also enable in HTTPD.CONF if HTTP support is desired)
	SetHandler gsoap-handler
	SOAPLibrary GSOAP_CALC_SERVER	# this system-level logical name points to the executable
</Location>
#===============================
#
#	service: current-time demo (not used here)
#	logical: $def/sys gsoap_current_time CSMIS$ROOT3:[DVLP._GSOAP_CURRENT_TIME]GSOAP_CURRENT_TIME.EXE
#
#<Location /gsoap_current_time>		# lowercase name (also enable in HTTPD.CONF if HTTP support is desired)
#	SetHandler gsoap-handler
#	SOAPLibrary GSOAP_CURRENT_TIME	# this system-level logical name points to the executable
#</Location>
#===============================
</VirtualHost>

My gSOAP Application for OpenVMS

Overview (Implements the PUSH-PUSH model)

Note: Due to a corporate security directive, all transmissions are encrypted via OpenSSL.

Flow #1 (Company 1 to 2 with response back)

	    Company #1			    Company #2
	    SOAP Client			    SOAP Server
+-------+  +---------------+		   +---------------+  +------+
| Human	+->| create ticket +-- HTTP POST ->| Queue Msg/Job +->| db + |
| Event	|  | update ticket |<- Status:200 -+ HTTP response |  | code |
+-------+  +---------------+		   +---------------+  +--+---+
	    SOAP Server			    SOAP Client		 |
	   +---------------+		   +---------------+	 |
	   | Queue Msg/Job |<- HTTP POST --+ Action: Reply |<----+
	   | HTTP Response +- Status:200 ->| within 60 sec |
	   +---------------+		   +---------------+

Flow #2 (Company 2 to 1 with response back)

	    Company #1			     Company #2
	    SOAP Server			     SOAP Client
 +------+  +---------------+		   +---------------+  +-------+
 | db + |<-+ Queue Msg/Job |<- HTTP POST --+ Update Ticket |<-+ Human |
 | code |  | HTTP response +- Status:200 ->| Close Ticket  |  | Event |
 +--+---+  +---------------+		   +---------------+  +-------+
    |	    SOAP Client			     SOAP Server
    |	   +---------------+		   +---------------+
    +----->| Action: Reply +-- HTTP POST ->| Queue Msg/Job |
	   | within 60 sec |<- Status:200 -+ HTTP Response |
	   +---------------+		   +---------------+

gSOAP Caveats (all platforms)

One of the things I like about gSOAP is that it is constantly being improved then rereleased. However, this caused me to waste an hour (totally my own fault) when I casually attempted to use demo client program calcclient.c from gSOAP-2.8.15 with demo server program calcserver.c from gSOAP-2.8.3 which caused the client to always display a result of '0' with no error messages. This was caused by the fact that file calc.h had changed between releases which affected generated code, wsdl, and data.

ver calc.h calc_add_req.xml
2.8.3
(old)
//gsoap ns service name:        calc
//gsoap ns service style:       document
//gsoap ns service encoding:    literal
//gsoap ns service namespace:   http://websrv.cs.fsu.edu/~engelen/calc.wsdl
//gsoap ns service location:    http://websrv.cs.fsu.edu/~engelen/calcserver.cgi

//gsoap ns schema namespace: urn:calc

int ns__add(double a, double b, double *result);
int ns__sub(double a, double b, double *result);
int ns__mul(double a, double b, double *result);
int ns__div(double a, double b, double *result);
int ns__pow(double a, double b, double *result);
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:ns="urn:calc">
 <SOAP-ENV:Body>
  <ns:add>
   <ns:a>0.0</ns:a>
   <ns:b>0.0</ns:b>
  </ns:add>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
2.8.15
(new)
//gsoap ns service name:        calc Simple calculator service
//gsoap ns service protocol:    SOAP
//gsoap ns service style:       rpc
//gsoap ns service encoding:    encoded
//gsoap ns service namespace:   http://websrv.cs.fsu.edu/~engelen/calc.wsdl
//gsoap ns service location:    http://websrv.cs.fsu.edu/~engelen/calcserver.cgi

//gsoap ns schema namespace:    urn:calc

//gsoap ns service method-documentation: add Sums two values
int ns__add(double a, double b, double *result);

//gsoap ns service method-documentation: sub Subtracts two values
int ns__sub(double a, double b, double *result);

//gsoap ns service method-documentation: mul Multiplies two values
int ns__mul(double a, double b, double *result);

//gsoap ns service method-documentation: div Divides two values
int ns__div(double a, double b, double *result);

//gsoap ns service method-documentation: pow Raises a to b
int ns__pow(double a, double b, double *result);
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:ns="urn:calc">
 <SOAP-ENV:Body 
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <ns:add>
   <a>0.0</a>
   <b>0.0</b>
  </ns:add>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>







To diagnose problems (without resorting to a packet sniffer) you might wish to insert these 3-4 lines into your server or client program. Remember that you must link against "gsoapdbg.olb" rather than "gsoap.olb".

soap_init(&soap);					// initialize (this line will already be present)
soap_set_recv_logfile(&soap, "server-recv.log");	// -+
soap_set_sent_logfile(&soap, "server-sent.log");	// -+- usually written to the Apache logging area
soap_set_test_logfile(&soap, "server-test.log");	// -+
soap_set_mode(&soap, SOAP_XML_STRICT);			// tell gSOAP to reject bad SOAP transactions (will throw an error)
soap_serve(&soap);					// serve as a CGI application (this line will already be present)

Installing "Apache SOAP" on OpenVMS Itanium (2018)

caveat: since this is based upon Tomcat 7.0 this procedure is slightly different from the previous install in 2010
  • Now execute this DCL command (notice that the source filename is uppercase while the destination is lowercase):
    $!	make your DCL session case-sensitive
    $ SET PROC/CASE=SENS/PARSE=EXTENDED
    $! copy with rename $ COPY AXIS2$ROOT:[openvms]AXIS2.WAR APACHE$COMMON:[JAKARTA.TOMCAT.webapps]axis2.war
    $! back to case-insensitive $ SET PROC/CASE=SENS/PARSE=TRADITIONAL
  • DO NOT use a browser to test axis2 just yet
  • visit the tomcat management page then click "services" where you will be prompted to log in
    • question: you have already added roles, usernames and passwords to file config/tomcat-users.xml then restarted tomcat, right? If not, click here
    • locate the hyperlink containing the text "/axis2" then click the stop button followed by the start button
    • if there are no errors, and tomcat is continuing to run, then you are good to go
    • if tomcat exited then check the various log files in sys$manager (why the system account? It is used to run Tomcat). If you see any error messages about "insufficient memory" or "Problem creating Java Virtual Machine" then you should increase Pgflquo (of the system) account to 2-million or 3-million depending upon the size and number of services
  • Now test the axis2 service as follows:
  • click the VERIFY link to make sure everything is in place and working
  • click the SERVICES link to make sure everything is in place and working
    • notice the Version service lists an operation called getVersion
  • click the ADMINISTRATION link (default settings: User="admin" Pass="axis2")
  • use a browser to see what services are currently offered:
  • here is the source code for two demos:
    ==============================================================================================
    title	   : axis2_service_demo_i64.txt
    author	   : Neil Rieck
    created	   : 2018.01.09
    purpose    : A "Simple Service" demo for Apache Axis2 on OpenVMS-8.3
    reference 1: Book "Quickstart Apache Axis2" by Deepal Jayasinghe
    reference 2: http://people.apache.org/~ruchithf/hw-axis2/
    notes	   : 1. case is important for files as well as directories (folders)
    	   : 2. AXIS2 will not deploy a service unless the extension is ".aar"
    	   : 3. SET PROC/CASE=SENS/PARSE=EXTENDED	! change VMS session to case-sensitive
    	   :    SET PROC/CASE=BLIND/PARSE=TRADITIONAL	! restore VMS sessions to default 
    	   : 4. the "ss" prefix means "simple service"
    ==============================================================================================
    $ SET PROC/CASE=SENS/PARSE=EXTENDED		! make your DCL session case-sensitive
    $ create SimpleService.java			! create a new file with this name
    //
    // The service implementation class
    //
    public class SimpleService {
    	//
    	// method: ssAdd 
    	//
    	public int ssAdd(int ssValue1, ssValue2) {
    		return ssValue1 + ssValue2;
    	}
    	//
    	// method: ssSubtract
    	//
    	public int ssSubtract(int ssValue1, ssValue2) {
    		return ssValue1 - ssValue2;
    	}
    	//
    	// method: ssEcho
    	//
    	public String ssEcho(String ssValue3) {
    		return "You sent: "+ ssValue3;
    	}
    }
    <<<---- hit CTRL-Z here to close the "create" command
    $!
    $! this next bit is important because the structure will be copied into the AAR file
    $!
    $ cre/dir [.TEMP]
    $ cre/dir [.TEMP.META-INF]
    $ create  [.TEMP.META-INF]services.xml
    <service name="SimpleService">
        <description>
    	Simple Service Hack
        </description>
        <parameter name="ServiceClass" locked="false">SimpleService</parameter>
        <operation name="ssAdd">
    	<messageReceiver
    		mep="http://www.w3.org/2004/08/wsdl/in-out"
    		class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
        </operation>
        <operation name="ssSubtract">
    	<messageReceiver
    		mep="http://www.w3.org/2004/08/wsdl/in-out"
    		class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
        </operation>
        <operation name="ssEcho">
    	<messageReceiver
    		mep="http://www.w3.org/2004/08/wsdl/in-out"
    		class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
        </operation>
    </service>
    <<<---- hit CTRL-Z here to close the "create" command
    $!
    $! for case-insensitive DCL sessions we double-quote to preserve case 
    $!
    $ javac SimpleService.java -d TEMP/
    $ jar cvf SimpleService.aar  -C TEMP/ META-INF/services.xml
    $ jar uvf SimpleService.aar  -C TEMP/ SimpleService.class
    $ unzip -l SimpleService.aar	! test the archive like so
    
            Archive:  AXIS2$ROOT:[000000.NEIL.SS]SimpleService.aar;21
              Length     Date   Time    Name
             --------    ----   ----    ----
                    0  01-09-18 13:41   META-INF/
                   70  01-09-18 13:41   META-INF/MANIFEST.MF
                  572  01-09-18 13:40   META-INF/services.xml
                  585  01-09-18 13:41   SimpleService.class
             --------                   -------
                 1227                   4 files
    $ copy SimpleService.aar	-
    	APACHE$COMMON:[JAKARTA.TOMCAT.webapps.axis2.WEB-INF.services]
    $! --- step 7 -------------------------------------------------------------
    
    Probe the service with any browser:
    
    	http://yada.net:8080/axis2/services/listServices view the available services
    	http://yada.net:8080/axis2/services/SimpleService?xsd view the associated xsd
    	http://yada.net:8080/axis2/services/SimpleService?wsdl view the associated wsdl
    	http://yada.net:8080/axis2/services/SimpleService?wsdl2 view the associated wsdl2
    
    Test the service methods with any browser:
    
    	http://yada.net:8080/axis2/services/SimpleService/ssEcho?param0=This is a test
    	http://yada.net:8080/axis2/services/SimpleService/ssAdd?param0=34&param1=12
    	http://yada.net:8080/axis2/services/SimpleService/ssSubtract?param0=34&param1=12
    
    Caveat: this kind of testing only works if you have include support for the HTTP GET method
    	(usually there with AXIS2; optional with gSOAP; not supported on OpenVMS where the
    	Apache module 'mod_gsoap.exe' blocks all HTTP GET operations except for '?wsdl')
    

Links:


Back to Home
Neil Rieck
Waterloo, Ontario, Canada.