spring gateway 动态crud路由信息

翻看了gateway中的控制RouteDefinition的累如下:

public class InMemoryRouteDefinitionRepository implements RouteDefinitionRepository {

    private final Map<String, RouteDefinition> routes = synchronizedMap(
            new LinkedHashMap<String, RouteDefinition>());

    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return route.flatMap(r -> {
            if (StringUtils.isEmpty(r.getId())) {
                return Mono.error(new IllegalArgumentException("id may not be empty"));
            }
            routes.put(r.getId(), r);
            return Mono.empty();
        });
    }

    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return routeId.flatMap(id -> {
            if (routes.containsKey(id)) {
                routes.remove(id);
                return Mono.empty();
            }
            return Mono.defer(() -> Mono.error(
                    new NotFoundException("RouteDefinition not found: " + routeId)));
        });
    }

    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        return Flux.fromIterable(routes.values());
    }

}

而且该类添加了条件判断了,如果有实现RouteDefinitionRepository接口的bean则不会初始化InMemoryRouteDefinitionRepository 

@Bean
    @ConditionalOnMissingBean(RouteDefinitionRepository.class)
    public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {
        return new InMemoryRouteDefinitionRepository();
    }

//这是在GatewayAutoConfiguration中的代码

所以我照猫画虎的搞了一个灵活的,这样就可以自由控制gateway中的route了。

package com.jd.ads.gateway.main;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import java.net.URI;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by zzq on 2020/5/28.
 */
@RestController
@RequestMapping("/route-definition")
public class AdsRouteDefinitionManager implements RouteDefinitionRepository, ApplicationEventPublisherAware {
    Map<String, RouteDefinition> routesMap = new ConcurrentHashMap<>();

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    private ApplicationEventPublisher publisher;

    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        return Flux.fromIterable(routesMap.values());
    }

    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return route.flatMap(r -> {
            if (StringUtils.isEmpty(r.getId())) {
                return Mono.error(new IllegalArgumentException("id may not be empty"));
            }
            routesMap.put(r.getId(), r);
            return Mono.empty();
        });
    }

    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return routeId.flatMap(id -> {
            if (routesMap.containsKey(id)) {
                routesMap.remove(id);
                return Mono.empty();
            }
            return Mono.defer(() -> Mono.error(
                    new NotFoundException("RouteDefinition not found: " + routeId)));
        });
    }
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.publisher = applicationEventPublisher;
    }

    private void notifyChanged() {
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
    }

    /**
     * 增加路由
     */
    @PostMapping("/add")
    public String add(@RequestBody RouteDefinition definition) {
        String id = definition.getId();
        if (routesMap.containsKey(id)) {
            return "already exists";
        }
        routesMap.put(id, definition);
        notifyChanged();
        return "success";
    }

    /**
     * 更新路由
     */
    @PostMapping("/update")
    public String update(@RequestBody RouteDefinition definition) {
        try {
            String id = definition.getId();
            if (routesMap.containsKey(id)) {
                routesMap.put(id, definition);
                return "success";
            }
            return "not exists RouteDefinition";
        } catch (Exception e) {
            return "update fail,not find route  routeId: " + definition.getId();
        }
    }

    /**
     * 删除路由
     */
    @GetMapping("/delete")
    public String delete(String id) {
        try {
            if (routesMap.containsKey(id)) {
                routesMap.remove(id);
                notifyChanged();
                return "delete success";
            }
            return "delete fail,id not exists";
        } catch (Exception e) {
            e.printStackTrace();
            return "delete fail";
        }

    }

    @PostConstruct
    public void init() {
        RouteDefinition addMethod = getAddMethod();
        routesMap.put(addMethod.getId(), addMethod);
        RouteDefinition deleteMethod = getDeleteMethod();
        routesMap.put(deleteMethod.getId(), deleteMethod);
        RouteDefinition updateMethod = getUpdateMethod();
        routesMap.put(updateMethod.getId(), updateMethod);
    }

    public RouteDefinition getAddMethod() {
        RouteDefinition definition = new RouteDefinition();
        definition.setId("local-add");
        URI uri = UriComponentsBuilder.fromUriString("forward:///route-definition/add").build().toUri();
        definition.setUri(uri);

        PredicateDefinition predicate = new PredicateDefinition();
        predicate.setName("Path");

        Map<String, String> predicateParams = new HashMap<>(8);
        predicateParams.put("pattern", "/route-definition/add");
        predicate.setArgs(predicateParams);
        definition.setPredicates(new ArrayList<PredicateDefinition>() {{
            add(predicate);
        }});
        System.out.println("definition:" + JSON.toJSONString(definition));
        return definition;
    }

    public RouteDefinition getUpdateMethod() {
        RouteDefinition definition = new RouteDefinition();
        definition.setId("local-update");
        URI uri = UriComponentsBuilder.fromUriString("forward:///route-definition/update").build().toUri();
        definition.setUri(uri);

        PredicateDefinition predicate = new PredicateDefinition();
        predicate.setName("Path");

        Map<String, String> predicateParams = new HashMap<>(8);
        predicateParams.put("pattern", "/route-definition/update");
        predicate.setArgs(predicateParams);
        definition.setPredicates(new ArrayList<PredicateDefinition>() {{
            add(predicate);
        }});
        System.out.println("definition:" + JSON.toJSONString(definition));
        return definition;
    }

    public RouteDefinition getDeleteMethod() {
        RouteDefinition definition = new RouteDefinition();
        definition.setId("local-delete");
        URI uri = UriComponentsBuilder.fromUriString("forward:///route-definition/delete").build().toUri();
        definition.setUri(uri);

        PredicateDefinition predicate = new PredicateDefinition();
        predicate.setName("Path");

        Map<String, String> predicateParams = new HashMap<>(8);
        predicateParams.put("pattern", "/route-definition/delete");
        predicate.setArgs(predicateParams);
        definition.setPredicates(new ArrayList<PredicateDefinition>() {{
            add(predicate);
        }});
        System.out.println("definition:" + JSON.toJSONString(definition));
        return definition;
    }
}
  /*

  RouteDefinition definition = new RouteDefinition();
        definition.setId("id1");
        URI uri = UriComponentsBuilder.fromHttpUrl("http://127.0.0.1:8001/").build().toUri();
        // URI uri = UriComponentsBuilder.fromHttpUrl("http://baidu.com").build().toUri();
        definition.setUri(uri);

        //定义第一个断言
        PredicateDefinition predicate = new PredicateDefinition();
        predicate.setName("Path");

        Map<String, String> predicateParams = new HashMap<>(8);
        predicateParams.put("pattern", "/post1");
        predicate.setArgs(predicateParams);
        definition.setPredicates(new ArrayList<PredicateDefinition>() {{
            add(predicate);
        }});
        routesMap.put(definition.getId(), definition);
        System.out.println("definition:" + JSON.toJSONString(definition));



        //定义Filter
        FilterDefinition filter = new FilterDefinition();
        filter.setName("AddRequestHeader");
        Map<String, String> filterParams = new HashMap<>(8);
        //该_genkey_前缀是固定的,见org.springframework.cloud.gateway.support.NameUtils类
        filterParams.put("_genkey_0", "header");
        filterParams.put("_genkey_1", "addHeader");
        filter.setArgs(filterParams);

        FilterDefinition filter1 = new FilterDefinition();
        filter1.setName("AddRequestParameter");
        Map<String, String> filter1Params = new HashMap<>(8);
        filter1Params.put("_genkey_0", "param");
        filter1Params.put("_genkey_1", "addParam");
        filter1.setArgs(filter1Params);

        definition.setFilters(Arrays.asList(filter, filter1));
        definition.setPredicates(Arrays.asList(predicate));
        //*/

//        System.out.println("definition:" + JSON.toJSONString(definition)

 

posted @ 2020-05-28 17:55  soft.push("zzq")  Views(548)  Comments(0)    收藏  举报