Skip to content

Commit e2df9bc

Browse files
artembilansnicoll
authored andcommitted
Expose Spring Integration global properties
Spring Integration comes with some global properties which can be configured via `META-INF/spring.integration.properties`. The framework then provides an `integrationGlobalProperties` bean as an `org.springframework.integration.context.IntegrationProperties` instance. This commit allows users to configure these using regular `application.properties`. If a `META-INF/spring.integration.properties` file exists, the values are used as fallback. See gh-25377
1 parent deaff1a commit e2df9bc

File tree

6 files changed

+413
-1
lines changed

6 files changed

+413
-1
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,23 @@
8080
TaskSchedulingAutoConfiguration.class })
8181
public class IntegrationAutoConfiguration {
8282

83+
@Bean(name = IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME)
84+
@ConditionalOnMissingBean(name = IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME)
85+
public static org.springframework.integration.context.IntegrationProperties integrationGlobalProperties(
86+
IntegrationProperties properties) {
87+
org.springframework.integration.context.IntegrationProperties integrationProperties = new org.springframework.integration.context.IntegrationProperties();
88+
integrationProperties.setChannelsAutoCreate(properties.getChannels().isAutoCreate());
89+
integrationProperties.setChannelsMaxUnicastSubscribers(properties.getChannels().getMaxUnicastSubscribers());
90+
integrationProperties.setChannelsMaxBroadcastSubscribers(properties.getChannels().getMaxBroadcastSubscribers());
91+
integrationProperties.setErrorChannelRequireSubscribers(properties.getChannels().isErrorRequireSubscribers());
92+
integrationProperties.setErrorChannelIgnoreFailures(properties.getChannels().isErrorIgnoreFailures());
93+
integrationProperties
94+
.setMessagingTemplateThrowExceptionOnLateReply(properties.getEndpoints().isThrowExceptionOnLateReply());
95+
integrationProperties.setReadOnlyHeaders(properties.getEndpoints().getReadOnlyHeaders());
96+
integrationProperties.setNoAutoStartupEndpoints(properties.getEndpoints().getNoAutoStartup());
97+
return integrationProperties;
98+
}
99+
83100
/**
84101
* Basic Spring Integration configuration.
85102
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright 2012-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.integration;
18+
19+
import java.io.FileNotFoundException;
20+
import java.io.IOException;
21+
import java.util.HashMap;
22+
import java.util.Map;
23+
24+
import org.springframework.boot.SpringApplication;
25+
import org.springframework.boot.env.EnvironmentPostProcessor;
26+
import org.springframework.boot.env.OriginTrackedMapPropertySource;
27+
import org.springframework.boot.env.PropertiesPropertySourceLoader;
28+
import org.springframework.boot.origin.Origin;
29+
import org.springframework.boot.origin.OriginLookup;
30+
import org.springframework.core.Ordered;
31+
import org.springframework.core.env.ConfigurableEnvironment;
32+
import org.springframework.core.env.PropertySource;
33+
import org.springframework.core.io.ClassPathResource;
34+
import org.springframework.core.io.Resource;
35+
import org.springframework.integration.context.IntegrationProperties;
36+
37+
/**
38+
* The {@link EnvironmentPostProcessor} for Spring Integration.
39+
*
40+
* @author Artem Bilan
41+
* @since 2.5
42+
*/
43+
public class IntegrationEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
44+
45+
@Override
46+
public int getOrder() {
47+
return Ordered.LOWEST_PRECEDENCE;
48+
}
49+
50+
@Override
51+
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
52+
registerIntegrationPropertiesFileSource(environment);
53+
}
54+
55+
private static void registerIntegrationPropertiesFileSource(ConfigurableEnvironment environment) {
56+
Resource integrationPropertiesResource = new ClassPathResource("META-INF/spring.integration.properties");
57+
PropertiesPropertySourceLoader loader = new PropertiesPropertySourceLoader();
58+
try {
59+
OriginTrackedMapPropertySource propertyFileSource = (OriginTrackedMapPropertySource) loader
60+
.load("integration-properties-file", integrationPropertiesResource).get(0);
61+
62+
environment.getPropertySources().addLast(new IntegrationPropertySource(propertyFileSource));
63+
}
64+
catch (FileNotFoundException ex) {
65+
// Ignore when no META-INF/spring.integration.properties file in classpath
66+
}
67+
catch (IOException ex) {
68+
throw new IllegalStateException(
69+
"Failed to load integration properties from " + integrationPropertiesResource, ex);
70+
}
71+
}
72+
73+
private static final class IntegrationPropertySource extends PropertySource<Map<String, Object>>
74+
implements OriginLookup<String> {
75+
76+
private static final String PREFIX = "spring.integration.";
77+
78+
private static final Map<String, String> KEYS_MAPPING = new HashMap<>();
79+
80+
static {
81+
KEYS_MAPPING.put(PREFIX + "channels.auto-create", IntegrationProperties.CHANNELS_AUTOCREATE);
82+
KEYS_MAPPING.put(PREFIX + "channels.max-unicast-subscribers",
83+
IntegrationProperties.CHANNELS_MAX_UNICAST_SUBSCRIBERS);
84+
KEYS_MAPPING.put(PREFIX + "channels.max-broadcast-subscribers",
85+
IntegrationProperties.CHANNELS_MAX_BROADCAST_SUBSCRIBERS);
86+
KEYS_MAPPING.put(PREFIX + "channels.error-require-subscribers",
87+
IntegrationProperties.ERROR_CHANNEL_REQUIRE_SUBSCRIBERS);
88+
KEYS_MAPPING.put(PREFIX + "channels.error-ignore-failures",
89+
IntegrationProperties.ERROR_CHANNEL_IGNORE_FAILURES);
90+
KEYS_MAPPING.put(PREFIX + "endpoints.throw-exception-on-late-reply",
91+
IntegrationProperties.THROW_EXCEPTION_ON_LATE_REPLY);
92+
KEYS_MAPPING.put(PREFIX + "endpoints.read-only-headers", IntegrationProperties.READ_ONLY_HEADERS);
93+
KEYS_MAPPING.put(PREFIX + "endpoints.no-auto-startup", IntegrationProperties.ENDPOINTS_NO_AUTO_STARTUP);
94+
}
95+
96+
private final OriginTrackedMapPropertySource origin;
97+
98+
IntegrationPropertySource(OriginTrackedMapPropertySource origin) {
99+
super("original-integration-properties", origin.getSource());
100+
this.origin = origin;
101+
}
102+
103+
@Override
104+
public Object getProperty(String name) {
105+
return this.origin.getProperty(KEYS_MAPPING.get(name));
106+
}
107+
108+
@Override
109+
public Origin getOrigin(String key) {
110+
return this.origin.getOrigin(KEYS_MAPPING.get(name));
111+
}
112+
113+
}
114+
115+
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationProperties.java

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,22 @@
3232
@ConfigurationProperties(prefix = "spring.integration")
3333
public class IntegrationProperties {
3434

35+
private final Channels channels = new Channels();
36+
37+
private final Endpoints endpoints = new Endpoints();
38+
3539
private final Jdbc jdbc = new Jdbc();
3640

3741
private final RSocket rsocket = new RSocket();
3842

43+
public Channels getChannels() {
44+
return this.channels;
45+
}
46+
47+
public Endpoints getEndpoints() {
48+
return this.endpoints;
49+
}
50+
3951
public Jdbc getJdbc() {
4052
return this.jdbc;
4153
}
@@ -44,6 +56,118 @@ public RSocket getRsocket() {
4456
return this.rsocket;
4557
}
4658

59+
public static class Channels {
60+
61+
/**
62+
* Whether to create input channels when no respective beans.
63+
*/
64+
private boolean autoCreate = true;
65+
66+
/**
67+
* Default number of max subscribers on unicasting channels.
68+
*/
69+
private int maxUnicastSubscribers = Integer.MAX_VALUE;
70+
71+
/**
72+
* Default number of max subscribers on broadcasting channels.
73+
*/
74+
private int maxBroadcastSubscribers = Integer.MAX_VALUE;
75+
76+
/**
77+
* Require subscribers flag for global 'errorChannel'.
78+
*/
79+
private boolean errorRequireSubscribers = true;
80+
81+
/**
82+
* Ignore failures flag for global 'errorChannel'.
83+
*/
84+
private boolean errorIgnoreFailures = true;
85+
86+
public void setAutoCreate(boolean autoCreate) {
87+
this.autoCreate = autoCreate;
88+
}
89+
90+
public boolean isAutoCreate() {
91+
return this.autoCreate;
92+
}
93+
94+
public void setMaxUnicastSubscribers(int maxUnicastSubscribers) {
95+
this.maxUnicastSubscribers = maxUnicastSubscribers;
96+
}
97+
98+
public int getMaxUnicastSubscribers() {
99+
return this.maxUnicastSubscribers;
100+
}
101+
102+
public void setMaxBroadcastSubscribers(int maxBroadcastSubscribers) {
103+
this.maxBroadcastSubscribers = maxBroadcastSubscribers;
104+
}
105+
106+
public int getMaxBroadcastSubscribers() {
107+
return this.maxBroadcastSubscribers;
108+
}
109+
110+
public void setErrorRequireSubscribers(boolean errorRequireSubscribers) {
111+
this.errorRequireSubscribers = errorRequireSubscribers;
112+
}
113+
114+
public boolean isErrorRequireSubscribers() {
115+
return this.errorRequireSubscribers;
116+
}
117+
118+
public void setErrorIgnoreFailures(boolean errorIgnoreFailures) {
119+
this.errorIgnoreFailures = errorIgnoreFailures;
120+
}
121+
122+
public boolean isErrorIgnoreFailures() {
123+
return this.errorIgnoreFailures;
124+
}
125+
126+
}
127+
128+
public static class Endpoints {
129+
130+
/**
131+
* Whether throw an exception on late reply for gateways.
132+
*/
133+
private boolean throwExceptionOnLateReply = false;
134+
135+
/**
136+
* Ignored headers during message building.
137+
*/
138+
private String[] readOnlyHeaders = {};
139+
140+
/**
141+
* Spring Integration endpoints do not start automatically.
142+
*/
143+
private String[] noAutoStartup = {};
144+
145+
public void setThrowExceptionOnLateReply(boolean throwExceptionOnLateReply) {
146+
this.throwExceptionOnLateReply = throwExceptionOnLateReply;
147+
}
148+
149+
public boolean isThrowExceptionOnLateReply() {
150+
return this.throwExceptionOnLateReply;
151+
}
152+
153+
public void setReadOnlyHeaders(String[] readOnlyHeaders) {
154+
this.readOnlyHeaders = readOnlyHeaders;
155+
}
156+
157+
public String[] getReadOnlyHeaders() {
158+
return this.readOnlyHeaders;
159+
}
160+
161+
public void setNoAutoStartup(String[] noAutoStartup) {
162+
this.noAutoStartup = noAutoStartup;
163+
}
164+
165+
public String[] getNoAutoStartup() {
166+
return this.noAutoStartup;
167+
}
168+
169+
}
170+
47171
public static class Jdbc {
48172

49173
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/"
@@ -139,7 +263,7 @@ public static class Server {
139263
/**
140264
* Whether to handle message mapping for RSocket via Spring Integration.
141265
*/
142-
boolean messageMappingEnabled;
266+
private boolean messageMappingEnabled;
143267

144268
public boolean isMessageMappingEnabled() {
145269
return this.messageMappingEnabled;

spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingL
77
org.springframework.context.ApplicationListener=\
88
org.springframework.boot.autoconfigure.BackgroundPreinitializer
99

10+
# Environment Post Processors
11+
org.springframework.boot.env.EnvironmentPostProcessor=\
12+
org.springframework.boot.autoconfigure.integration.IntegrationEnvironmentPostProcessor
13+
1014
# Auto Configuration Import Listeners
1115
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
1216
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

0 commit comments

Comments
 (0)