You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by cm...@apache.org on 2012/04/11 22:55:51 UTC

svn commit: r1324998 - in /camel/branches/camel-2.8.x/components/camel-jaxb/src: main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java test/java/org/apache/camel/example/DataFormatConcurrentTest.java

Author: cmueller
Date: Wed Apr 11 20:55:51 2012
New Revision: 1324998

URL: http://svn.apache.org/viewvc?rev=1324998&view=rev
Log:
CAMEL-3776: Add pooling support for JAXB data format

Modified:
    camel/branches/camel-2.8.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java
    camel/branches/camel-2.8.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java

Modified: camel/branches/camel-2.8.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java?rev=1324998&r1=1324997&r2=1324998&view=diff
==============================================================================
--- camel/branches/camel-2.8.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java (original)
+++ camel/branches/camel-2.8.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java Wed Apr 11 20:55:51 2012
@@ -26,6 +26,7 @@ import java.io.UnsupportedEncodingExcept
 import java.io.Writer;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
@@ -56,9 +57,12 @@ import org.slf4j.LoggerFactory;
 public class FallbackTypeConverter implements TypeConverter, TypeConverterAware {
     private static final transient Logger LOG = LoggerFactory.getLogger(FallbackTypeConverter.class);
     private Map<Class<?>, JAXBContext> contexts = new HashMap<Class<?>, JAXBContext>();
+    private Map<Class<?>, Unmarshaller> unmarshallers = new HashMap<Class<?>, Unmarshaller>();
     private TypeConverter parentTypeConverter;
     private boolean prettyPrint = true;
 
+    private ReentrantLock unmarshallerLock = new ReentrantLock();
+
     public boolean isPrettyPrint() {
         return prettyPrint;
     }
@@ -131,9 +135,7 @@ public class FallbackTypeConverter imple
             throw new IllegalArgumentException("Cannot convert from null value to JAXBSource");
         }
 
-        JAXBContext context = createContext(type);
-        // must create a new instance of unmarshaller as its not thread safe
-        Unmarshaller unmarshaller = context.createUnmarshaller();
+        Unmarshaller unmarshaller = getOrCreateUnmarshaller(type);
 
         if (parentTypeConverter != null) {
             InputStream inputStream = parentTypeConverter.convertTo(InputStream.class, value);
@@ -193,6 +195,7 @@ public class FallbackTypeConverter imple
     }
 
     protected Object unmarshal(Unmarshaller unmarshaller, Exchange exchange, Object value) throws JAXBException, UnsupportedEncodingException {
+        unmarshallerLock.lock();
         try {
             if (value instanceof InputStream) {
                 if (needFiltering(exchange)) {
@@ -211,6 +214,7 @@ public class FallbackTypeConverter imple
                 return unmarshaller.unmarshal((Source)value);
             }
         } finally {
+            unmarshallerLock.unlock();
             if (value instanceof Closeable) {
                 IOHelper.close((Closeable)value, "Unmarshalling", LOG);
             }
@@ -232,4 +236,13 @@ public class FallbackTypeConverter imple
         return context;
     }
 
+    protected synchronized <T> Unmarshaller getOrCreateUnmarshaller(Class<T> type) throws JAXBException {
+        Unmarshaller unmarshaller = unmarshallers.get(type);
+        if (unmarshaller == null) {
+            JAXBContext context = createContext(type);
+            unmarshaller = context.createUnmarshaller();
+            unmarshallers.put(type, unmarshaller);
+        }
+        return unmarshaller;
+    }
 }

Modified: camel/branches/camel-2.8.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java?rev=1324998&r1=1324997&r2=1324998&view=diff
==============================================================================
--- camel/branches/camel-2.8.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java (original)
+++ camel/branches/camel-2.8.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java Wed Apr 11 20:55:51 2012
@@ -60,6 +60,30 @@ public class DataFormatConcurrentTest ex
     }
 
     @Test
+    public void testUnmarshallFallbackConcurrent() throws Exception {
+        int counter = 10000;
+        final String payload = "<purchaseOrder name='Wine' amount='123.45' price='2.22'/>";
+        final CountDownLatch latch = new CountDownLatch(counter);
+        template.setDefaultEndpointUri("direct:unmarshalFallback");
+
+        ExecutorService pool = Executors.newFixedThreadPool(20);
+        //long start = System.currentTimeMillis();
+        for (int i = 0; i < counter; i++) {
+            pool.execute(new Runnable() {
+                public void run() {
+                    template.sendBody(payload);
+                    latch.countDown();
+                }
+            });
+        }
+
+        // should finish on fast machines in less than 3 seconds
+        assertTrue(latch.await(10, TimeUnit.SECONDS));
+        //long end = System.currentTimeMillis();
+        //System.out.println("took " + (end - start) + "ms");
+    }
+
+    @Test
     public void testSendConcurrent() throws Exception {
         MockEndpoint mock = getMockEndpoint("mock:result");
         mock.expectedMessageCount(size);
@@ -103,6 +127,10 @@ public class DataFormatConcurrentTest ex
                 from("direct:unmarshal")
                         .unmarshal(jaxb)
                         .to("mock:result");
+
+                from("direct:unmarshalFallback")
+                        .convertBodyTo(PurchaseOrder.class)
+                        .to("mock:result");
             }
         };
     }