/* * 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 * * 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.autoconfigure; import java.math.BigInteger; import java.util.List; import java.util.function.Supplier; import io.micrometer.core.instrument.MeterRegistry; import io.rsocket.RSocket; 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.ConditionalOnProperty; import org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.rsocket.context.RSocketServerBootstrap; import org.springframework.boot.rsocket.server.RSocketServerFactory; import org.springframework.cloud.gateway.rsocket.actuate.BrokerActuator; import org.springframework.cloud.gateway.rsocket.actuate.BrokerActuatorHandlerRegistration; import org.springframework.cloud.gateway.rsocket.cluster.ClusterJoinListener; import org.springframework.cloud.gateway.rsocket.cluster.ClusterService; import org.springframework.cloud.gateway.rsocket.cluster.RouteJoinListener; import org.springframework.cloud.gateway.rsocket.common.autoconfigure.GatewayRSocketCommonAutoConfiguration; import org.springframework.cloud.gateway.rsocket.core.GatewayRSocketFactory; import org.springframework.cloud.gateway.rsocket.core.GatewayServerRSocketFactoryProcessor; import org.springframework.cloud.gateway.rsocket.core.PendingRequestRSocketFactory; 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.routing.RoutingTableRoutes; import org.springframework.cloud.gateway.rsocket.routing.RoutingTableSocketAcceptorFilter; import org.springframework.cloud.gateway.rsocket.socketacceptor.GatewaySocketAcceptor; import org.springframework.cloud.gateway.rsocket.socketacceptor.SocketAcceptorFilter; import org.springframework.cloud.gateway.rsocket.socketacceptor.SocketAcceptorPredicate; import org.springframework.cloud.gateway.rsocket.socketacceptor.SocketAcceptorPredicateFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.messaging.rsocket.RSocketStrategies; import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler; import static org.springframework.cloud.gateway.rsocket.common.autoconfigure.GatewayRSocketCommonAutoConfiguration.ID_GENERATOR_BEAN_NAME; /** * @author Spencer Gibb */ @Configuration @ConditionalOnProperty(name = "spring.cloud.gateway.rsocket.enabled", matchIfMissing = true) @EnableConfigurationProperties @ConditionalOnClass(RSocket.class) @AutoConfigureBefore(RSocketServerAutoConfiguration.class) @AutoConfigureAfter(GatewayRSocketCommonAutoConfiguration.class) public class GatewayRSocketAutoConfiguration { @Bean public RoutingTable routingTable() { return new RoutingTable(); } // TODO: CompositeRoutes @Bean public RoutingTableRoutes registryRoutes(RoutingTable routingTable) { return new RoutingTableRoutes(routingTable); } @Bean public RoutingTableSocketAcceptorFilter registrySocketAcceptorFilter( RoutingTable routingTable) { return new RoutingTableSocketAcceptorFilter(routingTable); } @Bean public PendingRequestRSocketFactory pendingRequestRSocketFactory( RoutingTable routingTable, Routes routes, RSocketStrategies rSocketStrategies) { return new PendingRequestRSocketFactory(routingTable, routes, rSocketStrategies.metadataExtractor()); } @Bean public LoadBalancerFactory loadBalancerFactory(RoutingTable routingTable) { return new LoadBalancerFactory(routingTable); } @Bean public GatewayRSocketFactory gatewayRSocketFactory(RoutingTable routingTable, Routes routes, PendingRequestRSocketFactory pendingFactory, LoadBalancerFactory loadBalancerFactory, MeterRegistry meterRegistry, BrokerProperties properties, RSocketStrategies rSocketStrategies) { return new GatewayRSocketFactory(routingTable, routes, pendingFactory, loadBalancerFactory, meterRegistry, properties, rSocketStrategies.metadataExtractor()); } @Bean public BrokerProperties brokerProperties(Environment env, @Qualifier(ID_GENERATOR_BEAN_NAME) Supplier<BigInteger> idGenerator) { BrokerProperties properties = new BrokerProperties(); // set default from env if (env.containsProperty("spring.application.name")) { properties.setId(env.getProperty("spring.application.name")); } properties.setRouteId(idGenerator.get()); return properties; } @Bean public SocketAcceptorPredicateFilter socketAcceptorPredicateFilter( List<SocketAcceptorPredicate> predicates) { return new SocketAcceptorPredicateFilter(predicates); } @Bean public GatewaySocketAcceptor socketAcceptor(GatewayRSocketFactory rsocketFactory, List<SocketAcceptorFilter> filters, MeterRegistry meterRegistry, BrokerProperties properties, RSocketStrategies rSocketStrategies) { return new GatewaySocketAcceptor(rsocketFactory, filters, meterRegistry, properties, rSocketStrategies.metadataExtractor()); } @Bean public GatewayServerRSocketFactoryProcessor gatewayServerRSocketFactoryProcessor( BrokerProperties properties, MeterRegistry meterRegistry) { return new GatewayServerRSocketFactoryProcessor(properties, meterRegistry); } @Bean public RSocketServerBootstrap gatewayRSocketServerBootstrap( RSocketServerFactory rSocketServerFactory, GatewaySocketAcceptor gatewaySocketAcceptor) { return new RSocketServerBootstrap(rSocketServerFactory, gatewaySocketAcceptor); } @Bean @ConditionalOnProperty(value = "spring.cloud.gateway.rsocket.broker.actuator.enabled", matchIfMissing = true) public BrokerActuatorHandlerRegistration brokerActuatorHandlerRegistration( RoutingTable routingTable, RSocketMessageHandler messageHandler, BrokerProperties properties) { return new BrokerActuatorHandlerRegistration(routingTable, messageHandler, properties); } @Bean @ConditionalOnProperty(value = "spring.cloud.gateway.rsocket.broker.actuator.enabled", matchIfMissing = true) public BrokerActuator brokerActuator(BrokerProperties properties, ClusterService clusterService, RoutingTable routingTable) { return new BrokerActuator(properties, clusterService, routingTable); } @Configuration @ConditionalOnProperty(name = "spring.cloud.gateway.rsocket.cluster.enabled", matchIfMissing = true) protected static class ClusterConfiguration { @Bean public ClusterService clusterService() { return new ClusterService(); } @Bean public ClusterJoinListener clusterJoinListener(ClusterService clusterService, BrokerProperties properties, RSocketStrategies strategies, GatewayRSocketFactory gatewayRSocketFactory) { return new ClusterJoinListener(clusterService, properties, strategies, gatewayRSocketFactory); } @Bean public RouteJoinListener routeJoinListener(ClusterService clusterService, RoutingTable routingTable, BrokerProperties properties) { return new RouteJoinListener(clusterService, routingTable, properties); } } }