diff --git a/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/config/RSocketInboundGatewayParser.java b/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/config/RSocketInboundGatewayParser.java
new file mode 100644
index 0000000000..009385fe99
--- /dev/null
+++ b/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/config/RSocketInboundGatewayParser.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2002-2019 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
+ *
+ * https://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.rsocket.config;
+
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.integration.config.xml.AbstractInboundGatewayParser;
+import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
+import org.springframework.integration.rsocket.inbound.RSocketInboundGateway;
+
+/**
+ * Parser for the <inbound-gateway/> element of the 'rsocket' namespace.
+ *
+ * @author Mark Fisher
+ * @author Gary Russell
+ */
+public class RSocketInboundGatewayParser extends AbstractInboundGatewayParser {
+
+ @Override
+ protected Class> getBeanClass(Element element) {
+ return RSocketInboundGateway.class;
+ }
+
+ @Override
+ protected boolean isEligibleAttribute(String attributeName) {
+ return !attributeName.equals("path")
+ && !attributeName.equals("rsocket-strategies")
+ && !attributeName.equals("rsocket-connector")
+ && !attributeName.equals("request-element-type")
+ && super.isEligibleAttribute(attributeName);
+ }
+
+ @Override
+ protected void doPostProcess(BeanDefinitionBuilder builder, Element element) {
+ builder.addConstructorArgValue(element.getAttribute("path"));
+ IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "request-element-type",
+ "requestElementClass");
+ IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "rsocket-strategies",
+ "rSocketStrategies");
+ IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "rsocket-connector",
+ "RSocketConnector");
+ }
+
+}
diff --git a/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/config/RSocketNamespaceHandler.java b/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/config/RSocketNamespaceHandler.java
index a11974469d..a93edaf5d5 100644
--- a/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/config/RSocketNamespaceHandler.java
+++ b/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/config/RSocketNamespaceHandler.java
@@ -28,7 +28,8 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa
public class RSocketNamespaceHandler extends AbstractIntegrationNamespaceHandler {
public void init() {
-
+ registerBeanDefinitionParser("inbound-gateway", new RSocketInboundGatewayParser());
+ registerBeanDefinitionParser("outbound-gateway", new RSocketOutboundGatewayParser());
}
}
diff --git a/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/config/RSocketOutboundGatewayParser.java b/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/config/RSocketOutboundGatewayParser.java
new file mode 100644
index 0000000000..60cdb9d53c
--- /dev/null
+++ b/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/config/RSocketOutboundGatewayParser.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2019 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
+ *
+ * https://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.rsocket.config;
+
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.core.Conventions;
+import org.springframework.integration.config.xml.AbstractConsumerEndpointParser;
+import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
+import org.springframework.integration.rsocket.outbound.RSocketOutboundGateway;
+
+/**
+ * Parser for the 'outbound-gateway' element of the rsocket namespace.
+ *
+ * @author Artem Bilan
+ *
+ * @since 5.2
+ */
+public class RSocketOutboundGatewayParser extends AbstractConsumerEndpointParser {
+
+ @Override
+ protected String getInputChannelAttributeName() {
+ return "request-channel";
+ }
+
+ @Override
+ protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RSocketOutboundGateway.class);
+ BeanDefinition routeExpression =
+ IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression("route", "route-expression",
+ parserContext, element, true);
+ builder.addConstructorArgValue(routeExpression);
+ IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "client-rsocket-connector",
+ "clientRSocketConnector");
+ populateValueOrExpressionIfAny(builder, element, parserContext, "command");
+ populateValueOrExpressionIfAny(builder, element, parserContext, "publisher-element-type");
+ populateValueOrExpressionIfAny(builder, element, parserContext, "expected-response-type");
+ return builder;
+ }
+
+ private static void populateValueOrExpressionIfAny(BeanDefinitionBuilder builder, Element element,
+ ParserContext parserContext, String valueAttributeName) {
+
+ String expressionAttributeName = valueAttributeName + "-expression";
+
+ BeanDefinition expression =
+ IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression(valueAttributeName,
+ expressionAttributeName, parserContext, element, false);
+ if (expression != null) {
+ builder.addPropertyValue(Conventions.attributeNameToPropertyName(expressionAttributeName), expression);
+ }
+ }
+
+}
diff --git a/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/inbound/RSocketInboundGateway.java b/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/inbound/RSocketInboundGateway.java
index 86a26de8ed..3cf42a2751 100644
--- a/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/inbound/RSocketInboundGateway.java
+++ b/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/inbound/RSocketInboundGateway.java
@@ -94,7 +94,7 @@ public class RSocketInboundGateway extends MessagingGatewaySupport implements In
private ResolvableType requestElementType;
/**
- * Instantiate based on the provided path patterns to map this endpoint for incoming RSocket requests.
+ * Instantiate based on the provided Ant-style path patterns to map this endpoint for incoming RSocket requests.
* @param path the mapping patterns to use.
*/
public RSocketInboundGateway(String... path) {
diff --git a/spring-integration-rsocket/src/main/resources/org/springframework/integration/rsocket/config/spring-integration-rsocket-5.2.xsd b/spring-integration-rsocket/src/main/resources/org/springframework/integration/rsocket/config/spring-integration-rsocket-5.2.xsd
index 1054e74df4..8f16688f8c 100644
--- a/spring-integration-rsocket/src/main/resources/org/springframework/integration/rsocket/config/spring-integration-rsocket-5.2.xsd
+++ b/spring-integration-rsocket/src/main/resources/org/springframework/integration/rsocket/config/spring-integration-rsocket-5.2.xsd
@@ -1,21 +1,246 @@
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:tool="http://www.springframework.org/schema/tool"
+ xmlns:integration="http://www.springframework.org/schema/integration"
+ targetNamespace="http://www.springframework.org/schema/integration/rsocket"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified">
+ schemaLocation="https://www.springframework.org/schema/integration/spring-integration-5.2.xsd"/>
-
+
+ Defines the configuration elements for Spring Integration's RSocket channel adapters.
+
+
+
+
+
+ Configures a Messaging Gateway Endpoint for the
+ 'org.springframework.integration.rsocket.inbound.RSocketInboundGateway to receive RSocket
+ requests and produce RSocket responses.
+
+
+
+
+
+
+
+ The comma separated Ant-style path patterns this endpoint is mapped onto.
+
+
+
+
+
+
+
+
+
+
+
+ If a downstream exception is thrown and an error-channel is specified,
+ the MessagingException will be sent to this channel. Otherwise, any such exception
+ will be propagated to the calling system.
+
+
+
+
+
+
+ An 'RSocketStrategies' bean reference for encoding/decoding requests/replies.
+
+
+
+
+
+
+
+
+
+
+
+ An optional 'AbstractRSocketConnector' bean reference for endpoint mapping registration.
+
+
+
+
+
+
+
+
+
+
+
+ A 'Class' for a request message payload type (plain or `Publisher` element).
+
+
+
+
+
+
+
+
+
+
+
+
+ Configures a Consumer Endpoint for the
+ 'org.springframework.integration.rsocket.outbound.RSocketOutboundGateway' to send requests
+ over RSocket connections.
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies the order for invocation when this endpoint is connected as a
+ subscriber to a SubscribableChannel.
+
+
+
+
+
+
+ A 'route' for the target RSocket endpoint.
+ Mutually exclusive with 'route-expression'.
+
+
+
+
+
+
+ A SpEL expression to evaluate a 'route' for target RSocket endpoint at runtime
+ against request message.
+ Mutually exclusive with 'route'.
+
+
+
+
+
+
+ A 'Command' for RSocket request type.
+ Mutually exclusive with 'command-expression'.
+
+
+
+
+
+
+
+
+
+ A SpEL expression to evaluate a 'command' for RSocket request type at runtime
+ against request message.
+ Mutually exclusive with 'command'.
+
+
+
+
+
+
+ A 'Class' for a request message payload 'Publisher' type.
+ Mutually exclusive with 'publisher-element-type-expression'.
+
+
+
+
+
+
+ A SpEL expression to evaluate a 'Class' or 'ParameterizedTypeReference'
+ for a request message payload 'Publisher' type at runtime
+ against request message.
+ Mutually exclusive with 'publisher-element-type'.
+
+
+
+
+
+
+ A 'Class' for an RSocket response.
+ Mutually exclusive with 'expected-response-type-expression'.
+
+
+
+
+
+
+ A SpEL expression to evaluate a 'Class' or 'ParameterizedTypeReference'
+ for for an RSocket response at runtime
+ against request message.
+ Mutually exclusive with 'expected-response-type'.
+
+
+
+
+
+
+ A 'ClientRSocketConnector' for client side requests.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Defines common configuration for gateway adapters.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/config/RSocketInboundGatewayParserTests-context.xml b/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/config/RSocketInboundGatewayParserTests-context.xml
new file mode 100644
index 0000000000..d8f13b7c7d
--- /dev/null
+++ b/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/config/RSocketInboundGatewayParserTests-context.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/config/RSocketInboundGatewayParserTests.java b/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/config/RSocketInboundGatewayParserTests.java
new file mode 100644
index 0000000000..cf4cbf90c9
--- /dev/null
+++ b/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/config/RSocketInboundGatewayParserTests.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2019 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
+ *
+ * https://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.rsocket.config;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.rsocket.ClientRSocketConnector;
+import org.springframework.integration.rsocket.inbound.RSocketInboundGateway;
+import org.springframework.integration.test.util.TestUtils;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+
+/**
+ * @author Artem Bilan
+ *
+ * @since 5.2
+ */
+@SpringJUnitConfig
+@DirtiesContext
+public class RSocketInboundGatewayParserTests {
+
+ @Autowired
+ private ClientRSocketConnector clientRSocketConnector;
+
+ @Autowired
+ private RSocketInboundGateway inboundGateway;
+
+ @Test
+ void testOutboundGatewayParser() {
+ assertThat(TestUtils.getPropertyValue(this.inboundGateway, "rsocketConnector"))
+ .isSameAs(this.clientRSocketConnector);
+ assertThat(TestUtils.getPropertyValue(this.inboundGateway, "rsocketStrategies"))
+ .isSameAs(this.clientRSocketConnector.getRSocketStrategies());
+ assertThat(TestUtils.getPropertyValue(this.inboundGateway, "path"))
+ .isEqualTo(new String[] { "testPath" });
+ assertThat(TestUtils.getPropertyValue(this.inboundGateway, "requestElementType.resolved"))
+ .isEqualTo(byte[].class);
+ }
+
+}
diff --git a/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/config/RSocketOutboundGatewayParserTests-context.xml b/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/config/RSocketOutboundGatewayParserTests-context.xml
new file mode 100644
index 0000000000..61606b4be4
--- /dev/null
+++ b/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/config/RSocketOutboundGatewayParserTests-context.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/config/RSocketOutboundGatewayParserTests.java b/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/config/RSocketOutboundGatewayParserTests.java
new file mode 100644
index 0000000000..ce6ff83107
--- /dev/null
+++ b/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/config/RSocketOutboundGatewayParserTests.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 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
+ *
+ * https://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.rsocket.config;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.rsocket.ClientRSocketConnector;
+import org.springframework.integration.rsocket.outbound.RSocketOutboundGateway;
+import org.springframework.integration.test.util.TestUtils;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+
+/**
+ * @author Artem Bilan
+ *
+ * @since 5.2
+ */
+@SpringJUnitConfig
+@DirtiesContext
+public class RSocketOutboundGatewayParserTests {
+
+ @Autowired
+ private ClientRSocketConnector clientRSocketConnector;
+
+ @Autowired
+ private RSocketOutboundGateway outboundGateway;
+
+ @Test
+ void testOutboundGatewayParser() {
+ assertThat(TestUtils.getPropertyValue(this.outboundGateway, "clientRSocketConnector"))
+ .isSameAs(this.clientRSocketConnector);
+ assertThat(TestUtils.getPropertyValue(this.outboundGateway, "commandExpression.literalValue"))
+ .isEqualTo("fireAndForget");
+ assertThat(TestUtils.getPropertyValue(this.outboundGateway, "routeExpression.expression"))
+ .isEqualTo("'testRoute'");
+ assertThat(TestUtils.getPropertyValue(this.outboundGateway, "publisherElementTypeExpression.literalValue"))
+ .isEqualTo("byte[]");
+ assertThat(TestUtils.getPropertyValue(this.outboundGateway, "expectedResponseTypeExpression.literalValue"))
+ .isEqualTo("java.util.Date");
+ }
+
+}