From: Pete Dashwood on
I've had a couple of private mails after responding publicly here to a
request for help with accessing Web Services from COBOL.

Here is a VERY brief summary of the situation:

(Some parts of the following are reproduced from some documentation I wrote
and attached to the example COBOL code, as a Fujitsu NetCOBOL project)

WEB SERVICES ROCK!

This is the next step on in the components arena. A web service exposes some
or all of the properties and methods of a component to the Web. Why is that
important? Because it means you can write a component and deploy it once.
Anyone with access to your local intranet can access it, or, if you have
delusions of grandeur (or work for an international company), expose it to
the Internet and anyone on the planet can access it. And the responses, even
across great distances, are very fast. (A round trip from NZ to California
in under a second).

Instead of having to maintain packages you have issued and update them all,
you do it once (on your Web server) and any package using the service is
instantly using the new version.

Leaving aside the technicalities of it (which are quite awesome) this means
that design can take legacy functions and even subsystems, wrap them as a
Web service, and keep on using them until there is time to re-develop new
stuff (which will also be developed as a series of web services so there is
"overlap" and transparency.)

It means that currently disparate systems, possibly deployed on different
platforms, can become a series of web services that are completely platform
independent, but accessible by all. This facilitates better logical
integration without the need for physically making systems talk to each
other or access each other's data. (Data can be requested from a service;
how it is provided is immaterial)

Bottom Line:

Offering business functions as web services is likely to be the way of the
future. It is also a powerful way to integrate disparate systems.

GENERAL CONSIDERATIONS

What and why Web Services?

Web Services are the next step on from COM servers. They don't obviate COM
servers because these can be embedded in many useful places, but they DO
allow a piece of encapsulated functionality (a component) to be centralized
and maintained in ONE place, then accessed from anywhere on the planet.
(This has major implications when it comes to software distribution and
updates; no more hundreds of copies to be updated, just one.)

A web Service is a component that exposes some or all of itself to the Web.
Like all OO components it will have methods and properties, and it probably
takes (and returns) parameters. Pretty straightforward and not mysterious.
The clever bit is in HOW it is able to talk to any platform OS, on any
hardware, and realise the dream of data interoperability.

It does it through the magic of XML and a protocol called SOAP. (Originally,
"Simple Object Access Protocol", but now officially meaningless.)

But isn't SOAP obsolete?

Yes. It is being superseded by DotNET services. MS had hoped to stop
supporting SOAP by 2003 but it is so useful and embedded in so many of
their own products it has now been officially reprieved until 2008. Office
2003 comes with its own SOAP libraries and if you have this version of
Office you can use those libraries instead of standard SOAP. (Use
MSOSOAP.SoapClient30 instead of MSSOAP.SoapClient30).

All new development SHOULD use the DotNET methods instead of SOAP, but, as
NetCOBOL cannot use the DotNET libraries easily, that leaves most COBOL
users out in the cold.

So, use SOAP until you get into C#. This allows you to leverage your
existing COBOL code and also make use of web services. (When your COBOL is
finally converted to whatever it will become, it is VERY easy to replace
SOAP calls to a web service with DotNET calls to the same service.)

DotNET is where the future lies and it is being picked up for all OSes
(including UNIX/Linux) and will run on all platforms (possibly even
including mainframes). It can do this because it is NOT object code or an
API that would be machine/OS dependent; instead, it is intermediate code
which is compiled for whatever platform it is running on, as it is loaded.

The specific example included below.

This is a small COBOL .EXE that accesses a Web Service called AVS (Address
Validation Services). The web service is running (at time of writing; it
could change, but it really doesn't matter anyway, as long as it is visible
on a server somewhere.) on a server farm in San Francisco. You can access it
from Australia, or Germany just as easily as I access it from NZ. Responses
are immediate and the distances don't seem to matter.

AVS provides a fully selectable service of operations involving NZ postal
addresses. It covers flats, apartments, urban, rural, PO Box and private
bag, Post Restante, Counter Delivery and postcode and locality encoding. As
a bonus, it also returns a complete address from partial free-format data,
formatted in compliance with NZPO requirements.

You can present data to it in fixed (each field is defined and filled in the
interface block) or free format (a single string is passed in the ws-buffer
field of the interface block. AVS analyses and parses it then returns all
the fields and a formatted address).

(Fixed input may not function for the web service, although it is OK if you
are using AVS as a COM component). Just concatenate whatever fixed fields
you have and present them as free-format data to the web service.

So how and where would I use it?

You would plug the service in to any point in an application where you need
address services. Pass it what you have collected from the user, invoke it,
and select whatever you want to display back, or update a database. It
really is that simple.

It's a bit like "outsourcing" NZ postal address requirements. Fill in the
blanks, get the post code, update changed localities, whatever you want to
do.

Conclusion

Enabling your application for web services is a step towards the future.

It is no more complex to obtain the complete functionality described above,
than it is to simply get a valid postcode.

There are HUGE pitfalls in address processing. It is nowhere near as simple
as it first appears (the AVS engine took around 800 hours to write).
Because of changes to the address coding in NZ, localities and postcodes now
mean more than previously. A street and a postcode will uniquely identify an
address, but streets, postcodes, and localities are not unique. And not
everybody lives in town; the boxes and rural domains have their own
idiosyncracies.

PROS:

1. Calling a web service is simple and facilitates future conversion.
2. It is easy to outsource the functionality and not have to maintain and
update postal data as well as your application.
3. The interface is just as simple as calling a COM/ActiveX component.
4. No maintenance required.

CONS:

1. You must be online to use it.

HERE'S THE SAMPLE CODE IN FUJITSU NetCOBOL (Maybe someone can convert it to
NE or ACUCOBOL so we can see the differences...?) ANY COBOL that can support
accessing COM/ActiveX components can access the web service.

WARNING: You must have a SOAP library installed on your system. (It is the
SOAP component that accesses the WSDL for the service, generates the
required XML to transport your interface block and return it, and invokes
the web service method. As you can see, NO KNOWLEDGE OF XML or SOAP is
required to use the service, even though it would be impossible without
these protocols.) If you have MS Office 2003, use the MSOSOAP.SoapClient30
component, rather than the MSSOAP.SoapClient30 component. You can download
the SOAP Toolkit from:
http://www.microsoft.com/downloads/details.aspx?FamilyId=C943C0DD-CEEC-4088-9753-86F052EC8450&displaylang=en

NOTE: DO NOT COMPILE AND RUN THIS CODE! You won't see anything and it will
look as if it did nothing. Instead, compile it for debugging and step
through it, then everything becomes clear.

000010 IDENTIFICATION DIVISION.
000020 PROGRAM-ID. 'SOAPTest'.
000030*AUTHOR. Peter E. C. Dashwood.
000031*
000040* This program attempts to instantiate a SOAP Proxy class and
000050* access a Web Service using the new proxy...
000051*
000060*DATE_WRITTEN. May 2007.
000070 ENVIRONMENT DIVISION.
000080 configuration section.
000090 source-computer. IBM-PC.
000100 object-computer. IBM-PC.
000101 REPOSITORY.
000110 CLASS COM AS "*COM".
000120
000170
000200*------------------------ DATA DIVISION ---------------------
000210 DATA DIVISION.
000340*
000350 WORKING-STORAGE SECTION.
000360 01 in-interface-block pic x(8197).
000361 01 in-IB.
000362 12 in-ws-return pic x(5).
000363 88 in-ws-OK value '00000'. *> will contain
SQLSTATE if
000364 *> there is a DB error
000365 12 in-ws-message pic x(256). *> will contain SQLMSG if
000366 *> there is a DB error
000367 12 in-ws-buffer pic x(2048). *> holds free format address data
000368 *> this will be formatted on return
000369 12 in-ws-breakdown.
000370 15 in-ws-streetNo pic x(20).
000371 15 in-ws-POBoxNo pic x(15).
000372 15 in-ws-RDNo pic x(8).
000373 15 in-ws-street pic x(150).
000374 15 in-ws-locality pic x(150).
000375 15 in-ws-city pic x(50).
000376 15 in-ws-lobby pic x(150).
000377 15 in-ws-postCode pic x(4).
000378 15 in-ws-addressType pic x(1).
000379 15 in-ws-streetSDX pic x(4).
000380 15 in-ws-localitySDX pic x(4).
000381 15 in-ws-lobbySDX pic x(4).
000382 15 in-ws-prologue pic x(100).
000383 12 in-ws-interface pic x.
000384 88 in-free-format-input value '1'.
000385 88 fixed-field-input value '2'.
000386 88 XML-input value '3'.
000387 12 in-ws-streetMatchFlag pic x(1).
000388 88 street-fuzzy value '0'.
000389 88 street-exact value '1'.
000390 12 in-ws-localityMatchFlag pic x(1).
000391 88 locality-fuzzy value '0'.
000392 88 locality-exact value '1'.
000393 12 in-ws-repeatLocalityFlag pic x(1).
000394 88 no-Locality value '1'.
000395 88 repeatLocality value '0'. *> used if
Locality = City
000396 12 in-ws-ignoreInvalidPostcode pic x(1).
000397 88 ignoreInvalidPostCode value '1'.
000398 88 reportInvalidPostCode value '0'. *>stops if Post
Code is invalid
000399 12 in-ws-foreignFlag pic x(1).
000400 88 foreign-address value '1'. *>stops if foreign
address detected
000401 88 NOT-foreign-address value '0'.
000402
000403 01 out-interface-block pic x(8197).
000405 01 out-IB.
000406
000407 12 out-ws-return pic x(5).
000408 88 out-ws-OK value '00000'. *> will contain
SQLSTATE if
000409 *> there is a DB error
000410 12 out-ws-message pic x(256). *> will contain SQLMSG if
000411 *> there is a DB error
000412 12 out-ws-buffer pic x(2048). *> holds free format address data
000413 *> this will be formatted on return
000414 12 out-ws-breakdown.
000415 15 out-ws-streetNo pic x(20).
000416 15 out-ws-POBoxNo pic x(15).
000417 15 out-ws-RDNo pic x(8).
000418 15 out-ws-street pic x(150).
000419 15 out-ws-locality pic x(150).
000420 15 out-ws-city pic x(50).
000421 15 out-ws-lobby pic x(150).
000422 15 out-ws-postCode pic x(4).
000423 15 out-ws-addressType pic x(1).
000424 15 out-ws-streetSDX pic x(4).
000425 15 out-ws-localitySDX pic x(4).
000426 15 out-ws-lobbySDX pic x(4).
000427 15 out-ws-prologue pic x(100).
000428 12 out-ws-interface pic x.
000429 88 free-format-input value '1'.
000430 88 fixed-field-input value '2'.
000431 88 XML-input value '3'.
000432 12 out-ws-streetMatchFlag pic x(1).
000433 88 street-fuzzy value '0'.
000434 88 street-exact value '1'.
000435 12 out-ws-localityMatchFlag pic x(1).
000436 88 locality-fuzzy value '0'.
000437 88 locality-exact value '1'.
000438 12 out-ws-repeatLocalityFlag pic x(1).
000439 88 no-Locality value '1'.
000440 88 repeatLocality value '0'. *> used if
Locality = City
000441 12 out-ws-ignoreInvalidPostcode pic x(1).
000442 88 ignoreInvalidPostCode value '1'.
000443 88 reportInvalidPostCode value '0'. *>stops if Post
Code is invalid
000444 12 out-ws-foreignFlag pic x(1).
000445 88 foreign-address value '1'. *>stops if foreign
address detected
000446 88 NOT-foreign-address value '0'.
000447
000448
000449 01 WSDL-reference pic x(80) value
000450* WSDL to connect to the remote host (in San Francisco)
000451
'http://primacomputing.co.nz/AVSWebService/AVSWebService.asmx?WSDL'.
000452* WSDL to connect to my IIS server on my new VAIO notebook machine
over wireless LAN.
000453* 'http://bigblack/AVSWebService/AVSWebService.asmx?WSDL'.
000454*
000455* I have tested both of the above and they both work perfectly. Web
services can
000456* be hosted anywhere you like and accessed from anywhere on Earth.
It's magic...!!
000457* (Like DCOM+ on steroids...)
000458
000459 01 COMServer-ProgIDs.
000460 12 SOAP-ProgID pic x(19) value
000461 "MSSOAP.SoapClient30".
000462
000463 01 COMServer-Objects.
000464 12 objSOAPClient OBJECT REFERENCE COM.
000465
000466 01 subscripts usage comp-5.
000467 12 J pic s9(5).
000468 12 K pic s9(5).
000469
000470 01 end-flag pic x.
000471 88 not-finished value zero.
000472 88 finished value '1'.
000473
000487
000490 PROCEDURE DIVISION.
000500 MAIN SECTION.
000510 a000.
000520 perform startup-housekeeping
000530 perform main-logic until finished
000540 perform close-down
000550 .
000560 a999.
000570 stop run.
000580*-----------------------------------------------------------
000590 STARTUP-HOUSEKEEPING section.
000600 sh000.
000640 set not-finished to TRUE
000641* Instantiate SOAP COM Server...
000642 invoke COM "CREATE-OBJECT" using SOAP-ProgID
000643 returning objSOAPClient
000644 end-invoke
000645* Initialize the SOAP Server and point it at the WSDL for the Web
Service
000646 invoke objSOAPClient "mssoapinit"
000647 using WSDL-reference
000648 end-invoke
000649* At this point the objSOAPClient reference has become a proxy for the
AVS Web Service...
000650* This means you can reference any of the methods/properties/events
exposed by the Web Service,
000651* as if they belonged to the objSOAPClient object...
000652 .
000660 sh999.
000670 exit.
000680*-----------------------------------------------------------
000690 MAIN-LOGIC section.
000700 ml000.
000701*
000707*
000708* Now try the methods...
000709*
000710* The AVS Web Service only exposes one method, but the underlying COM
object has several.
000711
000712* Set up an address string... (Not essential... if you
000714* pass a blank interface block to AVS it will return a message in the
ws-message
000715* area telling you it was invalid...)
000716 move spaces to in-IB
000718 set in-free-format-input to TRUE
000719 move '97 21ST AVE TAURANGA' to in-ws-buffer *> A NZ address...
000720 move in-IB to in-interface-block
000721 *> Note that string parameters to COM objects must be 8197 bytes
000722 *> and must be elemental.
000723
000724 invoke objSOAPClient "ValidateNZaddress"
000725 using in-interface-block *> input interface
block...
000726 returning out-interface-block *> output interface block...
000727 *> Note that you could use
just one block
000728 *> but you must reference it
in and out because the
000729 *> Web Service expects in
and out parameters.
000730
000731 end-invoke
000732*========================== SOAP XML Stringing error fix
====================
000733* There is currently a problem with SOAP stripping out certain
characters
000734* in the returned string. This causes fields to be aligned
incorrectly. The
000735* following is a quick fix and won't be required once the service is
released.
000736*
000737 move 1 to K *> output buffer pointer
000746 perform
000756 varying J *> input buffer pointer (for this process)
000757 from 1
000758 by 1
000759 until K > function LENGTH (out-IB)
000760 move out-interface-block (J:1) to out-IB (K:1)
000761 add 1 to K
000762 if out-interface-block (J:1) = x'0A'
000763 move space to out-IB (K:1)
000764 add 1 to K
000765 end-if
000766 end-perform
000769
000770*
000771* ALL of the above code would be replaced by:
000772*
000773* move out-interface-block to out-IB
000774*
000775* ...once the COM server and SOAP wrapper are fixed. (I'm working on
it... :-))
000776*
000777*======================== End of SOAP XML Stringing error fix
==================
000778*
000779
000780* Debugging Note
000781*
000782* Now is a good time to look at out-ws-breakdown and out-ws-buffer...
000783*
000784* If you are stepping through this in the debugger, note that each
field has been
000785* filled in, (street number, street, locality, region, and postcode)
and the
000786* ws-buffer area now contains a properly formatted address which
complies with
000787* NZPO requirements, and has been converted to mixed case.
000788*
000789 set finished to TRUE
000790
000791 .
001210 ml999.
001220 exit.
001230*----------------------------------------------------------
001240 CLOSE-DOWN section.
001250 cd000.
001260 set objSOAPClient to NULL *> Help the garbage collector ...
001340 .
001350 cd999.
001360 exit.
001370*---------------- END OF PROGRAM 'SOAPTEST' ----------------

So, there you have it. I hope this is of help to those of you (I believe it
will be an increasing number over the next few years) who are trying to get
to grips with Web Services. Although this service is running and I have
opened it to you all, it won't be that way forever. I will be requiring a
logon and various authentications when the site hosting the service goes
live. In other words, if you want to try this out, do it fairly quickly...

Please post questions/comments here, rather than privately.

Pete.






From: Rene_Surop on
Hi Pete,

I'm quite fascinated by your code. Yes, web services really is an
online technology of the future.... but, do you have an "online" demo
of your Web Service application? Maybe on your Server so that we could
view how fast (or efficient) the execution is.

From: Rene_Surop on
Hi Pete,

I'm quite fascinated by your code... do you have an "online" demo on
your Web Service? Maybe on your Server so that we could view how fast
(or efficient) the execution is.

From: Pete Dashwood on

"Rene_Surop" <infodynamics_ph(a)yahoo.com> wrote in message
news:1179760635.367415.76750(a)36g2000prm.googlegroups.com...
> Hi Pete,
>
> I'm quite fascinated by your code. Yes, web services really is an
> online technology of the future.... but, do you have an "online" demo
> of your Web Service application? Maybe on your Server so that we could
> view how fast (or efficient) the execution is.
>
Absolutely. That's what I posted. It will run against a live (24/7) web
service. Step through it, it's fun :-)

I will be posting a downloadable desktop client (written in C#) to the web
site within the next couple of weeks (I really am absolutely flat out at the
moment). That will run a batch process on your desktop, accessing the remote
web service in real time, while you watch. You will be able to SEE the
addresses getting changed. I have it running currently on my notebook
desktop and everyone who has seen it is blown away... it's actually fun to
watch :-)

As you may have gathered, I am completely persuaded by web services, great
stuff!

Pete.


From: Charles Hottel on

"Pete Dashwood" <dashwood(a)removethis.enternet.co.nz> wrote in message
news:5bddsqF2sd0m9U1(a)mid.individual.net...
> I've had a couple of private mails after responding publicly here to a
> request for help with accessing Web Services from COBOL.
>
> Here is a VERY brief summary of the situation:
>
> (Some parts of the following are reproduced from some documentation I
> wrote and attached to the example COBOL code, as a Fujitsu NetCOBOL
> project)
>
> WEB SERVICES ROCK!
>
> This is the next step on in the components arena. A web service exposes
> some or all of the properties and methods of a component to the Web. Why
> is that important? Because it means you can write a component and deploy
> it once. Anyone with access to your local intranet can access it, or, if
> you have delusions of grandeur (or work for an international company),
> expose it to the Internet and anyone on the planet can access it. And the
> responses, even across great distances, are very fast. (A round trip from
> NZ to California in under a second).
>
> Instead of having to maintain packages you have issued and update them
> all, you do it once (on your Web server) and any package using the service
> is instantly using the new version.
>
> Leaving aside the technicalities of it (which are quite awesome) this
> means that design can take legacy functions and even subsystems, wrap them
> as a Web service, and keep on using them until there is time to re-develop
> new stuff (which will also be developed as a series of web services so
> there is "overlap" and transparency.)
>
> It means that currently disparate systems, possibly deployed on different
> platforms, can become a series of web services that are completely
> platform independent, but accessible by all. This facilitates better
> logical integration without the need for physically making systems talk to
> each other or access each other's data. (Data can be requested from a
> service; how it is provided is immaterial)
>
> Bottom Line:
>
> Offering business functions as web services is likely to be the way of the
> future. It is also a powerful way to integrate disparate systems.
>
> GENERAL CONSIDERATIONS
>
> What and why Web Services?
>
> Web Services are the next step on from COM servers. They don't obviate COM
> servers because these can be embedded in many useful places, but they DO
> allow a piece of encapsulated functionality (a component) to be
> centralized and maintained in ONE place, then accessed from anywhere on
> the planet. (This has major implications when it comes to software
> distribution and updates; no more hundreds of copies to be updated, just
> one.)
>
> A web Service is a component that exposes some or all of itself to the
> Web. Like all OO components it will have methods and properties, and it
> probably takes (and returns) parameters. Pretty straightforward and not
> mysterious. The clever bit is in HOW it is able to talk to any platform
> OS, on any hardware, and realise the dream of data interoperability.
>
> It does it through the magic of XML and a protocol called SOAP.
> (Originally, "Simple Object Access Protocol", but now officially
> meaningless.)
>
> But isn't SOAP obsolete?
>
> Yes. It is being superseded by DotNET services. MS had hoped to stop
> supporting SOAP by 2003 but it is so useful and embedded in so many of
> their own products it has now been officially reprieved until 2008. Office
> 2003 comes with its own SOAP libraries and if you have this version of
> Office you can use those libraries instead of standard SOAP. (Use
> MSOSOAP.SoapClient30 instead of MSSOAP.SoapClient30).
>
> All new development SHOULD use the DotNET methods instead of SOAP, but, as
> NetCOBOL cannot use the DotNET libraries easily, that leaves most COBOL
> users out in the cold.
>
> So, use SOAP until you get into C#. This allows you to leverage your
> existing COBOL code and also make use of web services. (When your COBOL is
> finally converted to whatever it will become, it is VERY easy to replace
> SOAP calls to a web service with DotNET calls to the same service.)
>
> DotNET is where the future lies and it is being picked up for all OSes
> (including UNIX/Linux) and will run on all platforms (possibly even
> including mainframes). It can do this because it is NOT object code or an
> API that would be machine/OS dependent; instead, it is intermediate code
> which is compiled for whatever platform it is running on, as it is loaded.
>
> The specific example included below.
>
> This is a small COBOL .EXE that accesses a Web Service called AVS (Address
> Validation Services). The web service is running (at time of writing; it
> could change, but it really doesn't matter anyway, as long as it is
> visible on a server somewhere.) on a server farm in San Francisco. You can
> access it from Australia, or Germany just as easily as I access it from
> NZ. Responses are immediate and the distances don't seem to matter.
>
> AVS provides a fully selectable service of operations involving NZ postal
> addresses. It covers flats, apartments, urban, rural, PO Box and private
> bag, Post Restante, Counter Delivery and postcode and locality encoding.
> As a bonus, it also returns a complete address from partial free-format
> data, formatted in compliance with NZPO requirements.
>
> You can present data to it in fixed (each field is defined and filled in
> the interface block) or free format (a single string is passed in the
> ws-buffer field of the interface block. AVS analyses and parses it then
> returns all the fields and a formatted address).
>
> (Fixed input may not function for the web service, although it is OK if
> you are using AVS as a COM component). Just concatenate whatever fixed
> fields you have and present them as free-format data to the web service.
>
> So how and where would I use it?
>
> You would plug the service in to any point in an application where you
> need address services. Pass it what you have collected from the user,
> invoke it, and select whatever you want to display back, or update a
> database. It really is that simple.
>
> It's a bit like "outsourcing" NZ postal address requirements. Fill in the
> blanks, get the post code, update changed localities, whatever you want to
> do.
>
> Conclusion
>
> Enabling your application for web services is a step towards the future.
>
> It is no more complex to obtain the complete functionality described
> above, than it is to simply get a valid postcode.
>
> There are HUGE pitfalls in address processing. It is nowhere near as
> simple as it first appears (the AVS engine took around 800 hours to
> write). Because of changes to the address coding in NZ, localities and
> postcodes now mean more than previously. A street and a postcode will
> uniquely identify an address, but streets, postcodes, and localities are
> not unique. And not everybody lives in town; the boxes and rural domains
> have their own idiosyncracies.
>
> PROS:
>
> 1. Calling a web service is simple and facilitates future conversion.
> 2. It is easy to outsource the functionality and not have to maintain and
> update postal data as well as your application.
> 3. The interface is just as simple as calling a COM/ActiveX component.
> 4. No maintenance required.
>
> CONS:
>
> 1. You must be online to use it.
>
> HERE'S THE SAMPLE CODE IN FUJITSU NetCOBOL (Maybe someone can convert it
> to NE or ACUCOBOL so we can see the differences...?) ANY COBOL that can
> support accessing COM/ActiveX components can access the web service.
>
> WARNING: You must have a SOAP library installed on your system. (It is the
> SOAP component that accesses the WSDL for the service, generates the
> required XML to transport your interface block and return it, and invokes
> the web service method. As you can see, NO KNOWLEDGE OF XML or SOAP is
> required to use the service, even though it would be impossible without
> these protocols.) If you have MS Office 2003, use the MSOSOAP.SoapClient30
> component, rather than the MSSOAP.SoapClient30 component. You can download
> the SOAP Toolkit from:
> http://www.microsoft.com/downloads/details.aspx?FamilyId=C943C0DD-CEEC-4088-9753-86F052EC8450&displaylang=en
>
> NOTE: DO NOT COMPILE AND RUN THIS CODE! You won't see anything and it will
> look as if it did nothing. Instead, compile it for debugging and step
> through it, then everything becomes clear.
>
> 000010 IDENTIFICATION DIVISION.
> 000020 PROGRAM-ID. 'SOAPTest'.
> 000030*AUTHOR. Peter E. C. Dashwood.
> 000031*
> 000040* This program attempts to instantiate a SOAP Proxy class and
> 000050* access a Web Service using the new proxy...
> 000051*
> 000060*DATE_WRITTEN. May 2007.
> 000070 ENVIRONMENT DIVISION.
> 000080 configuration section.
> 000090 source-computer. IBM-PC.
> 000100 object-computer. IBM-PC.
> 000101 REPOSITORY.
> 000110 CLASS COM AS "*COM".
> 000120
> 000170
> 000200*------------------------ DATA DIVISION ---------------------
> 000210 DATA DIVISION.
> 000340*
> 000350 WORKING-STORAGE SECTION.
> 000360 01 in-interface-block pic x(8197).
> 000361 01 in-IB.
> 000362 12 in-ws-return pic x(5).
> 000363 88 in-ws-OK value '00000'. *> will contain
> SQLSTATE if
> 000364 *> there is a DB error
> 000365 12 in-ws-message pic x(256). *> will contain SQLMSG if
> 000366 *> there is a DB error
> 000367 12 in-ws-buffer pic x(2048). *> holds free format address
> data
> 000368 *> this will be formatted on
> return
> 000369 12 in-ws-breakdown.
> 000370 15 in-ws-streetNo pic x(20).
> 000371 15 in-ws-POBoxNo pic x(15).
> 000372 15 in-ws-RDNo pic x(8).
> 000373 15 in-ws-street pic x(150).
> 000374 15 in-ws-locality pic x(150).
> 000375 15 in-ws-city pic x(50).
> 000376 15 in-ws-lobby pic x(150).
> 000377 15 in-ws-postCode pic x(4).
> 000378 15 in-ws-addressType pic x(1).
> 000379 15 in-ws-streetSDX pic x(4).
> 000380 15 in-ws-localitySDX pic x(4).
> 000381 15 in-ws-lobbySDX pic x(4).
> 000382 15 in-ws-prologue pic x(100).
> 000383 12 in-ws-interface pic x.
> 000384 88 in-free-format-input value '1'.
> 000385 88 fixed-field-input value '2'.
> 000386 88 XML-input value '3'.
> 000387 12 in-ws-streetMatchFlag pic x(1).
> 000388 88 street-fuzzy value '0'.
> 000389 88 street-exact value '1'.
> 000390 12 in-ws-localityMatchFlag pic x(1).
> 000391 88 locality-fuzzy value '0'.
> 000392 88 locality-exact value '1'.
> 000393 12 in-ws-repeatLocalityFlag pic x(1).
> 000394 88 no-Locality value '1'.
> 000395 88 repeatLocality value '0'. *> used if
> Locality = City
> 000396 12 in-ws-ignoreInvalidPostcode pic x(1).
> 000397 88 ignoreInvalidPostCode value '1'.
> 000398 88 reportInvalidPostCode value '0'. *>stops if
> Post Code is invalid
> 000399 12 in-ws-foreignFlag pic x(1).
> 000400 88 foreign-address value '1'. *>stops if
> foreign address detected
> 000401 88 NOT-foreign-address value '0'.
> 000402
> 000403 01 out-interface-block pic x(8197).
> 000405 01 out-IB.
> 000406
> 000407 12 out-ws-return pic x(5).
> 000408 88 out-ws-OK value '00000'. *> will contain
> SQLSTATE if
> 000409 *> there is a DB error
> 000410 12 out-ws-message pic x(256). *> will contain SQLMSG if
> 000411 *> there is a DB error
> 000412 12 out-ws-buffer pic x(2048). *> holds free format address
> data
> 000413 *> this will be formatted on
> return
> 000414 12 out-ws-breakdown.
> 000415 15 out-ws-streetNo pic x(20).
> 000416 15 out-ws-POBoxNo pic x(15).
> 000417 15 out-ws-RDNo pic x(8).
> 000418 15 out-ws-street pic x(150).
> 000419 15 out-ws-locality pic x(150).
> 000420 15 out-ws-city pic x(50).
> 000421 15 out-ws-lobby pic x(150).
> 000422 15 out-ws-postCode pic x(4).
> 000423 15 out-ws-addressType pic x(1).
> 000424 15 out-ws-streetSDX pic x(4).
> 000425 15 out-ws-localitySDX pic x(4).
> 000426 15 out-ws-lobbySDX pic x(4).
> 000427 15 out-ws-prologue pic x(100).
> 000428 12 out-ws-interface pic x.
> 000429 88 free-format-input value '1'.
> 000430 88 fixed-field-input value '2'.
> 000431 88 XML-input value '3'.
> 000432 12 out-ws-streetMatchFlag pic x(1).
> 000433 88 street-fuzzy value '0'.
> 000434 88 street-exact value '1'.
> 000435 12 out-ws-localityMatchFlag pic x(1).
> 000436 88 locality-fuzzy value '0'.
> 000437 88 locality-exact value '1'.
> 000438 12 out-ws-repeatLocalityFlag pic x(1).
> 000439 88 no-Locality value '1'.
> 000440 88 repeatLocality value '0'. *> used if
> Locality = City
> 000441 12 out-ws-ignoreInvalidPostcode pic x(1).
> 000442 88 ignoreInvalidPostCode value '1'.
> 000443 88 reportInvalidPostCode value '0'. *>stops if
> Post Code is invalid
> 000444 12 out-ws-foreignFlag pic x(1).
> 000445 88 foreign-address value '1'. *>stops if
> foreign address detected
> 000446 88 NOT-foreign-address value '0'.
> 000447
> 000448
> 000449 01 WSDL-reference pic x(80) value
> 000450* WSDL to connect to the remote host (in San Francisco)
> 000451
> 'http://primacomputing.co.nz/AVSWebService/AVSWebService.asmx?WSDL'.
> 000452* WSDL to connect to my IIS server on my new VAIO notebook machine
> over wireless LAN.
> 000453* 'http://bigblack/AVSWebService/AVSWebService.asmx?WSDL'.
> 000454*
> 000455* I have tested both of the above and they both work perfectly. Web
> services can
> 000456* be hosted anywhere you like and accessed from anywhere on Earth.
> It's magic...!!
> 000457* (Like DCOM+ on steroids...)
> 000458
> 000459 01 COMServer-ProgIDs.
> 000460 12 SOAP-ProgID pic x(19) value
> 000461 "MSSOAP.SoapClient30".
> 000462
> 000463 01 COMServer-Objects.
> 000464 12 objSOAPClient OBJECT REFERENCE COM.
> 000465
> 000466 01 subscripts usage comp-5.
> 000467 12 J pic s9(5).
> 000468 12 K pic s9(5).
> 000469
> 000470 01 end-flag pic x.
> 000471 88 not-finished value zero.
> 000472 88 finished value '1'.
> 000473
> 000487
> 000490 PROCEDURE DIVISION.
> 000500 MAIN SECTION.
> 000510 a000.
> 000520 perform startup-housekeeping
> 000530 perform main-logic until finished
> 000540 perform close-down
> 000550 .
> 000560 a999.
> 000570 stop run.
> 000580*-----------------------------------------------------------
> 000590 STARTUP-HOUSEKEEPING section.
> 000600 sh000.
> 000640 set not-finished to TRUE
> 000641* Instantiate SOAP COM Server...
> 000642 invoke COM "CREATE-OBJECT" using SOAP-ProgID
> 000643 returning objSOAPClient
> 000644 end-invoke
> 000645* Initialize the SOAP Server and point it at the WSDL for the Web
> Service
> 000646 invoke objSOAPClient "mssoapinit"
> 000647 using WSDL-reference
> 000648 end-invoke
> 000649* At this point the objSOAPClient reference has become a proxy for
> the AVS Web Service...
> 000650* This means you can reference any of the methods/properties/events
> exposed by the Web Service,
> 000651* as if they belonged to the objSOAPClient object...
> 000652 .
> 000660 sh999.
> 000670 exit.
> 000680*-----------------------------------------------------------
> 000690 MAIN-LOGIC section.
> 000700 ml000.
> 000701*
> 000707*
> 000708* Now try the methods...
> 000709*
> 000710* The AVS Web Service only exposes one method, but the underlying
> COM object has several.
> 000711
> 000712* Set up an address string... (Not essential... if you
> 000714* pass a blank interface block to AVS it will return a message in
> the ws-message
> 000715* area telling you it was invalid...)
> 000716 move spaces to in-IB
> 000718 set in-free-format-input to TRUE
> 000719 move '97 21ST AVE TAURANGA' to in-ws-buffer *> A NZ address...
> 000720 move in-IB to in-interface-block
> 000721 *> Note that string parameters to COM objects must be 8197
> bytes
> 000722 *> and must be elemental.
> 000723
> 000724 invoke objSOAPClient "ValidateNZaddress"
> 000725 using in-interface-block *> input interface
> block...
> 000726 returning out-interface-block *> output interface
> block...
> 000727 *> Note that you could use
> just one block
> 000728 *> but you must reference
> it in and out because the
> 000729 *> Web Service expects in
> and out parameters.
> 000730
> 000731 end-invoke
> 000732*========================== SOAP XML Stringing error fix
> ====================
> 000733* There is currently a problem with SOAP stripping out certain
> characters
> 000734* in the returned string. This causes fields to be aligned
> incorrectly. The
> 000735* following is a quick fix and won't be required once the service is
> released.
> 000736*
> 000737 move 1 to K *> output buffer pointer
> 000746 perform
> 000756 varying J *> input buffer pointer (for this process)
> 000757 from 1
> 000758 by 1
> 000759 until K > function LENGTH (out-IB)
> 000760 move out-interface-block (J:1) to out-IB (K:1)
> 000761 add 1 to K
> 000762 if out-interface-block (J:1) = x'0A'
> 000763 move space to out-IB (K:1)
> 000764 add 1 to K
> 000765 end-if
> 000766 end-perform
> 000769
> 000770*
> 000771* ALL of the above code would be replaced by:
> 000772*
> 000773* move out-interface-block to out-IB
> 000774*
> 000775* ...once the COM server and SOAP wrapper are fixed. (I'm working on
> it... :-))
> 000776*
> 000777*======================== End of SOAP XML Stringing error fix
> ==================
> 000778*
> 000779
> 000780* Debugging Note
> 000781*
> 000782* Now is a good time to look at out-ws-breakdown and
> out-ws-buffer...
> 000783*
> 000784* If you are stepping through this in the debugger, note that each
> field has been
> 000785* filled in, (street number, street, locality, region, and postcode)
> and the
> 000786* ws-buffer area now contains a properly formatted address which
> complies with
> 000787* NZPO requirements, and has been converted to mixed case.
> 000788*
> 000789 set finished to TRUE
> 000790
> 000791 .
> 001210 ml999.
> 001220 exit.
> 001230*----------------------------------------------------------
> 001240 CLOSE-DOWN section.
> 001250 cd000.
> 001260 set objSOAPClient to NULL *> Help the garbage collector ...
> 001340 .
> 001350 cd999.
> 001360 exit.
> 001370*---------------- END OF PROGRAM 'SOAPTEST' ----------------
>
> So, there you have it. I hope this is of help to those of you (I believe
> it will be an increasing number over the next few years) who are trying to
> get to grips with Web Services. Although this service is running and I
> have opened it to you all, it won't be that way forever. I will be
> requiring a logon and various authentications when the site hosting the
> service goes live. In other words, if you want to try this out, do it
> fairly quickly...
>
> Please post questions/comments here, rather than privately.
>
> Pete.
>
>
>
>
>
>

Thanks for these postings on web services, Pete.

You make me want to jump into C# but one of my problems with the pc world of
software has been maintaining my focus. So for now I am still pursuring
Java. Effective Java by Jousha Bloch is great and after that I believe I
will be ready for Design Patterns by Gamma etc. I tried to read Design
Patterns before but I kept having to consciously think about the meanings of
the terms. A recent skim showed me that now I have internalized the concepts
enough and have a more intuitive understanding when reading. I still have
much to learn and Java keeps evolving and I am still not up to date on all
the latest and greatest additions.

At some point where I feel I am prepared for anything I am called upon to do
at work with Java, I will look into C#, I have Murach's C# book.


 |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8
Prev: Microfocus Cobol "SLEEP" routine
Next: Help with Tcal