csupi created CXF-4559:
--------------------------
Summary: Part of SoapMessage content interchange between two
concurrent webservice calls
Key: CXF-4559
URL: https://issues.apache.org/jira/browse/CXF-4559
Project: CXF
Issue Type: Bug
Components: JAX-WS Runtime
Affects Versions: 2.5.6, 2.5.5, 2.5.4
Environment: Ubuntu 12.04
Reporter: csupi
Priority: Critical
I have a simple cxf webservice call with a DTO parameter. There is a HashMap
and some other fields in the DTO.
I realized that there are some cases where the content in the map is changed
somewhere on the server side.
I created a simple unit test. I put a String into the map and into a field
where the map is. Create a webservice with jetty and create 15 clients to call
my webservice 1000 times.
After the test execution I realized that about in the 2% of the calls, the
String in the map differs from the value in the field.
Here is my unit test:
{noformat}
package com.statlogics.credilogic.integrator.esb.impl.cxf;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import org.junit.Test;
public class WebserviceEndpointIt {
private static final int number_of_clients = 15;
private final AtomicInteger badCounter = new AtomicInteger(0);
private final AtomicInteger successCounter = new AtomicInteger(0);
@XmlAccessorType(XmlAccessType.FIELD)
public static class Event implements Serializable {
private static final long serialVersionUID = 1L;
private final HashMap<String, Object> map = new HashMap<String,
Object>();
private String expected;
private String i;
private String thread;
}
@WebService
public interface MockWebservice {
void doit(@WebParam(name = "message") Event message);
}
public class MockWebserviceImpl implements MockWebservice {
@Override
public void doit(final Event message) {
/*
* read the two strings from the FIELD and the MAP
*/
final String expected = message.expected;
final Object idFromMap = message.map == null ? null :
message.map.get("expected");
if (expected == null || idFromMap == null ||
!expected.equals(idFromMap)) {
WebserviceEndpointIt.this.badCounter.incrementAndGet();
} else {
WebserviceEndpointIt.this.successCounter.incrementAndGet();
}
}
}
@Test
public void testMyWebService() throws InterruptedException,
ExecutionException {
final MockWebservice endpoint = new MockWebserviceImpl();
final JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
svrFactory.setServiceClass(MockWebservice.class);
svrFactory.setAddress("http://localhost:9000/myService");
svrFactory.setServiceBean(endpoint);
svrFactory.create();
svrFactory.getInInterceptors().add(new LoggingInInterceptor());
final Collection<Callable<Object>> clients = new
ArrayList<Callable<Object>>();
for (int i = 0; i < number_of_clients; i++) {
final int thread = i;
clients.add(new Callable<Object>() {
@Override
public Object call() throws Exception {
final MockWebservice client = createClient();
for (int i = 0; i < 1000; i++) {
final Event message = new Event();
final String id = Integer.valueOf(thread).toString() +
"-" + Integer.valueOf(i).toString() + " "
+ UUID.randomUUID().toString();
/*
* put the same string into the MAP and the FIELD
*/
message.map.put("expected", id);
message.expected = id;
message.map.put("thread", Integer.valueOf(thread));
message.map.put("i", Integer.valueOf(i));
message.thread = Integer.valueOf(thread).toString();
message.i = Integer.valueOf(i).toString();
client.doit(message);
}
return null;
}
});
}
for (final Future<Object> item :
Executors.newFixedThreadPool(number_of_clients).invokeAll(clients)) {
item.get();
}
System.out.println("bad: " + this.badCounter.get() + " success: " +
this.successCounter.get());
}
private MockWebservice createClient() {
final JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(MockWebservice.class);
factory.setAddress("http://localhost:9000/myService");
final MockWebservice client = (MockWebservice) factory.create();
return client;
}
}
{noformat}
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira