Return-Path: X-Original-To: apmail-camel-commits-archive@www.apache.org Delivered-To: apmail-camel-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 070D998FB for ; Wed, 11 Apr 2012 20:14:51 +0000 (UTC) Received: (qmail 84753 invoked by uid 500); 11 Apr 2012 20:14:50 -0000 Delivered-To: apmail-camel-commits-archive@camel.apache.org Received: (qmail 84725 invoked by uid 500); 11 Apr 2012 20:14:50 -0000 Mailing-List: contact commits-help@camel.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@camel.apache.org Delivered-To: mailing list commits@camel.apache.org Received: (qmail 84717 invoked by uid 99); 11 Apr 2012 20:14:50 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 11 Apr 2012 20:14:50 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 11 Apr 2012 20:14:47 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 8F181238899C; Wed, 11 Apr 2012 20:14:26 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1324973 - in /camel/branches/camel-2.9.x/components/camel-jaxb/src: main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java test/java/org/apache/camel/example/DataFormatConcurrentTest.java Date: Wed, 11 Apr 2012 20:14:26 -0000 To: commits@camel.apache.org From: cmueller@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120411201426.8F181238899C@eris.apache.org> Author: cmueller Date: Wed Apr 11 20:14:25 2012 New Revision: 1324973 URL: http://svn.apache.org/viewvc?rev=1324973&view=rev Log: CAMEL-3776: Add pooling support for JAXB data format Modified: camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java Modified: camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java?rev=1324973&r1=1324972&r2=1324973&view=diff ============================================================================== --- camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java (original) +++ camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java Wed Apr 11 20:14:25 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; @@ -55,9 +56,12 @@ import org.slf4j.LoggerFactory; public class FallbackTypeConverter implements TypeConverter, TypeConverterAware { private static final transient Logger LOG = LoggerFactory.getLogger(FallbackTypeConverter.class); private Map, JAXBContext> contexts = new HashMap, JAXBContext>(); + private Map, Unmarshaller> unmarshallers = new HashMap, Unmarshaller>(); private TypeConverter parentTypeConverter; private boolean prettyPrint = true; + private ReentrantLock unmarshallerLock = new ReentrantLock(); + public boolean isPrettyPrint() { return prettyPrint; } @@ -130,9 +134,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); @@ -192,6 +194,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)) { @@ -210,6 +213,7 @@ public class FallbackTypeConverter imple return unmarshaller.unmarshal((Source)value); } } finally { + unmarshallerLock.unlock(); if (value instanceof Closeable) { IOHelper.close((Closeable)value, "Unmarshalling", LOG); } @@ -231,4 +235,13 @@ public class FallbackTypeConverter imple return context; } + protected synchronized Unmarshaller getOrCreateUnmarshaller(Class 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.9.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java?rev=1324973&r1=1324972&r2=1324973&view=diff ============================================================================== --- camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java (original) +++ camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java Wed Apr 11 20:14:25 2012 @@ -60,6 +60,30 @@ public class DataFormatConcurrentTest ex } @Test + public void testUnmarshallFallbackConcurrent() throws Exception { + int counter = 10000; + final String payload = ""; + 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"); } }; }