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

Reply via email to