INT-2628 Add ObjectNamingStrategy to IMBE
Allow customization of the generated ObjectName for the Integration components. JIRA: https://jira.springsource.org/browse/INT-2628 INT-2628 Polishing - Address PR comments - Rename `naming-strategy` to `object-naming-strategy` for consistency with `object-name-static-properties`
This commit is contained in:
committed by
Artem Bilan
parent
01ab48d664
commit
9849e2087d
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
@@ -33,7 +33,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Parser for the 'mbean-export' element of the integration JMX namespace.
|
||||
*
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
* @since 2.0
|
||||
@@ -61,7 +61,8 @@ public class MBeanExporterParser extends AbstractSingleBeanDefinitionParser {
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "object-name-static-properties");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "managed-components", "componentNamePatterns");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "shutdown-executor");
|
||||
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "object-naming-strategy", "namingStrategy");
|
||||
|
||||
builder.addPropertyValue("server", mbeanServer);
|
||||
this.registerMBeanExporterHelper(parserContext.getRegistry());
|
||||
}
|
||||
@@ -70,7 +71,7 @@ public class MBeanExporterParser extends AbstractSingleBeanDefinitionParser {
|
||||
BeanDefinitionBuilder mBeanExporterHelperBuilder = BeanDefinitionBuilder.rootBeanDefinition(MBeanExporterHelper.class);
|
||||
BeanDefinitionReaderUtils.registerWithGeneratedName(mBeanExporterHelperBuilder.getBeanDefinition(), registry);
|
||||
}
|
||||
|
||||
|
||||
private Object getMBeanServer(Element element, ParserContext parserContext) {
|
||||
String mbeanServer = element.getAttribute("server");
|
||||
if (StringUtils.hasText(mbeanServer)) {
|
||||
|
||||
@@ -167,7 +167,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements BeanPostP
|
||||
|
||||
private final MetadataMBeanInfoAssembler assembler = new MetadataMBeanInfoAssembler(attributeSource);
|
||||
|
||||
private final MetadataNamingStrategy namingStrategy = new MetadataNamingStrategy(attributeSource);
|
||||
private final MetadataNamingStrategy defaultNamingStrategy = new MetadataNamingStrategy(attributeSource);
|
||||
|
||||
private String[] componentNamePatterns = { "*" };
|
||||
|
||||
@@ -183,7 +183,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements BeanPostP
|
||||
super();
|
||||
// Shouldn't be necessary, but to be on the safe side...
|
||||
setAutodetect(false);
|
||||
setNamingStrategy(namingStrategy);
|
||||
setNamingStrategy(defaultNamingStrategy);
|
||||
setAssembler(assembler);
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements BeanPostP
|
||||
*/
|
||||
public void setDefaultDomain(String domain) {
|
||||
this.domain = domain;
|
||||
this.namingStrategy.setDefaultDomain(domain);
|
||||
this.defaultNamingStrategy.setDefaultDomain(domain);
|
||||
}
|
||||
|
||||
public void setComponentNamePatterns(String[] componentNamePatterns) {
|
||||
|
||||
@@ -204,6 +204,19 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="object-naming-strategy" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jmx.export.naming.ObjectNamingStrategy" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
An ObjectNamingStrategy to generate the MBean's ObjectName. See the reference documentation
|
||||
for details of the default ObjectName. Also see 'object-name-static-properties'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
@@ -18,11 +18,14 @@
|
||||
<jmx:mbean-export id="integratioMbeanExporter"
|
||||
server="mbs"
|
||||
default-domain="tests.MBeanExpoerterParser"
|
||||
object-name-static-properties="appProperties"/>
|
||||
object-name-static-properties="appProperties"
|
||||
object-naming-strategy="keyNamer"/>
|
||||
|
||||
<util:properties id="appProperties">
|
||||
<prop key="foo">foo</prop>
|
||||
<prop key="bar">bar</prop>
|
||||
</util:properties>
|
||||
|
||||
<bean id="keyNamer" class="org.springframework.jmx.export.naming.KeyNamingStrategy" />
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.integration.jmx.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Properties;
|
||||
@@ -57,6 +58,7 @@ public class MBeanExporterParserTests {
|
||||
assertTrue(properties.containsKey("foo"));
|
||||
assertTrue(properties.containsKey("bar"));
|
||||
assertEquals(server, exporter.getServer());
|
||||
assertSame(context.getBean("keyNamer"), TestUtils.getPropertyValue(exporter, "namingStrategy"));
|
||||
exporter.destroy();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:jmx="http://www.springframework.org/schema/integration/jmx"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/jmx
|
||||
http://www.springframework.org/schema/integration/jmx/spring-integration-jmx.xsd">
|
||||
|
||||
<jmx:mbean-export id="integrationMbeanExporter" server="mbs" default-domain="test.MBeanRegistration"
|
||||
object-naming-strategy="namer" />
|
||||
|
||||
<bean id="namer" class="org.springframework.integration.jmx.config.MBeanRegistrationCustomNamingTests$Namer" />
|
||||
|
||||
<context:mbean-server id="mbs" />
|
||||
|
||||
<int:channel id="testChannel" />
|
||||
|
||||
<int:service-activator id="service" input-channel="testChannel" method="get">
|
||||
<bean class="org.springframework.integration.jmx.config.MBeanRegistrationCustomNamingTests$Source"/>
|
||||
</int:service-activator>
|
||||
|
||||
<int:logging-channel-adapter id="logger" channel="testChannel"/>
|
||||
|
||||
<int:chain id="chain" input-channel="chainin">
|
||||
<int:transformer id="t1" expression="'foo'"/>
|
||||
<int:filter id="f1" expression="true"/>
|
||||
</int:chain>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.jmx.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jmx.export.naming.KeyNamingStrategy;
|
||||
import org.springframework.jmx.export.naming.ObjectNamingStrategy;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Gary Russell
|
||||
* @since 3.0
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class MBeanRegistrationCustomNamingTests {
|
||||
|
||||
@Autowired
|
||||
private MBeanServer server;
|
||||
|
||||
@Test
|
||||
public void testHandlerMBeanRegistration() throws Exception {
|
||||
Set<ObjectName> names = server.queryNames(new ObjectName("test.MBeanRegistration:type=Integration,componentType=MessageHandler,*"), null);
|
||||
assertEquals(6, names.size());
|
||||
assertTrue(names.contains(new ObjectName("test.MBeanRegistration:type=Integration,componentType=MessageHandler,name=chain,bean=endpoint")));
|
||||
assertTrue(names.contains(new ObjectName("test.MBeanRegistration:type=Integration,componentType=MessageHandler,name=chain$child.t1,bean=handler")));
|
||||
assertTrue(names.contains(new ObjectName("test.MBeanRegistration:type=Integration,componentType=MessageHandler,name=chain$child.f1,bean=handler")));
|
||||
}
|
||||
|
||||
public static class Source {
|
||||
public String get() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
|
||||
public static class Namer implements ObjectNamingStrategy {
|
||||
|
||||
private final ObjectNamingStrategy realNamer = new KeyNamingStrategy();
|
||||
@Override
|
||||
public ObjectName getObjectName(Object managedBean, String beanKey) throws MalformedObjectNameException {
|
||||
String actualBeanKey = beanKey.replace("type=", "type=Integration,componentType=");
|
||||
return realNamer.getObjectName(managedBean, actualBeanKey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -366,6 +366,46 @@
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
Custom elements can be appended to the object name by providing a reference to a
|
||||
<classname>Properties</classname> object in the <code>object-name-static-properties</code> attribute.
|
||||
</para>
|
||||
<para>
|
||||
Also, since <emphasis>Spring Integration 3.0</emphasis>, you can use a custom
|
||||
<ulink url="http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jmx/export/naming/ObjectNamingStrategy.html"
|
||||
>ObjectNamingStrategy</ulink>
|
||||
using the <code>object-naming-strategy</code> attribute. This permits greater control over the naming of the
|
||||
MBeans. For example, to group all Integration MBeans under
|
||||
an 'Integration' type. A simple custom naming strategy implementation might be:
|
||||
</para>
|
||||
<programlisting language="java"><![CDATA[public class Namer implements ObjectNamingStrategy {
|
||||
|
||||
private final ObjectNamingStrategy realNamer = new KeyNamingStrategy();
|
||||
@Override
|
||||
public ObjectName getObjectName(Object managedBean, String beanKey) throws MalformedObjectNameException {
|
||||
String actualBeanKey = beanKey.replace("type=", "type=Integration,componentType=");
|
||||
return realNamer.getObjectName(managedBean, actualBeanKey);
|
||||
}
|
||||
|
||||
}]]></programlisting>
|
||||
<para>
|
||||
The <code>beanKey</code> argument is a String containing the standard object name beginning with
|
||||
the <code>default-domain</code> and including any additional static properties.
|
||||
This example simply moves the standard <code>type</code> part to <code>componentType</code> and
|
||||
sets the <code>type</code> to 'Integration',
|
||||
enabling selection of all Integration MBeans in one query:
|
||||
<code>"my.domain:type=Integration,*</code>. This also groups the beans under one tree entry under the
|
||||
domain in tools like VisualVM.
|
||||
</para>
|
||||
<note>
|
||||
The default naming strategy is a
|
||||
<ulink url="http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jmx/export/naming/MetadataNamingStrategy.html"
|
||||
>MetadataNamingStrategy</ulink>. The exporter propagates the <code>default-domain</code> to that object to allow it
|
||||
to generate a fallback object name if parsing of the bean key fails. If your custom naming strategy is a
|
||||
<classname>MetadataNamingStrategy</classname> (or subclass), the exporter will <emphasis role="bold">not</emphasis>
|
||||
propagate the <code>default-domain</code>; you will need to configure it on your strategy bean.
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section id="jmx-channel-features">
|
||||
|
||||
@@ -63,12 +63,23 @@
|
||||
<section id="3.0-jmx">
|
||||
<title>JMX Support</title>
|
||||
<para>
|
||||
A new <code><int-jmx:tree-polling-channel-adapter/></code> is provided; this
|
||||
adapter queries the JMX MBean tree and sends a message with a payload that is the
|
||||
graph of objects that matches the query. By default the MBeans are mapped to
|
||||
primitives and simple Objects like Map, List and arrays - permitting simple
|
||||
transformation, for example, to JSON
|
||||
<xref linkend="jmx"/>.
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
A new <code><int-jmx:tree-polling-channel-adapter/></code> is provided; this
|
||||
adapter queries the JMX MBean tree and sends a message with a payload that is the
|
||||
graph of objects that matches the query. By default the MBeans are mapped to
|
||||
primitives and simple Objects like Map, List and arrays - permitting simple
|
||||
transformation, for example, to JSON.
|
||||
</listitem>
|
||||
<listitem>
|
||||
The <classname>IntegrationMBeanExporter</classname> now allows the configuration of
|
||||
a custom <classname>ObjectNamingStrategy</classname> using the <code>naming-strategy</code>
|
||||
attribute.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
For more information, see <xref linkend="jmx"/>.
|
||||
</para>
|
||||
</section>
|
||||
<section id="3.0-tail">
|
||||
|
||||
Reference in New Issue
Block a user