Author: davsclaus
Date: Mon Jul 14 03:17:41 2008
New Revision: 676541

URL: http://svn.apache.org/viewvc?rev=676541&view=rev
Log:
CAMEL-702: A proposed fix for CAMEL-702. Gert will take a look too. Concurrency 
issue with camel-saon. WORK IN PROGRESS!!

Added:
    
activemq/camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryURLBasedConcurrencyTest.java
Modified:
    
activemq/camel/trunk/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
    
activemq/camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryConcurrencyTest.java
    
activemq/camel/trunk/components/camel-saxon/src/test/resources/log4j.properties

Modified: 
activemq/camel/trunk/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java?rev=676541&r1=676540&r2=676541&view=diff
==============================================================================
--- 
activemq/camel/trunk/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
 (original)
+++ 
activemq/camel/trunk/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
 Mon Jul 14 03:17:41 2008
@@ -30,8 +30,6 @@
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.atomic.AtomicBoolean;
 import javax.xml.transform.Result;
 import javax.xml.transform.Source;
 import javax.xml.transform.dom.DOMResult;
@@ -80,8 +78,6 @@
     private ResultFormat resultsFormat = ResultFormat.DOM;
     private Properties properties = new Properties();
     private Class resultType;
-    private final Semaphore lock = new Semaphore(1);
-    private final AtomicBoolean initialized = new AtomicBoolean(false);
 
     @Override
     public String toString() {
@@ -97,20 +93,10 @@
     }
 
     public Object evaluate(Exchange exchange) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Evaluation " + expression + " for exchange: " + 
exchange);
+        }
         try {
-            // handle concurrency issue when initializing, allow only one to 
initialize
-            if (!initialized.get()) {
-                try {
-                    lock.acquire();
-                    if (!initialized.get()) {
-                        initialize();
-                        initialized.set(true);
-                    }
-                } finally {
-                    lock.release();
-                }
-            }
-
             if (resultType != null) {
                 if (resultType.equals(String.class)) {
                     return evaluateAsString(exchange);
@@ -305,7 +291,7 @@
     // Properties
     // 
-------------------------------------------------------------------------
 
-    public XQueryExpression getExpression() throws IOException, XPathException 
{
+    public synchronized XQueryExpression getExpression() throws IOException, 
XPathException {
         if (expression == null) {
             expression = createQueryExpression(getStaticQueryContext());
             clearBuilderReferences();
@@ -313,7 +299,7 @@
         return expression;
     }
 
-    public Configuration getConfiguration() {
+    public synchronized Configuration getConfiguration() {
         if (configuration == null) {
             configuration = new Configuration();
             configuration.setHostLanguage(Configuration.XQUERY);
@@ -325,7 +311,7 @@
         this.configuration = configuration;
     }
 
-    public StaticQueryContext getStaticQueryContext() {
+    public synchronized StaticQueryContext getStaticQueryContext() {
         if (staticQueryContext == null) {
             staticQueryContext = new StaticQueryContext(getConfiguration());
             Set<Map.Entry<String, String>> entries = 
namespacePrefixes.entrySet();
@@ -441,17 +427,12 @@
      * been created lets nullify references here
      */
     protected void clearBuilderReferences() {
-        // TODO: These causes problems if we null them in concurrency 
environments
-        //staticQueryContext = null;
-        //configuration = null;
+        staticQueryContext = null;
+        configuration = null;
     }
 
     protected boolean matches(Exchange exchange, List results) {
         return ObjectHelper.matches(results);
     }
 
-    protected void initialize() throws XPathException, IOException {
-        getExpression();
-    }
-
 }

Modified: 
activemq/camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryConcurrencyTest.java
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryConcurrencyTest.java?rev=676541&r1=676540&r2=676541&view=diff
==============================================================================
--- 
activemq/camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryConcurrencyTest.java
 (original)
+++ 
activemq/camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryConcurrencyTest.java
 Mon Jul 14 03:17:41 2008
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.xquery;
 
+import java.util.Random;
+
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.builder.DeadLetterChannelBuilder;
 import org.apache.camel.builder.RouteBuilder;
@@ -43,8 +45,13 @@
                 public void run() {
                     int start = threadCount * 20;
                     for (int i = 0; i < 20; i++) {
-                        Object response = template.sendBody("seda:in",
-                            "<person id='" + (start + i) + "'>James</person>");
+                        try {
+                            // do some random sleep to simulate spread in user 
activity
+                            Thread.sleep(new Random().nextInt(100));
+                        } catch (InterruptedException e) {
+                            // ignore
+                        }
+                        template.sendBody("seda:in", "<person><id>" + (start + 
i) + "</id><name>James</name></person>");
                     }
                 }
             });
@@ -59,11 +66,11 @@
             public void configure() throws Exception {
                 // only retry at max 2 times to cather
                 // if set to 0 we can get interal Saxon errors - SENR0001
-                errorHandler(new 
DeadLetterChannelBuilder().maximumRedeliveries(2));
+                errorHandler(new 
DeadLetterChannelBuilder().maximumRedeliveries(1));
 
                 from("seda:in")
                     .thread(10)
-                    .transform().xquery("/person/@id", String.class)
+                    .transform().xquery("/person/id", String.class)
                     .to("mock:result");
             }
         };

Added: 
activemq/camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryURLBasedConcurrencyTest.java
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryURLBasedConcurrencyTest.java?rev=676541&view=auto
==============================================================================
--- 
activemq/camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryURLBasedConcurrencyTest.java
 (added)
+++ 
activemq/camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryURLBasedConcurrencyTest.java
 Mon Jul 14 03:17:41 2008
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.xquery;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.DeadLetterChannelBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+/**
+ * Concurrency test of XQuery.
+ */
+public class XQueryURLBasedConcurrencyTest extends ContextTestSupport {
+
+    // TODO: Work in progress
+
+    public void testConcurrency() throws Exception {
+        int total = 1;
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(total);
+
+        // setup a task executor to be able send the messages in parallel
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(5);
+        executor.afterPropertiesSet();
+        for (int i = 0; i < 1; i++) {
+            final int threadCount = i;
+            executor.execute(new Runnable() {
+                public void run() {
+                    int start = threadCount * 20;
+                    for (int i = 0; i < 1; i++) {
+                        template.sendBody("seda:in",
+                            "<mail><subject>" + (start + i) + 
"</subject><body>Hello world!</body></mail>");
+                    }
+                }
+            });
+        }
+
+        mock.assertIsSatisfied();
+        mock.assertNoDuplicates(body());
+    }
+
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                // only retry at max 2 times to cather
+                // if set to 0 we can get interal Saxon errors - SENR0001
+                errorHandler(new 
DeadLetterChannelBuilder().maximumRedeliveries(2));
+
+                from("seda:in")
+                    .thread(10)
+                    
.to("xquery:org/apache/camel/component/xquery/transform.xquery")
+                    .to("mock:result");
+            }
+        };
+    }
+}
\ No newline at end of file

Modified: 
activemq/camel/trunk/components/camel-saxon/src/test/resources/log4j.properties
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-saxon/src/test/resources/log4j.properties?rev=676541&r1=676540&r2=676541&view=diff
==============================================================================
--- 
activemq/camel/trunk/components/camel-saxon/src/test/resources/log4j.properties 
(original)
+++ 
activemq/camel/trunk/components/camel-saxon/src/test/resources/log4j.properties 
Mon Jul 14 03:17:41 2008
@@ -20,7 +20,7 @@
 #
 log4j.rootLogger=INFO, file
 
-#log4j.logger.org.apache.camel=DEBUG
+log4j.logger.org.apache.camel=DEBUG
 
 # CONSOLE appender not used by default
 log4j.appender.out=org.apache.log4j.ConsoleAppender


Reply via email to