From 77d0becd9797b50cad44f230be373afd4874cf01 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Tue, 16 Aug 2016 16:04:07 -0400 Subject: [PATCH] INT-4066: Expose RMI Factory Bean JIRA: https://jira.spring.io/browse/INT-4066 Allow customization. Rename To RmiProxyFactoryBeanConfigurer Polishing More Polishing Polishing --- .../integration/rmi/RmiOutboundGateway.java | 51 +++++++++++++++++-- .../rmi/config/RmiOutboundGatewayParser.java | 11 +++- .../rmi/config/spring-integration-rmi-5.0.xsd | 14 +++++ .../RmiOutboundGatewayParserTests-context.xml | 6 +++ .../config/RmiOutboundGatewayParserTests.java | 11 +++- src/reference/asciidoc/rmi.adoc | 41 +++++++++++++++ 6 files changed, 127 insertions(+), 7 deletions(-) diff --git a/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/RmiOutboundGateway.java b/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/RmiOutboundGateway.java index 20c0c8e7a6..0f53a91058 100644 --- a/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/RmiOutboundGateway.java +++ b/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/RmiOutboundGateway.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 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. @@ -37,14 +37,33 @@ public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler { private final RequestReplyExchanger proxy; + private final RmiProxyFactoryBeanConfigurer configurer; + /** + * Construct an instance with a `RequestReplyExchanger` built from the + * default {@link RmiProxyFactoryBean}. + * @param url the url. + */ public RmiOutboundGateway(String url) { - this.proxy = this.createProxy(url); + this(url, null); + } + + /** + * Construct an instance with a `RequestReplyExchanger` built from the + * default {@link RmiProxyFactoryBean} which can be modified by the + * configurer. + * @param url the url. + * @param configurer the {@link RmiProxyFactoryBeanConfigurer}. + * @since 4.3.2 + */ + public RmiOutboundGateway(String url, RmiProxyFactoryBeanConfigurer configurer) { + this.configurer = configurer; + this.proxy = createProxy(url); } public void setReplyChannel(MessageChannel replyChannel) { - this.setOutputChannel(replyChannel); + setOutputChannel(replyChannel); } @Override @@ -64,7 +83,10 @@ public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler { try { Message reply = this.proxy.exchange(requestMessage); if (reply != null) { - reply = this.getMessageBuilderFactory().fromMessage(reply).copyHeadersIfAbsent(message.getHeaders()).build(); + reply = getMessageBuilderFactory() + .fromMessage(reply) + .copyHeadersIfAbsent(message.getHeaders()) + .build(); } return reply; } @@ -72,7 +94,8 @@ public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler { throw new MessageHandlingException(message, e); } catch (RemoteAccessException e) { - throw new MessageHandlingException(message, "Remote failure in RmiOutboundGateway: " + this.getComponentName(), e); + throw new MessageHandlingException(message, "Remote failure in RmiOutboundGateway: " + + this.getComponentName(), e); } } @@ -82,8 +105,26 @@ public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler { proxyFactory.setServiceUrl(url); proxyFactory.setLookupStubOnStartup(false); proxyFactory.setRefreshStubOnConnectFailure(true); + if (this.configurer != null) { + this.configurer.configure(proxyFactory); + } proxyFactory.afterPropertiesSet(); return (RequestReplyExchanger) proxyFactory.getObject(); } + /** + * Allows configuration of the proxy factory bean before the RMI proxy is created. + * @since 4.3.2 + */ + public interface RmiProxyFactoryBeanConfigurer { + + /** + * Perform additional configuration of the factory bean before the + * {@code RequestReplyExchanger} is created. + * @param factoryBean the factory bean. + */ + void configure(RmiProxyFactoryBean factoryBean); + + } + } diff --git a/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParser.java b/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParser.java index 0cd2b1b481..ea9cae789d 100644 --- a/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParser.java +++ b/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParser.java @@ -20,9 +20,11 @@ import java.rmi.registry.Registry; 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; /** @@ -34,7 +36,7 @@ public class RmiOutboundGatewayParser extends AbstractOutboundGatewayParser { @Override protected String getGatewayClassName(Element element) { - return "org.springframework.integration.rmi.RmiOutboundGateway"; + return RmiOutboundGateway.class.getName(); } @Override @@ -50,4 +52,11 @@ public class RmiOutboundGatewayParser extends AbstractOutboundGatewayParser { return "rmi://" + host + ":" + port + "/" + RmiInboundGateway.SERVICE_NAME_PREFIX + remoteChannel; } + @Override + protected void postProcessGateway(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) { + if (StringUtils.hasText(element.getAttribute("configurer"))) { + builder.addConstructorArgReference(element.getAttribute("configurer")); + } + } + } diff --git a/spring-integration-rmi/src/main/resources/org/springframework/integration/rmi/config/spring-integration-rmi-5.0.xsd b/spring-integration-rmi/src/main/resources/org/springframework/integration/rmi/config/spring-integration-rmi-5.0.xsd index 8c91357c89..7d821fd740 100644 --- a/spring-integration-rmi/src/main/resources/org/springframework/integration/rmi/config/spring-integration-rmi-5.0.xsd +++ b/spring-integration-rmi/src/main/resources/org/springframework/integration/rmi/config/spring-integration-rmi-5.0.xsd @@ -114,6 +114,20 @@ + + + + Specify a 'RmiProxyFactoryBeanConfigurer' to further configure the RmiProxyFactoryBean + before it creates the proxy - use this, for example, + to customize the RemoteInvocationFactory. + + + + + + + + diff --git a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests-context.xml b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests-context.xml index 27d88d3384..102914efee 100644 --- a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests-context.xml +++ b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests-context.xml @@ -16,6 +16,7 @@ order="23" request-channel="localChannel" remote-channel="testChannel" + configurer="configurer" host="localhost"/> @@ -30,6 +31,11 @@ + + + + diff --git a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests.java b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests.java index bc51255a73..0c6db3b17b 100644 --- a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests.java +++ b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests.java @@ -19,8 +19,11 @@ package org.springframework.integration.rmi.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import org.junit.BeforeClass; import org.junit.Test; @@ -39,6 +42,7 @@ 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.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -70,6 +74,9 @@ public class RmiOutboundGatewayParserTests { @Autowired private PollableChannel replyChannel; + @Autowired + private RmiOutboundGateway.RmiProxyFactoryBeanConfigurer configurer; + @Autowired @Qualifier("gateway.handler") RmiOutboundGateway gateway; @@ -89,9 +96,11 @@ public class RmiOutboundGatewayParserTests { } @Test - public void testOrder() { + public void testProperties() { assertEquals(23, TestUtils.getPropertyValue(gateway, "order")); assertTrue(TestUtils.getPropertyValue(gateway, "requiresReply", Boolean.class)); + assertSame(this.configurer, TestUtils.getPropertyValue(this.gateway, "configurer")); + verify(this.configurer).configure(any(RmiProxyFactoryBean.class)); } @Test diff --git a/src/reference/asciidoc/rmi.adoc b/src/reference/asciidoc/rmi.adoc index e595269607..42163e8822 100644 --- a/src/reference/asciidoc/rmi.adoc +++ b/src/reference/asciidoc/rmi.adoc @@ -75,3 +75,44 @@ The following code snippet shows the different configuration for an outbound rmi remote-channel="testChannel" host="localhost"/> ---- + +=== Configuring with Java Configuration + +[source, java] +---- +@Bean +public RmiInboundGateway inbound() { + RmiInboundGateway gateway = new RmiInboundGateway(); + gateway.setRequestChannel(requestChannel()); + gateway.setRegistryHost("host"); + gateway.setRegistryPort(port); + return gateway; +} + +@Bean +@ServiceActivator(inputChannel="inChannel") +public RmiOutboundGateway outbound() { + RmiOutboundGateway gateway = new RmiOutboundGateway("rmi://host:port/" + + RmiInboundGateway.SERVICE_NAME_PREFIX + "remoteChannelName"); + return gateway; +} +---- + +Starting with _version 4.3_, the outbound gateway has a second constructor that takes a RmiProxyFactoryBeanConfigurer instance along with the service url argument. +This allows further configuration before the proxy is created; for example, to inject a Spring Security `ContextPropagatingRemoteInvocationFactory`: + +[source, java] +---- +@Bean +@ServiceActivator(inputChannel="inChannel") +public RmiOutboundGateway outbound() { + RmiOutboundGateway gateway = new RmiOutboundGateway("rmi://host:port/" + + RmiInboundGateway.SERVICE_NAME_PREFIX + "remoteChannelName", + pfb -> { + pfb.setRemoteInvocationFactory(new ContextPropagatingRemoteInvocationFactory()); + }); + return gateway; +} +---- + +Starting with _version 5.0_, this can be set using the XML namespace, using the `configurer` attribute.