Splits gateway RSocket support in to Common, Client and Broker Modules

Metadata moved to common module. Auto config sets up metadata parsing.
Client module created with properties and helper classes for ease
of using RouteSetup and Forwarding metadata.
This commit is contained in:
Spencer Gibb
2019-09-09 18:40:29 -04:00
parent 0cb9af12ed
commit dee0516e87
76 changed files with 1094 additions and 264 deletions

View File

@@ -43,6 +43,21 @@
<artifactId>spring-cloud-gateway-rsocket</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket-broker</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>

View File

@@ -29,129 +29,12 @@
<artifactId>spring-cloud-gateway-rsocket</artifactId>
<name>Spring Cloud Gateway RSocket</name>
<description>Spring Cloud Gateway RSocket</description>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.rsocket</groupId>
<artifactId>rsocket-core</artifactId>
</dependency>
<dependency>
<groupId>io.rsocket</groupId>
<artifactId>rsocket-micrometer</artifactId>
</dependency>
<dependency>
<groupId>io.rsocket</groupId>
<artifactId>rsocket-transport-netty</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>org.roaringbitmap</groupId>
<artifactId>RoaringBitmap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
<executions>
<!-- Replacing default-compile as it is treated specially by maven -->
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<!-- Replacing default-testCompile as it is treated specially by maven -->
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>java8plus</id>
<activation>
<jdk>[1.8,2.0)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<modules>
<module>spring-cloud-gateway-rsocket-common</module>
<module>spring-cloud-gateway-rsocket-client</module>
<module>spring-cloud-gateway-rsocket-broker</module>
</modules>
</project>

View File

@@ -0,0 +1,168 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2018-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
~
~ 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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket</artifactId>
<version>2.2.0.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket-broker</artifactId>
<name>Spring Cloud Gateway RSocket Broker</name>
<description>Spring Cloud Gateway RSocket Broker</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.rsocket</groupId>
<artifactId>rsocket-core</artifactId>
</dependency>
<dependency>
<groupId>io.rsocket</groupId>
<artifactId>rsocket-micrometer</artifactId>
</dependency>
<dependency>
<groupId>io.rsocket</groupId>
<artifactId>rsocket-transport-netty</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>org.roaringbitmap</groupId>
<artifactId>RoaringBitmap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket-common</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
<executions>
<!-- Replacing default-compile as it is treated specially by maven -->
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<!-- Replacing default-testCompile as it is treated specially by maven -->
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>java8plus</id>
<activation>
<jdk>[1.8,2.0)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -20,9 +20,9 @@ import java.math.BigInteger;
import java.util.Map;
import java.util.Objects;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata.Key;
import org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata.Key;
import org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;

View File

@@ -29,7 +29,7 @@ import io.rsocket.frame.SetupFrameFlyweight;
import io.rsocket.util.DefaultPayload;
import org.springframework.cloud.gateway.rsocket.autoconfigure.GatewayRSocketProperties;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.routing.RoutingTable;
import org.springframework.context.SmartLifecycle;
import org.springframework.core.io.buffer.DataBufferFactory;

View File

@@ -20,9 +20,9 @@ import java.math.BigInteger;
import java.util.Map;
import java.util.Objects;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata.Key;
import org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata.Key;
import org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
@@ -38,7 +38,8 @@ public final class RouteJoin {
private final Map<Key, String> tags;
public RouteJoin(BigInteger brokerId, BigInteger routeId, long timestamp, String serviceName, Map<Key, String> tags) {
public RouteJoin(BigInteger brokerId, BigInteger routeId, long timestamp,
String serviceName, Map<Key, String> tags) {
this.brokerId = brokerId;
this.routeId = routeId;
this.timestamp = timestamp;
@@ -75,27 +76,24 @@ public final class RouteJoin {
return false;
}
RouteJoin routeJoin = (RouteJoin) o;
return this.timestamp == routeJoin.timestamp &&
Objects.equals(this.brokerId, routeJoin.brokerId) &&
Objects.equals(this.routeId, routeJoin.routeId) &&
Objects.equals(this.serviceName, routeJoin.serviceName) &&
Objects.equals(this.tags, routeJoin.tags);
return this.timestamp == routeJoin.timestamp
&& Objects.equals(this.brokerId, routeJoin.brokerId)
&& Objects.equals(this.routeId, routeJoin.routeId)
&& Objects.equals(this.serviceName, routeJoin.serviceName)
&& Objects.equals(this.tags, routeJoin.tags);
}
@Override
public int hashCode() {
return Objects.hash(this.brokerId, this.routeId, this.timestamp, this.serviceName, this.tags);
return Objects.hash(this.brokerId, this.routeId, this.timestamp, this.serviceName,
this.tags);
}
@Override
public String toString() {
return new ToStringCreator(this)
.append("brokerId", brokerId)
.append("routeId", routeId)
.append("timestamp", timestamp)
.append("serviceName", serviceName)
.append("tags", tags)
.toString();
return new ToStringCreator(this).append("brokerId", brokerId)
.append("routeId", routeId).append("timestamp", timestamp)
.append("serviceName", serviceName).append("tags", tags).toString();
}

View File

@@ -57,9 +57,9 @@ public final class RouteRemove {
return false;
}
RouteRemove routeJoin = (RouteRemove) o;
return this.timestamp == routeJoin.timestamp &&
Objects.equals(this.brokerId, routeJoin.brokerId) &&
Objects.equals(this.routeId, routeJoin.routeId);
return this.timestamp == routeJoin.timestamp
&& Objects.equals(this.brokerId, routeJoin.brokerId)
&& Objects.equals(this.routeId, routeJoin.routeId);
}
@Override
@@ -69,11 +69,8 @@ public final class RouteRemove {
@Override
public String toString() {
return new ToStringCreator(this)
.append("brokerId", brokerId)
.append("routeId", routeId)
.append("timestamp", timestamp)
.toString();
return new ToStringCreator(this).append("brokerId", brokerId)
.append("routeId", routeId).append("timestamp", timestamp).toString();
}

View File

@@ -21,21 +21,20 @@ import java.util.List;
import io.micrometer.core.instrument.MeterRegistry;
import io.rsocket.RSocket;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.rsocket.messaging.RSocketStrategiesCustomizer;
import org.springframework.boot.rsocket.server.RSocketServerBootstrap;
import org.springframework.boot.rsocket.server.RSocketServerFactory;
import org.springframework.cloud.gateway.rsocket.actuate.GatewayRSocketActuator;
import org.springframework.cloud.gateway.rsocket.actuate.GatewayRSocketActuatorRegistrar;
import org.springframework.cloud.gateway.rsocket.common.autoconfigure.GatewayRSocketCommonAutoConfiguration;
import org.springframework.cloud.gateway.rsocket.core.GatewayRSocketFactory;
import org.springframework.cloud.gateway.rsocket.core.GatewayServerRSocketFactoryCustomizer;
import org.springframework.cloud.gateway.rsocket.core.PendingRequestRSocketFactory;
import org.springframework.cloud.gateway.rsocket.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.route.Routes;
import org.springframework.cloud.gateway.rsocket.routing.LoadBalancerFactory;
import org.springframework.cloud.gateway.rsocket.routing.RoutingTable;
@@ -48,14 +47,9 @@ import org.springframework.cloud.gateway.rsocket.socketacceptor.SocketAcceptorPr
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.messaging.rsocket.DefaultMetadataExtractor;
import org.springframework.messaging.rsocket.MetadataExtractor;
import org.springframework.messaging.rsocket.RSocketStrategies;
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
import static org.springframework.cloud.gateway.rsocket.metadata.Forwarding.FORWARDING_MIME_TYPE;
import static org.springframework.cloud.gateway.rsocket.metadata.RouteSetup.ROUTE_SETUP_MIME_TYPE;
/**
* @author Spencer Gibb
*/
@@ -65,6 +59,7 @@ import static org.springframework.cloud.gateway.rsocket.metadata.RouteSetup.ROUT
@EnableConfigurationProperties
@ConditionalOnClass(RSocket.class)
@AutoConfigureBefore(RSocketServerAutoConfiguration.class)
@AutoConfigureAfter(GatewayRSocketCommonAutoConfiguration.class)
public class GatewayRSocketAutoConfiguration {
@Bean
@@ -127,23 +122,8 @@ public class GatewayRSocketAutoConfiguration {
public GatewaySocketAcceptor socketAcceptor(GatewayRSocketFactory rsocketFactory,
List<SocketAcceptorFilter> filters, MeterRegistry meterRegistry,
GatewayRSocketProperties properties, RSocketStrategies rSocketStrategies) {
MetadataExtractor metadataExtractor = registerMimeTypes(rSocketStrategies);
return new GatewaySocketAcceptor(rsocketFactory, filters, meterRegistry,
properties, metadataExtractor);
}
public static MetadataExtractor registerMimeTypes(
RSocketStrategies rSocketStrategies) {
MetadataExtractor metadataExtractor = rSocketStrategies.metadataExtractor();
// TODO: see if possible to make easier in framework.
if (metadataExtractor instanceof DefaultMetadataExtractor) {
DefaultMetadataExtractor extractor = (DefaultMetadataExtractor) metadataExtractor;
extractor.metadataToExtract(FORWARDING_MIME_TYPE, Forwarding.class,
Forwarding.METADATA_KEY);
extractor.metadataToExtract(ROUTE_SETUP_MIME_TYPE, RouteSetup.class,
RouteSetup.METADATA_KEY);
}
return metadataExtractor;
properties, rSocketStrategies.metadataExtractor());
}
@Bean
@@ -159,14 +139,6 @@ public class GatewayRSocketAutoConfiguration {
return new RSocketServerBootstrap(rSocketServerFactory, gatewaySocketAcceptor);
}
@Bean
public RSocketStrategiesCustomizer gatewayRSocketStrategiesCustomizer() {
return strategies -> {
strategies.decoder(new Forwarding.Decoder(), new RouteSetup.Decoder())
.encoder(new Forwarding.Encoder(), new RouteSetup.Encoder());
};
}
@Bean
public GatewayRSocketActuatorRegistrar gatewayRSocketActuatorRegistrar(
RoutingTable routingTable, RSocketMessageHandler messageHandler,

View File

@@ -25,7 +25,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.rsocket.autoconfigure.GatewayRSocketProperties;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.messaging.rsocket.MetadataExtractor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

View File

@@ -23,9 +23,9 @@ import io.rsocket.Payload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.rsocket.common.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.common.metadata.Metadata;
import org.springframework.cloud.gateway.rsocket.filter.AbstractRSocketExchange;
import org.springframework.cloud.gateway.rsocket.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.metadata.Metadata;
import org.springframework.messaging.rsocket.MetadataExtractor;
/**

View File

@@ -32,7 +32,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.rsocket.autoconfigure.GatewayRSocketProperties;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.route.Route;
import org.springframework.cloud.gateway.rsocket.route.Routes;
import org.springframework.cloud.gateway.rsocket.routing.LoadBalancerFactory;

View File

@@ -21,15 +21,15 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.rsocket.autoconfigure.GatewayRSocketProperties;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.route.Routes;
import org.springframework.cloud.gateway.rsocket.routing.LoadBalancerFactory;
import org.springframework.cloud.gateway.rsocket.routing.RoutingTable;
import org.springframework.messaging.rsocket.MetadataExtractor;
import org.springframework.util.Assert;
import static org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey.ROUTE_ID;
import static org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey.SERVICE_NAME;
import static org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey.ROUTE_ID;
import static org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey.SERVICE_NAME;
public class GatewayRSocketFactory {

View File

@@ -33,8 +33,8 @@ import reactor.core.publisher.Mono;
import reactor.core.publisher.MonoProcessor;
import reactor.util.function.Tuple2;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.filter.RSocketFilter.Success;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.route.Route;
import org.springframework.cloud.gateway.rsocket.routing.RoutingTable.RegisteredEvent;
import org.springframework.messaging.rsocket.MetadataExtractor;

View File

@@ -27,7 +27,7 @@ import org.apache.commons.logging.LogFactory;
import reactor.core.Disposable;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.route.Route;
import org.springframework.cloud.gateway.rsocket.route.Routes;
import org.springframework.cloud.gateway.rsocket.routing.RoutingTable;

View File

@@ -23,9 +23,9 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.core.GatewayExchange;
import org.springframework.cloud.gateway.rsocket.core.GatewayFilter;
import org.springframework.cloud.gateway.rsocket.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.support.AsyncPredicate;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;

View File

@@ -27,7 +27,7 @@ import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuple2;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
public class LoadBalancerFactory {

View File

@@ -39,8 +39,8 @@ import reactor.core.publisher.FluxSink;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -95,8 +95,8 @@ public class RoutingTable {
routeEntry.getTags().forEach((key, value) -> {
// TODO: deal with string keys?
RoaringBitmap bitmap = tagsToBitmaps.computeIfAbsent(
new TagKey(key, value), k -> new RoaringBitmap());
RoaringBitmap bitmap = tagsToBitmaps.computeIfAbsent(new TagKey(key, value),
k -> new RoaringBitmap());
bitmap.add(internalId);
});
@@ -232,8 +232,11 @@ public class RoutingTable {
}
static class RouteEntry {
private final RSocket rSocket;
private final TagsMetadata tagsMetadata;
private final Long timestamp;
RouteEntry(RSocket rSocket, TagsMetadata tagsMetadata) {
@@ -277,6 +280,7 @@ public class RoutingTable {
.toString();
// @formatter:on
}
}
static class TagKey {

View File

@@ -30,9 +30,9 @@ import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.core.GatewayExchange;
import org.springframework.cloud.gateway.rsocket.core.GatewayFilter;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.route.Route;
import org.springframework.cloud.gateway.rsocket.route.Routes;
import org.springframework.cloud.gateway.rsocket.support.AsyncPredicate;

View File

@@ -32,9 +32,9 @@ import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.rsocket.autoconfigure.GatewayRSocketProperties;
import org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.core.GatewayRSocketFactory;
import org.springframework.cloud.gateway.rsocket.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.metrics.MicrometerResponderRSocket;
import org.springframework.messaging.rsocket.MetadataExtractor;
import org.springframework.util.MimeType;

View File

@@ -21,8 +21,8 @@ import java.math.BigInteger;
import io.rsocket.ConnectionSetupPayload;
import io.rsocket.RSocket;
import org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.filter.AbstractRSocketExchange;
import org.springframework.cloud.gateway.rsocket.metadata.RouteSetup;
public class SocketAcceptorExchange extends AbstractRSocketExchange {

View File

@@ -30,8 +30,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.gateway.rsocket.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.common.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup;
import org.springframework.messaging.rsocket.RSocketRequester;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.SocketUtils;
@@ -47,6 +47,7 @@ import static org.springframework.cloud.gateway.rsocket.actuate.GatewayRSocketAc
public class GatewayRSocketActuatorIntegrationTests {
private final Random random = new Random();
@Autowired
private RSocketRequester.Builder requesterBuilder;
@@ -71,7 +72,8 @@ public class GatewayRSocketActuatorIntegrationTests {
BrokerInfo data = BrokerInfo.of(brokerId).build();
Mono<BrokerInfo> result = callActuator(brokerId, BrokerInfo.class, data, BROKER_INFO_PATH);
Mono<BrokerInfo> result = callActuator(brokerId, BrokerInfo.class, data,
BROKER_INFO_PATH);
StepVerifier.create(result)
.consumeNextWith(res -> assertThat(res).isNotNull().isEqualTo(data))
@@ -86,7 +88,8 @@ public class GatewayRSocketActuatorIntegrationTests {
RouteJoin data = RouteJoin.builder().brokerId(brokerId).routeId(routeId)
.serviceName("testServiceName").build();
Mono<RouteJoin> result = callActuator(brokerId, RouteJoin.class, data, ROUTE_JOIN_PATH);
Mono<RouteJoin> result = callActuator(brokerId, RouteJoin.class, data,
ROUTE_JOIN_PATH);
StepVerifier.create(result)
.consumeNextWith(res -> assertThat(res).isNotNull().isEqualTo(data))
@@ -101,7 +104,8 @@ public class GatewayRSocketActuatorIntegrationTests {
RouteRemove data = RouteRemove.builder().brokerId(brokerId).routeId(routeId)
.build();
Mono<RouteRemove> result = callActuator(brokerId, RouteRemove.class, data, ROUTE_REMOVE_PATH);
Mono<RouteRemove> result = callActuator(brokerId, RouteRemove.class, data,
ROUTE_REMOVE_PATH);
StepVerifier.create(result)
.consumeNextWith(res -> assertThat(res).isNotNull().isEqualTo(data))
@@ -115,12 +119,11 @@ public class GatewayRSocketActuatorIntegrationTests {
.setupMetadata(routeSetup, RouteSetup.ROUTE_SETUP_MIME_TYPE)
.connectTcp("localhost", port).block();
Forwarding forwarding = Forwarding.of(brokerId).serviceName("gateway").disableProxy()
.build();
Forwarding forwarding = Forwarding.of(brokerId).serviceName("gateway")
.disableProxy().build();
return requester.route(path)
.metadata(forwarding, Forwarding.FORWARDING_MIME_TYPE).data(data)
.retrieveMono(type);
return requester.route(path).metadata(forwarding, Forwarding.FORWARDING_MIME_TYPE)
.data(data).retrieveMono(type);
}
@SpringBootConfiguration

View File

@@ -39,17 +39,17 @@ import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;
import org.springframework.cloud.gateway.rsocket.autoconfigure.GatewayRSocketProperties;
import org.springframework.cloud.gateway.rsocket.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.metadata.Metadata;
import org.springframework.cloud.gateway.rsocket.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey;
import org.springframework.cloud.gateway.rsocket.common.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.common.metadata.Metadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey;
import org.springframework.cloud.gateway.rsocket.common.test.MetadataEncoder;
import org.springframework.cloud.gateway.rsocket.route.DefaultRoute;
import org.springframework.cloud.gateway.rsocket.route.Route;
import org.springframework.cloud.gateway.rsocket.route.Routes;
import org.springframework.cloud.gateway.rsocket.routing.LoadBalancerFactory;
import org.springframework.cloud.gateway.rsocket.routing.RoutingTable;
import org.springframework.cloud.gateway.rsocket.test.MetadataEncoder;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.messaging.rsocket.DefaultMetadataExtractor;
import org.springframework.messaging.rsocket.MetadataExtractor;
@@ -60,7 +60,7 @@ 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.when;
import static org.springframework.cloud.gateway.rsocket.metadata.Forwarding.FORWARDING_MIME_TYPE;
import static org.springframework.cloud.gateway.rsocket.common.metadata.Forwarding.FORWARDING_MIME_TYPE;
/**
* @author Spencer Gibb

View File

@@ -23,9 +23,9 @@ import org.junit.Test;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.cloud.gateway.rsocket.common.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.core.GatewayExchange;
import org.springframework.cloud.gateway.rsocket.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.route.Route;
import org.springframework.cloud.gateway.rsocket.routing.RoutingTable.RegisteredEvent;
import org.springframework.cloud.gateway.rsocket.routing.RoutingTable.RouteEntry;

View File

@@ -26,8 +26,8 @@ import org.roaringbitmap.RoaringBitmap;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey;
import org.springframework.core.style.ToStringCreator;
import static org.assertj.core.api.Assertions.assertThat;
@@ -140,8 +140,7 @@ public class RoutingTableTests {
routeId);
assertThat(routingTable.routeEntries).containsKey(routeId);
tagsMetadata.getTags().forEach((key, value) -> {
RoutingTable.TagKey tagKey = new RoutingTable.TagKey(key,
value);
RoutingTable.TagKey tagKey = new RoutingTable.TagKey(key, value);
assertThat(routingTable.tagsToBitmaps).containsKey(tagKey);
RoaringBitmap bitmap = routingTable.tagsToBitmaps.get(tagKey);
assertThat(bitmap.contains(internalId));

View File

@@ -32,12 +32,12 @@ import org.junit.Test;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.rsocket.autoconfigure.GatewayRSocketProperties;
import org.springframework.cloud.gateway.rsocket.common.metadata.Metadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.test.MetadataEncoder;
import org.springframework.cloud.gateway.rsocket.core.GatewayRSocket;
import org.springframework.cloud.gateway.rsocket.core.GatewayRSocketFactory;
import org.springframework.cloud.gateway.rsocket.metadata.Metadata;
import org.springframework.cloud.gateway.rsocket.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.test.MetadataEncoder;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.messaging.rsocket.DefaultMetadataExtractor;
import org.springframework.messaging.rsocket.PayloadUtils;
@@ -48,7 +48,7 @@ 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.when;
import static org.springframework.cloud.gateway.rsocket.metadata.RouteSetup.ROUTE_SETUP_MIME_TYPE;
import static org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup.ROUTE_SETUP_MIME_TYPE;
/**
* @author Spencer Gibb

View File

@@ -45,13 +45,14 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.cloud.gateway.rsocket.common.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey;
import org.springframework.cloud.gateway.rsocket.common.test.MetadataEncoder;
import org.springframework.cloud.gateway.rsocket.core.GatewayExchange;
import org.springframework.cloud.gateway.rsocket.core.GatewayFilter;
import org.springframework.cloud.gateway.rsocket.core.GatewayFilterChain;
import org.springframework.cloud.gateway.rsocket.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.metadata.RouteSetup;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata;
import org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey;
import org.springframework.cloud.gateway.rsocket.socketacceptor.SocketAcceptorExchange;
import org.springframework.cloud.gateway.rsocket.socketacceptor.SocketAcceptorFilter;
import org.springframework.cloud.gateway.rsocket.socketacceptor.SocketAcceptorFilterChain;
@@ -63,8 +64,8 @@ import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.messaging.rsocket.RSocketStrategies;
import static io.netty.buffer.Unpooled.EMPTY_BUFFER;
import static org.springframework.cloud.gateway.rsocket.metadata.Metadata.COMPOSITE_MIME_TYPE;
import static org.springframework.cloud.gateway.rsocket.metadata.RouteSetup.ROUTE_SETUP_MIME_TYPE;
import static org.springframework.cloud.gateway.rsocket.common.metadata.Metadata.COMPOSITE_MIME_TYPE;
import static org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup.ROUTE_SETUP_MIME_TYPE;
@SpringBootApplication
public class PingPongApp {

View File

@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2018-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
~
~ 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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket</artifactId>
<version>2.2.0.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket-client</artifactId>
<name>Spring Cloud Gateway RSocket Client</name>
<description>Spring Cloud Gateway RSocket Client</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
<executions>
<!-- Replacing default-compile as it is treated specially by maven -->
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<!-- Replacing default-testCompile as it is treated specially by maven -->
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>java8plus</id>
<activation>
<jdk>[1.8,2.0)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,75 @@
/*
* Copyright 2013-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.cloud.gateway.rsocket.client;
import java.util.function.Consumer;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.rsocket.common.metadata.Forwarding;
import org.springframework.messaging.rsocket.RSocketRequester;
public class BrokerClient {
private final ClientProperties properties;
private final RSocketRequester.Builder builder;
public BrokerClient(ClientProperties properties, RSocketRequester.Builder builder) {
this.properties = properties;
this.builder = builder;
}
public ClientProperties getProperties() {
return this.properties;
}
public RSocketRequester.Builder getRSocketRequesterBuilder() {
return this.builder;
}
public Mono<RSocketRequester> connect() {
return connect(builder);
}
public Mono<RSocketRequester> connect(RSocketRequester.Builder requesterBuilder) {
ClientProperties.Broker broker = properties.getBroker();
switch (broker.getConnectionType()) {
case WEBSOCKET:
return requesterBuilder.connectWebSocket(broker.getWsUri());
}
return requesterBuilder.connectTcp(broker.getHost(), broker.getPort());
}
public Consumer<RSocketRequester.RequestSpec> forwarding(String destServiceName) {
return requestSpec -> {
Forwarding forwarding = Forwarding.of(properties.getRouteId())
.serviceName(destServiceName).build();
requestSpec.metadata(forwarding, Forwarding.FORWARDING_MIME_TYPE);
};
}
public Consumer<RSocketRequester.RequestSpec> forwarding(
Consumer<Forwarding.Builder> builderConsumer) {
return requestSpec -> {
Forwarding.Builder builder = Forwarding.of(properties.getRouteId());
builderConsumer.accept(builder);
requestSpec.metadata(builder.build(), Forwarding.FORWARDING_MIME_TYPE);
};
}
}

View File

@@ -0,0 +1,170 @@
/*
* Copyright 2013-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.cloud.gateway.rsocket.client;
import java.math.BigInteger;
import java.net.URI;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey;
import org.springframework.core.style.ToStringCreator;
import org.springframework.validation.annotation.Validated;
@ConfigurationProperties("spring.cloud.gateway.rsocket.client")
@Validated
public class ClientProperties {
@NotNull
private BigInteger routeId;
@NotEmpty
private String serviceName;
private Map<WellKnownKey, String> tags = new LinkedHashMap<>();
private Map<String, String> customTags = new LinkedHashMap<>();
@Valid
private Broker broker = new Broker();
public BigInteger getRouteId() {
return this.routeId;
}
public void setRouteId(BigInteger routeId) {
this.routeId = routeId;
}
public String getServiceName() {
return this.serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public Map<WellKnownKey, String> getTags() {
return this.tags;
}
public void setTags(Map<WellKnownKey, String> tags) {
this.tags = tags;
}
public Map<String, String> getCustomTags() {
return this.customTags;
}
public void setCustomTags(Map<String, String> customTags) {
this.customTags = customTags;
}
public Broker getBroker() {
return this.broker;
}
public void setBroker(Broker broker) {
this.broker = broker;
}
@Override
public String toString() {
// @formatter:off
return new ToStringCreator(this)
.append("routeId", routeId)
.append("serviceName", serviceName)
.append("tags", tags)
.append("customTags", customTags)
.append("broker", broker)
.toString();
// @formatter:on
}
public enum ConnectionType {
/** TCP RSocket connection. */
TCP,
/** WEBSOCKET RSocket connection. */
WEBSOCKET
}
public static class Broker {
// FIXME: validate based on connectionType
private String host;
private int port;
@NotNull
private ConnectionType connectionType = ConnectionType.TCP;
private URI wsUri;
public String getHost() {
return this.host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return this.port;
}
public void setPort(int port) {
this.port = port;
}
public ConnectionType getConnectionType() {
return this.connectionType;
}
public void setConnectionType(ConnectionType connectionType) {
this.connectionType = connectionType;
}
public URI getWsUri() {
return this.wsUri;
}
public void setWsUri(URI wsUri) {
this.wsUri = wsUri;
}
@Override
public String toString() {
// @formatter:off
return new ToStringCreator(this)
.append("host", host)
.append("port", port)
.append("wsUri", wsUri)
.append("connectionType", connectionType)
.toString();
// @formatter:on
}
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright 2013-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.cloud.gateway.rsocket.client;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.function.Supplier;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.rsocket.RSocket;
import io.rsocket.micrometer.MicrometerRSocketInterceptor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration;
import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.messaging.rsocket.RSocketRequester;
import org.springframework.messaging.rsocket.RSocketStrategies;
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
/**
* @author Spencer Gibb
*/
@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.rsocket.enabled",
matchIfMissing = true)
@EnableConfigurationProperties
@ConditionalOnClass({ RSocket.class, RSocketRequester.class })
@AutoConfigureAfter(RSocketStrategiesAutoConfiguration.class)
@AutoConfigureBefore(RSocketRequesterAutoConfiguration.class)
public class GatewayRSocketClientAutoConfiguration {
/**
* Name of client id generator bean.
*/
public static final String RSOCKET_CLIENT_ID_GENERATOR_NAME = "rsocketClientIdGenerator";
private final RSocketMessageHandler messageHandler;
private final SecureRandom secureRandom = new SecureRandom();
public GatewayRSocketClientAutoConfiguration(RSocketMessageHandler handler) {
messageHandler = handler;
}
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
public RSocketRequester.Builder gatewayRSocketRequesterBuilder(
RSocketStrategies strategies, ClientProperties properties,
MeterRegistry meterRegistry) {
RouteSetup.Builder routeSetup = RouteSetup.of(properties.getRouteId(),
properties.getServiceName());
properties.getTags().forEach(routeSetup::with);
properties.getCustomTags().forEach(routeSetup::with);
MicrometerRSocketInterceptor interceptor = new MicrometerRSocketInterceptor(
meterRegistry, Tag.of("servicename", properties.getServiceName()));
return RSocketRequester.builder()
.setupMetadata(routeSetup.build(), RouteSetup.ROUTE_SETUP_MIME_TYPE)
.rsocketStrategies(strategies).rsocketFactory(
rsocketFactory -> rsocketFactory.addRequesterPlugin(interceptor)
.acceptor(messageHandler.responder()));
}
@Bean
public BrokerClient brokerClient(RSocketRequester.Builder builder,
ClientProperties properties) {
return new BrokerClient(properties, builder);
}
@Bean(name = RSOCKET_CLIENT_ID_GENERATOR_NAME)
@ConditionalOnMissingBean(name = RSOCKET_CLIENT_ID_GENERATOR_NAME)
public Supplier<BigInteger> rsocketClientIdGenerator() {
return () -> {
byte[] bytes = new byte[16];
secureRandom.nextBytes(bytes);
return new BigInteger(bytes);
};
}
@Bean
public ClientProperties clientProperties(
@Qualifier(RSOCKET_CLIENT_ID_GENERATOR_NAME) Supplier<BigInteger> clientIdGenerator) {
ClientProperties clientProperties = new ClientProperties();
clientProperties.setRouteId(clientIdGenerator.get());
return clientProperties;
}
}

View File

@@ -0,0 +1,3 @@
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.gateway.rsocket.client.GatewayRSocketClientAutoConfiguration

View File

@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2018-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
~
~ 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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket</artifactId>
<version>2.2.0.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket-common</artifactId>
<name>Spring Cloud Gateway RSocket Common</name>
<description>Spring Cloud Gateway RSocket Common</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.rsocket</groupId>
<artifactId>rsocket-core</artifactId>
</dependency>
<dependency>
<groupId>io.rsocket</groupId>
<artifactId>rsocket-micrometer</artifactId>
</dependency>
<dependency>
<groupId>io.rsocket</groupId>
<artifactId>rsocket-transport-netty</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>org.roaringbitmap</groupId>
<artifactId>RoaringBitmap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
<executions>
<!-- Replacing default-compile as it is treated specially by maven -->
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<!-- Replacing default-testCompile as it is treated specially by maven -->
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>java8plus</id>
<activation>
<jdk>[1.8,2.0)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2013-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.cloud.gateway.rsocket.common.autoconfigure;
import io.rsocket.RSocket;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.rsocket.messaging.RSocketStrategiesCustomizer;
import org.springframework.cloud.gateway.rsocket.common.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Spencer Gibb
*/
@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.rsocket.enabled",
matchIfMissing = true)
@EnableConfigurationProperties
@ConditionalOnClass(RSocket.class)
@AutoConfigureBefore(RSocketStrategiesAutoConfiguration.class)
public class GatewayRSocketCommonAutoConfiguration {
@Bean
public RSocketStrategiesCustomizer gatewayRSocketStrategiesCustomizer() {
return strategies -> {
strategies.decoder(new Forwarding.Decoder(), new RouteSetup.Decoder())
.encoder(new Forwarding.Encoder(), new RouteSetup.Encoder());
};
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2013-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.cloud.gateway.rsocket.common.autoconfigure;
import io.rsocket.RSocket;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.gateway.rsocket.common.metadata.Forwarding;
import org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.rsocket.DefaultMetadataExtractor;
import org.springframework.messaging.rsocket.MetadataExtractor;
import org.springframework.messaging.rsocket.RSocketStrategies;
import static org.springframework.cloud.gateway.rsocket.common.metadata.Forwarding.FORWARDING_MIME_TYPE;
import static org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetup.ROUTE_SETUP_MIME_TYPE;
/**
* @author Spencer Gibb
*/
@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.rsocket.enabled",
matchIfMissing = true)
@EnableConfigurationProperties
@ConditionalOnClass(RSocket.class)
@AutoConfigureAfter({ GatewayRSocketCommonAutoConfiguration.class })
public class GatewayRSocketCommonMetadataAutoConfiguration implements InitializingBean {
private final ApplicationContext context;
public GatewayRSocketCommonMetadataAutoConfiguration(ApplicationContext context) {
this.context = context;
}
@Override
public void afterPropertiesSet() {
RSocketStrategies rSocketStrategies = this.context
.getBean(RSocketStrategies.class);
MetadataExtractor metadataExtractor = rSocketStrategies.metadataExtractor();
// TODO: see if possible to make easier in framework.
if (metadataExtractor instanceof DefaultMetadataExtractor) {
DefaultMetadataExtractor extractor = (DefaultMetadataExtractor) metadataExtractor;
extractor.metadataToExtract(FORWARDING_MIME_TYPE, Forwarding.class,
Forwarding.METADATA_KEY);
extractor.metadataToExtract(ROUTE_SETUP_MIME_TYPE, RouteSetup.class,
RouteSetup.METADATA_KEY);
}
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.gateway.rsocket.metadata;
package org.springframework.cloud.gateway.rsocket.common.metadata;
import java.math.BigInteger;
import java.util.Map;
@@ -36,8 +36,8 @@ import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
import org.springframework.util.MimeType;
import static org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey.ROUTE_ID;
import static org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey.SERVICE_NAME;
import static org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey.ROUTE_ID;
import static org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey.SERVICE_NAME;
// TODO: currently an ENVELOPE frame in RSocket extension, also discarding metadata
public final class Forwarding extends TagsMetadata {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.gateway.rsocket.metadata;
package org.springframework.cloud.gateway.rsocket.common.metadata;
import io.rsocket.metadata.WellKnownMimeType;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.gateway.rsocket.metadata;
package org.springframework.cloud.gateway.rsocket.common.metadata;
import java.math.BigInteger;
import java.util.Map;
@@ -81,7 +81,7 @@ public final class RouteSetup extends TagsMetadata {
// @formatter:off
TagsMetadata tagsMetadata = TagsMetadata.builder(this)
.with(WellKnownKey.SERVICE_NAME, getServiceName())
.with(WellKnownKey.ROUTE_ID, getId().toString())
.with(WellKnownKey.ROUTE_ID, id == null ? null : getId().toString())
.build();
// @formatter:on

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.gateway.rsocket.metadata;
package org.springframework.cloud.gateway.rsocket.common.metadata;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
@@ -35,8 +35,8 @@ import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.NettyDataBuffer;
import org.springframework.util.Assert;
import static org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey.ROUTE_ID;
import static org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey.SERVICE_NAME;
import static org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey.ROUTE_ID;
import static org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey.SERVICE_NAME;
public class TagsMetadata {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.gateway.rsocket.metadata;
package org.springframework.cloud.gateway.rsocket.common.metadata;
import java.util.Arrays;
import java.util.HashMap;

View File

@@ -0,0 +1,4 @@
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.gateway.rsocket.common.autoconfigure.GatewayRSocketCommonAutoConfiguration,\
org.springframework.cloud.gateway.rsocket.common.autoconfigure.GatewayRSocketCommonMetadataAutoConfiguration

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.gateway.rsocket.metadata;
package org.springframework.cloud.gateway.rsocket.common.metadata;
import java.util.Map;
@@ -28,7 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.gateway.rsocket.test.MetadataEncoder;
import org.springframework.cloud.gateway.rsocket.common.test.MetadataEncoder;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.messaging.rsocket.MetadataExtractor;
import org.springframework.messaging.rsocket.RSocketStrategies;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.gateway.rsocket.metadata;
package org.springframework.cloud.gateway.rsocket.common.metadata;
import java.math.BigInteger;
import java.util.LinkedHashMap;
@@ -22,12 +22,12 @@ import java.util.LinkedHashMap;
import io.netty.buffer.ByteBuf;
import org.junit.Test;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata.Key;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata.Key;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.gateway.rsocket.metadata.RouteSetupTests.MAX_BIGINT;
import static org.springframework.cloud.gateway.rsocket.metadata.RouteSetupTests.TWO_BYTE_BIGINT;
import static org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey.REGION;
import static org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetupTests.MAX_BIGINT;
import static org.springframework.cloud.gateway.rsocket.common.metadata.RouteSetupTests.TWO_BYTE_BIGINT;
import static org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey.REGION;
public class ForwardingTests {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.gateway.rsocket.metadata;
package org.springframework.cloud.gateway.rsocket.common.metadata;
import java.util.Map;
@@ -28,7 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.gateway.rsocket.test.MetadataEncoder;
import org.springframework.cloud.gateway.rsocket.common.test.MetadataEncoder;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.messaging.rsocket.MetadataExtractor;
import org.springframework.messaging.rsocket.RSocketStrategies;

View File

@@ -14,17 +14,17 @@
* limitations under the License.
*/
package org.springframework.cloud.gateway.rsocket.metadata;
package org.springframework.cloud.gateway.rsocket.common.metadata;
import java.math.BigInteger;
import io.netty.buffer.ByteBuf;
import org.junit.Test;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata.Key;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata.Key;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey.REGION;
import static org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey.REGION;
public class RouteSetupTests {

View File

@@ -14,16 +14,16 @@
* limitations under the License.
*/
package org.springframework.cloud.gateway.rsocket.metadata;
package org.springframework.cloud.gateway.rsocket.common.metadata;
import io.netty.buffer.ByteBuf;
import org.junit.Test;
import org.springframework.cloud.gateway.rsocket.metadata.TagsMetadata.Key;
import org.springframework.cloud.gateway.rsocket.common.metadata.TagsMetadata.Key;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey.ROUTE_ID;
import static org.springframework.cloud.gateway.rsocket.metadata.WellKnownKey.SERVICE_NAME;
import static org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey.ROUTE_ID;
import static org.springframework.cloud.gateway.rsocket.common.metadata.WellKnownKey.SERVICE_NAME;
public class TagsMetadataTests {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.gateway.rsocket.test;
package org.springframework.cloud.gateway.rsocket.common.test;
import java.util.Collections;
import java.util.LinkedHashMap;

View File

@@ -28,4 +28,5 @@
<suppress files=".*Route\.java" checks="FinalClass"/>
<suppress files=".*HystrixGatewayFilterFactory\.java" checks="AvoidNestedBlocks"/>
<suppress files=".*WellKnownKey\.java" checks="JavadocVariable"/>
<suppress files=".*MetadataEncoder\.java" checks="JavadocMethod"/>
</suppressions>