From 5db5f5fb7a73353b9ad01ac9ab5a575864da06a6 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Wed, 14 Jul 2010 16:16:03 +0000 Subject: [PATCH] INT-1018 added namespace support for operation-invoking-outbound-gateway --- .../jmx/config/JmxNamespaceHandler.java | 2 + ...perationInvokingOutboundGatewayParser.java | 47 +++++++ .../jmx/config/spring-integration-jmx-2.0.xsd | 15 +++ ...onInvokingOutboundGatewayTests-context.xml | 54 ++++++++ ...OperationInvokingOutboundGatewayTests.java | 123 ++++++++++++++++++ .../integration/jmx/config/TestBean.java | 7 + 6 files changed, 248 insertions(+) create mode 100644 spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayParser.java create mode 100644 spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayTests-context.xml create mode 100644 spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayTests.java diff --git a/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/JmxNamespaceHandler.java b/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/JmxNamespaceHandler.java index 6acc15dc54..323dc41046 100644 --- a/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/JmxNamespaceHandler.java +++ b/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/JmxNamespaceHandler.java @@ -22,12 +22,14 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa * Namespace handler for Spring Integration's jmx namespace. * * @author Mark Fisher + * @author Oleg Zhurakousky * @since 2.0 */ public class JmxNamespaceHandler extends AbstractIntegrationNamespaceHandler { public void init() { this.registerBeanDefinitionParser("operation-invoking-channel-adapter", new OperationInvokingChannelAdapterParser()); + this.registerBeanDefinitionParser("operation-invoking-outbound-gateway", new OperationInvokingOutboundGatewayParser()); this.registerBeanDefinitionParser("attribute-polling-channel-adapter", new AttributePollingChannelAdapterParser()); this.registerBeanDefinitionParser("notification-listening-channel-adapter", new NotificationListeningChannelAdapterParser()); this.registerBeanDefinitionParser("notification-publishing-channel-adapter", new NotificationPublishingChannelAdapterParser()); diff --git a/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayParser.java b/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayParser.java new file mode 100644 index 0000000000..0799210fac --- /dev/null +++ b/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayParser.java @@ -0,0 +1,47 @@ +/* + * Copyright 2002-2010 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 org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.integration.config.xml.AbstractConsumerEndpointParser; +import org.springframework.integration.config.xml.IntegrationNamespaceUtils; +import org.w3c.dom.Element; + +/** + * @author Oleg Zhurakousky + * @since 2.0 + */ +public class OperationInvokingOutboundGatewayParser extends AbstractConsumerEndpointParser{ + + @Override + protected String getInputChannelAttributeName() { + return "request-channel"; + } + + @Override + protected BeanDefinitionBuilder parseHandler(Element element, + ParserContext parserContext) { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition( + "org.springframework.integration.jmx.OperationInvokingMessageHandler"); + IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "mbean-server", "server"); + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "default-object-name"); + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "default-operation-name"); + IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel", "outputChannel"); + return builder; + } + +} diff --git a/spring-integration-jmx/src/main/resources/org/springframework/integration/jmx/config/spring-integration-jmx-2.0.xsd b/spring-integration-jmx/src/main/resources/org/springframework/integration/jmx/config/spring-integration-jmx-2.0.xsd index 4b4cfcb9ab..dcab9bde80 100644 --- a/spring-integration-jmx/src/main/resources/org/springframework/integration/jmx/config/spring-integration-jmx-2.0.xsd +++ b/spring-integration-jmx/src/main/resources/org/springframework/integration/jmx/config/spring-integration-jmx-2.0.xsd @@ -37,6 +37,21 @@ + + + + Defines an outbound Gateway which allows for Message-driven invocation of managed operations that return values + + + + + + + + + + + diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayTests-context.xml b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayTests-context.xml new file mode 100644 index 0000000000..dbc4728ce2 --- /dev/null +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayTests-context.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayTests.java new file mode 100644 index 0000000000..a1347938e9 --- /dev/null +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayTests.java @@ -0,0 +1,123 @@ +/* + * Copyright 2002-2010 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 java.util.List; + +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.integration.channel.PollableChannel; +import org.springframework.integration.core.Message; +import org.springframework.integration.core.MessageChannel; +import org.springframework.integration.jmx.JmxHeaders; +import org.springframework.integration.message.MessageBuilder; +import org.springframework.integration.message.StringMessage; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * @author Oleg Zhurakousky + * + */ +@ContextConfiguration +@RunWith(SpringJUnit4ClassRunner.class) +public class OperationInvokingOutboundGatewayTests { + @Autowired + @Qualifier("noDefaultInput") + private MessageChannel noDefaultInput; + + @Autowired + @Qualifier("noDefaultOutput") + private PollableChannel noDefaultOutput; + @Autowired + @Qualifier("noDefaultInputA") + private MessageChannel noDefaultInputA; + + @Autowired + @Qualifier("noDefaultOutputA") + private PollableChannel noDefaultOutputA; + + @Autowired + @Qualifier("defaultInput") + private MessageChannel defaultInput; + + @Autowired + @Qualifier("defaultOutput") + private PollableChannel defaultOutput; + + @Autowired + private TestBean testBeanForDefaultsGateway; + + @Autowired + private TestBean testBeanForNoDefaultsGateway; + @After + public void resetLists() { + testBeanForDefaultsGateway.messages.clear(); + testBeanForNoDefaultsGateway.messages.clear(); + } + + @Test + public void adapterWithoutNoDefaultsAndReturn() throws Exception { + noDefaultInput.send(createMessageWithHeadersForReturnCase("1")); + assertEquals(1, ((List)noDefaultOutput.receive().getPayload()).size()); + noDefaultInput.send(createMessageWithHeadersForReturnCase("2")); + assertEquals(2, ((List)noDefaultOutput.receive().getPayload()).size()); + noDefaultInput.send(createMessageWithHeadersForReturnCase("3")); + assertEquals(3, ((List)noDefaultOutput.receive().getPayload()).size()); + } + + @Test + public void adapterWithoutNoDefaultsAndReturnAndReplyChannel() throws Exception { + noDefaultInputA.send(createMessageWithHeadersForReturnCaseAndReplyChannel("1", noDefaultOutputA)); + assertEquals(1, ((List)noDefaultOutputA.receive().getPayload()).size()); + noDefaultInputA.send(createMessageWithHeadersForReturnCaseAndReplyChannel("2", noDefaultOutputA)); + assertEquals(2, ((List)noDefaultOutputA.receive().getPayload()).size()); + noDefaultInputA.send(createMessageWithHeadersForReturnCaseAndReplyChannel("3", noDefaultOutputA)); + assertEquals(3, ((List)noDefaultOutputA.receive().getPayload()).size()); + } + + @Test + public void adapterWithoutDefaultsAndReturn() throws Exception { + defaultInput.send(new StringMessage("1")); + assertEquals(1, ((List)defaultOutput.receive().getPayload()).size()); + defaultInput.send(new StringMessage("2")); + assertEquals(2, ((List)defaultOutput.receive().getPayload()).size()); + defaultInput.send(new StringMessage("3")); + assertEquals(3, ((List)defaultOutput.receive().getPayload()).size()); + } + + private static Message createMessageWithHeadersForReturnCase(String payload) { + String objectName = "org.springframework.integration.jmx.config:name=testBeanForNoDefaultsGateway,type=TestBean"; + return MessageBuilder.withPayload(payload) + .setHeader(JmxHeaders.OBJECT_NAME, objectName) + .setHeader(JmxHeaders.OPERATION_NAME, "testWithReturn") + .build(); + } + + private static Message createMessageWithHeadersForReturnCaseAndReplyChannel(String payload, MessageChannel replyChannel) { + String objectName = "org.springframework.integration.jmx.config:name=testBeanForNoDefaultsGateway,type=TestBean"; + return MessageBuilder.withPayload(payload) + .setHeader(JmxHeaders.OBJECT_NAME, objectName) + .setHeader(JmxHeaders.OPERATION_NAME, "testWithReturn") + .setReplyChannel(replyChannel) + .build(); + } +} diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/TestBean.java b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/TestBean.java index 538f84c71d..fa34a4a236 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/TestBean.java +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/TestBean.java @@ -25,6 +25,7 @@ import org.springframework.jmx.export.annotation.ManagedResource; /** * @author Mark Fisher + * @author Oleg Zhurakousky * @since 2.0 */ @ManagedResource @@ -41,5 +42,11 @@ public class TestBean { public void test(String text) { this.messages.add(text); } + + @ManagedOperation + public List testWithReturn(String text) { + this.messages.add(text); + return messages; + } }