This is an automated email from the ASF dual-hosted git repository.

klease pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 4bd5aa5  CAMEL-17866: fix CamelSqlGeneratedKeyRows issue. (#7300)
4bd5aa5 is described below

commit 4bd5aa5b7a15c3b59ea5ab4909b54a40274754da
Author: klease <[email protected]>
AuthorDate: Wed Mar 30 19:43:06 2022 +0200

    CAMEL-17866: fix CamelSqlGeneratedKeyRows issue. (#7300)
    
    CamelSqlGeneratedKeyRows is not populated if already exists because input
    headers were overwriting the new output header.
    Change code to set headers on input message instead of using deprecated
    getOut() method. Ensure that input body is set to null in case of 
EMPTY_RESULT
    on SelectOne queries.
---
 .../apache/camel/component/sql/SqlProducer.java    |  23 ++---
 .../component/sql/CamelSqlEmptyResultTest.java     |   4 +
 .../component/sql/SqlGeneratedKeysInLoopTest.java  | 113 +++++++++++++++++++++
 3 files changed, 126 insertions(+), 14 deletions(-)

diff --git 
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java
 
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java
index c34bac9..ca2840b 100644
--- 
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java
+++ 
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java
@@ -131,14 +131,10 @@ public class SqlProducer extends DefaultProducer {
         } else {
             data = processInternal(exchange, statementCreator, sql, 
preparedQuery, shouldRetrieveGeneratedKeys);
         }
-        exchange.getOut().getHeaders().putAll(exchange.getIn().getHeaders());
-        if (getEndpoint().isNoop() || getEndpoint().getOutputHeader() != null 
|| data == null) {
-            exchange.getOut().setBody(exchange.getIn().getBody());
-        }
         if (getEndpoint().getOutputHeader() != null) {
-            exchange.getOut().setHeader(getEndpoint().getOutputHeader(), data 
== EMPTY_RESULT ? null : data);
-        } else if (data != null && data != EMPTY_RESULT && 
!getEndpoint().isNoop()) {
-            exchange.getOut().setBody(data);
+            exchange.getIn().setHeader(getEndpoint().getOutputHeader(), data 
== EMPTY_RESULT ? null : data);
+        } else if (data != null && !getEndpoint().isNoop()) {
+            exchange.getIn().setBody(data == EMPTY_RESULT ? null : data);
         }
     }
 
@@ -184,22 +180,21 @@ public class SqlProducer extends DefaultProducer {
                             } else {
                                 throw new IllegalArgumentException("Invalid 
outputType=" + outputType);
                             }
-                            
exchange.getOut().setHeader(SqlConstants.SQL_ROW_COUNT, rowCount);
+                            
exchange.getIn().setHeader(SqlConstants.SQL_ROW_COUNT, rowCount);
                         } else {
-                            
exchange.getOut().setHeader(SqlConstants.SQL_UPDATE_COUNT, ps.getUpdateCount());
-                            
exchange.getOut().setBody(exchange.getIn().getBody());
+                            
exchange.getIn().setHeader(SqlConstants.SQL_UPDATE_COUNT, ps.getUpdateCount());
                         }
                     }
 
                     if (shouldRetrieveGeneratedKeys) {
                         if (isResultSet) {
                             // we won't return generated keys for SELECT 
statements
-                            
exchange.getOut().setHeader(SqlConstants.SQL_GENERATED_KEYS_DATA, 
Collections.EMPTY_LIST);
-                            
exchange.getOut().setHeader(SqlConstants.SQL_GENERATED_KEYS_ROW_COUNT, 0);
+                            
exchange.getIn().setHeader(SqlConstants.SQL_GENERATED_KEYS_DATA, 
Collections.EMPTY_LIST);
+                            
exchange.getIn().setHeader(SqlConstants.SQL_GENERATED_KEYS_ROW_COUNT, 0);
                         } else {
                             List<?> generatedKeys = 
getEndpoint().queryForList(ps.getGeneratedKeys(), false);
-                            
exchange.getOut().setHeader(SqlConstants.SQL_GENERATED_KEYS_DATA, 
generatedKeys);
-                            
exchange.getOut().setHeader(SqlConstants.SQL_GENERATED_KEYS_ROW_COUNT, 
generatedKeys.size());
+                            
exchange.getIn().setHeader(SqlConstants.SQL_GENERATED_KEYS_DATA, generatedKeys);
+                            
exchange.getIn().setHeader(SqlConstants.SQL_GENERATED_KEYS_ROW_COUNT, 
generatedKeys.size());
                         }
                     }
 
diff --git 
a/components/camel-sql/src/test/java/org/apache/camel/component/sql/CamelSqlEmptyResultTest.java
 
b/components/camel-sql/src/test/java/org/apache/camel/component/sql/CamelSqlEmptyResultTest.java
index 58c242f..a2fd450 100644
--- 
a/components/camel-sql/src/test/java/org/apache/camel/component/sql/CamelSqlEmptyResultTest.java
+++ 
b/components/camel-sql/src/test/java/org/apache/camel/component/sql/CamelSqlEmptyResultTest.java
@@ -27,6 +27,8 @@ import 
org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
 
+import static org.junit.jupiter.api.Assertions.assertNull;
+
 public class CamelSqlEmptyResultTest extends CamelTestSupport {
 
     private EmbeddedDatabase db;
@@ -62,6 +64,8 @@ public class CamelSqlEmptyResultTest extends CamelTestSupport 
{
         template.sendBody("seda:in", "");
 
         assertMockEndpointsSatisfied();
+        Object header = 
out.getReceivedExchanges().get(0).getIn().getHeader("PersonID");
+        assertNull(header, "PersonID header should be null");
     }
 
     @Override
diff --git 
a/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlGeneratedKeysInLoopTest.java
 
b/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlGeneratedKeysInLoopTest.java
new file mode 100644
index 0000000..d6183c7
--- /dev/null
+++ 
b/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlGeneratedKeysInLoopTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.sql;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class SqlGeneratedKeysInLoopTest extends CamelTestSupport {
+
+    private EmbeddedDatabase db;
+    private Exchange[] results = new Exchange[2];
+
+    @Override
+    @BeforeEach
+    public void setUp() throws Exception {
+        // Only HSQLDB seem to handle:
+        // - more than one generated column in row
+        // - return all keys generated in batch insert
+        db = new EmbeddedDatabaseBuilder()
+                
.setType(EmbeddedDatabaseType.HSQL).addScript("sql/createAndPopulateDatabase3.sql").build();
+
+        super.setUp();
+    }
+
+    @Override
+    @AfterEach
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        db.shutdown();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                getContext().getComponent("sql", 
SqlComponent.class).setDataSource(db);
+                from("direct:batchinloop").loop(2)
+                        .to("sql:insert into projects (project, license, 
description) values (#, #, #)?batch=true")
+                        .process(out -> {
+                            results[(Integer) 
out.getProperty(Exchange.LOOP_INDEX)] = out.copy();
+                        })
+                        .end();
+            }
+        };
+    }
+
+    @Test
+    public void testRetrieveGeneratedKeysForBatchInLoop() throws Exception {
+        // first we create our exchange using the endpoint
+        Endpoint endpoint = context.getEndpoint("direct:batchinloop");
+
+        Exchange exchange = endpoint.createExchange();
+        List<Object[]> payload = new ArrayList<>(4);
+        payload.add(new Object[] { "project 1", "ASF", "new project 1" });
+        payload.add(new Object[] { "project 2", "ASF", "new project 2" });
+        exchange.getIn().setBody(payload);
+        exchange.getIn().setHeader(SqlConstants.SQL_RETRIEVE_GENERATED_KEYS, 
true);
+
+        template.send(endpoint, exchange);
+        checkResults();
+    }
+
+    private void checkResults() {
+        for (int i = 0; i < results.length; i++) {
+            Exchange out = results[i];
+            int id = (Integer) out.getProperty(Exchange.LOOP_INDEX) * 2 + 3;
+            @SuppressWarnings("unchecked")
+            List<Map<String, Object>> generatedKeys
+                    = 
out.getMessage().getHeader(SqlConstants.SQL_GENERATED_KEYS_DATA, List.class);
+            assertNotNull(generatedKeys,
+                    "out body could not be converted to a List - was: " + 
out.getMessage().getBody());
+            assertEquals(2, generatedKeys.size());
+            for (Map<String, Object> row : generatedKeys) {
+                assertEquals(id++, row.get("ID"), "auto increment value should 
be " + (id - 1));
+            }
+            assertEquals(2, 
out.getMessage().getHeader(SqlConstants.SQL_GENERATED_KEYS_ROW_COUNT),
+                    "generated keys row count should be two");
+        }
+    }
+
+}

Reply via email to