|
16 | 16 |
|
17 | 17 | package org.springframework.boot.autoconfigure.integration;
|
18 | 18 |
|
| 19 | +import java.util.concurrent.BlockingQueue; |
| 20 | +import java.util.concurrent.LinkedBlockingQueue; |
| 21 | + |
19 | 22 | import javax.management.MBeanServer;
|
20 | 23 | import javax.sql.DataSource;
|
21 | 24 |
|
22 | 25 | import io.rsocket.transport.ClientTransport;
|
23 | 26 | import io.rsocket.transport.netty.client.TcpClientTransport;
|
| 27 | +import org.assertj.core.api.InstanceOfAssertFactories; |
24 | 28 | import org.junit.jupiter.api.Test;
|
25 | 29 |
|
26 | 30 | import org.springframework.beans.DirectFieldAccessor;
|
|
37 | 41 | import org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration;
|
38 | 42 | import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration;
|
39 | 43 | import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
|
| 44 | +import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException; |
40 | 45 | import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
|
41 | 46 | import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
42 | 47 | import org.springframework.boot.sql.init.DatabaseInitializationSettings;
|
|
47 | 52 | import org.springframework.core.io.ResourceLoader;
|
48 | 53 | import org.springframework.integration.annotation.IntegrationComponentScan;
|
49 | 54 | import org.springframework.integration.annotation.MessagingGateway;
|
| 55 | +import org.springframework.integration.annotation.ServiceActivator; |
| 56 | +import org.springframework.integration.channel.QueueChannel; |
50 | 57 | import org.springframework.integration.config.IntegrationManagementConfigurer;
|
51 | 58 | import org.springframework.integration.context.IntegrationContextUtils;
|
52 | 59 | import org.springframework.integration.endpoint.MessageProcessorMessageSource;
|
|
55 | 62 | import org.springframework.integration.rsocket.IntegrationRSocketEndpoint;
|
56 | 63 | import org.springframework.integration.rsocket.ServerRSocketConnector;
|
57 | 64 | import org.springframework.integration.rsocket.ServerRSocketMessageHandler;
|
| 65 | +import org.springframework.integration.scheduling.PollerMetadata; |
58 | 66 | import org.springframework.integration.support.channel.HeaderChannelRegistry;
|
59 | 67 | import org.springframework.jdbc.BadSqlGrammarException;
|
60 | 68 | import org.springframework.jdbc.core.JdbcOperations;
|
61 | 69 | import org.springframework.jmx.export.MBeanExporter;
|
62 | 70 | import org.springframework.messaging.Message;
|
| 71 | +import org.springframework.messaging.MessageHandler; |
63 | 72 | import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
|
64 | 73 | import org.springframework.scheduling.TaskScheduler;
|
| 74 | +import org.springframework.scheduling.support.CronTrigger; |
65 | 75 |
|
66 | 76 | import static org.assertj.core.api.Assertions.assertThat;
|
67 | 77 | import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
@@ -390,6 +400,53 @@ void whenTheUserDefinesTheirOwnDatabaseInitializerThenTheAutoConfiguredIntegrati
|
390 | 400 | .hasBean("customInitializer"));
|
391 | 401 | }
|
392 | 402 |
|
| 403 | + @Test |
| 404 | + void defaultPoller() { |
| 405 | + this.contextRunner.withUserConfiguration(PollingConsumerConfiguration.class).run((context) -> { |
| 406 | + assertThat(context).hasSingleBean(PollerMetadata.class); |
| 407 | + PollerMetadata metadata = context.getBean(PollerMetadata.DEFAULT_POLLER, PollerMetadata.class); |
| 408 | + assertThat(metadata.getMaxMessagesPerPoll()).isEqualTo(PollerMetadata.MAX_MESSAGES_UNBOUNDED); |
| 409 | + assertThat(metadata.getReceiveTimeout()).isEqualTo(PollerMetadata.DEFAULT_RECEIVE_TIMEOUT); |
| 410 | + assertThat(metadata.getTrigger()).isNull(); |
| 411 | + }); |
| 412 | + } |
| 413 | + |
| 414 | + @Test |
| 415 | + void whenCustomPollerPropertiesAreSetThenTheyAreReflectedInPollerMetadata() { |
| 416 | + this.contextRunner.withUserConfiguration(PollingConsumerConfiguration.class) |
| 417 | + .withPropertyValues("spring.integration.poller.cron=* * * ? * *", |
| 418 | + "spring.integration.poller.max-messages-per-poll=1", |
| 419 | + "spring.integration.poller.receive-timeout=10s") |
| 420 | + .run((context) -> { |
| 421 | + assertThat(context).hasSingleBean(PollerMetadata.class); |
| 422 | + PollerMetadata metadata = context.getBean(PollerMetadata.DEFAULT_POLLER, PollerMetadata.class); |
| 423 | + assertThat(metadata.getMaxMessagesPerPoll()).isEqualTo(1L); |
| 424 | + assertThat(metadata.getReceiveTimeout()).isEqualTo(10000L); |
| 425 | + assertThat(metadata.getTrigger()).asInstanceOf(InstanceOfAssertFactories.type(CronTrigger.class)) |
| 426 | + .satisfies((trigger) -> assertThat(trigger.getExpression()).isEqualTo("* * * ? * *")); |
| 427 | + }); |
| 428 | + } |
| 429 | + |
| 430 | + @Test |
| 431 | + void whenPollerPropertiesForMultipleTriggerTypesAreSetThenRefreshFails() { |
| 432 | + this.contextRunner |
| 433 | + .withPropertyValues("spring.integration.poller.cron=* * * ? * *", |
| 434 | + "spring.integration.poller.fixed-delay=1s") |
| 435 | + .run((context) -> assertThat(context).hasFailed().getFailure() |
| 436 | + .hasRootCauseExactlyInstanceOf(MutuallyExclusiveConfigurationPropertiesException.class) |
| 437 | + .getRootCause() |
| 438 | + .asInstanceOf( |
| 439 | + InstanceOfAssertFactories.type(MutuallyExclusiveConfigurationPropertiesException.class)) |
| 440 | + .satisfies((ex) -> { |
| 441 | + assertThat(ex.getConfiguredNames()).containsExactlyInAnyOrder( |
| 442 | + "spring.integration.poller.cron", "spring.integration.poller.fixed-delay"); |
| 443 | + assertThat(ex.getMutuallyExclusiveNames()).containsExactlyInAnyOrder( |
| 444 | + "spring.integration.poller.cron", "spring.integration.poller.fixed-delay", |
| 445 | + "spring.integration.poller.fixed-rate"); |
| 446 | + })); |
| 447 | + |
| 448 | + } |
| 449 | + |
393 | 450 | @Configuration(proxyBeanMethods = false)
|
394 | 451 | static class CustomMBeanExporter {
|
395 | 452 |
|
@@ -478,4 +535,25 @@ IntegrationDataSourceInitializer customInitializer(DataSource dataSource, Resour
|
478 | 535 |
|
479 | 536 | }
|
480 | 537 |
|
| 538 | + @Configuration(proxyBeanMethods = false) |
| 539 | + static class PollingConsumerConfiguration { |
| 540 | + |
| 541 | + @Bean |
| 542 | + QueueChannel testChannel() { |
| 543 | + return new QueueChannel(); |
| 544 | + } |
| 545 | + |
| 546 | + @Bean |
| 547 | + BlockingQueue<Message<?>> sink() { |
| 548 | + return new LinkedBlockingQueue<>(); |
| 549 | + } |
| 550 | + |
| 551 | + @ServiceActivator(inputChannel = "testChannel") |
| 552 | + @Bean |
| 553 | + MessageHandler handler(BlockingQueue<Message<?>> sink) { |
| 554 | + return sink::add; |
| 555 | + } |
| 556 | + |
| 557 | + } |
| 558 | + |
481 | 559 | }
|
0 commit comments