java WebService request timeout - java

My problem is that I call a remote web service that requires more than 60 seconds to respond and this causes a timeout exception. I do not want any timeout check: I just want the sender to wait until the web service ends. I tried to set:
HttpSession httpSession = getThreadLocalRequest().getSession();
httpSession.setMaxInactiveInterval(120000);
getThreadLocalRequest().setAttribute("session", httpSession);
to modify the web.xml session-timeout (even though I do not think that it is related with my problem) to create a custom HttpRequest. Timeout persists. Is there any way to shutdown this check?

Found the solution:
/* Connect to the service */
ClientProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
factoryBean.setServiceClass(MyService.class);
factoryBean.setAddress("service-url");
myService = (MyService) factoryBean.create();
/* Retrive HTTP client policy and set the receive timeout */
Client client = ClientProxy.getClient(myService);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = httpConduit.getClient();
httpClientPolicy.setReceiveTimeout(timeoutMilliseconds);

httpSession.setMaxInactiveInterval is not what you're after.
You probably want to set connectTimeout and readTimeout on URLConnection.
How to do that, depends on what tool you use to call the remote webservice.
Can you add some more details about the service, if it's a SOAP-service, REST-service etc, and what library you use to call the service?

Related

Apache CXF Client proxy settings

I am trying to Develop a Consumer for Soap Service using the tutorial at
http://cxf.apache.org/docs/developing-a-consumer.html
In the section ,"Setting Connection Properties with Contexts" I am looking at the code below
// Set request context property.
java.util.Map<String, Object> requestContext =
((javax.xml.ws.BindingProvider)port).getRequestContext();
requestContext.put(ContextPropertyName, PropertyValue);
// Invoke an operation.
port.SomeOperation();
Can someone tell me if I can set the proxy server settings using the requestContext properties and how ?. My code is running behind a proxy and I need the outgoings SOAP calls to use proxy server settings.
Proxy setting are usually set by using httpconduit object
HelloService hello = new HelloService();
HelloPortType helloPort = cliente.getHelloPort();
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(helloPort);
HTTPConduit http = (HTTPConduit) client.getConduit();
http.getClient().setProxyServer("proxy");
http.getClient().setProxyServerPort(8080);
http.getProxyAuthorization().setUserName("user proxy");
http.getProxyAuthorization().setPassword("password proxy");

How to set timeout to JAX-RS client with CXF

I am working on a Rest Client and I am using CXF with JAX-RS.
The problem that I have is that I cannot find any way to override the default timeout values of the client.
A simple client:
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/MyApp");
target = target.path("jsp/Test.jsp");
Response response = target.request().get();
I have read that there are two timeout properties in CXF called ReceiveTimeout and ConnectionTimeout but I have not managed to find a way to set them in my client.
I have tried client.property("ReceiveTimeout", 5000); but it doesn't work.
I have seen examples of using an xml configuration file to configure the client but I prefer not to take that path if it is possible.
Any ideas?
HTTPConduit conduit = WebClient.getConfig(webClient).getHttpConduit();
conduit.getClient().setConnectionTimeout(1000 * 3);
conduit.getClient().setReceiveTimeout(1000 * 3);
You can find the correct properties in org.apache.cxf.jaxrs.client.spec.ClientImpl:
"http.connection.timeout" and "http.receive.timeout"
So just use them as property when building the client:
ClientBuilder.newClient().property("http.receive.timeout", 1000);
With JAX-RS 2.1 (supported from CXF 3.2) you can use these standard methods in ClientBuilder:
connectTimeout(long timeout, TimeUnit unit);
readTimeout(long timeout, TimeUnit unit);
See also: https://github.com/eclipse-ee4j/jaxrs-api/issues/467
You can try something like this:
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(30000);
http.setClient(httpClientPolicy);
see http://cxf.apache.org/javadoc/latest/org/apache/cxf/transports/http/configuration/HTTPClientPolicy.html

Do Jersey client support NTLM proxy

I'm trying to make a jersey client call using NTLM proxy? is that possible as i was not able to get any clear information on the same. Did anyone tried before?
Yes it is possible to configure the Jersey Client to connect through a proxy server that requires NTLM authentication.
Here is a simplified code snippet that prepares a suitable ClientConfig that should work with Jersey v2.5+:
final ClientConfig config = new ClientConfig();
config.property(ClientProperties.PROXY_URI, "http://myproxy.com:8000");
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
final AuthScope ntlmAuthScope =
new AuthScope("myproxy.com", 8000, AuthScope.ANY_REALM, "NTLM");
credentialsProvider.setCredentials(
ntlmAuthScope,
new NTCredentials("user", "password", "hostname", "domain") );
config.property(
ApacheClientProperties.CREDENTIALS_PROVIDER, credentialsProvider);
config.connectorProvider(new ApacheConnectorProvider());
Client client = ClientBuilder.newClient(config);
Please note: I am using the Apache HttpClient connector with Jersey Client - you may require slightly different code if you are using another client transport connector.
You may also need to add the following line to your code if you want your POST/PUT requests to be buffered (and therefore repeatable) in response to any 407 authentication challenges that come back from your proxy server:
config.property(ClientProperties.REQUEST_ENTITY_PROCESSING,
RequestEntityProcessing.BUFFERED);

How to make a new connection for each POST request with Jersey Client

My program is supposed to make multiple POST requests to a https site and I need it to do a SSL-handshake each time it does a new request.
However it seems to only do the handshake the first time and then use the existing connection to do the other requests without a new handshake. I'm sure it doesn't do the handshake later times, because the first time it takes about 700 ms to do the request and receive a response, but later ones only take about 30 ms.
Here's how I initialize the client: (Am I missing some property here?)
SSLContext context = SSLContext.getInstance("SSL");
context.init(kms, trustAllCerts, null);
SSLContext.setDefault(context);
ClientConfig config = new DefaultClientConfig();
config.getProperties().put(ClientConfig.PROPERTY_READ_TIMEOUT, timeout * 1000);
config.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, false);
config.getFeatures().put(ClientConfig.FEATURE_DISABLE_XML_SECURITY, true);
client = Client.create(config);
And here's how I make the actual request:
ClientResponse cr = service.type(MediaType.APPLICATION_XML).accept(MediaType.APPLICATION_XML).post(ClientResponse.class, batch);
(The service variable is the Builder class, which creates the ClientRequest. It's where the URL is specified.)
Any ideas, please?
HTTP has persistent connections, and SSL has resumable sessions, both of which are specifically intended to prevent what you are trying to accomplish.
You probably turn them both off somehow for your testing purposes, if you delve into the innards of your servers, but I really don't see the point of testing a configuration you would be mad to deploy in production.

JAXWS - help required to set WSDL request timeout

Im using Metro 2.0 and J2SE5. The application I have written does not know about the external WebService at compile time, it finds them at runtime based on a business logic XML file, therefore I perform a WSDL request.
The sample code I have written is as follows:
String wsdlServiceName = ...;
String wsdlURL = ...;
Document payload = ...;
final String nsURI = ...;
final QName serviceName = new QName(nsURI, wsdlServiceName + "Service");
final QName servicePort = new QName(nsURI, wsdlServiceName + "Port");
// Create service and the dispatcher for the SOAP message
Service service = Service.create(new URL(wsdlURL), serviceName);
dispatch = service.createDispatch(servicePort, SOAPMessage.class, Service.Mode.MESSAGE);
// Set timeouts
dispatch.getRequestContext().put("com.sun.xml.internal.ws.request.timeout", 3000);
dispatch.getRequestContext().put("com.sun.xml.internal.ws.connect.timeout", 3000);
// Create the outgoing SOAP request
SOAPBinding soapBinding = (SOAPBinding) dispatch.getBinding();
request = soapBinding.getMessageFactory().createMessage();
SOAPBody requestBody = request.getSOAPBody();
requestBody.addDocument(payload);
// Invoke web service operation
SOAPMessage response = dispatch.invoke(request);
The timeout works correctly when the Web Service is invoked ( dispatcher.invoke(request) )
HOWEVER the WSDL is requested before the timeouts are set, and if the Web Service is not responding it takes 90 seconds before the connection is timed-out.
Is it possible to set the timeouts before the WSDL is requested ? You need a dispatcher to set the timeouts, but that is done AFTER the Service is created that requests the WSDL?! (ie. Service.create() )
Try the setting system property
sun.net.client.defaultConnectTimeout
but from Networking Properties it says it may not be supported for in future releases
However I would suggest to cache the WSDL and not access it remotely.
It is better performance wise especially if you are working with a WSDL that is not expected to change frequently.
We just ran into this same issue, and tried all of the settings mentioned above - likewise, to no avail.
Our solution was to download the WSDL to a temporary file first, using URL.openConnection() (setting the timeouts on the connection with: URLConnection.setConnectionTimeout(), and URLConnection.setReadTimeout()). We then generate a url for this file with: File.toURI().toURL(), which we pass to the service constructor that takes a URL.
This approach lets you dynamically fetch the current WSDL, while explicitly controlling the timeout. We then set the timeout for subsequent calls to the service as you show in the original post.

Categories