Skip to content

Commit 9cf52b7

Browse files
artembilangaryrussell
authored andcommitted
Fix double MBean registrations
After `MessagingAnnotationPostProcessor` fix for the late endpoints registration we end up with the fact that `IntegrationMBeanExporter` tries to register an `MBean` for the `MessageHandler/MessageSource` one more time after parsing an `AbstractEndpoint`. We don't fail because we catch an exception for already registered MBean and just log it with ERROR * Fix `IntegrationMBeanExporter` to check for `MessageHandler/MessageSource` presence in the registered `objectNames` * Some refactoring in the `IntegrationMBeanExporter` and fixes for Sonar smells
1 parent 9883b65 commit 9cf52b7

File tree

1 file changed

+52
-52
lines changed

1 file changed

+52
-52
lines changed

spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java

+52-52
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
2727
import java.util.concurrent.atomic.AtomicBoolean;
2828
import java.util.concurrent.atomic.AtomicLong;
2929
import java.util.concurrent.atomic.AtomicReference;
30+
import java.util.stream.Collectors;
3031

3132
import javax.lang.model.SourceVersion;
3233
import javax.management.DynamicMBean;
@@ -176,7 +177,6 @@ public IntegrationMBeanExporter() {
176177

177178
/**
178179
* Static properties that will be added to all object names.
179-
*
180180
* @param objectNameStaticProperties the objectNameStaticProperties to set
181181
*/
182182
public void setObjectNameStaticProperties(Map<String, String> objectNameStaticProperties) {
@@ -186,7 +186,6 @@ public void setObjectNameStaticProperties(Map<String, String> objectNameStaticPr
186186
/**
187187
* The JMX domain to use for MBeans registered. Defaults to <code>spring.application</code> (which is useful in
188188
* SpringSource HQ).
189-
*
190189
* @param domain the domain name to set
191190
*/
192191
public void setDefaultDomain(String domain) {
@@ -446,7 +445,6 @@ private MessageHandler handlerInAnonymousWrapper(final Object bean) {
446445
/**
447446
* Copy of private method in super class. Needed so we can avoid using the bean factory to extract the bean again,
448447
* and risk it being a proxy (which it almost certainly is by now).
449-
*
450448
* @param bean the bean instance to register
451449
* @param beanKey the bean name or human readable version if auto-generated
452450
* @return the JMX object name of the MBean that was registered
@@ -504,7 +502,6 @@ public void destroy() {
504502

505503
/**
506504
* Shutdown active components.
507-
*
508505
* @param howLong The time to wait in total for all activities to complete
509506
* in milliseconds.
510507
*/
@@ -557,8 +554,7 @@ private void doShutdown() {
557554
*/
558555
@ManagedOperation
559556
public void stopMessageSources() {
560-
for (Entry<String, MessageSourceMetrics> entry : this.allSourcesByName.entrySet()) {
561-
MessageSourceMetrics sourceMetrics = entry.getValue();
557+
for (MessageSourceMetrics sourceMetrics : this.allSourcesByName.values()) {
562558
if (sourceMetrics instanceof Lifecycle) {
563559
if (logger.isInfoEnabled()) {
564560
logger.info("Stopping message source " + sourceMetrics);
@@ -592,8 +588,7 @@ public void stopInboundMessageProducers() {
592588
@ManagedOperation
593589
public void stopActiveChannels() {
594590
// Stop any "active" channels (JMS etc).
595-
for (Entry<String, MessageChannelMetrics> entry : this.allChannelsByName.entrySet()) {
596-
MessageChannelMetrics metrics = entry.getValue();
591+
for (MessageChannelMetrics metrics : this.allChannelsByName.values()) {
597592
MessageChannel channel = (MessageChannel) metrics;
598593
if (channel instanceof Lifecycle) {
599594
if (logger.isInfoEnabled()) {
@@ -608,8 +603,7 @@ protected final void orderlyShutdownCapableComponentsBefore() {
608603
logger.debug("Initiating stop OrderlyShutdownCapable components");
609604
Map<String, OrderlyShutdownCapable> components = this.applicationContext
610605
.getBeansOfType(OrderlyShutdownCapable.class);
611-
for (Entry<String, OrderlyShutdownCapable> componentEntry : components.entrySet()) {
612-
OrderlyShutdownCapable component = componentEntry.getValue();
606+
for (OrderlyShutdownCapable component : components.values()) {
613607
int n = component.beforeShutdown();
614608
if (logger.isInfoEnabled()) {
615609
logger.info("Initiated stop for component " + component + "; it reported " + n + " active messages");
@@ -622,8 +616,7 @@ protected final void orderlyShutdownCapableComponentsAfter() {
622616
logger.debug("Finalizing stop OrderlyShutdownCapable components");
623617
Map<String, OrderlyShutdownCapable> components = this.applicationContext
624618
.getBeansOfType(OrderlyShutdownCapable.class);
625-
for (Entry<String, OrderlyShutdownCapable> componentEntry : components.entrySet()) {
626-
OrderlyShutdownCapable component = componentEntry.getValue();
619+
for (OrderlyShutdownCapable component : components.values()) {
627620
int n = component.afterShutdown();
628621
if (logger.isInfoEnabled()) {
629622
logger.info("Finalized stop for component " + component + "; it reported " + n + " active messages");
@@ -668,13 +661,11 @@ public long getActiveHandlerCountLong() {
668661

669662
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Queued Message Count")
670663
public int getQueuedMessageCount() {
671-
int count = 0;
672-
for (MessageChannelMetrics monitor : this.channels) {
673-
if (monitor instanceof QueueChannel) {
674-
count += ((QueueChannel) monitor).getQueueSize();
675-
}
676-
}
677-
return count;
664+
return this.channels.stream()
665+
.filter(QueueChannel.class::isInstance)
666+
.map(QueueChannel.class::cast)
667+
.mapToInt(QueueChannel::getQueueSize)
668+
.sum();
678669
}
679670

680671
@ManagedAttribute
@@ -779,7 +770,7 @@ private void registerHandlers() {
779770
private void registerHandler(MessageHandlerMetrics handler) {
780771
MessageHandlerMetrics monitor = enhanceHandlerMonitor(handler);
781772
String name = monitor.getManagedName();
782-
if (matches(this.componentNamePatterns, name)) {
773+
if (!this.objectNames.containsKey(handler) && matches(this.componentNamePatterns, name)) {
783774
String beanKey = getHandlerBeanKey(monitor);
784775
if (logger.isInfoEnabled()) {
785776
logger.info("Registering MessageHandler " + name);
@@ -797,7 +788,7 @@ private void registerSource(MessageSourceMetrics source) {
797788
MessageSourceMetrics monitor = enhanceSourceMonitor(source);
798789
String name = monitor.getManagedName();
799790
this.allSourcesByName.put(name, monitor);
800-
if (matches(this.componentNamePatterns, name)) {
791+
if (!this.objectNames.containsKey(source) && matches(this.componentNamePatterns, name)) {
801792
String beanKey = getSourceBeanKey(monitor);
802793
if (logger.isInfoEnabled()) {
803794
logger.info("Registering MessageSource " + name);
@@ -917,17 +908,14 @@ private String getStaticNames() {
917908
if (this.objectNameStaticProperties.isEmpty()) {
918909
return "";
919910
}
920-
StringBuilder builder = new StringBuilder();
921911

922-
for (Entry<Object, Object> entry : this.objectNameStaticProperties.entrySet()) {
923-
builder.append("," + entry.getKey() + "=" + entry.getValue());
924-
}
925-
return builder.toString();
912+
return ',' + this.objectNameStaticProperties.entrySet()
913+
.stream()
914+
.map((entry) -> entry.getKey() + "=" + entry.getValue())
915+
.collect(Collectors.joining(","));
926916
}
927917

928918
private MessageHandlerMetrics enhanceHandlerMonitor(MessageHandlerMetrics monitor) {
929-
MessageHandlerMetrics result = monitor;
930-
931919
if (monitor.getManagedName() != null && monitor.getManagedType() != null) {
932920
return monitor;
933921
}
@@ -956,11 +944,21 @@ private MessageHandlerMetrics enhanceHandlerMonitor(MessageHandlerMetrics monito
956944
endpoint = null;
957945
}
958946
}
959-
if (name != null && name.startsWith('_' + SI_PACKAGE)) {
960-
name = getInternalComponentName(name);
961-
source = "internal";
947+
return buildMessageHandlerMetrics(monitor, name, endpointName, source, endpoint);
948+
}
949+
950+
private MessageHandlerMetrics buildMessageHandlerMetrics(MessageHandlerMetrics monitor,
951+
String name, String endpointName, String source, IntegrationConsumer endpoint) {
952+
953+
MessageHandlerMetrics result = monitor;
954+
String managedType = source;
955+
String managedName = name;
956+
957+
if (managedName != null && managedName.startsWith('_' + SI_PACKAGE)) {
958+
managedName = getInternalComponentName(managedName);
959+
managedType = "internal";
962960
}
963-
if (name != null && name.startsWith(SI_PACKAGE)) {
961+
if (managedName != null && name.startsWith(SI_PACKAGE)) {
964962
MessageChannel inputChannel = endpoint.getInputChannel();
965963
if (inputChannel != null) {
966964
if (!this.anonymousHandlerCounters.containsKey(inputChannel)) {
@@ -976,34 +974,32 @@ private MessageHandlerMetrics enhanceHandlerMonitor(MessageHandlerMetrics monito
976974
if (total > 1) {
977975
suffix = "#" + total;
978976
}
979-
name = inputChannel + suffix;
980-
source = "anonymous";
977+
managedName = inputChannel + suffix;
978+
managedType = "anonymous";
981979
}
982980
}
983981

984982
if (endpoint instanceof Lifecycle) {
985983
result = wrapMessageHandlerInLifecycleMetrics(monitor, (Lifecycle) endpoint);
986984
}
987985

988-
if (name == null) {
986+
if (managedName == null) {
989987
if (monitor instanceof NamedComponent) {
990-
name = ((NamedComponent) monitor).getComponentName();
988+
managedName = ((NamedComponent) monitor).getComponentName();
991989
}
992-
if (name == null) {
993-
name = monitor.toString();
990+
if (managedName == null) {
991+
managedName = monitor.toString();
994992
}
995-
source = "handler";
993+
managedType = "handler";
996994
}
997995

998996
if (endpointName != null) {
999997
this.endpointsByMonitor.put(monitor, endpointName);
1000998
}
1001999

1002-
result.setManagedType(source);
1003-
result.setManagedName(name);
1004-
1000+
result.setManagedType(managedType);
1001+
result.setManagedName(managedName);
10051002
return result;
1006-
10071003
}
10081004

10091005
/**
@@ -1038,8 +1034,6 @@ private String getInternalComponentName(String name) {
10381034
}
10391035

10401036
private MessageSourceMetrics enhanceSourceMonitor(MessageSourceMetrics monitor) {
1041-
MessageSourceMetrics result = monitor;
1042-
10431037
if (monitor.getManagedName() != null) {
10441038
return monitor;
10451039
}
@@ -1082,6 +1076,13 @@ private MessageSourceMetrics enhanceSourceMonitor(MessageSourceMetrics monitor)
10821076
name = getInternalComponentName(name);
10831077
source = "internal";
10841078
}
1079+
return buildMessageSourceMetricsIfAny(monitor, name, endpointName, source, endpoint);
1080+
}
1081+
1082+
private MessageSourceMetrics buildMessageSourceMetricsIfAny(MessageSourceMetrics monitor, String name,
1083+
String endpointName, String source, Object endpoint) {
1084+
1085+
MessageSourceMetrics result = monitor;
10851086
if (name != null && name.startsWith(SI_PACKAGE)) {
10861087
Object target = endpoint;
10871088
if (endpoint instanceof Advised) {
@@ -1122,21 +1123,20 @@ else if (target instanceof SourcePollingChannelAdapter) {
11221123
}
11231124

11241125
if (endpoint instanceof Lifecycle) {
1125-
result = wrapMessageSourceInLifecycleMetrics(monitor, endpoint);
1126+
result = wrapMessageSourceInLifecycleMetrics(result, endpoint);
11261127
}
11271128

11281129
if (name == null) {
1129-
name = monitor.toString();
1130+
name = result.toString();
11301131
source = "source";
11311132
}
11321133

11331134
if (endpointName != null) {
1134-
this.endpointsByMonitor.put(monitor, endpointName);
1135+
this.endpointsByMonitor.put(result, endpointName);
11351136
}
11361137

1137-
monitor.setManagedType(source);
1138-
monitor.setManagedName(name);
1139-
1138+
result.setManagedType(source);
1139+
result.setManagedName(name);
11401140
return result;
11411141
}
11421142

0 commit comments

Comments
 (0)