Spring Cloud Gateway動的ルーティング構成


この記事は学習を記録するために使用されます.
ここでは主に符号化方式により動的回路を実現する
#カスタムRouteDefinitionWriter
Spring Cloud GatewayデフォルトのRouteDefinitionWriter実装クラスはorg.springframework.cloud.gateway.route.InMemoryRouteDefinitionRepository、Route情報は現在のインスタンスのメモリに保存されます.これはクラスタ環境で同期の問題が発生するため、redisを使用して非同期の問題を解決します.
 
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
 *   Redis         (     InMemoryRouteDefinitionRepository)
 * 
 *     :        getRouteDefinitions,      ,       ,      Map ,      Map  。
 *
 * @since 2018 7 9    2:39:02
 */
@Component
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {
    public static final String  GATEWAY_ROUTES = "geteway_routes";
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Override
    public Flux getRouteDefinitions() {
        List routeDefinitions = new ArrayList<>();
        redisTemplate.opsForHash().values(GATEWAY_ROUTES).stream().forEach(routeDefinition -> {
            routeDefinitions.add(JSON.parseObject(routeDefinition.toString(), RouteDefinition.class));
        });
        return Flux.fromIterable(routeDefinitions);
    }
    @Override
    public Mono save(Mono route) {
        return route
                .flatMap(routeDefinition -> {
                    redisTemplate.opsForHash().put(GATEWAY_ROUTES, routeDefinition.getId(),
                            JSON.toJSONString(routeDefinition));
                    return Mono.empty();
                });
    }
    @Override
    public Mono delete(Mono routeId) {
        return routeId.flatMap(id -> {
            if (redisTemplate.opsForHash().hasKey(GATEWAY_ROUTES, id)) {
                redisTemplate.opsForHash().delete(GATEWAY_ROUTES, id);
                return Mono.empty();
            }
            return Mono.defer(() -> Mono.error(new NotFoundException("RouteDefinition not found: " + routeId)));
        });
    }
}