Deprecate RMI module

* Remove tests from SI-RMI since the module is deprecated
* Mention such a deprecation in the docs
This commit is contained in:
Artem Bilan
2020-07-24 11:03:39 -04:00
parent 5ec71d4b4a
commit 92410b942c
18 changed files with 46 additions and 853 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -25,7 +25,6 @@ import org.springframework.integration.support.context.NamedComponent;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.remoting.rmi.RmiServiceExporter;
import org.springframework.remoting.support.RemoteInvocationExecutor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -36,14 +35,18 @@ import org.springframework.util.StringUtils;
* @author Mark Fisher
* @author Artem Bilan
* @author Gary Russell
*
* @deprecated since 5.4 with no replacement.
*/
@Deprecated
public class RmiInboundGateway extends MessagingGatewaySupport
implements RequestReplyExchanger {
public static final String SERVICE_NAME_PREFIX = "org.springframework.integration.rmiGateway.";
private final RmiServiceExporter exporter = new RmiServiceExporter();
private final org.springframework.remoting.rmi.RmiServiceExporter exporter =
new org.springframework.remoting.rmi.RmiServiceExporter();
private String requestChannelName;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -23,7 +23,6 @@ import org.springframework.integration.handler.AbstractReplyProducingMessageHand
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.remoting.rmi.RmiProxyFactoryBean;
/**
* An outbound Messaging Gateway for RMI-based remoting.
@@ -31,7 +30,10 @@ import org.springframework.remoting.rmi.RmiProxyFactoryBean;
* @author Mark Fisher
* @author Gary Russell
* @author Artem Bilan
*
* @deprecated since 5.4 with no replacement.
*/
@Deprecated
public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler {
private final RequestReplyExchanger proxy;
@@ -40,7 +42,7 @@ public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler {
/**
* Construct an instance with a `RequestReplyExchanger` built from the
* default {@link RmiProxyFactoryBean}.
* default {@link org.springframework.remoting.rmi.RmiProxyFactoryBean}.
* @param url the url.
*/
public RmiOutboundGateway(String url) {
@@ -49,7 +51,7 @@ public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler {
/**
* Construct an instance with a `RequestReplyExchanger` built from the
* default {@link RmiProxyFactoryBean} which can be modified by the
* default {@link org.springframework.remoting.rmi.RmiProxyFactoryBean} which can be modified by the
* configurer.
* @param url the url.
* @param configurer the {@link RmiProxyFactoryBeanConfigurer}.
@@ -86,7 +88,8 @@ public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler {
}
private RequestReplyExchanger createProxy(String url) {
RmiProxyFactoryBean proxyFactory = new RmiProxyFactoryBean();
org.springframework.remoting.rmi.RmiProxyFactoryBean proxyFactory =
new org.springframework.remoting.rmi.RmiProxyFactoryBean();
proxyFactory.setServiceInterface(RequestReplyExchanger.class);
proxyFactory.setServiceUrl(url);
proxyFactory.setLookupStubOnStartup(false);
@@ -109,7 +112,7 @@ public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler {
* {@code RequestReplyExchanger} is created.
* @param factoryBean the factory bean.
*/
void configure(RmiProxyFactoryBean factoryBean);
void configure(org.springframework.remoting.rmi.RmiProxyFactoryBean factoryBean);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -21,14 +21,16 @@ 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.rmi.RmiInboundGateway;
/**
* Parser for the <inbound-gateway/> element of the 'rmi' namespace.
*
* @author Mark Fisher
* @author Gary Russell
*
* @deprecated since 5.4 with no replacement.
*/
@Deprecated
public class RmiInboundGatewayParser extends AbstractInboundGatewayParser {
private static final String REMOTE_INVOCATION_EXECUTOR_ATTRIBUTE = "remote-invocation-executor";
@@ -36,7 +38,7 @@ public class RmiInboundGatewayParser extends AbstractInboundGatewayParser {
@Override
protected String getBeanClassName(Element element) {
return RmiInboundGateway.class.getName();
return org.springframework.integration.rmi.RmiInboundGateway.class.getName();
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -22,7 +22,10 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa
* Namespace handler for Spring Integration's <em>rmi</em> namespace.
*
* @author Mark Fisher
*
* @deprecated since 5.4 with no replacement.
*/
@Deprecated
public class RmiNamespaceHandler extends AbstractIntegrationNamespaceHandler {
public void init() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -23,20 +23,21 @@ import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundGatewayParser;
import org.springframework.integration.rmi.RmiInboundGateway;
import org.springframework.integration.rmi.RmiOutboundGateway;
import org.springframework.util.StringUtils;
/**
* Parser for the &lt;outbound-gateway/&gt; element of the 'rmi' namespace.
*
* @author Mark Fisher
*
* @deprecated since 5.4 with no replacement.
*/
@Deprecated
public class RmiOutboundGatewayParser extends AbstractOutboundGatewayParser {
@Override
protected String getGatewayClassName(Element element) {
return RmiOutboundGateway.class.getName();
return org.springframework.integration.rmi.RmiOutboundGateway.class.getName();
}
@Override
@@ -49,7 +50,8 @@ public class RmiOutboundGatewayParser extends AbstractOutboundGatewayParser {
}
String portAttribute = element.getAttribute("port");
String port = StringUtils.hasText(portAttribute) ? portAttribute : "" + Registry.REGISTRY_PORT;
return "rmi://" + host + ":" + port + "/" + RmiInboundGateway.SERVICE_NAME_PREFIX + remoteChannel;
return "rmi://" + host + ":" + port + "/"
+ org.springframework.integration.rmi.RmiInboundGateway.SERVICE_NAME_PREFIX + remoteChannel;
}
@Override

View File

@@ -1,62 +0,0 @@
<?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:int="http://www.springframework.org/schema/integration"
xmlns:int-rmi="http://www.springframework.org/schema/integration/rmi"
xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/rmi https://www.springframework.org/schema/integration/rmi/spring-integration-rmi.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Good -->
<int:channel id="good" />
<int-rmi:outbound-gateway remote-channel="foo" host="localhost"
request-channel="good" reply-channel="reply" port="#{@port}">
<int-rmi:transactional/>
</int-rmi:outbound-gateway>
<bean id="transactionManager" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="org.springframework.transaction.PlatformTransactionManager"/>
</bean>
<int-rmi:inbound-gateway request-channel="foo" registry-port="#{@port}" />
<int:service-activator input-channel="foo" expression="'reply:' + payload" />
<int:channel id="reply">
<int:queue/>
</int:channel>
<bean id="port" class="java.lang.Integer">
<constructor-arg value="#{T(org.springframework.util.SocketUtils).findAvailableTcpPort()}" />
</bean>
<!-- Bad -->
<int:channel id="bad" />
<int-rmi:outbound-gateway remote-channel="bar" host="localhost"
request-channel="bad" reply-channel="reply"
port="#{@port}"/>
<int-rmi:inbound-gateway request-channel="bar" registry-port="#{@port}"
error-channel="errors" />
<int:channel id="bar" /> <!-- Dispatcher has no subscribers to error channel -->
<int:service-activator input-channel="errors" expression="'error:' + payload.failedMessage.payload" />
<!-- Ugly -->
<int:channel id="ugly" />
<int-rmi:outbound-gateway remote-channel="baz" host="localhost"
request-channel="ugly" reply-channel="reply"
port="#{@port}"/>
<int-rmi:inbound-gateway request-channel="baz" registry-port="#{@port}" />
<int:channel id="baz" /> <!-- Dispatcher has no subscribers no error channel -->
</beans>

View File

@@ -1,97 +0,0 @@
/*
* Copyright 2013-2020 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.rmi;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.integration.MessageDispatchingException;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageDeliveryException;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.SubscribableChannel;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
/**
* @author Gary Russell
* @author Artem Bilan
*
* @since 3.0
*
*/
@SpringJUnitConfig
@DirtiesContext
public class BackToBackTests {
@Autowired
private SubscribableChannel good;
@Autowired
private SubscribableChannel bad;
@Autowired
private SubscribableChannel ugly;
@Autowired
private PollableChannel reply;
@Autowired
private AbstractApplicationContext context;
@Autowired
private PlatformTransactionManager transactionManager;
@Test
public void testGood() {
good.send(new GenericMessage<>("foo"));
Message<?> reply = this.reply.receive(0);
assertThat(reply).isNotNull();
assertThat(reply.getPayload()).isEqualTo("reply:foo");
verify(this.transactionManager).getTransaction(any(TransactionDefinition.class));
}
@Test
public void testBad() {
bad.send(new GenericMessage<>("foo"));
Message<?> reply = this.reply.receive(0);
assertThat(reply).isNotNull();
assertThat(reply.getPayload()).isEqualTo("error:foo");
}
@Test
public void testUgly() {
context.setId("context");
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() -> ugly.send(new GenericMessage<>("foo")))
.withCauseInstanceOf(MessageDeliveryException.class)
.withRootCauseInstanceOf(MessageDispatchingException.class)
.withMessageContaining("Dispatcher has no subscribers for channel 'context.baz'.");
}
}

View File

@@ -1,180 +0,0 @@
/*
* Copyright 2002-2020 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.rmi;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import java.rmi.RemoteException;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.gateway.RequestReplyExchanger;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.remoting.RemoteLookupFailureException;
import org.springframework.remoting.rmi.RmiServiceExporter;
import org.springframework.util.SocketUtils;
/**
* @author Mark Fisher
* @author Gary Russell
* @author Artem Bilan
*/
public class RmiOutboundGatewayTests {
private static final QueueChannel OUTPUT = new QueueChannel(1);
private static int RMI_PORT;
private static RmiServiceExporter EXPORTER;
private static RmiOutboundGateway GATEWAY;
@BeforeAll
static void setup() throws RemoteException {
RMI_PORT = SocketUtils.findAvailableTcpPort();
EXPORTER = new RmiServiceExporter();
EXPORTER.setService(new TestExchanger());
EXPORTER.setServiceInterface(RequestReplyExchanger.class);
EXPORTER.setServiceName("testRemoteHandler");
EXPORTER.setRegistryPort(RMI_PORT);
EXPORTER.afterPropertiesSet();
GATEWAY = new RmiOutboundGateway("rmi://localhost:" + RMI_PORT + "/testRemoteHandler");
GATEWAY.setOutputChannel(OUTPUT);
}
@AfterAll
static void tearDown() throws RemoteException {
EXPORTER.destroy();
}
@Test
void serializablePayload() {
GATEWAY.handleMessage(new GenericMessage<>("test"));
Message<?> replyMessage = OUTPUT.receive(0);
assertThat(replyMessage).isNotNull();
assertThat(replyMessage.getPayload()).isEqualTo("TEST");
}
@Test
void failedMessage() {
GenericMessage<String> message = new GenericMessage<>("fail");
assertThatExceptionOfType(MessagingException.class)
.isThrownBy(() -> GATEWAY.handleMessage(message))
.satisfies((ex) -> {
assertThat(ex.getFailedMessage()).isSameAs(message);
assertThat(((MessagingException) ex.getCause()).getFailedMessage().getPayload()).isEqualTo("bar");
});
}
@Test
void serializableAttribute() {
Message<String> requestMessage = MessageBuilder.withPayload("test")
.setHeader("testAttribute", "foo").build();
GATEWAY.handleMessage(requestMessage);
Message<?> replyMessage = OUTPUT.receive(0);
assertThat(replyMessage).isNotNull();
assertThat(replyMessage.getHeaders().get("testAttribute")).isEqualTo("foo");
}
@Test
void nonSerializablePayload() {
NonSerializableTestObject payload = new NonSerializableTestObject();
Message<?> requestMessage = new GenericMessage<>(payload);
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() -> GATEWAY.handleMessage(requestMessage));
}
@Test
void nonSerializableAttribute() {
Message<String> requestMessage = MessageBuilder.withPayload("test")
.setHeader("testAttribute", new NonSerializableTestObject()).build();
GATEWAY.handleMessage(requestMessage);
Message<?> reply = OUTPUT.receive(0);
assertThat(requestMessage.getHeaders().get("testAttribute")).isNotNull();
assertThat(reply.getHeaders().get("testAttribute")).isNotNull();
}
@Test
void invalidServiceName() {
RmiOutboundGateway gateway = new RmiOutboundGateway("rmi://localhost:" + RMI_PORT + "/noSuchService");
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() -> gateway.handleMessage(new GenericMessage<>("test")))
.withCauseInstanceOf(RemoteLookupFailureException.class);
}
@Test
void invalidHost() {
RmiOutboundGateway gateway = new RmiOutboundGateway("rmi://noSuchHost:1099/testRemoteHandler");
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() -> gateway.handleMessage(new GenericMessage<>("test")))
.withCauseInstanceOf(RemoteLookupFailureException.class);
}
@Test
void invalidUrl() {
RmiOutboundGateway gateway = new RmiOutboundGateway("https://sample.com/");
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() -> gateway.handleMessage(new GenericMessage<>("test")))
.withCauseInstanceOf(RemoteLookupFailureException.class);
}
private static class TestExchanger implements RequestReplyExchanger {
TestExchanger() {
super();
}
@Override
public Message<?> exchange(Message<?> message) {
if (message.getPayload().equals("fail")) {
new AbstractReplyProducingMessageHandler() {
@Override
protected Object handleRequestMessage(Message<?> requestMessage) {
throw new RuntimeException("foo");
}
}.handleMessage(new GenericMessage<>("bar"));
}
return new GenericMessage<>(message.getPayload().toString().toUpperCase(), message.getHeaders());
}
}
private static class NonSerializableTestObject {
NonSerializableTestObject() {
super();
}
}
}

View File

@@ -1,12 +0,0 @@
<?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:rmi="http://www.springframework.org/schema/integration/rmi"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/rmi
https://www.springframework.org/schema/integration/rmi/spring-integration-rmi.xsd">
<rmi:outbound-gateway remote-channel="remote" request-channel="local" host="testhost" auto-startup="false"/>
</beans>

View File

@@ -1,81 +0,0 @@
/*
* Copyright 2002-2020 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.rmi.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.context.ApplicationContext;
import org.springframework.integration.channel.MessagePublishingErrorHandler;
import org.springframework.integration.channel.NullChannel;
import org.springframework.integration.channel.PublishSubscribeChannel;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.MessageChannel;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.util.ErrorHandler;
/**
* @author Mark Fisher
* @author Artem Bilan
* @author Gary Russell
*
* @since 1.0.3
*/
@SpringJUnitConfig
@DirtiesContext
public class DefaultConfigurationTests {
@Autowired
private ApplicationContext context;
@Test
public void verifyErrorChannel() {
Object errorChannel = context.getBean("errorChannel");
assertThat(errorChannel).isNotNull();
assertThat(errorChannel.getClass()).isEqualTo(PublishSubscribeChannel.class);
}
@Test
public void verifyNullChannel() {
Object nullChannel = context.getBean("nullChannel");
assertThat(nullChannel).isNotNull();
assertThat(nullChannel.getClass()).isEqualTo(NullChannel.class);
}
@Test
public void verifyTaskScheduler() {
Object taskScheduler = context.getBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME);
assertThat(taskScheduler.getClass()).isEqualTo(ThreadPoolTaskScheduler.class);
ErrorHandler errorHandler = TestUtils.getPropertyValue(taskScheduler, "errorHandler", ErrorHandler.class);
assertThat(errorHandler.getClass()).isEqualTo(MessagePublishingErrorHandler.class);
MessageChannel defaultErrorChannel = TestUtils.getPropertyValue(errorHandler,
"messagingTemplate.defaultDestination", MessageChannel.class);
assertThat(defaultErrorChannel).isNull();
errorHandler.handleError(new Throwable());
defaultErrorChannel = TestUtils.getPropertyValue(errorHandler, "messagingTemplate.defaultDestination",
MessageChannel.class);
assertThat(defaultErrorChannel).isNotNull();
assertThat(defaultErrorChannel).isEqualTo(context.getBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME));
}
}

View File

@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:rmi="http://www.springframework.org/schema/integration/rmi"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/rmi
https://www.springframework.org/schema/integration/rmi/spring-integration-rmi.xsd">
<message-history/>
<channel id="testChannel"/>
<channel id="testErrorChannel"/>
<rmi:inbound-gateway id="gatewayWithDefaults" request-channel="testChannel" auto-startup="false"
registry-port="#{T(org.springframework.integration.rmi.config.RmiInboundGatewayParserTests).PORT}"/>
<rmi:inbound-gateway id="gatewayWithCustomProperties" request-channel="testChannel"
expect-reply="false" request-timeout="123" reply-timeout="456" auto-startup="false"
registry-port="#{T(org.springframework.integration.rmi.config.RmiInboundGatewayParserTests).PORT}"/>
<rmi:inbound-gateway id="gatewayWithHostAndErrorChannel" request-channel="testChannel" registry-host="localhost"
error-channel="testErrorChannel" auto-startup="false"
registry-port="#{T(org.springframework.integration.rmi.config.RmiInboundGatewayParserTests).PORT}"/>
<rmi:inbound-gateway id="gatewayWithPort" request-channel="testChannel" auto-startup="false"
registry-port="#{T(org.springframework.integration.rmi.config.RmiInboundGatewayParserTests).PORT}"/>
<rmi:inbound-gateway id="gatewayWithExecutorRef"
request-channel="testChannel"
remote-invocation-executor="invocationExecutor"
auto-startup="false"
registry-port="#{T(org.springframework.integration.rmi.config.RmiInboundGatewayParserTests).PORT}"/>
<beans:bean id="invocationExecutor"
class="org.springframework.integration.rmi.config.StubRemoteInvocationExecutor"/>
</beans:beans>

View File

@@ -1,94 +0,0 @@
/*
* Copyright 2002-2020 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.rmi.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.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.rmi.RmiInboundGateway;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.MessageChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.util.SocketUtils;
/**
* @author Mark Fisher
* @author Gary Russell
* @author Artem Bilan
*/
@SpringJUnitConfig
@DirtiesContext
public class RmiInboundGatewayParserTests {
public static final int PORT = SocketUtils.findAvailableTcpPort();
@Autowired
@Qualifier("testChannel")
private MessageChannel channel;
@Autowired
private ApplicationContext context;
@Test
public void gatewayWithDefaultsAndHistory() {
RmiInboundGateway gateway = (RmiInboundGateway) this.context.getBean("gatewayWithDefaults");
assertThat(gateway.getComponentName()).isEqualTo("gatewayWithDefaults");
assertThat(gateway.getComponentType()).isEqualTo("rmi:inbound-gateway");
assertThat(TestUtils.getPropertyValue(gateway, "expectReply", Boolean.class)).isTrue();
assertThat(gateway.getRequestChannel()).isSameAs(this.channel);
assertThat(TestUtils.getPropertyValue(gateway, "messagingTemplate.sendTimeout")).isEqualTo(1000L);
assertThat(TestUtils.getPropertyValue(gateway, "messagingTemplate.receiveTimeout")).isEqualTo(1000L);
}
@Test
public void gatewayWithCustomProperties() {
RmiInboundGateway gateway = (RmiInboundGateway) context.getBean("gatewayWithCustomProperties");
assertThat(TestUtils.getPropertyValue(gateway, "expectReply", Boolean.class)).isFalse();
assertThat(gateway.getRequestChannel()).isSameAs(this.channel);
assertThat(TestUtils.getPropertyValue(gateway, "messagingTemplate.sendTimeout")).isEqualTo(123L);
assertThat(TestUtils.getPropertyValue(gateway, "messagingTemplate.receiveTimeout")).isEqualTo(456L);
}
@Test
public void gatewayWithHost() {
RmiInboundGateway gateway = (RmiInboundGateway) context.getBean("gatewayWithHostAndErrorChannel");
assertThat(TestUtils.getPropertyValue(gateway, "registryHost")).isEqualTo("localhost");
assertThat(gateway.getErrorChannel()).isSameAs(context.getBean("testErrorChannel"));
}
@Test
public void gatewayWithPort() {
RmiInboundGateway gateway = (RmiInboundGateway) context.getBean("gatewayWithPort");
assertThat(TestUtils.getPropertyValue(gateway, "registryPort")).isEqualTo(PORT);
}
@Test
public void gatewayWithRemoteInvocationExecutorReference() {
RmiInboundGateway gateway = (RmiInboundGateway) context.getBean("gatewayWithExecutorRef");
Object remoteInvocationExecutor = TestUtils.getPropertyValue(gateway, "remoteInvocationExecutor");
assertThat(remoteInvocationExecutor).isNotNull();
assertThat(remoteInvocationExecutor).isInstanceOf(StubRemoteInvocationExecutor.class);
}
}

View File

@@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:rmi="http://www.springframework.org/schema/integration/rmi"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/rmi
https://www.springframework.org/schema/integration/rmi/spring-integration-rmi.xsd">
<channel id="localChannel"/>
<rmi:outbound-gateway id="gateway"
order="23"
request-channel="localChannel"
remote-channel="testChannel"
configurer="configurer"
host="localhost"
port="#{T(org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests).port}"/>
<channel id="advisedChannel"/>
<rmi:outbound-gateway id="advised"
request-channel="advisedChannel"
remote-channel="testChannel"
requires-reply="false"
host="localhost"
port="#{T(org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests).port}">
<rmi:request-handler-advice-chain>
<beans:ref bean="advice"/>
</rmi:request-handler-advice-chain>
</rmi:outbound-gateway>
<beans:bean id="configurer" class="org.mockito.Mockito" factory-method="mock">
<beans:constructor-arg
value="org.springframework.integration.rmi.RmiOutboundGateway$RmiProxyFactoryBeanConfigurer"/>
</beans:bean>
<beans:bean id="advice"
class="org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests$FooAdvice"/>
<chain input-channel="rmiOutboundGatewayInsideChain">
<rmi:outbound-gateway remote-channel="testChannel"
host="localhost"
port="#{T(org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests).port}"
requires-reply="false"/>
</chain>
<channel id="remoteChannel"/>
<rmi:inbound-gateway request-channel="remoteChannel"
registry-port="#{T(org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests).port}"/>
<service-activator input-channel="remoteChannel" expression="payload.toUpperCase()"/>
<channel id="replyChannel">
<queue/>
</channel>
<chain input-channel="requestReplyRmiWithChainChannel" output-channel="replyChannel">
<rmi:outbound-gateway remote-channel="remoteChannel"
host="localhost"
port="#{T(org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests).port}"/>
</chain>
</beans:beans>

View File

@@ -1,149 +0,0 @@
/*
* Copyright 2002-2020 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.rmi.config;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
import org.springframework.integration.rmi.RmiInboundGateway;
import org.springframework.integration.rmi.RmiOutboundGateway;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.remoting.rmi.RmiProxyFactoryBean;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.util.SocketUtils;
/**
* @author Mark Fisher
* @author Gary Russell
* @author Artem Bilan
*/
@SpringJUnitConfig
@DirtiesContext
public class RmiOutboundGatewayParserTests {
public static final int port = SocketUtils.findAvailableTcpPort();
private static final QueueChannel testChannel = new QueueChannel();
private static final RmiInboundGateway rmiInboundGateway = new RmiInboundGateway();
@Autowired
public FooAdvice advice;
@Autowired
private MessageChannel advisedChannel;
@Autowired
private MessageChannel rmiOutboundGatewayInsideChain;
@Autowired
private MessageChannel requestReplyRmiWithChainChannel;
@Autowired
private PollableChannel replyChannel;
@Autowired
private RmiOutboundGateway.RmiProxyFactoryBeanConfigurer configurer;
@Autowired
@Qualifier("gateway.handler")
RmiOutboundGateway gateway;
@Autowired
@Qualifier("advised.handler")
RmiOutboundGateway advised;
@BeforeAll
public static void setupTestInboundGateway() {
testChannel.setBeanName("testChannel");
rmiInboundGateway.setRequestChannel(testChannel);
rmiInboundGateway.setRegistryPort(port);
rmiInboundGateway.setExpectReply(false);
rmiInboundGateway.setBeanFactory(mock(BeanFactory.class));
rmiInboundGateway.afterPropertiesSet();
}
@AfterAll
public static void destroyInboundGateway() {
rmiInboundGateway.destroy();
}
@Test
public void testProperties() {
assertThat(TestUtils.getPropertyValue(gateway, "order")).isEqualTo(23);
assertThat(TestUtils.getPropertyValue(gateway, "requiresReply", Boolean.class)).isTrue();
assertThat(TestUtils.getPropertyValue(this.gateway, "configurer")).isSameAs(this.configurer);
verify(this.configurer).configure(any(RmiProxyFactoryBean.class));
}
@Test
public void directInvocation() {
assertThat(TestUtils.getPropertyValue(advised, "requiresReply", Boolean.class)).isFalse();
advisedChannel.send(new GenericMessage<>("test"));
Message<?> result = testChannel.receive(1000);
assertThat(result).isNotNull();
assertThat(result.getPayload()).isEqualTo("test");
assertThat(advice.adviceCalled).isEqualTo(1);
}
@Test //INT-1029
public void testRmiOutboundGatewayInsideChain() {
rmiOutboundGatewayInsideChain.send(MessageBuilder.withPayload("test").build());
Message<?> result = testChannel.receive(1000);
assertThat(result).isNotNull();
assertThat(result.getPayload()).isEqualTo("test");
}
@Test //INT-1029
public void testRmiRequestReplyWithinChain() {
requestReplyRmiWithChainChannel.send(MessageBuilder.withPayload("test").build());
Message<?> result = replyChannel.receive(1000);
assertThat(result).isNotNull();
assertThat(result.getPayload()).isEqualTo("TEST");
}
public static class FooAdvice extends AbstractRequestHandlerAdvice {
int adviceCalled;
@Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) {
adviceCalled++;
return callback.execute();
}
}
}

View File

@@ -1,26 +0,0 @@
/*
* 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.rmi.config;
import org.springframework.remoting.support.DefaultRemoteInvocationExecutor;
/**
* @author Mark Fisher
*/
public class StubRemoteInvocationExecutor extends DefaultRemoteInvocationExecutor {
}

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %p [%t] [%c] - %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="org.springframework.integration" level="warn"/>
<Logger name="org.springframework.integration.rmi" level="warn"/>
<Root level="warn">
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>

View File

@@ -1,6 +1,7 @@
[[rmi]]
== RMI Support
IMPORTANT: this module is deprecated since 5.4 with no replacement and will be removed in 6.0.
This chapter explains how to use channel adapters that are specific to RMI (Remote Method Invocation) to distribute a system over multiple JVMs.
The first section deals with sending messages over RMI.

View File

@@ -38,13 +38,6 @@ See <<./redis.adoc#redis-stream-outbound,Redis Stream Outbound Channel Adapter>>
A Renewable lock registry has been introduced to allow renew lease of a distributed lock.
See <<./jdbc.adoc#jdbc-lock-registry,JDBC implementation>> for more information.
==== TCP Changes
Connection factories now support multiple sending components (`TcpSender`); they remain limited to one receiving component (`TcpListener`).
This allows, for example, an inbound gateway and outbound channel adapter to share the same factory, supporting both request/reply and arbitrary messaging from the server to the client.
Shared factories should not be used with outbound gateways, unless single-use connections or the `ThreadAffinityClientConnectionFactory` are being used.
See <<./ip.adoc#ip-collaborating-adapters,Collaborating Channel Adapters>> and <<./ip.adoc#tcp-gateways, TCP Gateways>> for more information.
[[x5.4-general]]
=== General Changes
@@ -53,3 +46,17 @@ See <<./gateway.adoc#gateway-default-reply-channel,Setting the Default Reply Cha
The aggregator (and resequencer) can now expire orphaned groups (groups in a persistent store where no new messages arrive after an application restart).
See <<./aggregator.adoc#aggregator-expiring-groups, Aggregator Expiring Groups>> for more information.
[[x5.4-tcp]]
=== TCP Changes
Connection factories now support multiple sending components (`TcpSender`); they remain limited to one receiving component (`TcpListener`).
This allows, for example, an inbound gateway and outbound channel adapter to share the same factory, supporting both request/reply and arbitrary messaging from the server to the client.
Shared factories should not be used with outbound gateways, unless single-use connections or the `ThreadAffinityClientConnectionFactory` are being used.
See <<./ip.adoc#ip-collaborating-adapters,Collaborating Channel Adapters>> and <<./ip.adoc#tcp-gateways, TCP Gateways>> for more information.
[[x5.4-rmi]]
=== RMI Changes
The `spring-integration-rmi` module is deprecated with no replacement and is going to be removed in the next major version.
See <<./rmi.adoc#rmi, RMI Support>> for more information.