From ebec500abd85d10b9eb584a8794f1abba4acf0f6 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Fri, 17 Jul 2020 11:26:40 -0400 Subject: [PATCH] Upgrade dependencies to the latest snapshots * Fix HTTP & WebFlux for a new CORS logic when `*` pattern is used together with `allowCredentials` * Fix RSocket module for deprecated API in SF * The deprecated RMI API is left for the upcoming changes --- build.gradle | 10 +++---- ...tegrationRequestMappingHandlerMapping.java | 14 ++++++++-- .../http/inbound/CrossOriginTests.java | 12 ++++++--- .../rsocket/ClientRSocketConnector.java | 27 ++++++++++++------- .../config/spring-integration-rsocket.xsd | 2 +- ...SocketOutboundGatewayIntegrationTests.java | 24 ++++++++++++----- ...tegrationRequestMappingHandlerMapping.java | 14 ++++++++-- 7 files changed, 73 insertions(+), 30 deletions(-) diff --git a/build.gradle b/build.gradle index d6a47a742e..7d6a5cf74e 100644 --- a/build.gradle +++ b/build.gradle @@ -91,17 +91,17 @@ ext { reactorVersion = '2020.0.0-M1' resilience4jVersion = '1.5.0' romeToolsVersion = '1.12.2' - rsocketVersion = '1.0.1' + rsocketVersion = '1.1.0-SNAPSHOT' saajVersion = '1.5.2' servletApiVersion = '4.0.1' smackVersion = '4.3.4' soapVersion = '1.4.0' - springAmqpVersion = project.hasProperty('springAmqpVersion') ? project.springAmqpVersion : '2.3.0-M1' - springDataVersion = project.hasProperty('springDataVersion') ? project.springDataVersion : '2020.0.0-M1' + springAmqpVersion = project.hasProperty('springAmqpVersion') ? project.springAmqpVersion : '2.3.0-SNAPSHOT' + springDataVersion = project.hasProperty('springDataVersion') ? project.springDataVersion : '2020.0.0-SNAPSHOT' springKafkaVersion = '2.5.4.BUILD-SNAPSHOT' - springSecurityVersion = project.hasProperty('springSecurityVersion') ? project.springSecurityVersion : '5.4.0-M1' + springSecurityVersion = project.hasProperty('springSecurityVersion') ? project.springSecurityVersion : '5.4.0-SNAPSHOT' springRetryVersion = '1.3.0' - springVersion = project.hasProperty('springVersion') ? project.springVersion : '5.3.0-M1' + springVersion = project.hasProperty('springVersion') ? project.springVersion : '5.3.0-SNAPSHOT' springWsVersion = '3.0.9.RELEASE' tomcatVersion = "9.0.36" xstreamVersion = '1.4.12' diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/inbound/IntegrationRequestMappingHandlerMapping.java b/spring-integration-http/src/main/java/org/springframework/integration/http/inbound/IntegrationRequestMappingHandlerMapping.java index 6941a350e0..a495fb7718 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/inbound/IntegrationRequestMappingHandlerMapping.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/inbound/IntegrationRequestMappingHandlerMapping.java @@ -19,6 +19,7 @@ package org.springframework.integration.http.inbound; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; @@ -175,10 +176,19 @@ public final class IntegrationRequestMappingHandlerMapping extends RequestMappin for (RequestMethod requestMethod : crossOrigin.getMethod()) { config.addAllowedMethod(requestMethod.name()); } - config.setAllowedOrigins(Arrays.asList(crossOrigin.getOrigin())); config.setAllowedHeaders(Arrays.asList(crossOrigin.getAllowedHeaders())); config.setExposedHeaders(Arrays.asList(crossOrigin.getExposedHeaders())); - config.setAllowCredentials(crossOrigin.getAllowCredentials()); + Boolean allowCredentials = crossOrigin.getAllowCredentials(); + config.setAllowCredentials(allowCredentials); + List allowedOrigins = Arrays.asList(crossOrigin.getOrigin()); + if (Boolean.TRUE.equals(allowCredentials) + && CollectionUtils.contains(allowedOrigins.iterator(), CorsConfiguration.ALL)) { + config.setAllowedOriginPatterns(allowedOrigins); + } + else { + config.setAllowedOrigins(allowedOrigins); + } + if (crossOrigin.getMaxAge() != -1) { config.setMaxAge(crossOrigin.getMaxAge()); } diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/inbound/CrossOriginTests.java b/spring-integration-http/src/test/java/org/springframework/integration/http/inbound/CrossOriginTests.java index f4404d5e0c..c628198f64 100644 --- a/spring-integration-http/src/test/java/org/springframework/integration/http/inbound/CrossOriginTests.java +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/inbound/CrossOriginTests.java @@ -85,7 +85,8 @@ public class CrossOriginTests { CorsConfiguration config = getCorsConfiguration(chain, false); assertThat(config).isNotNull(); assertThat(config.getAllowedMethods().toArray()).isEqualTo(new String[] { "GET" }); - assertThat(config.getAllowedOrigins().toArray()).isEqualTo(new String[] { "*" }); + assertThat(config.getAllowedOrigins()).isNull(); + assertThat(config.getAllowedOriginPatterns().toArray()).isEqualTo(new String[] { "*" }); assertThat(config.getAllowCredentials()).isTrue(); assertThat(config.getAllowedHeaders().toArray()).isEqualTo(new String[] { "*" }); assertThat(config.getExposedHeaders()).isEmpty(); @@ -116,7 +117,8 @@ public class CrossOriginTests { CorsConfiguration config = getCorsConfiguration(chain, true); assertThat(config).isNotNull(); assertThat(config.getAllowedMethods().toArray()).isEqualTo(new String[] { "GET" }); - assertThat(config.getAllowedOrigins().toArray()).isEqualTo(new String[] { "*" }); + assertThat(config.getAllowedOrigins()).isNull(); + assertThat(config.getAllowedOriginPatterns().toArray()).isEqualTo(new String[] { "*" }); assertThat(config.getAllowCredentials()).isTrue(); assertThat(config.getAllowedHeaders().toArray()).isEqualTo(new String[] { "*" }); assertThat(config.getExposedHeaders()).isEmpty(); @@ -133,7 +135,8 @@ public class CrossOriginTests { CorsConfiguration config = getCorsConfiguration(chain, true); assertThat(config).isNotNull(); assertThat(config.getAllowedMethods().toArray()).isEqualTo(new String[] { "*" }); - assertThat(config.getAllowedOrigins().toArray()).isEqualTo(new String[] { "*" }); + assertThat(config.getAllowedOrigins()).isNull(); + assertThat(config.getAllowedOriginPatterns().toArray()).isEqualTo(new String[] { "*" }); assertThat(config.getAllowedHeaders().toArray()).isEqualTo(new String[] { "*" }); assertThat(config.getAllowCredentials()).isTrue(); assertThat(config.getExposedHeaders()).isNull(); @@ -149,7 +152,8 @@ public class CrossOriginTests { CorsConfiguration config = getCorsConfiguration(chain, true); assertThat(config).isNotNull(); assertThat(config.getAllowedMethods().toArray()).isEqualTo(new String[] { "*" }); - assertThat(config.getAllowedOrigins().toArray()).isEqualTo(new String[] { "*" }); + assertThat(config.getAllowedOrigins()).isNull(); + assertThat(config.getAllowedOriginPatterns().toArray()).isEqualTo(new String[] { "*" }); assertThat(config.getAllowedHeaders().toArray()).isEqualTo(new String[] { "*" }); assertThat(config.getAllowCredentials()).isTrue(); assertThat(config.getExposedHeaders()).isNull(); diff --git a/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/ClientRSocketConnector.java b/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/ClientRSocketConnector.java index 21ea7cf883..74c06ba6ea 100644 --- a/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/ClientRSocketConnector.java +++ b/spring-integration-rsocket/src/main/java/org/springframework/integration/rsocket/ClientRSocketConnector.java @@ -26,11 +26,12 @@ import org.springframework.messaging.rsocket.RSocketRequester; import org.springframework.util.Assert; import org.springframework.util.MimeType; +import io.rsocket.core.RSocketConnector; import io.rsocket.transport.ClientTransport; import io.rsocket.transport.netty.client.TcpClientTransport; import io.rsocket.transport.netty.client.WebsocketClientTransport; -import reactor.core.Disposable; import reactor.core.publisher.Mono; +import reactor.core.publisher.Sinks; /** * A client {@link AbstractRSocketConnector} extension to the RSocket connection. @@ -82,7 +83,7 @@ public class ClientRSocketConnector extends AbstractRSocketConnector { /** * Instantiate a connector based on the provided {@link ClientTransport}. * @param clientTransport the {@link ClientTransport} to use. - * @see RSocketRequester.Builder#connect(ClientTransport) + * @see RSocketRequester.Builder#transport(ClientTransport) */ public ClientRSocketConnector(ClientTransport clientTransport) { super(new IntegrationRSocketMessageHandler()); @@ -175,18 +176,27 @@ public class ClientRSocketConnector extends AbstractRSocketConnector { public void afterPropertiesSet() { super.afterPropertiesSet(); - this.rsocketRequesterMono = + Sinks.StandaloneMonoSink rsocketConnector = Sinks.promise(); + + RSocketRequester rsocketRequester = RSocketRequester.builder() .dataMimeType(getDataMimeType()) .metadataMimeType(getMetadataMimeType()) .rsocketStrategies(getRSocketStrategies()) .setupData(this.setupData) .setupRoute(this.setupRoute, this.setupRouteVars) - .rsocketConnector(this.connectorConfigurer) - .rsocketConnector((connector) -> - connector.acceptor(this.rSocketMessageHandler.responder())) .apply((builder) -> this.setupMetadata.forEach(builder::setupMetadata)) - .connect(this.clientTransport) + .rsocketConnector(this.connectorConfigurer) + .rsocketConnector((connector) -> { + connector.acceptor(this.rSocketMessageHandler.responder()); + rsocketConnector.success(connector); + }) + .transport(this.clientTransport); + + this.rsocketRequesterMono = + rsocketConnector.asMono() + .flatMap(rSocketConnector -> rSocketConnector.connect(this.clientTransport)) + .thenReturn(rsocketRequester) .cache(); } @@ -205,8 +215,7 @@ public class ClientRSocketConnector extends AbstractRSocketConnector { @Override public void destroy() { this.rsocketRequesterMono - .map(RSocketRequester::rsocket) - .doOnNext(Disposable::dispose) + .doOnNext(RSocketRequester::dispose) .subscribe(); } diff --git a/spring-integration-rsocket/src/main/resources/org/springframework/integration/rsocket/config/spring-integration-rsocket.xsd b/spring-integration-rsocket/src/main/resources/org/springframework/integration/rsocket/config/spring-integration-rsocket.xsd index 59a17afff7..58d7599a75 100644 --- a/spring-integration-rsocket/src/main/resources/org/springframework/integration/rsocket/config/spring-integration-rsocket.xsd +++ b/spring-integration-rsocket/src/main/resources/org/springframework/integration/rsocket/config/spring-integration-rsocket.xsd @@ -22,7 +22,7 @@ Configures a Messaging Gateway Endpoint for the - 'org.springframework.integration.rsocket.inbound.RSocketInboundGateway to receive RSocket + 'org.springframework.integration.rsocket.inbound.RSocketInboundGateway' to receive RSocket requests and produce RSocket responses. diff --git a/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/outbound/RSocketOutboundGatewayIntegrationTests.java b/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/outbound/RSocketOutboundGatewayIntegrationTests.java index 3ebbbd7617..1cf39595ed 100644 --- a/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/outbound/RSocketOutboundGatewayIntegrationTests.java +++ b/spring-integration-rsocket/src/test/java/org/springframework/integration/rsocket/outbound/RSocketOutboundGatewayIntegrationTests.java @@ -59,8 +59,10 @@ import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import io.rsocket.RSocket; +import io.rsocket.core.RSocketConnector; import io.rsocket.core.RSocketServer; import io.rsocket.frame.decoder.PayloadDecoder; +import io.rsocket.transport.netty.client.TcpClientTransport; import io.rsocket.transport.netty.server.CloseableChannel; import io.rsocket.transport.netty.server.TcpServerTransport; import reactor.core.Disposable; @@ -497,14 +499,22 @@ public class RSocketOutboundGatewayIntegrationTests { @Bean(destroyMethod = "dispose") @Nullable public RSocket rsocketForServerRequests() { - return RSocketRequester.builder() + Sinks.StandaloneMonoSink rsocketConnector = Sinks.promise(); + + RSocketRequester.builder() .setupRoute("clientConnect") - .rsocketConnector(connector -> - connector.acceptor( - RSocketMessageHandler.responder(RSocketStrategies.create(), controller()))) - .connectTcp("localhost", server.address().getPort()) - .block() - .rsocket(); + .rsocketConnector(connector -> { + connector.acceptor( + RSocketMessageHandler.responder(RSocketStrategies.create(), controller())); + rsocketConnector.success(connector); + }) + .tcp("localhost", server.address().getPort()); + + return rsocketConnector.asMono() + .flatMap(rSocketConnector -> + rSocketConnector.connect( + TcpClientTransport.create("localhost", server.address().getPort()))) + .block(); } @Bean diff --git a/spring-integration-webflux/src/main/java/org/springframework/integration/webflux/inbound/WebFluxIntegrationRequestMappingHandlerMapping.java b/spring-integration-webflux/src/main/java/org/springframework/integration/webflux/inbound/WebFluxIntegrationRequestMappingHandlerMapping.java index 03f492b6cf..cba417e9e3 100644 --- a/spring-integration-webflux/src/main/java/org/springframework/integration/webflux/inbound/WebFluxIntegrationRequestMappingHandlerMapping.java +++ b/spring-integration-webflux/src/main/java/org/springframework/integration/webflux/inbound/WebFluxIntegrationRequestMappingHandlerMapping.java @@ -18,6 +18,7 @@ package org.springframework.integration.webflux.inbound; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import org.springframework.beans.BeansException; @@ -151,10 +152,19 @@ public class WebFluxIntegrationRequestMappingHandlerMapping extends RequestMappi for (RequestMethod requestMethod : crossOrigin.getMethod()) { config.addAllowedMethod(requestMethod.name()); } - config.setAllowedOrigins(Arrays.asList(crossOrigin.getOrigin())); config.setAllowedHeaders(Arrays.asList(crossOrigin.getAllowedHeaders())); config.setExposedHeaders(Arrays.asList(crossOrigin.getExposedHeaders())); - config.setAllowCredentials(crossOrigin.getAllowCredentials()); + Boolean allowCredentials = crossOrigin.getAllowCredentials(); + config.setAllowCredentials(allowCredentials); + List allowedOrigins = Arrays.asList(crossOrigin.getOrigin()); + if (Boolean.TRUE.equals(allowCredentials) + && CollectionUtils.contains(allowedOrigins.iterator(), CorsConfiguration.ALL)) { + config.setAllowedOriginPatterns(allowedOrigins); + } + else { + config.setAllowedOrigins(allowedOrigins); + } + if (crossOrigin.getMaxAge() != -1) { config.setMaxAge(crossOrigin.getMaxAge()); }