
Is the WSDL the ONLY specification for a service?
If you hold the opinion that the WSDL should be a replacement for a decent document specifying the service design, then it leads me to conclude one of two things. Either your system is very simple with services that contain just a few parameters, or you're happy to spend a lot of time talking and hand holding service consumers through the process of understanding the business purpose of particular fields and methods.
When it comes to working with systems that are more mature in years, restrictions like short 7 character field names and autormatically assigned program names are something we're used to, but developers from the OO world do tend to get a bit freaked out if we don't warm them up to the idea. In practice it's nothing that a short email and a data dictionary in a spreadsheet can't fix. If you have a service design document, so much the better. After all, we're all programmers, and once they have imported and interpreted the fields that we're passing out of 2E they will rename classes so that the names to suit their requirements.
When will 2E generate “friendly names” in WSDLs?
The situation as it stands today is workable, but it is good to know that there has been some suggestion from the 2E development team at CA that support could be added post v8.5 to pass narrative text from 2E into the web service publishing process and give fields and methods more friendly names. [CA 2E 8.5 Presentation - September 2009 Page 81 “More meaningful WSDL”]
Whether this feature will make it into CA 2E v8.6, we will have to wait and see. The upcoming release has focused on support for multiple occurrence arrays, also needed to increase the power of the web service generation. No details have been published yet about exactly which web service enhancements have been added. [CA 2E 8.6 Preview - June 2011 Page 28 “release 8.6 – other features”]
If you want to vote for this feature and let CA know it's something that you need, there is a suggestion on the new CA Ideation website. CA Ideation - Meaningful Names In WSDL
It could make the difference between the feature making it into the next version, or being left out.
Practical tips for good 2E WSDL generation
The details which follow are based upon our direct experience publishing web services from 2E generated COBOL. I'm fairly sure that the fundementals of parameter generation remain true for RPG, for technical reasons I haven't been able to try this out.
The first thing to remember is that it's not actually 2E which is writing the WSDL. The 2E generation process is creating ILE programs which post compilation make a call to IBM provided scripts which “publish” the ILE service program as a web service. The publishing steps make use of ILE Program Call Markup Language (PCML) for details of the program parameters and harnesses this information to create a thin Java wrapper program which acts as a bridge between the ILE program and the web server. It's the Java wrapper which is responsible for the WSDL generation.
The structure of the program's parameters have a big impact on the way the PCML is generated and consequently the information which is displayed in the generated WSDL.
Passed as FLD or RCD – the difference is clear
During my 2E youth the importance of defining the parameters of external programs to be defined as one field per parameter, “passed as FLD”, was always stressed. The exact reason is lost on me now as much time as passed, but it was certainly the standard at many places I worked.
When it comes to defining parameters for programs which will be published as web services there distinct disadvantage in passing the fields as one per parameter, aka “passed as FLD”. Here's why:
Example of a WSDL generated from a simple COBOL 2E RTV access path passed as FLD.
<xs:complexType name="XXABXFKInput">
<xs:sequence>
<xs:element minOccurs="0" name="_P0RTN" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P1PARM" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P2PARM" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P3PARM" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P4PARM" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P5PARM" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P6PARM" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P7PARM" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
What we have is a simple access path of 6 character fields, plus the standard program return code which is automatically added at the start. But look! When passing as FLD the implementation name of the field is dropped in the WSDL in favour of a sequential identifier, this is decidedly unhelpful. You can think of it as giving someone a map which has all the places names removed, and it's not going to win us 2E developers any points with the people we hand the WSDL to.
Contrast this with the WSDL generated from the same function, but we switch the parameter definition for the 2E to be “passed as RCD”.
Example of a WSDL generated from a simple COBOL 2E RTV access path passed as RCD.
<xs:complexType name="P1PARM">
<xs:sequence>
<xs:element minOccurs="0" name="_P1COMMTD" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P1COMPANY" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P1COUNTRY" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P1CAAMGD" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P1CTRYCODE" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P1EXTGRP" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P1EXTUSR" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="XXABXFKInput">
<xs:sequence>
<xs:element minOccurs="0" name="_P0RTN" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="_P1PARM" nillable="true" type="ax22:P1PARM"/>
</xs:sequence>
</xs:complexType>
The same information has now been encoded in 2 separate elements of XML of the WSDL. The first gives the 6 fields on the retrieval index which is being passed along with their names. The second structure defines the return code directly and then references back to the first to tie in the 6 fields.
This is quite a marked difference in the content of the WSDL, in fact comparing the 2 WSDLs side-by-side it is easy to see that the publishing process has interpreted them in totally different ways because one generated program had multiple parameters, each of a single field (FLD), while the second iteration of the program passed all the fields as a data structure in a single parameter (RCD).
Before we draw any conclusions from this, let us consider our brother and sister developers in Java/.Net/any language, who will be using the WSDLs. Which type would they prefer?
Well, my extensive research (having a chat across the desk with a colleague), tells me that it doesn't make any difference to them. Both methods result in recognisable objects being created within their programming environments, and as I said earlier once they understand what the fields and methods are they will rename and restructure things to suit their way of working.
Define arrays, pass as RCD
Even for the simplest services you should be considering passing everything as RCD. Preserving the field names is only part of the reason, it is also important to consider the maintenance of the service over it's lifetime.
Rather than using one or more access paths to template parameter fields, create a new entry in *Arrays specifically for each web service, use this in the service functions parameter definition. If you prefer to separate input and output parameters, you can create an array definition for each, but try to keep the number of parameter arrays as few as possible.
In our application we try to have just three, the first is common system parameters (message text, session identifier), then the inputs (including “both/dual”), finally the outputs. We pass all the arrays as RCD. The resulting WSDL will be generated with 3 groups of parameters which contain named fields from each of the 2E arrays.
Another benefit of passing RCD
One more point on the difference between the definition of passing as FLD or RCD for the a 2E web service, ILE modules have a 32 parameter field limit which we bumped into a while back. In 2E this would be an access path or array containing more than 32 fields defined in a single parameter entry and passed as FLD. This defintion will cause the compile of the ILE module to fail. Read the details why here http://www-03.ibm.com/systems/i/software/iws/limitations.html
Consistency, for now and the future
Using the same technique consistently for all the 2E web services which you create means also that the principles of SOA are being followed, a topic which was discussed in an earlier post in this series, Applying SOA to CA 2E Web Services.
We have found benefits when defining parameters for 2E web service programs is to using 2E *Arrays to define the list of fields, and then specify that the fields should be passed as RCD. This gives a better balance of a stable (maintainable) parameter interface, the ability to separate inputs and outputs, a well structured WSDL and stays within the limits of ILE modules.
Further posts on the adoption of SOA and creation of web services using CA 2E to follow. Check this page for updates.
Matthew Morris is a developer and director at Desynit. Desynit works with companies around the world, looking to improve the business benefits of their existing systems, with lower costs and less risk. If you are interested in knowing more about this topic, or have comments, contact the author via email matthew.morris@desynit.com