From 769b5039b6d2eb5bdfd8459e42171ffebbc3668c Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Thu, 7 Oct 2021 17:19:51 -0400 Subject: [PATCH 1/2] Fix Integration `fixedRate` property setting The `spring.integration.poller.fixed-rate` property must be set to the constructor of the `PeriodicTrigger` and its `fixedRate` flag should be set to `true`. The current code-base has it exactly opposite: the flag is set to `true` when `fixed-delay` is provided. * Fix `IntegrationAutoConfiguration.asTrigger()` method for the proper `fixedRate` setting logic. * Cover the change with a new test-case * Add a message handling verification to the `defaultPoller()` test to be sure that poller auto-configuration works as it is claimed. See gh-28237 --- .../IntegrationAutoConfiguration.java | 4 ++-- .../IntegrationAutoConfigurationTests.java | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java index ba4c8aa28ca..6b6e5851512 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java @@ -140,10 +140,10 @@ public class IntegrationAutoConfiguration { return new CronTrigger(poller.getCron()); } if (poller.getFixedDelay() != null) { - return createPeriodicTrigger(poller.getFixedDelay(), poller.getInitialDelay(), true); + return createPeriodicTrigger(poller.getFixedDelay(), poller.getInitialDelay(), false); } if (poller.getFixedRate() != null) { - return createPeriodicTrigger(poller.getFixedRate(), poller.getInitialDelay(), false); + return createPeriodicTrigger(poller.getFixedRate(), poller.getInitialDelay(), true); } return null; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java index fad104b02ef..3dd63794eee 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java @@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.integration; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; import javax.management.MBeanServer; import javax.sql.DataSource; @@ -70,8 +71,10 @@ import org.springframework.jmx.export.MBeanExporter; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHandler; import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler; +import org.springframework.messaging.support.GenericMessage; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.support.CronTrigger; +import org.springframework.scheduling.support.PeriodicTrigger; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -408,6 +411,12 @@ class IntegrationAutoConfigurationTests { assertThat(metadata.getMaxMessagesPerPoll()).isEqualTo(PollerMetadata.MAX_MESSAGES_UNBOUNDED); assertThat(metadata.getReceiveTimeout()).isEqualTo(PollerMetadata.DEFAULT_RECEIVE_TIMEOUT); assertThat(metadata.getTrigger()).isNull(); + + GenericMessage testMessage = new GenericMessage<>("test"); + context.getBean("testChannel", QueueChannel.class).send(testMessage); + @SuppressWarnings("unchecked") + BlockingQueue> sink = context.getBean("sink", BlockingQueue.class); + assertThat(sink.poll(10, TimeUnit.SECONDS)).isSameAs(testMessage); }); } @@ -447,6 +456,21 @@ class IntegrationAutoConfigurationTests { } + @Test + void whenFixedRatePollerPropertyIsSetThenItIsReflectedAsFixedRatePropetyOfPeriodicTrigger() { + this.contextRunner.withUserConfiguration(PollingConsumerConfiguration.class) + .withPropertyValues("spring.integration.poller.fixed-rate=5000").run((context) -> { + assertThat(context).hasSingleBean(PollerMetadata.class); + PollerMetadata metadata = context.getBean(PollerMetadata.DEFAULT_POLLER, PollerMetadata.class); + assertThat(metadata.getTrigger()) + .asInstanceOf(InstanceOfAssertFactories.type(PeriodicTrigger.class)) + .satisfies((trigger) -> { + assertThat(trigger.getPeriod()).isEqualTo(5000L); + assertThat(trigger.isFixedRate()).isTrue(); + }); + }); + } + @Configuration(proxyBeanMethods = false) static class CustomMBeanExporter { From e978654c8884faaee4dcb509ec7ffbbb49274744 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Wed, 13 Oct 2021 08:58:16 +0200 Subject: [PATCH 2/2] Polish "Fix Integration `fixedRate` property setting" See gh-28237 --- .../IntegrationAutoConfigurationTests.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java index 3dd63794eee..d90a1cb29cc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java @@ -414,9 +414,7 @@ class IntegrationAutoConfigurationTests { GenericMessage testMessage = new GenericMessage<>("test"); context.getBean("testChannel", QueueChannel.class).send(testMessage); - @SuppressWarnings("unchecked") - BlockingQueue> sink = context.getBean("sink", BlockingQueue.class); - assertThat(sink.poll(10, TimeUnit.SECONDS)).isSameAs(testMessage); + assertThat(context.getBean("sink", BlockingQueue.class).poll(10, TimeUnit.SECONDS)).isSameAs(testMessage); }); } @@ -457,7 +455,22 @@ class IntegrationAutoConfigurationTests { } @Test - void whenFixedRatePollerPropertyIsSetThenItIsReflectedAsFixedRatePropetyOfPeriodicTrigger() { + void whenFixedDelayPollerPropertyIsSetThenItIsReflectedAsFixedDelayPropertyOfPeriodicTrigger() { + this.contextRunner.withUserConfiguration(PollingConsumerConfiguration.class) + .withPropertyValues("spring.integration.poller.fixed-delay=5000").run((context) -> { + assertThat(context).hasSingleBean(PollerMetadata.class); + PollerMetadata metadata = context.getBean(PollerMetadata.DEFAULT_POLLER, PollerMetadata.class); + assertThat(metadata.getTrigger()) + .asInstanceOf(InstanceOfAssertFactories.type(PeriodicTrigger.class)) + .satisfies((trigger) -> { + assertThat(trigger.getPeriod()).isEqualTo(5000L); + assertThat(trigger.isFixedRate()).isFalse(); + }); + }); + } + + @Test + void whenFixedRatePollerPropertyIsSetThenItIsReflectedAsFixedRatePropertyOfPeriodicTrigger() { this.contextRunner.withUserConfiguration(PollingConsumerConfiguration.class) .withPropertyValues("spring.integration.poller.fixed-rate=5000").run((context) -> { assertThat(context).hasSingleBean(PollerMetadata.class);