INT-1416: replace control-bus with mbean-exporter

This commit is contained in:
David Syer
2010-09-03 12:39:00 +00:00
parent c7cfa6fdbc
commit 4c3287d2c3
9 changed files with 39 additions and 38 deletions

View File

@@ -25,7 +25,6 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.integration.Message;
import org.springframework.integration.MessageHeaders;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.jmx.JmxHeaders;
import org.springframework.integration.jmx.OperationInvokingMessageHandler;
@@ -43,7 +42,7 @@ public class ControlBus implements BeanFactoryAware, InitializingBean {
public static final String TARGET_BEAN_NAME = JmxHeaders.PREFIX + "_controlBus_targetBeanName";
private volatile SubscribableChannel operationChannel;
private final SubscribableChannel operationChannel;
private volatile ListableBeanFactory beanFactory;
@@ -51,16 +50,12 @@ public class ControlBus implements BeanFactoryAware, InitializingBean {
private final MBeanServer server;
/**
* Create a {@link ControlBus}.
*/
public ControlBus(ObjectNameLocator locator, MBeanServer server) {
public ControlBus(ObjectNameLocator locator, MBeanServer server, SubscribableChannel operationChannel) {
this.exporter = locator;
this.server = server;
}
public void setOperationChannel(SubscribableChannel operationChannel) {
this.operationChannel = operationChannel;
}
@@ -78,16 +73,12 @@ public class ControlBus implements BeanFactoryAware, InitializingBean {
Assert.isTrue(beanFactory instanceof ListableBeanFactory, "A ListableBeanFactory is required.");
this.beanFactory = (ListableBeanFactory) beanFactory;
}
public void afterPropertiesSet() throws Exception {
OperationInvokingMessageHandler handler = new ControlBusOperationInvokingMessageHandler();
handler.setBeanFactory(this.beanFactory);
handler.setServer(this.server);
handler.afterPropertiesSet();
if (this.operationChannel == null) {
this.operationChannel = new DirectChannel();
}
this.operationChannel.subscribe(handler);
}

View File

@@ -33,7 +33,7 @@ public class JmxNamespaceHandler extends AbstractIntegrationNamespaceHandler {
this.registerBeanDefinitionParser("attribute-polling-channel-adapter", new AttributePollingChannelAdapterParser());
this.registerBeanDefinitionParser("notification-listening-channel-adapter", new NotificationListeningChannelAdapterParser());
this.registerBeanDefinitionParser("notification-publishing-channel-adapter", new NotificationPublishingChannelAdapterParser());
this.registerBeanDefinitionParser("control-bus", new ControlBusParser());
this.registerBeanDefinitionParser("mbean-exporter", new MBeanExporterParser());
}
}

View File

@@ -18,10 +18,10 @@ package org.springframework.integration.jmx.config;
import javax.management.MBeanServerFactory;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.util.StringUtils;
@@ -31,20 +31,23 @@ import org.w3c.dom.Element;
* @author Mark Fisher
* @since 2.0
*/
public class ControlBusParser extends AbstractSimpleBeanDefinitionParser {
public class MBeanExporterParser extends AbstractBeanDefinitionParser {
@Override
protected String getBeanClassName(Element element) {
return "org.springframework.integration.control.ControlBus";
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
Object mbeanServer = getMBeanServer(element, parserContext);
builder.addConstructorArgValue(getMBeanExporter(element, parserContext, mbeanServer));
builder.addConstructorArgValue(mbeanServer);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "operation-channel");
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition("org.springframework.integration.monitor.IntegrationMBeanExporter");
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "domain");
builder.addPropertyValue("server", mbeanServer);
if (StringUtils.hasText(element.getAttribute("operation-channel"))) {
AbstractBeanDefinition controlBus = getControlBus(element, parserContext, mbeanServer, builder
.getRawBeanDefinition());
parserContext.getRegistry().registerBeanDefinition(
parserContext.getReaderContext().generateBeanName(controlBus), controlBus);
}
return builder.getBeanDefinition();
}
private Object getMBeanServer(Element element, ParserContext parserContext) {
@@ -57,12 +60,14 @@ public class ControlBusParser extends AbstractSimpleBeanDefinitionParser {
}
}
private BeanMetadataElement getMBeanExporter(Element element, ParserContext parserContext, Object mbeanServer) {
private AbstractBeanDefinition getControlBus(Element element, ParserContext parserContext, Object mbeanServer,
Object mbeanExporter) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition("org.springframework.integration.monitor.IntegrationMBeanExporter");
.genericBeanDefinition("org.springframework.integration.control.ControlBus");
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "domain");
builder.addPropertyValue("server", mbeanServer);
builder.addConstructorArgValue(mbeanExporter);
builder.addConstructorArgValue(mbeanServer);
builder.addConstructorArgReference(element.getAttribute("operation-channel"));
return builder.getBeanDefinition();
}

View File

@@ -105,11 +105,11 @@
</xsd:complexType>
</xsd:element>
<xsd:element name="control-bus">
<xsd:element name="mbean-exporter">
<xsd:annotation>
<xsd:documentation>
Defines a Control Bus that exports Message Channels and Endpoints as MBeans
and connects to an "operation channel".
Exports Message Channels and Endpoints as MBeans
and optionally connects to an "operation channel".
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
@@ -126,7 +126,8 @@
<xsd:attribute name="operation-channel" use="optional">
<xsd:annotation>
<xsd:documentation>
The Message Channel that can be used to send operation commands to
If provided a control bus will be created and subscribed to the Message Channel.
The channel can then be used to send operation commands to
this Control Bus. It must implement SubscribableChannel.
</xsd:documentation>
<xsd:appinfo>
@@ -140,7 +141,7 @@
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="adapterType">
<xsd:annotation>
<xsd:documentation>

View File

@@ -87,6 +87,7 @@ public class ControlBusOperationChannelTests {
BeanDefinition controlBusDef = new RootBeanDefinition(ControlBus.class);
controlBusDef.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("mbeanServer"));
controlBusDef.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("exporter"));
controlBusDef.getConstructorArgumentValues().addGenericArgumentValue(new DirectChannel());
context.registerBeanDefinition("controlBus", controlBusDef);
return exporterDef;
}

View File

@@ -189,6 +189,7 @@ public class ControlBusTests {
BeanDefinition controlBusDef = new RootBeanDefinition(ControlBus.class);
controlBusDef.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("mbeanServer"));
controlBusDef.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("exporter"));
controlBusDef.getConstructorArgumentValues().addGenericArgumentValue(new DirectChannel());
context.registerBeanDefinition("controlBus", controlBusDef);
return exporterDef;
}

View File

@@ -5,6 +5,8 @@
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<int:channel id="controlChannel" />
<int:channel id="testDirectChannel" />
<int:channel id="testQueueChannel">
@@ -22,6 +24,7 @@
<bean id="controlBus" class="org.springframework.integration.control.ControlBus">
<constructor-arg ref="mbeanExporter" />
<constructor-arg ref="mbeanServer" />
<constructor-arg ref="controlChannel" />
</bean>
<bean id="mbeanExporter" class="org.springframework.integration.monitor.IntegrationMBeanExporter">

View File

@@ -17,6 +17,6 @@
<si:channel id="testChannel"/>
<jmx:control-bus id="controlBus" mbean-server="mbs" operation-channel="testChannel" domain="tests.ControlBusParser"/>
<jmx:mbean-exporter id="controlBus" mbean-server="mbs" operation-channel="testChannel" domain="tests.ControlBusParser"/>
</beans>

View File

@@ -36,15 +36,14 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class ControlBusParserTests {
public class MBeanExporterParserTests {
@Autowired
private ApplicationContext context;
@Test
public void test() throws InterruptedException {
ControlBus controlBus = this.context.getBean("controlBus", ControlBus.class);
ControlBus controlBus = this.context.getBean(ControlBus.class);
assertEquals(controlBus.getOperationChannel(), this.context.getBean("testChannel"));
MBeanServer server = this.context.getBean("mbs", MBeanServer.class);
MBeanExporter exporter = (MBeanExporter) new DirectFieldAccessor(controlBus).getPropertyValue("exporter");