|
28 | 28 | import java.util.concurrent.atomic.AtomicLong; |
29 | 29 | import java.util.concurrent.atomic.AtomicReference; |
30 | 30 |
|
| 31 | +import javax.lang.model.SourceVersion; |
31 | 32 | import javax.management.DynamicMBean; |
32 | 33 | import javax.management.JMException; |
33 | 34 | import javax.management.ObjectName; |
@@ -157,6 +158,8 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati |
157 | 158 |
|
158 | 159 | private final AtomicBoolean shuttingDown = new AtomicBoolean(); |
159 | 160 |
|
| 161 | + private boolean quoteNames; |
| 162 | + |
160 | 163 |
|
161 | 164 | public IntegrationMBeanExporter() { |
162 | 165 | super(); |
@@ -216,6 +219,14 @@ public void setEmbeddedValueResolver(StringValueResolver resolver) { |
216 | 219 |
|
217 | 220 | @Override |
218 | 221 | public void afterSingletonsInstantiated() { |
| 222 | + if (this.applicationContext.containsBean(IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME)) { |
| 223 | + Properties props = this.applicationContext |
| 224 | + .getBean(IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME, Properties.class); |
| 225 | + String prop = props.getProperty("spring.integration.jmx.quote.names"); |
| 226 | + if (prop != null) { |
| 227 | + this.quoteNames = Boolean.parseBoolean(prop); |
| 228 | + } |
| 229 | + } |
219 | 230 | Map<String, MessageHandlerMetrics> messageHandlers = |
220 | 231 | this.applicationContext.getBeansOfType(MessageHandlerMetrics.class); |
221 | 232 | for (Entry<String, MessageHandlerMetrics> entry : messageHandlers.entrySet()) { |
@@ -744,28 +755,43 @@ private Object extractTarget(Object bean) { |
744 | 755 | } |
745 | 756 |
|
746 | 757 | private String getChannelBeanKey(String channel) { |
747 | | - String name = "" + channel; |
748 | | - if (name.startsWith("org.springframework.integration")) { |
749 | | - name = name + ",source=anonymous"; |
| 758 | + String extra = ""; |
| 759 | + if (channel.startsWith("org.springframework.integration")) { |
| 760 | + extra = ",source=anonymous"; |
750 | 761 | } |
751 | | - return String.format(this.domain + ":type=MessageChannel,name=%s" + getStaticNames(), name); |
| 762 | + return String.format(this.domain + ":type=MessageChannel,name=%s%s" + getStaticNames(), |
| 763 | + quoteIfNecessary(channel), extra); |
752 | 764 | } |
753 | 765 |
|
754 | 766 | private String getHandlerBeanKey(MessageHandlerMetrics handler) { |
755 | 767 | // This ordering of keys seems to work with default settings of JConsole |
756 | 768 | return String.format(this.domain + ":type=MessageHandler,name=%s,bean=%s" + getStaticNames(), |
757 | | - handler.getManagedName(), handler.getManagedType()); |
| 769 | + quoteIfNecessary(handler.getManagedName()), quoteIfNecessary(handler.getManagedType())); |
758 | 770 | } |
759 | 771 |
|
760 | 772 | private String getSourceBeanKey(MessageSourceMetrics source) { |
761 | 773 | // This ordering of keys seems to work with default settings of JConsole |
762 | 774 | return String.format(this.domain + ":type=MessageSource,name=%s,bean=%s" + getStaticNames(), |
763 | | - source.getManagedName(), source.getManagedType()); |
| 775 | + quoteIfNecessary(source.getManagedName()), quoteIfNecessary(source.getManagedType())); |
764 | 776 | } |
765 | 777 |
|
766 | 778 | private String getEndpointBeanKey(AbstractEndpoint endpoint, String name, String source) { |
767 | 779 | // This ordering of keys seems to work with default settings of JConsole |
768 | | - return String.format(this.domain + ":type=ManagedEndpoint,name=%s,bean=%s" + getStaticNames(), name, source); |
| 780 | + return String.format(this.domain + ":type=ManagedEndpoint,name=%s,bean=%s" + getStaticNames(), |
| 781 | + quoteIfNecessary(name), source); |
| 782 | + } |
| 783 | + |
| 784 | + /* |
| 785 | + * https://www.oracle.com/technetwork/java/javase/tech/best-practices-jsp-136021.html |
| 786 | + * |
| 787 | + * The set of characters in a value is also limited. If special characters may |
| 788 | + * occur, it is recommended that the value be quoted, using ObjectName.quote. If |
| 789 | + * the value for a given key is sometimes quoted, then it should always be quoted. |
| 790 | + * By default, if a value is a string (rather than a number, say), then it should |
| 791 | + * be quoted unless you are sure that it will never contain special characters. |
| 792 | + */ |
| 793 | + private String quoteIfNecessary(String name) { |
| 794 | + return SourceVersion.isName(name) ? name : this.quoteNames ? ObjectName.quote(name) : name; |
769 | 795 | } |
770 | 796 |
|
771 | 797 | private String getStaticNames() { |
|
0 commit comments