Skip to content

Commit 1014258

Browse files
artembilangaryrussell
authored andcommitted
INT-4513: Clean IntManageConf from removed beans
JIRA: https://jira.spring.io/browse/INT-4513 The `IntegrationManagementConfigurer` keeps metrics beans in its local stores. When we add beans at runtime, they are not removed from those caches after their removal * Implement `DestructionAwareBeanPostProcessor` in the `IntegrationManagementConfigurer` and clean up caches according provided bean type and its name * Improve `ManualFlowTests` and `FtpTests` to be sure that `IntegrationManagementConfigurer` caches are cleared after destroying `IntegrationFlowRegistration` **Cherry-pick to 5.0.x**
1 parent c50a135 commit 1014258

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

spring-integration-core/src/main/java/org/springframework/integration/support/management/IntegrationManagementConfigurer.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import org.springframework.beans.BeansException;
2828
import org.springframework.beans.factory.BeanNameAware;
2929
import org.springframework.beans.factory.SmartInitializingSingleton;
30-
import org.springframework.beans.factory.config.BeanPostProcessor;
30+
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
3131
import org.springframework.context.ApplicationContext;
3232
import org.springframework.context.ApplicationContextAware;
3333
import org.springframework.integration.core.MessageSource;
@@ -52,8 +52,9 @@
5252
* @since 4.2
5353
*
5454
*/
55-
public class IntegrationManagementConfigurer implements SmartInitializingSingleton, ApplicationContextAware,
56-
BeanNameAware, BeanPostProcessor {
55+
public class IntegrationManagementConfigurer
56+
implements SmartInitializingSingleton, ApplicationContextAware, BeanNameAware,
57+
DestructionAwareBeanPostProcessor {
5758

5859
private static final Log logger = LogFactory.getLog(IntegrationManagementConfigurer.class);
5960

@@ -233,7 +234,8 @@ public void afterSingletonsInstantiated() {
233234
this.metricsFactory = new DefaultMetricsFactory();
234235
}
235236
this.sourceConfigurers.putAll(this.applicationContext.getBeansOfType(MessageSourceMetricsConfigurer.class));
236-
Map<String, IntegrationManagement> managed = this.applicationContext.getBeansOfType(IntegrationManagement.class);
237+
Map<String, IntegrationManagement> managed = this.applicationContext
238+
.getBeansOfType(IntegrationManagement.class);
237239
for (Entry<String, IntegrationManagement> entry : managed.entrySet()) {
238240
IntegrationManagement bean = entry.getValue();
239241
if (!bean.getOverrides().loggingConfigured) {
@@ -246,7 +248,8 @@ public void afterSingletonsInstantiated() {
246248
}
247249

248250
private void injectCaptor() {
249-
Map<String, IntegrationManagement> managed = this.applicationContext.getBeansOfType(IntegrationManagement.class);
251+
Map<String, IntegrationManagement> managed = this.applicationContext
252+
.getBeansOfType(IntegrationManagement.class);
250253
for (Entry<String, IntegrationManagement> entry : managed.entrySet()) {
251254
IntegrationManagement bean = entry.getValue();
252255
if (!bean.getOverrides().loggingConfigured) {
@@ -267,6 +270,30 @@ public Object postProcessAfterInitialization(Object bean, String beanName) throw
267270
return bean;
268271
}
269272

273+
@Override
274+
public boolean requiresDestruction(Object bean) {
275+
return bean instanceof MessageChannelMetrics ||
276+
bean instanceof MessageHandlerMetrics ||
277+
bean instanceof MessageSourceMetrics;
278+
}
279+
280+
@Override
281+
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
282+
if (bean instanceof MessageChannelMetrics) {
283+
this.channelsByName.remove(beanName);
284+
}
285+
else if (bean instanceof MessageHandlerMetrics) {
286+
if (this.handlersByName.remove(beanName) == null) {
287+
this.handlersByName.remove(beanName + ".handler");
288+
}
289+
}
290+
else if (bean instanceof MessageSourceMetrics) {
291+
if (this.sourcesByName.remove(beanName) == null) {
292+
this.sourcesByName.remove(beanName + ".source");
293+
}
294+
}
295+
}
296+
270297
private Object doConfigureMetrics(Object bean, String name) {
271298
if (bean instanceof MessageChannelMetrics) {
272299
configureChannelMetrics(name, (MessageChannelMetrics) bean);

spring-integration-core/src/test/java/org/springframework/integration/dsl/manualflow/ManualFlowTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@
5959
import org.springframework.context.annotation.Scope;
6060
import org.springframework.integration.channel.QueueChannel;
6161
import org.springframework.integration.config.EnableIntegration;
62+
import org.springframework.integration.config.EnableIntegrationManagement;
6263
import org.springframework.integration.config.EnableMessageHistory;
64+
import org.springframework.integration.config.IntegrationManagementConfigurer;
6365
import org.springframework.integration.core.MessageProducer;
6466
import org.springframework.integration.core.MessagingTemplate;
6567
import org.springframework.integration.dsl.IntegrationFlow;
@@ -113,6 +115,9 @@ public class ManualFlowTests {
113115
@Autowired
114116
private SmartLifecycleRoleController roleController;
115117

118+
@Autowired
119+
private IntegrationManagementConfigurer integrationManagementConfigurer;
120+
116121
@Test
117122
@SuppressWarnings("unchecked")
118123
public void testWithAnonymousMessageProducerStart() {
@@ -127,9 +132,11 @@ protected void doStart() {
127132

128133
};
129134
QueueChannel channel = new QueueChannel();
135+
channel.setBeanName("channel");
130136
IntegrationFlowBuilder flowBuilder = IntegrationFlows.from(producer);
131137

132138
BridgeHandler bridgeHandler = new BridgeHandler();
139+
bridgeHandler.setBeanName("bridge");
133140

134141
IntegrationFlow flow =
135142
flowBuilder.handle(bridgeHandler)
@@ -144,9 +151,15 @@ protected void doStart() {
144151

145152
assertTrue(replyProducers.contains(bridgeHandler));
146153

154+
assertNotNull(this.integrationManagementConfigurer.getChannelMetrics("channel"));
155+
assertNotNull(this.integrationManagementConfigurer.getHandlerMetrics("bridge"));
156+
147157
flowRegistration.destroy();
148158

149159
assertFalse(replyProducers.contains(bridgeHandler));
160+
161+
assertNull(this.integrationManagementConfigurer.getChannelMetrics("channel"));
162+
assertNull(this.integrationManagementConfigurer.getHandlerMetrics("bridge"));
150163
}
151164

152165
@Test
@@ -525,6 +538,7 @@ public void testConcurrentRegistration() throws InterruptedException {
525538
@Configuration
526539
@EnableIntegration
527540
@EnableMessageHistory
541+
@EnableIntegrationManagement
528542
public static class RootConfiguration {
529543

530544
@Bean

spring-integration-ftp/src/test/java/org/springframework/integration/ftp/dsl/FtpTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
import org.springframework.integration.IntegrationMessageHeaderAccessor;
4747
import org.springframework.integration.channel.QueueChannel;
4848
import org.springframework.integration.config.EnableIntegration;
49+
import org.springframework.integration.config.EnableIntegrationManagement;
50+
import org.springframework.integration.config.IntegrationManagementConfigurer;
4951
import org.springframework.integration.core.MessageSource;
5052
import org.springframework.integration.dsl.IntegrationFlow;
5153
import org.springframework.integration.dsl.IntegrationFlows;
@@ -85,6 +87,9 @@ public class FtpTests extends FtpTestSupport {
8587
@Autowired
8688
private ApplicationContext context;
8789

90+
@Autowired
91+
private IntegrationManagementConfigurer integrationManagementConfigurer;
92+
8893
@Test
8994
public void testFtpInboundFlow() throws IOException {
9095
QueueChannel out = new QueueChannel();
@@ -132,7 +137,12 @@ public void testFtpInboundFlow() throws IOException {
132137

133138
MessageSource<?> source = context.getBean(FtpInboundFileSynchronizingMessageSource.class);
134139
assertThat(TestUtils.getPropertyValue(source, "maxFetchSize"), equalTo(10));
140+
141+
assertNotNull(this.integrationManagementConfigurer.getSourceMetrics("ftpInboundAdapter.source"));
142+
135143
registration.destroy();
144+
145+
assertNull(this.integrationManagementConfigurer.getSourceMetrics("ftpInboundAdapter.source"));
136146
}
137147

138148
@Test
@@ -221,6 +231,7 @@ public void testFtpMgetFlow() {
221231

222232
@Configuration
223233
@EnableIntegration
234+
@EnableIntegrationManagement
224235
public static class ContextConfiguration {
225236

226237
}

0 commit comments

Comments
 (0)