@ -16,11 +16,15 @@
@@ -16,11 +16,15 @@
package org.springframework.boot.autoconfigure.integration ;
import java.util.concurrent.BlockingQueue ;
import java.util.concurrent.LinkedBlockingQueue ;
import javax.management.MBeanServer ;
import javax.sql.DataSource ;
import io.rsocket.transport.ClientTransport ;
import io.rsocket.transport.netty.client.TcpClientTransport ;
import org.assertj.core.api.InstanceOfAssertFactories ;
import org.junit.jupiter.api.Test ;
import org.springframework.beans.DirectFieldAccessor ;
@ -37,6 +41,7 @@ import org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfig
@@ -37,6 +41,7 @@ import org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfig
import org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration ;
import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration ;
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration ;
import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException ;
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer ;
import org.springframework.boot.sql.init.DatabaseInitializationMode ;
import org.springframework.boot.sql.init.DatabaseInitializationSettings ;
@ -47,6 +52,8 @@ import org.springframework.context.annotation.Primary;
@@ -47,6 +52,8 @@ import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ResourceLoader ;
import org.springframework.integration.annotation.IntegrationComponentScan ;
import org.springframework.integration.annotation.MessagingGateway ;
import org.springframework.integration.annotation.ServiceActivator ;
import org.springframework.integration.channel.QueueChannel ;
import org.springframework.integration.config.IntegrationManagementConfigurer ;
import org.springframework.integration.context.IntegrationContextUtils ;
import org.springframework.integration.endpoint.MessageProcessorMessageSource ;
@ -55,13 +62,16 @@ import org.springframework.integration.rsocket.ClientRSocketConnector;
@@ -55,13 +62,16 @@ import org.springframework.integration.rsocket.ClientRSocketConnector;
import org.springframework.integration.rsocket.IntegrationRSocketEndpoint ;
import org.springframework.integration.rsocket.ServerRSocketConnector ;
import org.springframework.integration.rsocket.ServerRSocketMessageHandler ;
import org.springframework.integration.scheduling.PollerMetadata ;
import org.springframework.integration.support.channel.HeaderChannelRegistry ;
import org.springframework.jdbc.BadSqlGrammarException ;
import org.springframework.jdbc.core.JdbcOperations ;
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.scheduling.TaskScheduler ;
import org.springframework.scheduling.support.CronTrigger ;
import static org.assertj.core.api.Assertions.assertThat ;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType ;
@ -390,6 +400,53 @@ class IntegrationAutoConfigurationTests {
@@ -390,6 +400,53 @@ class IntegrationAutoConfigurationTests {
. hasBean ( "customInitializer" ) ) ;
}
@Test
void defaultPoller ( ) {
this . contextRunner . withUserConfiguration ( PollingConsumerConfiguration . class ) . run ( ( context ) - > {
assertThat ( context ) . hasSingleBean ( PollerMetadata . class ) ;
PollerMetadata metadata = context . getBean ( PollerMetadata . DEFAULT_POLLER , PollerMetadata . class ) ;
assertThat ( metadata . getMaxMessagesPerPoll ( ) ) . isEqualTo ( PollerMetadata . MAX_MESSAGES_UNBOUNDED ) ;
assertThat ( metadata . getReceiveTimeout ( ) ) . isEqualTo ( PollerMetadata . DEFAULT_RECEIVE_TIMEOUT ) ;
assertThat ( metadata . getTrigger ( ) ) . isNull ( ) ;
} ) ;
}
@Test
void whenCustomPollerPropertiesAreSetThenTheyAreReflectedInPollerMetadata ( ) {
this . contextRunner . withUserConfiguration ( PollingConsumerConfiguration . class )
. withPropertyValues ( "spring.integration.poller.cron=* * * ? * *" ,
"spring.integration.poller.max-messages-per-poll=1" ,
"spring.integration.poller.receive-timeout=10s" )
. run ( ( context ) - > {
assertThat ( context ) . hasSingleBean ( PollerMetadata . class ) ;
PollerMetadata metadata = context . getBean ( PollerMetadata . DEFAULT_POLLER , PollerMetadata . class ) ;
assertThat ( metadata . getMaxMessagesPerPoll ( ) ) . isEqualTo ( 1L ) ;
assertThat ( metadata . getReceiveTimeout ( ) ) . isEqualTo ( 10000L ) ;
assertThat ( metadata . getTrigger ( ) ) . asInstanceOf ( InstanceOfAssertFactories . type ( CronTrigger . class ) )
. satisfies ( ( trigger ) - > assertThat ( trigger . getExpression ( ) ) . isEqualTo ( "* * * ? * *" ) ) ;
} ) ;
}
@Test
void whenPollerPropertiesForMultipleTriggerTypesAreSetThenRefreshFails ( ) {
this . contextRunner
. withPropertyValues ( "spring.integration.poller.cron=* * * ? * *" ,
"spring.integration.poller.fixed-delay=1s" )
. run ( ( context ) - > assertThat ( context ) . hasFailed ( ) . getFailure ( )
. hasRootCauseExactlyInstanceOf ( MutuallyExclusiveConfigurationPropertiesException . class )
. getRootCause ( )
. asInstanceOf (
InstanceOfAssertFactories . type ( MutuallyExclusiveConfigurationPropertiesException . class ) )
. satisfies ( ( ex ) - > {
assertThat ( ex . getConfiguredNames ( ) ) . containsExactlyInAnyOrder (
"spring.integration.poller.cron" , "spring.integration.poller.fixed-delay" ) ;
assertThat ( ex . getMutuallyExclusiveNames ( ) ) . containsExactlyInAnyOrder (
"spring.integration.poller.cron" , "spring.integration.poller.fixed-delay" ,
"spring.integration.poller.fixed-rate" ) ;
} ) ) ;
}
@Configuration ( proxyBeanMethods = false )
static class CustomMBeanExporter {
@ -478,4 +535,25 @@ class IntegrationAutoConfigurationTests {
@@ -478,4 +535,25 @@ class IntegrationAutoConfigurationTests {
}
@Configuration ( proxyBeanMethods = false )
static class PollingConsumerConfiguration {
@Bean
QueueChannel testChannel ( ) {
return new QueueChannel ( ) ;
}
@Bean
BlockingQueue < Message < ? > > sink ( ) {
return new LinkedBlockingQueue < > ( ) ;
}
@ServiceActivator ( inputChannel = "testChannel" )
@Bean
MessageHandler handler ( BlockingQueue < Message < ? > > sink ) {
return sink : : add ;
}
}
}