Repository: camel
Updated Branches:
  refs/heads/master f5614efb8 -> 5fc96ef45


CAMEL-9162: camel-elsql component


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/ed0f42a1
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/ed0f42a1
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/ed0f42a1

Branch: refs/heads/master
Commit: ed0f42a1434cda23b85a140a40a54bdf3ae0c8b5
Parents: 6cf9956
Author: Claus Ibsen <davscl...@apache.org>
Authored: Sun Oct 4 14:33:06 2015 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Mon Oct 5 10:54:53 2015 +0200

----------------------------------------------------------------------
 components/camel-elsql/pom.xml                  |  1 +
 .../camel/component/elsql/ElsqlComponent.java   | 55 +++++++------
 .../camel/component/elsql/ElsqlEndpoint.java    | 21 ++---
 .../camel/component/elsql/ElsqlProducer.java    | 19 +++--
 .../component/elsql/ElsqlSqlMapSource.java      | 54 +++++++++++++
 .../camel/component/elsql/ElsqlSqlParams.java   | 68 ----------------
 .../elsql/ElsqlSqlProcessingStrategy.java       |  6 +-
 .../component/elsql/ElSqlDataSourceTest.java    | 85 ++++++++++++++++++++
 .../src/test/resources/elsql/projects.elsql     |  5 ++
 .../src/test/resources/log4j.properties         | 39 +++++++++
 .../resources/sql/createAndPopulateDatabase.sql | 23 ++++++
 .../camel/component/sql/SqlComponent.java       |  4 +
 .../apache/camel/component/sql/SqlEndpoint.java | 73 ++++++++++-------
 13 files changed, 314 insertions(+), 139 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-elsql/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-elsql/pom.xml b/components/camel-elsql/pom.xml
index d82bb05..f45f7e6 100644
--- a/components/camel-elsql/pom.xml
+++ b/components/camel-elsql/pom.xml
@@ -34,6 +34,7 @@
       org.apache.camel.component.elsql.*;${camel.osgi.version}
     </camel.osgi.export.pkg>
     <camel.osgi.import.pkg>
+      org.apache.camel.component.sql.*,
       !org.apache.camel.component.elsql.*,
       ${camel.osgi.import.defaults},
       *

http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlComponent.java
----------------------------------------------------------------------
diff --git 
a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlComponent.java
 
b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlComponent.java
index ddea39d..40e6530 100644
--- 
a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlComponent.java
+++ 
b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlComponent.java
@@ -20,20 +20,20 @@ import java.util.Map;
 import javax.sql.DataSource;
 
 import com.opengamma.elsql.ElSqlConfig;
-import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
-import org.apache.camel.component.sql.SqlComponent;
+import org.apache.camel.impl.UriEndpointComponent;
 import org.apache.camel.util.CamelContextHelper;
 import org.apache.camel.util.IntrospectionSupport;
-import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 
-public class ElsqlComponent extends SqlComponent {
+public class ElsqlComponent extends UriEndpointComponent {
 
+    private DataSource dataSource;
     private ElSqlConfig elSqlConfig;
     private String resourceUri;
 
-    public ElsqlComponent(CamelContext context) {
-        super(context, ElsqlEndpoint.class);
+    public ElsqlComponent() {
+        super(ElsqlEndpoint.class);
     }
 
     @Override
@@ -57,12 +57,12 @@ public class ElsqlComponent extends SqlComponent {
             throw new IllegalArgumentException("DataSource must be 
configured");
         }
 
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(target);
+        NamedParameterJdbcTemplate jdbcTemplate = new 
NamedParameterJdbcTemplate(target);
         IntrospectionSupport.setProperties(jdbcTemplate, parameters, 
"template.");
 
         String elsqlName = remaining;
         String resUri = resourceUri;
-        String[] part = remaining.split("/");
+        String[] part = remaining.split(":");
         if (part.length == 2) {
             elsqlName = part[0];
             resUri = part[1];
@@ -104,6 +104,27 @@ public class ElsqlComponent extends SqlComponent {
         return endpoint;
     }
 
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        if (elSqlConfig == null) {
+            elSqlConfig = ElSqlConfig.DEFAULT;
+        }
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop();
+    }
+
+    public DataSource getDataSource() {
+        return dataSource;
+    }
+
+    /**
+     * Sets the DataSource to use to communicate with the database.
+     */
     public ElSqlConfig getElSqlConfig() {
         return elSqlConfig;
     }
@@ -126,22 +147,4 @@ public class ElsqlComponent extends SqlComponent {
         this.resourceUri = resourceUri;
     }
 
-    /**
-     * Sets the DataSource to use to communicate with the database.
-     */
-    @Override
-    public void setDataSource(DataSource dataSource) {
-        super.setDataSource(dataSource);
-    }
-
-    /**
-     * Sets whether to use placeholder and replace all placeholder characters 
with ? sign in the SQL queries.
-     * <p/>
-     * This option is default <tt>true</tt>
-     */
-    @Override
-    public void setUsePlaceholder(boolean usePlaceholder) {
-        super.setUsePlaceholder(usePlaceholder);
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlEndpoint.java
----------------------------------------------------------------------
diff --git 
a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlEndpoint.java
 
b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlEndpoint.java
index 8ef9845..9025d30 100644
--- 
a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlEndpoint.java
+++ 
b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlEndpoint.java
@@ -25,20 +25,19 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.component.sql.SqlEndpoint;
-import org.apache.camel.component.sql.SqlPrepareStatementStrategy;
-import org.apache.camel.component.sql.SqlProcessingStrategy;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriPath;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.ResourceHelper;
-import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 
-@UriEndpoint(scheme = "elsql", title = "SQL", syntax = 
"elsql:elsqlName/resourceUri", consumerClass = ElsqlConsumer.class, label = 
"database,sql")
+@UriEndpoint(scheme = "elsql", title = "SQL", syntax = 
"elsql:elsqlName:resourceUri", consumerClass = ElsqlConsumer.class, label = 
"database,sql")
 public class ElsqlEndpoint extends SqlEndpoint {
 
     private volatile ElSql elSql;
+    private NamedParameterJdbcTemplate jdbcTemplate;
 
     @UriPath
     @Metadata(required = "true")
@@ -48,18 +47,21 @@ public class ElsqlEndpoint extends SqlEndpoint {
     @UriParam
     private ElSqlConfig elSqlConfig;
 
-    public ElsqlEndpoint(String uri, Component component, JdbcTemplate 
jdbcTemplate, String elsqlName, String resourceUri) {
-        super(uri, component, jdbcTemplate, null);
+    public ElsqlEndpoint(String uri, Component component, 
NamedParameterJdbcTemplate jdbcTemplate, String elsqlName, String resourceUri) {
+        super(uri, component, null, null);
         this.elsqlName = elsqlName;
         this.resourceUri = resourceUri;
+        this.jdbcTemplate = jdbcTemplate;
     }
 
     @Override
     public Consumer createConsumer(Processor processor) throws Exception {
+        // TODO: must be named
+        /*
         SqlProcessingStrategy proStrategy = new 
ElsqlSqlProcessingStrategy(elsqlName, elSql);
         SqlPrepareStatementStrategy preStategy = new 
ElsqlSqlPrepareStatementStrategy();
 
-        ElsqlConsumer consumer = new ElsqlConsumer(this, processor, 
getJdbcTemplate(), elsqlName, preStategy, proStrategy);
+        ElsqlConsumer consumer = new ElsqlConsumer(this, processor, 
jdbcTemplate, elsqlName, preStategy, proStrategy);
         consumer.setMaxMessagesPerPoll(getMaxMessagesPerPoll());
         consumer.setOnConsume(getOnConsume());
         consumer.setOnConsumeFailed(getOnConsumeFailed());
@@ -70,11 +72,13 @@ public class ElsqlEndpoint extends SqlEndpoint {
         consumer.setRouteEmptyResultSet(isRouteEmptyResultSet());
         configureConsumer(consumer);
         return consumer;
+        */
+        return null;
     }
 
     @Override
     public Producer createProducer() throws Exception {
-        ElsqlProducer result = new ElsqlProducer(this, elSql, elsqlName, 
getJdbcTemplate());
+        ElsqlProducer result = new ElsqlProducer(this, elSql, elsqlName, 
jdbcTemplate);
         return result;
     }
 
@@ -86,7 +90,6 @@ public class ElsqlEndpoint extends SqlEndpoint {
         ObjectHelper.notNull(resourceUri, "resourceUri", this);
 
         URL url = 
ResourceHelper.resolveMandatoryResourceAsUrl(getCamelContext().getClassResolver(),
 resourceUri);
-
         elSql = ElSql.parse(elSqlConfig, url);
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlProducer.java
----------------------------------------------------------------------
diff --git 
a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlProducer.java
 
b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlProducer.java
index 73925d3..fa3f5df 100644
--- 
a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlProducer.java
+++ 
b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlProducer.java
@@ -22,14 +22,16 @@ import java.sql.SQLException;
 import java.util.List;
 
 import com.opengamma.elsql.ElSql;
+import com.opengamma.elsql.SpringSqlParams;
 import org.apache.camel.Exchange;
 import org.apache.camel.component.sql.SqlConstants;
 import org.apache.camel.component.sql.SqlEndpoint;
 import org.apache.camel.component.sql.SqlOutputType;
 import org.apache.camel.impl.DefaultProducer;
 import org.springframework.dao.DataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.core.PreparedStatementCallback;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
+import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 
 import static org.springframework.jdbc.support.JdbcUtils.closeResultSet;
 
@@ -37,9 +39,9 @@ public class ElsqlProducer extends DefaultProducer {
 
     private final ElSql elSql;
     private final String elSqlName;
-    private final JdbcTemplate jdbcTemplate;
+    private final NamedParameterJdbcTemplate jdbcTemplate;
 
-    public ElsqlProducer(SqlEndpoint endpoint, ElSql elSql, String elSqlName, 
JdbcTemplate jdbcTemplate) {
+    public ElsqlProducer(SqlEndpoint endpoint, ElSql elSql, String elSqlName, 
NamedParameterJdbcTemplate jdbcTemplate) {
         super(endpoint);
         this.elSql = elSql;
         this.elSqlName = elSqlName;
@@ -55,19 +57,22 @@ public class ElsqlProducer extends DefaultProducer {
     public void process(final Exchange exchange) throws Exception {
         Object data = exchange.getIn().getBody();
 
-        final String sql = elSql.getSql(elSqlName, new 
ElsqlSqlParams(exchange, data));
+        final SqlParameterSource param = new ElsqlSqlMapSource(exchange, data);
+        final String sql = elSql.getSql(elSqlName, new SpringSqlParams(param));
+        log.debug("ElSql @{} using sql: {}", elSqlName, sql);
 
-        jdbcTemplate.execute(sql, new PreparedStatementCallback<Object>() {
+        jdbcTemplate.execute(sql, param, new 
PreparedStatementCallback<Object>() {
             @Override
             public Object doInPreparedStatement(PreparedStatement ps) throws 
SQLException, DataAccessException {
                 ResultSet rs = null;
                 try {
                     boolean isResultSet = ps.execute();
                     if (isResultSet) {
+                        rs = ps.getResultSet();
+
                         // preserve headers first, so we can override the 
SQL_ROW_COUNT header
                         
exchange.getOut().getHeaders().putAll(exchange.getIn().getHeaders());
 
-                        rs = ps.getResultSet();
                         SqlOutputType outputType = 
getEndpoint().getOutputType();
                         log.trace("Got result list from query: {}, 
outputType={}", rs, outputType);
                         if (outputType == SqlOutputType.SelectList) {
@@ -99,8 +104,6 @@ public class ElsqlProducer extends DefaultProducer {
                         } else {
                             throw new IllegalArgumentException("Invalid 
outputType=" + outputType);
                         }
-                    } else {
-                        
exchange.getIn().setHeader(SqlConstants.SQL_UPDATE_COUNT, ps.getUpdateCount());
                     }
                 } finally {
                     closeResultSet(rs);

http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlMapSource.java
----------------------------------------------------------------------
diff --git 
a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlMapSource.java
 
b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlMapSource.java
new file mode 100644
index 0000000..e8035b0
--- /dev/null
+++ 
b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlMapSource.java
@@ -0,0 +1,54 @@
+/**
+ * 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.elsql;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.camel.Exchange;
+import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
+
+public class ElsqlSqlMapSource extends MapSqlParameterSource {
+
+    private final Exchange exchange;
+    private final Map<?, ?> bodyMap;
+    private final Map<?, ?> headersMap;
+
+    public ElsqlSqlMapSource(Exchange exchange, Object body) {
+        this.exchange = exchange;
+        this.bodyMap = 
safeMap(exchange.getContext().getTypeConverter().tryConvertTo(Map.class, body));
+        this.headersMap = safeMap(exchange.getIn().getHeaders());
+
+        addValue("body", body);
+
+        for (Map.Entry<?, ?> entry : bodyMap.entrySet()) {
+            String name = entry.getKey().toString();
+            Object value = entry.getValue();
+            addValue(name, value);
+        }
+        for (Map.Entry<?, ?> entry : headersMap.entrySet()) {
+            String name = entry.getKey().toString();
+            Object value = entry.getValue();
+            addValue(name, value);
+        }
+    }
+
+    private static Map<?, ?> safeMap(Map<?, ?> map) {
+        return (map == null || map.isEmpty()) ? Collections.emptyMap() : map;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlParams.java
----------------------------------------------------------------------
diff --git 
a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlParams.java
 
b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlParams.java
deleted file mode 100644
index 6822e8b..0000000
--- 
a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlParams.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * 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.elsql;
-
-import java.util.Collections;
-import java.util.Map;
-
-import com.opengamma.elsql.SqlParams;
-import org.apache.camel.Exchange;
-import org.apache.camel.language.simple.SimpleLanguage;
-
-public class ElsqlSqlParams implements SqlParams {
-
-    private final Exchange exchange;
-    private final Map<?, ?> bodyMap;
-    private final Map<?, ?> headersMap;
-
-    public ElsqlSqlParams(Exchange exchange, Object body) {
-        this.exchange = exchange;
-        this.bodyMap = 
safeMap(exchange.getContext().getTypeConverter().tryConvertTo(Map.class, body));
-        this.headersMap = safeMap(exchange.getIn().getHeaders());
-    }
-
-    private static Map<?, ?> safeMap(Map<?, ?> map) {
-        return (map == null || map.isEmpty()) ? Collections.emptyMap() : map;
-    }
-
-    @Override
-    public boolean contains(String variable) {
-        if (variable.startsWith("${") && variable.endsWith("}")) {
-            return SimpleLanguage.expression(variable).evaluate(exchange, 
Object.class) != null;
-        } else if (bodyMap.containsKey(variable)) {
-            return true;
-        } else if (headersMap.containsKey(variable)) {
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public Object get(String variable) {
-        if (variable.startsWith("${") && variable.endsWith("}")) {
-            return SimpleLanguage.expression(variable).evaluate(exchange, 
Object.class) != null;
-        } else if (bodyMap.containsKey(variable)) {
-            return bodyMap.get(variable);
-        } else if (headersMap.containsKey(variable)) {
-            return headersMap.get(variable);
-        }
-
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlProcessingStrategy.java
----------------------------------------------------------------------
diff --git 
a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlProcessingStrategy.java
 
b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlProcessingStrategy.java
index d22c33e..1134088 100644
--- 
a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlProcessingStrategy.java
+++ 
b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlSqlProcessingStrategy.java
@@ -20,6 +20,7 @@ import java.sql.PreparedStatement;
 import java.sql.SQLException;
 
 import com.opengamma.elsql.ElSql;
+import com.opengamma.elsql.SpringSqlParams;
 import org.apache.camel.Exchange;
 import org.apache.camel.component.sql.SqlEndpoint;
 import org.apache.camel.component.sql.SqlProcessingStrategy;
@@ -28,6 +29,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.dao.DataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.core.PreparedStatementCallback;
+import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 
 public class ElsqlSqlProcessingStrategy implements SqlProcessingStrategy {
 
@@ -42,7 +44,9 @@ public class ElsqlSqlProcessingStrategy implements 
SqlProcessingStrategy {
 
     @Override
     public int commit(final SqlEndpoint endpoint, final Exchange exchange, 
final Object data, final JdbcTemplate jdbcTemplate, final String query) throws 
Exception {
-        String sql = elSql.getSql(elSqlName, new ElsqlSqlParams(exchange, 
data));
+        final SqlParameterSource param = new ElsqlSqlMapSource(exchange, data);
+        final String sql = elSql.getSql(elSqlName, new SpringSqlParams(param));
+        LOG.debug("ElSql @{} using sql: {}", elSqlName, sql);
 
         return jdbcTemplate.execute(sql, new 
PreparedStatementCallback<Integer>() {
             @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-elsql/src/test/java/org/apache/camel/component/elsql/ElSqlDataSourceTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-elsql/src/test/java/org/apache/camel/component/elsql/ElSqlDataSourceTest.java
 
b/components/camel-elsql/src/test/java/org/apache/camel/component/elsql/ElSqlDataSourceTest.java
new file mode 100644
index 0000000..858daf4
--- /dev/null
+++ 
b/components/camel-elsql/src/test/java/org/apache/camel/component/elsql/ElSqlDataSourceTest.java
@@ -0,0 +1,85 @@
+/**
+ * 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.elsql;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.After;
+import org.junit.Test;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+
+public class ElSqlDataSourceTest extends CamelTestSupport {
+
+    private EmbeddedDatabase db;
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry jndi = super.createRegistry();
+
+        // this is the database we create with some initial data for our unit 
test
+        db = new EmbeddedDatabaseBuilder()
+                
.setType(EmbeddedDatabaseType.DERBY).addScript("sql/createAndPopulateDatabase.sql").build();
+
+        jndi.bind("dataSource", db);
+
+        return jndi;
+    }
+
+    @Test
+    public void testSimpleBody() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+
+        template.sendBody("direct:simple", "XXX");
+
+        mock.assertIsSatisfied();
+
+        // the result is a List
+        List<?> received = assertIsInstanceOf(List.class, 
mock.getReceivedExchanges().get(0).getIn().getBody());
+
+        // and each row in the list is a Map
+        Map<?, ?> row = assertIsInstanceOf(Map.class, received.get(0));
+
+        // and we should be able the get the project from the map that should 
be Linux
+        assertEquals("Linux", row.get("PROJECT"));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        db.shutdown();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:simple")
+                        
.to("elsql:projects:elsql/projects.elsql?dataSource=dataSource")
+                        .to("mock:result");
+            }
+        };
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-elsql/src/test/resources/elsql/projects.elsql
----------------------------------------------------------------------
diff --git a/components/camel-elsql/src/test/resources/elsql/projects.elsql 
b/components/camel-elsql/src/test/resources/elsql/projects.elsql
new file mode 100644
index 0000000..75dfe51
--- /dev/null
+++ b/components/camel-elsql/src/test/resources/elsql/projects.elsql
@@ -0,0 +1,5 @@
+@NAME(projects)
+  SELECT *
+  FROM projects
+  WHERE license = :body
+  ORDER BY id

http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-elsql/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/components/camel-elsql/src/test/resources/log4j.properties 
b/components/camel-elsql/src/test/resources/log4j.properties
new file mode 100755
index 0000000..d5af410
--- /dev/null
+++ b/components/camel-elsql/src/test/resources/log4j.properties
@@ -0,0 +1,39 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
+
+#
+# The logging properties used for testing
+#
+log4j.rootLogger=INFO, out
+
+#log4j.logger.org.apache.camel.component.sql=DEBUG
+#log4j.logger.org.apache.camel.component.sql=TRACE
+log4j.logger.org.apache.camel.component.elsql=DEBUG
+#log4j.logger.org.apache.camel.component.elsql=TRACE
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - 
%m%n
+
+# File appender
+log4j.appender.file=org.apache.log4j.FileAppender
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - 
%m%n
+log4j.appender.file.file=target/camel-elsql-test.log
+log4j.appender.file.append=true

http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-elsql/src/test/resources/sql/createAndPopulateDatabase.sql
----------------------------------------------------------------------
diff --git 
a/components/camel-elsql/src/test/resources/sql/createAndPopulateDatabase.sql 
b/components/camel-elsql/src/test/resources/sql/createAndPopulateDatabase.sql
new file mode 100644
index 0000000..65206c2
--- /dev/null
+++ 
b/components/camel-elsql/src/test/resources/sql/createAndPopulateDatabase.sql
@@ -0,0 +1,23 @@
+-- ------------------------------------------------------------------------
+-- 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.
+-- ------------------------------------------------------------------------
+
+-- START SNIPPET: e1
+create table projects (id integer primary key, project varchar(10), license 
varchar(5));
+insert into projects values (1, 'Camel', 'ASF');
+insert into projects values (2, 'AMQ', 'ASF');
+insert into projects values (3, 'Linux', 'XXX');
+-- END SNIPPET: e1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java
----------------------------------------------------------------------
diff --git 
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java
 
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java
index 1d9ada5..7236392 100755
--- 
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java
+++ 
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java
@@ -41,6 +41,10 @@ public class SqlComponent extends UriEndpointComponent {
         super(SqlEndpoint.class);
     }
 
+    public SqlComponent(Class<? extends Endpoint> endpointClass) {
+        super(endpointClass);
+    }
+
     public SqlComponent(CamelContext context) {
         super(context, SqlEndpoint.class);
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/ed0f42a1/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
----------------------------------------------------------------------
diff --git 
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
 
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
index af0d4ad..761c125 100644
--- 
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
+++ 
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
@@ -49,52 +49,73 @@ import 
org.springframework.jdbc.core.RowMapperResultSetExtractor;
 public class SqlEndpoint extends DefaultPollingEndpoint {
     private JdbcTemplate jdbcTemplate;
 
-    @UriPath @Metadata(required = "true")
+    @UriPath(description = "Sets the SQL query to perform") @Metadata(required 
= "true")
+
     private String query;
-    @UriParam
+    @UriParam(description = "Sets the reference to a DataSource to lookup from 
the registry, to use for communicating with the database.")
     @Deprecated
     private String dataSourceRef;
-    @UriParam
+    @UriParam(description = "Sets the DataSource to use to communicate with 
the database.")
     private DataSource dataSource;
-    @UriParam(label = "producer")
+    @UriParam(label = "producer", description = "Enables or disables batch 
mode")
     private boolean batch;
-    @UriParam(label = "consumer")
+    @UriParam(label = "consumer", description = "Sets the maximum number of 
messages to poll")
     private int maxMessagesPerPoll;
-    @UriParam(label = "consumer,advanced")
+    @UriParam(label = "consumer,advanced",
+            description = "Allows to plugin to use a custom 
org.apache.camel.component.sql.SqlProcessingStrategy to execute queries when 
the consumer has processed the rows/batch.")
     private SqlProcessingStrategy processingStrategy;
-    @UriParam(label = "advanced")
+    @UriParam(label = "advanced",
+            description = "Allows to plugin to use a custom 
org.apache.camel.component.sql.SqlPrepareStatementStrategy to control 
preparation of the query and prepared statement.")
     private SqlPrepareStatementStrategy prepareStatementStrategy;
-    @UriParam(label = "consumer")
+    @UriParam(label = "consumer",
+            description = "After processing each row then this query can be 
executed, if the Exchange was processed successfully, for example to mark the 
row as processed. The query can have parameter.")
     private String onConsume;
-    @UriParam(label = "consumer")
+    @UriParam(label = "consumer",
+            description = "After processing each row then this query can be 
executed, if the Exchange failed, for example to mark the row as failed. The 
query can have parameter.")
     private String onConsumeFailed;
-    @UriParam(label = "consumer")
+    @UriParam(label = "consumer",
+            description = "After processing the entire batch, this query can 
be executed to bulk update rows etc. The query cannot have parameters.")
     private String onConsumeBatchComplete;
-    @UriParam(label = "consumer", defaultValue = "true")
+    @UriParam(label = "consumer", defaultValue = "true",
+            description = "Sets how resultset should be delivered to route. 
Indicates delivery as either a list or individual object. defaults to true.")
     private boolean useIterator = true;
-    @UriParam(label = "consumer")
+    @UriParam(label = "consumer",
+            description = "Sets whether empty resultset should be allowed to 
be sent to the next hop. Defaults to false. So the empty resultset will be 
filtered out.")
     private boolean routeEmptyResultSet;
-    @UriParam(label = "consumer", defaultValue = "-1")
+    @UriParam(label = "consumer", defaultValue = "-1", description = "Sets an 
expected update count to validate when using onConsume.")
     private int expectedUpdateCount = -1;
-    @UriParam(label = "consumer")
+    @UriParam(label = "consumer", description = "Sets whether to break batch 
if onConsume failed.")
     private boolean breakBatchOnConsumeFail;
-    @UriParam(defaultValue = "true")
+    @UriParam(defaultValue = "true", description = "Whether to allow using 
named parameters in the queries.")
     private boolean allowNamedParameters = true;
-    @UriParam(label = "producer,advanced")
+    @UriParam(label = "producer,advanced",
+            description = "If enabled then the populateStatement method from 
org.apache.camel.component.sql.SqlPrepareStatementStrategy is always invoked, "
+                    + "also if there is no expected parameters to be prepared. 
When this is false then the populateStatement is only invoked if there is 1"
+                    + " or more expected parameters to be set; for example 
this avoids reading the message body/headers for SQL queries with no 
parameters.")
     private boolean alwaysPopulateStatement;
-    @UriParam(defaultValue = ",")
+    @UriParam(defaultValue = ",",
+            description = "The separator to use when parameter values is taken 
from message body (if the body is a String type), to be inserted at # 
placeholders."
+            + "Notice if you use named parameters, then a Map type is used 
instead. The default value is ,")
     private char separator = ',';
-    @UriParam(defaultValue = "SelectList")
+    @UriParam(defaultValue = "SelectList", description = "Make the output of 
consumer or producer to SelectList as List of Map, or SelectOne as single Java 
object in the following way:"
+            + "a) If the query has only single column, then that JDBC Column 
object is returned. (such as SELECT COUNT( * ) FROM PROJECT will return a Long 
object."
+            + "b) If the query has more than one column, then it will return a 
Map of that result."
+            + "c) If the outputClass is set, then it will convert the query 
result into an Java bean object by calling all the setters that match the 
column names."
+            + "It will assume your class has a default constructor to create 
instance with."
+            + "d) If the query resulted in more than one rows, it throws an 
non-unique result exception.")
     private SqlOutputType outputType = SqlOutputType.SelectList;
-    @UriParam
+    @UriParam(description = "Specify the full package and class name to use as 
conversion when outputType=SelectOne.")
     private String outputClass;
-    @UriParam(label = "producer,advanced")
+    @UriParam(label = "producer,advanced", description = "If set greater than 
zero, then Camel will use this count value of parameters to replace instead of"
+            + " querying via JDBC metadata API. This is useful if the JDBC 
vendor could not return correct parameters count, then user may override 
instead.")
     private int parametersCount;
-    @UriParam(label = "producer")
+    @UriParam(label = "producer", description = "If set, will ignore the 
results of the SQL query and use the existing IN message as the OUT message for 
the continuation of processing")
     private boolean noop;
-    @UriParam
+    @UriParam(description = "Store the query result in a header instead of the 
message body. By default, outputHeader == null and the query result is stored"
+            + " in the message body, any existing content in the message body 
is discarded. If outputHeader is set, the value is used as the name of the 
header"
+            + " to store the query result and the original message body is 
preserved.")
     private String outputHeader;
-    @UriParam(label = "producer")
+    @UriParam(label = "producer", description = "Whether to use the message 
body as the SQL and then headers for parameters. If this option is enabled then 
the SQL in the uri is not used.")
     private boolean useMessageBodyForSql;
 
     public SqlEndpoint() {
@@ -372,9 +393,7 @@ public class SqlEndpoint extends DefaultPollingEndpoint {
     }
 
     /**
-     * Sets how resultset should be delivered to route.
-     * Indicates delivery as either a list or individual object.
-     * defaults to true.
+     * Sets how resultset should be delivered to route. Indicates delivery as 
either a list or individual object. defaults to true.
      */
     public void setUseIterator(boolean useIterator) {
         this.useIterator = useIterator;
@@ -386,7 +405,7 @@ public class SqlEndpoint extends DefaultPollingEndpoint {
 
     /**
      * Sets whether empty resultset should be allowed to be sent to the next 
hop.
-     * defaults to false. So the empty resultset will be filtered out.
+     * Defaults to false. So the empty resultset will be filtered out.
      */
     public void setRouteEmptyResultSet(boolean routeEmptyResultSet) {
         this.routeEmptyResultSet = routeEmptyResultSet;

Reply via email to