Showing posts with label Websphere. Show all posts
Showing posts with label Websphere. Show all posts

Friday, June 11, 2010

How to change the endpoint defined in the WSDL

Why should one do that? There might be several different reasons, I'll write about the one that moved me. We are developing a new integrated enterprise application for a customer that is located in another city: the core of the system is developed in RPG-LE and uses a cool UI that greatly extends the classic "green screen". The system is deployed on an iSeries and exposes Axis2 Web Services through an IBM Websphere Application Server; these services are accessed by a web application hosted in a protected network that is used by local offices all over Italy.

We periodically update their core system in a direct way, but for security reasons we do not have administrative access to their application server, so whenever we release an update we have to contact them and wait for them to republish the Web Services. As, despite of all my efforts to persuade the decisors, this still happens manually (nemo propheta in patria), every now and then we experience strange behaviours in remote clients.

As I still haven't managed to obtain dedicated services instances and databases for tests (see above) I must revert to plain old manual testing. More or less, as I definitely don't want to jump on the bandwagon of keyboard monkeys that seems so in fashion. Lazy as every good programmer should be (if nothing else I still got something of a good programmer) at least I have partly automated the process with a combination of Selenium, wsmonitor and Poster.

What I still missed was the possibility to easily override the endpoint defined in the WSDL I used when I generated the client in NetBeans for a scenario like this: we develop the core, expose the services, generate a client, use it in the remote application, run it and check that everything is working fine, deploy to the customer, ask them to republish the services, generate a client, use it in the remote application, run it and check that everything is working fine and it is not. And if you're wondering, yes there is some echo in this room.

As a matter of fact, every now and then we got as an answer a SOAP fault with a crystal clear message like

java.lang.NumberFormatException: High-order nibble of the byte at array offset 11 is not valid.  Byte value: 40

WTF??? At this point we normally check that the customer properly deployed the services diffing the WSDLs, then eventually contact them, but that's not always as easy as we'd wish. To get further informations (and to speedup the test process) I would like to use Poster to test that the service is working as expected, but for that I need the content to post. That's where wsmonitor would come useful, but it turns out that I cannot update the client through it:

Please enable REST support in WEB-INF/conf/axis2.xml

Before you ask, they wouldn't allow it. So I had to directly generate a client from their anthracite coal grey box (don't call it black, they'd be resented about it) but have it point to my local wsmonitor instead (I'm afraid either NetBeans still has to catch up a little with this or I have to find out how to sort it out) to see the outgoing and incoming messages.

Now the real magic you've been waiting for (well maybe you haven't, but I sure did): the client code generated by NetBeans looks like this snippet:

MyService service = new MyService();
MyServicePortType port =
service.getMyServiceSOAP11PortHttp();

At this point the port refers to the endpoint defined in the remote WSDL. To override it all you need to do is add this line:

((BindingProvider) port).getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://localhost:12345/path/to/MyService");

So what? as awkward as it might seem, the fastest solutions (obviously as far as I know, which is not much) turned out to generate the client from the original WSDL, debug the client application, start the wsmonitor, change the endpoint on the fly and apply the code changes class as needed, and... ta-daaah! here are the SOAP messages!

From this point on I can happily close everything else and switch to Poster: until a click on the POST button returns me a valid message I don't even waste a second on my IDE or on the client application.

Why did I choose 12345 for the port? Because

...that's the stupidest combination I've ever heard of in my life! That's the kinda thing an idiot would have on his luggage!

Now, if you're yelling

1, 2, 3, 4, 5? That's amazing! I've got the same combination on my luggage!

console yourself, you're not alone :-)

Tuesday, May 13, 2008

Web Services Interoperability?

After some discussions I've finally managed to persuade the iSeries administrator to expose some of his applications as services instead of giving other teams accounts to access the databases. We chose a test program, discussed a little, agreed on data and operations, and moved to our favourite IDEs (WDSC in his case, NetBeans in mine).

Time required to build a web service in WDSC starting from an RPGLE program: about 30 minutes, due to the fact that we never tried it before.

Time required to build a client in NetBeans importing the WSDL published on the integrated Websphere: about 5 minutes.

Time required to actually integrate the client and the server: we are still trying to figure that out... the client reports a connection error (but it managed to retrieve the WSDL and generate all the necessary stuff without any problem), the server reports a not better specified moduleData null error (but we managed to locally test the service all right), we report a serious headache.

As always, the devil lies in the details. But where exactly is too often unknown.

Naturally, exporting the WAR file and installing it on a Tomcat instance results in a long and incomprehensible stack trace (did you really think it could be so easy?).

So we tried another approach: we installed an Apache Tomcat instance on the WDSC and selected it as the target runtime for a new application. Magically it all worked fine (after we manually edited the WSDL which reported a wonderful localhost in the wsdlsoap:address attribute), even when we installed the same war file on another server with another Tomcat instance.

The next activity will consist in deploying the application on the Tomcat that resides in the DMZ... All we have to find out is what to open on the firewall. But, for now, let's call it a day.