views:

262

answers:

1

Hello fellow Coders,

I have to implement a webservice client to a given WSDL file. I used the SDK's 'wsimport' tool to create Java classes from the WSDL as well as a class that wrap's the webservice's only method (enhanceAddress(auth, param, address)) into a simple java method. So far, so good. The webservice is functional and returning results correcty. The code looks like this:

try {
  EnhancedAddressList uniservResponse = getWebservicePort().enhanceAddress(m_auth, m_param, uniservAddress);
  //Where the Port^ is the HTTP Soap 1.2 Endpoint
}catch (Throwable e) {
  throw new AddressValidationException("Error during uniserv webservice request.", e);
}

The Problem now: I need to get Information about the connection and any error that might occur in order to populate various JMX values (such as COUNT_READ_TIMEOUT, COUNT_CONNECT_TIMEOUT, ...) Unfortunately, the method does not officially throw any Exceptions, so in order to get details about a ConnectException, i need to use getCause() on the ClientTransportException that will be thrown.

Even worse: I tried to test the read timeout value, but there is none. I changed the service's location in the wsdl file to post the request to a php script that simply waits forever and does not return. Guess what: The web service client does not time out but waits forever as well (I killed the app after 30+ minutes of waiting). That is not an option for my application as i eventually run out of tcp connections if some of them get 'stuck'.

The enhanceAddress(auth, param, address) method is not implemented but annotated with javax.jws.* Annotations, meaning that i cannot see/change/inspect the code that is actually executed.

Do i have any option but to throw the whole wsimport/javax.jsw-stuff away and implement my own soap client?

+1  A: 

to setup read-timeout and connect timeouts you can configure the binding parameters when you setup your Service and Port instances:


    Service = new Service();

    Port = Service.getPort();

    ((BindingProvider) Port).getRequestContext().put(
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
            "http://localhost:8080/service");
    ((BindingProvider) Port).getRequestContext().put(
            BindingProviderProperties.CONNECT_TIMEOUT,
            30);
    ((BindingProvider) Port).getRequestContext().put(
            BindingProviderProperties.REQUEST_TIMEOUT,
            30);

now whenever you execute a service via "Port" you will get response timeouts and/or connection timeouts if the backend is slow to respond. the values follow the timeout values of the Socket Class.

when these timeouts are exceeded you will get timeout exeption or a connection exception and you can put counter-code to keep track of how many you get.

Helter Scelter
Since I had the Problem 2 weeks ago, I wrote my own client. Despite that, I tested your approach and it is working! I did find a similar piece of code back then, but somehow it gave me a ClassCastException when I tried to cast to BindingProvider.
f1sh