|
1 | 1 | /* |
2 | | - * Copyright 2012-2023 the original author or authors. |
| 2 | + * Copyright 2012-2024 the original author or authors. |
3 | 3 | * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | * you may not use this file except in compliance with the License. |
|
16 | 16 |
|
17 | 17 | package org.springframework.boot.autoconfigure.integration; |
18 | 18 |
|
| 19 | +import java.beans.PropertyDescriptor; |
19 | 20 | import java.time.Duration; |
| 21 | +import java.util.List; |
20 | 22 | import java.util.concurrent.BlockingQueue; |
21 | 23 | import java.util.concurrent.LinkedBlockingQueue; |
22 | 24 | import java.util.concurrent.TimeUnit; |
| 25 | +import java.util.stream.Stream; |
23 | 26 |
|
24 | 27 | import javax.management.MBeanServer; |
25 | 28 | import javax.sql.DataSource; |
|
32 | 35 | import reactor.core.publisher.Mono; |
33 | 36 |
|
34 | 37 | import org.springframework.beans.DirectFieldAccessor; |
| 38 | +import org.springframework.beans.PropertyAccessorFactory; |
35 | 39 | import org.springframework.boot.autoconfigure.AutoConfigurations; |
36 | 40 | import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; |
37 | 41 | import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration.IntegrationComponentScanConfiguration; |
|
82 | 86 | import org.springframework.scheduling.TaskScheduler; |
83 | 87 | import org.springframework.scheduling.support.CronTrigger; |
84 | 88 | import org.springframework.scheduling.support.PeriodicTrigger; |
| 89 | +import org.springframework.test.util.ReflectionTestUtils; |
85 | 90 |
|
86 | 91 | import static org.assertj.core.api.Assertions.assertThat; |
87 | 92 | import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
@@ -295,55 +300,63 @@ void taskSchedulerCanBeCustomized() { |
295 | 300 |
|
296 | 301 | @Test |
297 | 302 | void integrationGlobalPropertiesAutoConfigured() { |
298 | | - this.contextRunner.withPropertyValues("spring.integration.channel.auto-create=false", |
| 303 | + String[] propertyValues = { "spring.integration.channel.auto-create=false", |
299 | 304 | "spring.integration.channel.max-unicast-subscribers=2", |
300 | 305 | "spring.integration.channel.max-broadcast-subscribers=3", |
301 | 306 | "spring.integration.error.require-subscribers=false", "spring.integration.error.ignore-failures=false", |
| 307 | + "spring.integration.endpoint.defaultTimeout=60s", |
302 | 308 | "spring.integration.endpoint.throw-exception-on-late-reply=true", |
303 | 309 | "spring.integration.endpoint.read-only-headers=ignoredHeader", |
304 | | - "spring.integration.endpoint.no-auto-startup=notStartedEndpoint,_org.springframework.integration.errorLogger") |
305 | | - .run((context) -> { |
306 | | - assertThat(context).hasSingleBean(org.springframework.integration.context.IntegrationProperties.class); |
307 | | - org.springframework.integration.context.IntegrationProperties integrationProperties = context |
308 | | - .getBean(org.springframework.integration.context.IntegrationProperties.class); |
309 | | - assertThat(integrationProperties.isChannelsAutoCreate()).isFalse(); |
310 | | - assertThat(integrationProperties.getChannelsMaxUnicastSubscribers()).isEqualTo(2); |
311 | | - assertThat(integrationProperties.getChannelsMaxBroadcastSubscribers()).isEqualTo(3); |
312 | | - assertThat(integrationProperties.isErrorChannelRequireSubscribers()).isFalse(); |
313 | | - assertThat(integrationProperties.isErrorChannelIgnoreFailures()).isFalse(); |
314 | | - assertThat(integrationProperties.isMessagingTemplateThrowExceptionOnLateReply()).isTrue(); |
315 | | - assertThat(integrationProperties.getReadOnlyHeaders()).containsOnly("ignoredHeader"); |
316 | | - assertThat(integrationProperties.getNoAutoStartupEndpoints()).containsOnly("notStartedEndpoint", |
317 | | - "_org.springframework.integration.errorLogger"); |
318 | | - }); |
| 310 | + "spring.integration.endpoint.no-auto-startup=notStartedEndpoint,_org.springframework.integration.errorLogger" }; |
| 311 | + assertThat(propertyValues).hasSameSizeAs(globalIntegrationPropertyNames()); |
| 312 | + this.contextRunner.withPropertyValues(propertyValues).run((context) -> { |
| 313 | + assertThat(context).hasSingleBean(org.springframework.integration.context.IntegrationProperties.class); |
| 314 | + org.springframework.integration.context.IntegrationProperties integrationProperties = context |
| 315 | + .getBean(org.springframework.integration.context.IntegrationProperties.class); |
| 316 | + assertThat(integrationProperties.isChannelsAutoCreate()).isFalse(); |
| 317 | + assertThat(integrationProperties.getChannelsMaxUnicastSubscribers()).isEqualTo(2); |
| 318 | + assertThat(integrationProperties.getChannelsMaxBroadcastSubscribers()).isEqualTo(3); |
| 319 | + assertThat(integrationProperties.isErrorChannelRequireSubscribers()).isFalse(); |
| 320 | + assertThat(integrationProperties.isErrorChannelIgnoreFailures()).isFalse(); |
| 321 | + assertThat(integrationProperties.getEndpointsDefaultTimeout()).isEqualTo(60000); |
| 322 | + assertThat(integrationProperties.isMessagingTemplateThrowExceptionOnLateReply()).isTrue(); |
| 323 | + assertThat(integrationProperties.getReadOnlyHeaders()).containsOnly("ignoredHeader"); |
| 324 | + assertThat(integrationProperties.getNoAutoStartupEndpoints()).containsOnly("notStartedEndpoint", |
| 325 | + "_org.springframework.integration.errorLogger"); |
| 326 | + }); |
319 | 327 | } |
320 | 328 |
|
321 | 329 | @Test |
322 | 330 | void integrationGlobalPropertiesUseConsistentDefault() { |
| 331 | + List<PropertyAccessor> properties = List |
| 332 | + .of("isChannelsAutoCreate", "getChannelsMaxUnicastSubscribers", "getChannelsMaxBroadcastSubscribers", |
| 333 | + "isErrorChannelRequireSubscribers", "isErrorChannelIgnoreFailures", "getEndpointsDefaultTimeout", |
| 334 | + "isMessagingTemplateThrowExceptionOnLateReply", "getReadOnlyHeaders", "getNoAutoStartupEndpoints") |
| 335 | + .stream() |
| 336 | + .map(PropertyAccessor::new) |
| 337 | + .toList(); |
| 338 | + assertThat(properties).hasSameSizeAs(globalIntegrationPropertyNames()); |
323 | 339 | org.springframework.integration.context.IntegrationProperties defaultIntegrationProperties = new org.springframework.integration.context.IntegrationProperties(); |
324 | 340 | this.contextRunner.run((context) -> { |
325 | 341 | assertThat(context).hasSingleBean(org.springframework.integration.context.IntegrationProperties.class); |
326 | 342 | org.springframework.integration.context.IntegrationProperties integrationProperties = context |
327 | 343 | .getBean(org.springframework.integration.context.IntegrationProperties.class); |
328 | | - assertThat(integrationProperties.isChannelsAutoCreate()) |
329 | | - .isEqualTo(defaultIntegrationProperties.isChannelsAutoCreate()); |
330 | | - assertThat(integrationProperties.getChannelsMaxUnicastSubscribers()) |
331 | | - .isEqualTo(defaultIntegrationProperties.getChannelsMaxBroadcastSubscribers()); |
332 | | - assertThat(integrationProperties.getChannelsMaxBroadcastSubscribers()) |
333 | | - .isEqualTo(defaultIntegrationProperties.getChannelsMaxBroadcastSubscribers()); |
334 | | - assertThat(integrationProperties.isErrorChannelRequireSubscribers()) |
335 | | - .isEqualTo(defaultIntegrationProperties.isErrorChannelIgnoreFailures()); |
336 | | - assertThat(integrationProperties.isErrorChannelIgnoreFailures()) |
337 | | - .isEqualTo(defaultIntegrationProperties.isErrorChannelIgnoreFailures()); |
338 | | - assertThat(integrationProperties.isMessagingTemplateThrowExceptionOnLateReply()) |
339 | | - .isEqualTo(defaultIntegrationProperties.isMessagingTemplateThrowExceptionOnLateReply()); |
340 | | - assertThat(integrationProperties.getReadOnlyHeaders()) |
341 | | - .isEqualTo(defaultIntegrationProperties.getReadOnlyHeaders()); |
342 | | - assertThat(integrationProperties.getNoAutoStartupEndpoints()) |
343 | | - .isEqualTo(defaultIntegrationProperties.getNoAutoStartupEndpoints()); |
| 344 | + properties.forEach((property) -> assertThat(property.get(integrationProperties)) |
| 345 | + .isEqualTo(property.get(defaultIntegrationProperties))); |
344 | 346 | }); |
345 | 347 | } |
346 | 348 |
|
| 349 | + private List<String> globalIntegrationPropertyNames() { |
| 350 | + return Stream |
| 351 | + .of(PropertyAccessorFactory |
| 352 | + .forBeanPropertyAccess(new org.springframework.integration.context.IntegrationProperties()) |
| 353 | + .getPropertyDescriptors()) |
| 354 | + .map(PropertyDescriptor::getName) |
| 355 | + .filter((name) -> !"class".equals(name)) |
| 356 | + .filter((name) -> !"taskSchedulerPoolSize".equals(name)) |
| 357 | + .toList(); |
| 358 | + } |
| 359 | + |
347 | 360 | @Test |
348 | 361 | void integrationGlobalPropertiesUserBeanOverridesAutoConfiguration() { |
349 | 362 | org.springframework.integration.context.IntegrationProperties userIntegrationProperties = new org.springframework.integration.context.IntegrationProperties(); |
@@ -604,4 +617,23 @@ MessageHandler handler(BlockingQueue<Message<?>> sink) { |
604 | 617 |
|
605 | 618 | } |
606 | 619 |
|
| 620 | + static class PropertyAccessor { |
| 621 | + |
| 622 | + private final String name; |
| 623 | + |
| 624 | + PropertyAccessor(String name) { |
| 625 | + this.name = name; |
| 626 | + } |
| 627 | + |
| 628 | + Object get(org.springframework.integration.context.IntegrationProperties properties) { |
| 629 | + return ReflectionTestUtils.invokeMethod(properties, this.name); |
| 630 | + } |
| 631 | + |
| 632 | + @Override |
| 633 | + public String toString() { |
| 634 | + return this.name; |
| 635 | + } |
| 636 | + |
| 637 | + } |
| 638 | + |
607 | 639 | } |
0 commit comments