I have recently been doing some work on a system from my 'youth'. The system is an HPe3000, which theoretically 'died' in 2006. But these systems were from the old HP - High Performance - High Cost. There are still countless companies around the world relying on them for day to day running, and they are still going strong. For these companies, they are doing a great job.
However, for a machine built at the turn of the century - there are some things they can't do. But generally where there is a will, there is a way.
The work I have been doing, needed to call 3rd party API's and web services and updating the HPe30000 database with the results. The HPe3000 has networking capability, and calling a web service is possible, but calling a web service that sends, receives and parses JSON, in COBOL, is difficult - if not impossible.
As there are not many of us HP veterans left, I chatted this over with Doug Werth from Beechglen Development. We had a chat about what was possible, and what wasn't, which helped clarify things.
Having developed software in the past, using TCP/IP sockets to interface with HPe3000's, PC's and Unix boxes, I decided it was definitely possible, and the way to go. TCP/IP sockets are fast and reliable, and available on most, if not all, platforms. Once you get into using them, there aren't many calls you need to use. Beechglen also have a freeware Sockets XL that masks the sockets calling complexity for COBOL developers which really helps.
I had 2 different scenarios to deal with - on-line validation and batch validation. I decided the way forward was using a PC as the 'middle man', and writing a C# app to handle the comms.
The batch implementation was the easier of the 2 tasks, so that was my start. I designed a messaging system using Sockets, the HPe3000 being the client, and the PC being the server. The PC server sits listening on a port for a TCP connection from the HPe3000. Meanwhile the HPe3000 has the port number and IP address of the PC. It requests a socket, sends a Connect request to the server PC, and listens for a response. The server PC sends the response, and then waits on a receive. The 2 processes then exchange messages, each one waiting for a reply after sending a reply.
The PC server handles all the API calls, in this case to a site in the UK. The PC is doing all the JSON parsing and handling the web calls, and any errors. The results are handled by the HPe3000, and the database updated accordingly.
This may sound a lot of work, but generally we are getting sub-second response, although this is less important in batch. When the batch is finished, the PC 'server' starts up a new instance, and sits listening for connection request. As I wanted some interaction on the server, I didn't choose to write this as a service, but using the Task Scheduler, the process is started at logon, and will restart if it fails.
The response time does mean though, that on-line validation should be quick enough. The architecture was similar, but not the same. There is a listener process on the PC server, again listening on a known port, but this is a 'port server'. Again, the HPe3000 sends a 'Connect' request to the 'port server'. The 'port server' accepts it, but this time, this server looks for a free port number, and returns that to the HP3000. This 'port server' then creates a new server process, starting it with the new port number obtained. This new server listens for a connection on the port it has been passed. Meanwhile, the 'port server' restarts and listens for the next connection request - Phew!
Why are we doing this? We are doing it so that each process on the HP3000 talks to its own process on the server. Doing it this way means that the response is again sub-second and the multiple on-line Order Entry system operatives are not kept waiting.
This method is easy to expand to call virtually any web service and return the results to the HPe3000, or any older system that supports sockets.
I have written some sample code to demonstrate this. The HPe3000 sample client in COBOL can be downloaded here and the C# Windows console source project can be downloaded here. The guts of the 'server' is around 250 lines of code, and the COBOL client is less than 200 lines - COBOL!!
The programs demonstrate 2 functions. There is a simple message program, which simply exchanges message between the HPe3000 and a PC Client on the network. You just need to change the IP address in the HPe3000 program. Change the line:-
MOVE "10.0.0.123" TO PC-SERVER-IP.
Start the server progam which will sit waiting for a connection. Then start the COBOL progam which will need the SOCKXL and SOCKETXL.NET.SYS from Beechglen.
You are prompted on the HPe3000 to enter text. It will pass the message to the server program where you can answer and send the reply back to the HPe3000 as shown in the screen shots below.
You see above the messages being passed from Client to Server and back. Enter "END" to terminate the process.
The server process also shows you how to call a web service, get a result, and send the result back to the HPe3000. The sample user OpenWeatherMap and you will have to sign up to get an API key, which is free. The server source code needs the API key inserting.
public static string apiKey = ""; // append to calls - get the key from https://openweathermap.org/
Start the programs as below, but when prompted on the HPe3000, enter Weather:City where City is the city you want the weather forecast from. The forecast is in Centigrade but can be changed to Fahrenheit by changing metric to imperial in the call to the API. The default is Kelvin. The 'Weather' is case sensitive. This sample shows the deserialization of the JSON returned by the API, and formats a message to send back to the HPe3000.
The screenshots below show the data flow.
And the data flow on the PC is:-
The C# 'server' shows 2 ways Sockets can be used. This may be of little use to most people, but it demonstrates how easy it is to implement a Client/Server model to make use of any API's, but I do hope it helps someone.