GH-145 send-timeout(-expression) and XSD for them
Fixes GH-145 (https://github.com/spring-projects/spring-integration-kafka/issues/145)
This commit is contained in:
@@ -67,6 +67,14 @@ public class KafkaOutboundChannelAdapterParser extends AbstractOutboundChannelAd
|
||||
kafkaProducerMessageHandlerBuilder.addPropertyValue("partitionIdExpression", partitionIdExpressionDef);
|
||||
}
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(kafkaProducerMessageHandlerBuilder, element, "sync");
|
||||
|
||||
BeanDefinition sendTimeoutExpressionDef =
|
||||
IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression("send-timeout",
|
||||
"send-timeout-expression", parserContext, element, false);
|
||||
if (sendTimeoutExpressionDef != null) {
|
||||
kafkaProducerMessageHandlerBuilder.addPropertyValue("sendTimeoutExpression", sendTimeoutExpressionDef);
|
||||
}
|
||||
|
||||
return kafkaProducerMessageHandlerBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.MessageTimeoutException;
|
||||
import org.springframework.integration.expression.ExpressionUtils;
|
||||
import org.springframework.integration.expression.ValueExpression;
|
||||
import org.springframework.integration.handler.AbstractMessageHandler;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.kafka.support.KafkaHeaders;
|
||||
@@ -60,7 +61,7 @@ public class KafkaProducerMessageHandler<K, V> extends AbstractMessageHandler {
|
||||
|
||||
private boolean sync;
|
||||
|
||||
private long sendTimeout = DEFAULT_SEND_TIMEOUT;
|
||||
private Expression sendTimeoutExpression = new ValueExpression<>(DEFAULT_SEND_TIMEOUT);
|
||||
|
||||
public KafkaProducerMessageHandler(final KafkaTemplate<K, V> kafkaTemplate) {
|
||||
Assert.notNull(kafkaTemplate, "kafkaTemplate cannot be null");
|
||||
@@ -95,12 +96,27 @@ public class KafkaProducerMessageHandler<K, V> extends AbstractMessageHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a timeout in milliseconds how long {@link KafkaProducerMessageHandler}
|
||||
* should wait wait for send operation results. Defaults to 10 seconds.
|
||||
* Specify a timeout in milliseconds for how long this
|
||||
* {@link KafkaProducerMessageHandler} should wait wait for send operation
|
||||
* results. Defaults to 10 seconds. The timeout is applied only in {@link #sync} mode.
|
||||
* @param sendTimeout the timeout to wait for result fo send operation.
|
||||
* @since 2.0.1
|
||||
*/
|
||||
public void setSendTimeout(long sendTimeout) {
|
||||
this.sendTimeout = sendTimeout;
|
||||
setSendTimeoutExpression(new ValueExpression<>(sendTimeout));
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a SpEL expression to evaluate a timeout in milliseconds for how long this
|
||||
* {@link KafkaProducerMessageHandler} should wait wait for send operation
|
||||
* results. Defaults to 10 seconds. The timeout is applied only in {@link #sync} mode.
|
||||
* @param sendTimeoutExpression the {@link Expression} for timeout to wait for result
|
||||
* fo send operation.
|
||||
* @since 2.1.1
|
||||
*/
|
||||
public void setSendTimeoutExpression(Expression sendTimeoutExpression) {
|
||||
Assert.notNull(sendTimeoutExpression, "'sendTimeoutExpression' must not be null");
|
||||
this.sendTimeoutExpression = sendTimeoutExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -149,12 +165,13 @@ public class KafkaProducerMessageHandler<K, V> extends AbstractMessageHandler {
|
||||
}
|
||||
}
|
||||
if (this.sync) {
|
||||
if (this.sendTimeout < 0) {
|
||||
Long sendTimeout = this.sendTimeoutExpression.getValue(this.evaluationContext, message, Long.class);
|
||||
if (sendTimeout == null || sendTimeout < 0) {
|
||||
future.get();
|
||||
}
|
||||
else {
|
||||
try {
|
||||
future.get(this.sendTimeout, TimeUnit.MILLISECONDS);
|
||||
future.get(sendTimeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (TimeoutException te) {
|
||||
throw new MessageTimeoutException(message, "Timeout waiting for response from KafkaProducer", te);
|
||||
|
||||
@@ -99,15 +99,37 @@
|
||||
<xsd:attribute name="sync">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies whether to block the sending thread until the producer
|
||||
callback has been invoked, indicating the broker has accepted the
|
||||
message (or an exception thrown if the send fails). Default: false.
|
||||
Specifies whether to block the sending thread until the producer
|
||||
callback has been invoked, indicating the broker has accepted the
|
||||
message (or an exception thrown if the send fails). Default: false.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:int xsd:boolean"/>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="send-timeout">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specifies a timeout in milliseconds for how long the 'KafkaProducerMessageHandler'
|
||||
should wait wait for send operation results. Defaults to 10 seconds.
|
||||
The timeout is applied only in 'sync' mode.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:int xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="send-timeout-expression">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specifies an expression that is evaluated to determine a timeout in milliseconds
|
||||
for how long the 'KafkaProducerMessageHandler'
|
||||
should wait wait for send operation results. Defaults to 10 seconds.
|
||||
The timeout is applied only in 'sync' mode.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="order">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-kafka="http://www.springframework.org/schema/integration/kafka"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration/kafka http://www.springframework.org/schema/integration/kafka/spring-integration-kafka.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<int:channel id="inputToKafka" />
|
||||
|
||||
@@ -18,7 +17,8 @@
|
||||
sync="true"
|
||||
topic="foo"
|
||||
message-key-expression="'bar'"
|
||||
partition-id-expression="'2'">
|
||||
partition-id-expression="'2'"
|
||||
send-timeout-expression="1000">
|
||||
<int-kafka:request-handler-advice-chain>
|
||||
<bean class="org.springframework.integration.handler.advice.RequestHandlerCircuitBreakerAdvice" />
|
||||
</int-kafka:request-handler-advice-chain>
|
||||
@@ -40,6 +40,7 @@
|
||||
kafka-template="template"
|
||||
auto-startup="false"
|
||||
channel="inputToKafka"
|
||||
partition-id="#{0}" />
|
||||
partition-id="#{0}"
|
||||
send-timeout="500" />
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -68,12 +68,15 @@ public class KafkaOutboundAdapterParserTests {
|
||||
assertThat(TestUtils.getPropertyValue(messageHandler, "messageKeyExpression.expression")).isEqualTo("'bar'");
|
||||
assertThat(TestUtils.getPropertyValue(messageHandler, "partitionIdExpression.expression")).isEqualTo("'2'");
|
||||
assertThat(TestUtils.getPropertyValue(messageHandler, "sync", Boolean.class)).isTrue();
|
||||
assertThat(TestUtils.getPropertyValue(messageHandler, "sendTimeoutExpression.expression")).isEqualTo("1000");
|
||||
|
||||
messageHandler
|
||||
= this.appContext.getBean("kafkaOutboundChannelAdapter2.handler", KafkaProducerMessageHandler.class);
|
||||
assertThat(messageHandler).isNotNull();
|
||||
assertThat(TestUtils.getPropertyValue(messageHandler, "partitionIdExpression.literalValue")).isEqualTo("0");
|
||||
assertThat(TestUtils.getPropertyValue(messageHandler, "sync", Boolean.class)).isFalse();
|
||||
|
||||
assertThat(TestUtils.getPropertyValue(messageHandler, "sendTimeoutExpression.literalValue")).isEqualTo("500");
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user