INT-4559: JDBC Gateway: return List for maxRows>1
JIRA: https://jira.spring.io/browse/INT-4559 * Return a single item from result only if `maxRows == null || maxRows == 1` * Remove deprecated `max-rows-per-poll` from the `JdbcOutboundGateway.java` and its XSD and parsers
This commit is contained in:
committed by
Gary Russell
parent
1d54f9663a
commit
aa075439fc
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
@@ -89,24 +90,12 @@ public class JdbcOutboundGateway extends AbstractReplyProducingMessageHandler im
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of rows to pull out of the query results per poll (if
|
||||
* greater than zero, otherwise all rows will be packed into the outgoing message).
|
||||
* The value is ultimately set on the underlying {@link JdbcPollingChannelAdapter}.
|
||||
* If not specified this value will default to {@code 1}.
|
||||
* This parameter is only applicable if a selectQuery was provided. Null values
|
||||
* are not permitted.
|
||||
* @param maxRowsPerPoll the number of rows to select. Must not be null.
|
||||
* @deprecated since 5.1 in favor of {@link #setMaxRows(Integer)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setMaxRowsPerPoll(Integer maxRowsPerPoll) {
|
||||
setMaxRows(maxRowsPerPoll);
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of rows to query.
|
||||
* The value is ultimately set on the underlying {@link JdbcPollingChannelAdapter}.
|
||||
* The value is set on the underlying {@link JdbcPollingChannelAdapter}.
|
||||
* Also used to check before producing reply:
|
||||
* if result has only one item and {@code maxRows} is not set or configured to {@code 1},
|
||||
* only that item is returned. Otherwise the whole list.
|
||||
* If not specified this value will default to {@code 1}.
|
||||
* This parameter is only applicable if a selectQuery was provided. Null values
|
||||
* are not permitted.
|
||||
@@ -159,32 +148,29 @@ public class JdbcOutboundGateway extends AbstractReplyProducingMessageHandler im
|
||||
this.poller.setMaxRows(this.maxRows);
|
||||
}
|
||||
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
if (this.handler != null) {
|
||||
this.handler.setBeanFactory(this.getBeanFactory());
|
||||
this.handler.setBeanFactory(beanFactory);
|
||||
this.handler.afterPropertiesSet();
|
||||
}
|
||||
|
||||
if (!this.sqlParameterSourceFactorySet && this.getBeanFactory() != null) {
|
||||
if (!this.sqlParameterSourceFactorySet && beanFactory != null) {
|
||||
((ExpressionEvaluatingSqlParameterSourceFactory) this.sqlParameterSourceFactory)
|
||||
.setBeanFactory(this.getBeanFactory());
|
||||
.setBeanFactory(beanFactory);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object handleRequestMessage(Message<?> requestMessage) {
|
||||
|
||||
List<?> list;
|
||||
List<?> list = Collections.emptyList();
|
||||
|
||||
if (this.handler != null) {
|
||||
list = this.handler.executeUpdateQuery(requestMessage, this.keysGenerated);
|
||||
}
|
||||
else {
|
||||
list = Collections.emptyList();
|
||||
}
|
||||
|
||||
if (this.poller != null) {
|
||||
SqlParameterSource sqlQueryParameterSource = this.sqlParameterSourceFactory
|
||||
.createParameterSource(requestMessage);
|
||||
SqlParameterSource sqlQueryParameterSource =
|
||||
this.sqlParameterSourceFactory.createParameterSource(requestMessage);
|
||||
if (this.keysGenerated) {
|
||||
if (!list.isEmpty()) {
|
||||
if (list.size() == 1) {
|
||||
@@ -196,15 +182,12 @@ public class JdbcOutboundGateway extends AbstractReplyProducingMessageHandler im
|
||||
}
|
||||
}
|
||||
list = this.poller.doPoll(sqlQueryParameterSource);
|
||||
if (list.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Object payload = list;
|
||||
if (list.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (list.size() == 1) {
|
||||
if (list.size() == 1 && (this.maxRows == null || this.maxRows == 1)) {
|
||||
payload = list.get(0);
|
||||
}
|
||||
return payload;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -71,24 +71,6 @@ public class JdbcOutboundGatewayParser extends AbstractConsumerEndpointParser {
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element,
|
||||
"request-prepared-statement-setter");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "row-mapper");
|
||||
|
||||
|
||||
// TODO remove deprecated option in the next version
|
||||
boolean hasMaxRowsPerPoll = element.hasAttribute("max-rows-per-poll");
|
||||
boolean hasMaxRows = element.hasAttribute("max-rows");
|
||||
|
||||
if (hasMaxRowsPerPoll) {
|
||||
parserContext.getReaderContext()
|
||||
.warning("The 'max-rows-per-poll' is deprecated in favor of 'max-rows'", element);
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "max-rows-per-poll");
|
||||
|
||||
if (hasMaxRows) {
|
||||
parserContext.getReaderContext()
|
||||
.warning("The 'max-rows' has a precedence over 'max-rows-per-poll'", element);
|
||||
}
|
||||
}
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "max-rows");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "keys-generated");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout", "sendTimeout");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -74,25 +74,7 @@ public class JdbcPollingChannelAdapterParser extends AbstractPollingInboundChann
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "row-mapper");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "update-sql-parameter-source-factory");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "select-sql-parameter-source");
|
||||
|
||||
// TODO remove deprecated option in the next version
|
||||
boolean hasMaxRowsPerPoll = element.hasAttribute("max-rows-per-poll");
|
||||
boolean hasMaxRows = element.hasAttribute("max-rows");
|
||||
|
||||
if (hasMaxRowsPerPoll) {
|
||||
parserContext.getReaderContext()
|
||||
.warning("The 'max-rows-per-poll' is deprecated in favor of 'max-rows'", element);
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "max-rows-per-poll");
|
||||
|
||||
if (hasMaxRows) {
|
||||
parserContext.getReaderContext()
|
||||
.warning("The 'max-rows' has a precedence over 'max-rows-per-poll'", element);
|
||||
}
|
||||
}
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "max-rows");
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "update", "updateSql");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "update-per-row");
|
||||
|
||||
|
||||
@@ -367,18 +367,6 @@
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="max-rows-per-poll" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
[DEPRECATED] When using a select query, you can set a
|
||||
custom limit regarding the number of rows
|
||||
extracted. Otherwise by default only the first
|
||||
row will be extracted into the outgoing message.
|
||||
If set to '0' all rows are extracted.
|
||||
Deprecated since 5.1 in favor of 'max-rows'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="max-rows" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
|
||||
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.verify;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
@@ -222,7 +223,7 @@ public class JdbcOutboundGatewayParserTests {
|
||||
|
||||
accessor = new DirectFieldAccessor(messagingTemplate);
|
||||
|
||||
Long sendTimeout = (Long) accessor.getPropertyValue("sendTimeout");
|
||||
Long sendTimeout = (Long) accessor.getPropertyValue("sendTimeout");
|
||||
assertThat(sendTimeout).as("Wrong sendTimeout").isEqualTo(Long.valueOf(444L));
|
||||
|
||||
}
|
||||
@@ -258,7 +259,8 @@ public class JdbcOutboundGatewayParserTests {
|
||||
assertThat(maxRowsPerPoll).as("maxRowsPerPoll should default to 10").isEqualTo(Integer.valueOf(10));
|
||||
}
|
||||
|
||||
@Test //INT-1029
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testOutboundGatewayInsideChain() {
|
||||
setUp("handlingMapPayloadJdbcOutboundGatewayTest.xml", getClass());
|
||||
|
||||
@@ -274,10 +276,18 @@ public class JdbcOutboundGatewayParserTests {
|
||||
|
||||
PollableChannel outbound = this.context.getBean("replyChannel", PollableChannel.class);
|
||||
Message<?> reply = outbound.receive(10000);
|
||||
assertThat(reply).isNotNull();
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, ?> payload = (Map<String, ?>) reply.getPayload();
|
||||
assertThat(payload.get("name")).isEqualTo("bar");
|
||||
|
||||
|
||||
assertThat(reply)
|
||||
.isNotNull()
|
||||
.extracting(Message::getPayload)
|
||||
.isInstanceOf(List.class)
|
||||
.asList()
|
||||
.hasSize(1)
|
||||
.element(0)
|
||||
.isInstanceOf(Map.class)
|
||||
.satisfies(map -> assertThat((Map<String, String>) map)
|
||||
.containsEntry("name", "bar"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<si:chain input-channel="jdbcOutboundGatewayInsideChain" output-channel="replyChannel">
|
||||
<outbound-gateway id="jdbc-outbound-gateway-within-chain" query="select * from foos where id=:headers[id]"
|
||||
update="insert into foos (id, status, name) values (:headers[id], 0, :payload[foo])"
|
||||
max-rows="2"
|
||||
data-source="dataSource" requires-reply="false"/>
|
||||
|
||||
</si:chain>
|
||||
|
||||
Reference in New Issue
Block a user