From 92edbe4107e2fc79ac501be89f5f97f277496cc1 Mon Sep 17 00:00:00 2001 From: bruceppeng Date: Fri, 14 Jan 2022 17:06:02 +0800 Subject: [PATCH 1/3] =?UTF-8?q?gateway=E5=A2=9E=E5=8A=A0=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=9A=84=E8=83=BD=E5=8A=9B=EF=BC=8C=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E7=94=A8=E6=88=B7url=E8=87=AA=E5=8A=A8=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E5=88=B0=E6=B3=A8=E5=86=8C=E7=9A=84=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PolarisGatewayAutoConfiguration.java | 12 ++ .../core/route/DynamicRouteService.java | 103 +++++++++++++++++ .../scg/filter/DynamicRouteScgFilter.java | 107 ++++++++++++++++++ 3 files changed, 222 insertions(+) create mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/route/DynamicRouteService.java create mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/config/PolarisGatewayAutoConfiguration.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/config/PolarisGatewayAutoConfiguration.java index cf8c1743..759e94c9 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/config/PolarisGatewayAutoConfiguration.java +++ b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/config/PolarisGatewayAutoConfiguration.java @@ -19,6 +19,8 @@ package com.tencent.cloud.polaris.gateway.config; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.http.ZuulServlet; +import com.tencent.cloud.polaris.gateway.core.route.DynamicRouteService; +import com.tencent.cloud.polaris.gateway.core.scg.filter.DynamicRouteScgFilter; import com.tencent.cloud.polaris.gateway.core.scg.filter.Metadata2HeaderScgFilter; import com.tencent.cloud.polaris.gateway.core.scg.filter.MetadataFirstScgFilter; import com.tencent.cloud.polaris.gateway.core.scg.filter.RateLimitScgFilter; @@ -73,6 +75,16 @@ public class PolarisGatewayAutoConfiguration { public GlobalFilter metadata2HeaderScgFilter() { return new Metadata2HeaderScgFilter(); } + + @Bean + public DynamicRouteService dynamicRouteService() { + return new DynamicRouteService(); + } + + @Bean + public DynamicRouteScgFilter dynamicRouteFilter() { + return new DynamicRouteScgFilter(); + } } } diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/route/DynamicRouteService.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/route/DynamicRouteService.java new file mode 100644 index 00000000..536ec069 --- /dev/null +++ b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/route/DynamicRouteService.java @@ -0,0 +1,103 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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 com.tencent.cloud.polaris.gateway.core.route; + +import javax.annotation.Resource; +import org.springframework.cloud.gateway.event.RefreshRoutesEvent; +import org.springframework.cloud.gateway.route.RouteDefinition; +import org.springframework.cloud.gateway.route.RouteDefinitionWriter; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationEventPublisherAware; +import reactor.core.publisher.Mono; + + +/** + * dynamic route service. + * + * @author bruceppeng + */ +public class DynamicRouteService implements ApplicationEventPublisherAware { + + @Resource + private RouteDefinitionWriter routeDefinitionWriter; + + private ApplicationEventPublisher publisher; + + private void notifyChanged() { + this.publisher.publishEvent(new RefreshRoutesEvent(this)); + } + + + /** + * add route. + * @param definition definition + * @return sucess + */ + public String add(RouteDefinition definition) { + routeDefinitionWriter.save(Mono.just(definition)).subscribe(); + notifyChanged(); + return "success"; + } + + + /** + * update route. + * @param definition definition + * @return sucess + */ + public String update(RouteDefinition definition) { + try { + this.routeDefinitionWriter.delete(Mono.just(definition.getId())); + } catch (Exception e) { + return "update fail,not find route routeId: " + definition.getId(); + } + try { + routeDefinitionWriter.save(Mono.just(definition)).subscribe(); + notifyChanged(); + return "success"; + } catch (Exception e) { + return "update route fail"; + } + + + } + + /** + * delete route. + * @param id id + * @return sucess + */ + public String delete(String id) { + try { + this.routeDefinitionWriter.delete(Mono.just(id)).subscribe(); + + notifyChanged(); + return "delete success"; + } catch (Exception e) { + e.printStackTrace(); + return "delete fail"; + } + + } + + @Override + public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + this.publisher = applicationEventPublisher; + } + +} \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java new file mode 100644 index 00000000..e04be40c --- /dev/null +++ b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java @@ -0,0 +1,107 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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 com.tencent.cloud.polaris.gateway.core.scg.filter; + +import com.tencent.cloud.metadata.constant.MetadataConstant; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import com.tencent.cloud.polaris.gateway.core.route.DynamicRouteService; +import java.net.URI; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.config.GatewayProperties; +import org.springframework.cloud.gateway.filter.FilterDefinition; +import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition; +import org.springframework.cloud.gateway.route.RouteDefinition; +import org.springframework.core.Ordered; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; +import reactor.core.publisher.Mono; + +/** + * Filter for implement dynamic route. + * + * @author kan peng + */ +public class DynamicRouteScgFilter implements WebFilter, Ordered { + + private static final Logger LOG = LoggerFactory.getLogger(DynamicRouteScgFilter.class); + + @Autowired + private DynamicRouteService dynamicRouteService; + + @Autowired + private GatewayProperties gatewayProperties; + + @Override + public int getOrder() { + return MetadataConstant.OrderConstant.FILTER_ORDER + 1; + } + + @Override + public Mono filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) { + + + ServerHttpRequest serverHttpRequest = serverWebExchange.getRequest(); + String requestPath = serverHttpRequest.getURI().getPath(); + String[] pathList = requestPath.split("/"); + String id = pathList[1]; + String path = String.format("/%s/**",id); + + //判断是否已经加载此route + for(RouteDefinition routeDefinition: gatewayProperties.getRoutes()){ + if (id.equals(routeDefinition.getId())){ + return webFilterChain.filter(serverWebExchange) + .doOnError(throwable -> LOG.error("handle DynamicRouteFilter[{}] error.", MetadataContextHolder.get(), throwable)) + .doFinally((type) -> MetadataContextHolder.remove()); + } + } + + RouteDefinition definition = new RouteDefinition(); + definition.setId(id); + URI uri = URI.create("lb://"+id); + definition.setUri(uri); + + //定义第一个断言 + PredicateDefinition predicate = new PredicateDefinition(); + predicate.setName("Path"); + + Map predicateParams = new HashMap<>(8); + predicateParams.put("pattern", path); + predicate.setArgs(predicateParams); + + //定义Filter + FilterDefinition filter = new FilterDefinition(); + filter.setName("StripPrefix"); + filter.addArg("parts","1"); + + definition.setFilters(Arrays.asList(filter)); + definition.setPredicates(Arrays.asList(predicate)); + dynamicRouteService.add(definition); + + return webFilterChain.filter(serverWebExchange) + .doOnError(throwable -> LOG.error("handle DynamicRouteFilter[{}] error.", MetadataContextHolder.get(), throwable)) + .doFinally((type) -> MetadataContextHolder.remove()); + } + +} \ No newline at end of file From e7c678c086baaabb132aa54d6a455144ebede8c6 Mon Sep 17 00:00:00 2001 From: bruceppeng Date: Fri, 14 Jan 2022 17:41:59 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=B0=86=E4=B8=AD=E6=96=87=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=E6=94=B9=E6=88=90=E8=8B=B1=E6=96=87=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gateway/core/scg/filter/DynamicRouteScgFilter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java index e04be40c..f25a7a1c 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java +++ b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java @@ -68,7 +68,7 @@ public class DynamicRouteScgFilter implements WebFilter, Ordered { String id = pathList[1]; String path = String.format("/%s/**",id); - //判断是否已经加载此route + //Check whether the route has been loaded for(RouteDefinition routeDefinition: gatewayProperties.getRoutes()){ if (id.equals(routeDefinition.getId())){ return webFilterChain.filter(serverWebExchange) @@ -82,7 +82,7 @@ public class DynamicRouteScgFilter implements WebFilter, Ordered { URI uri = URI.create("lb://"+id); definition.setUri(uri); - //定义第一个断言 + //Define the first assertion PredicateDefinition predicate = new PredicateDefinition(); predicate.setName("Path"); @@ -90,7 +90,7 @@ public class DynamicRouteScgFilter implements WebFilter, Ordered { predicateParams.put("pattern", path); predicate.setArgs(predicateParams); - //定义Filter + //Define Filter FilterDefinition filter = new FilterDefinition(); filter.setName("StripPrefix"); filter.addArg("parts","1"); From 406364feb65a48bf057764f056a443dfbe9e7953 Mon Sep 17 00:00:00 2001 From: bruceppeng Date: Fri, 14 Jan 2022 17:50:56 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=EF=BC=8C=E5=8E=BB=E6=8E=89=E6=97=A0=E7=94=A8=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gateway/core/scg/filter/DynamicRouteScgFilter.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java index f25a7a1c..d3018884 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java +++ b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java @@ -71,9 +71,7 @@ public class DynamicRouteScgFilter implements WebFilter, Ordered { //Check whether the route has been loaded for(RouteDefinition routeDefinition: gatewayProperties.getRoutes()){ if (id.equals(routeDefinition.getId())){ - return webFilterChain.filter(serverWebExchange) - .doOnError(throwable -> LOG.error("handle DynamicRouteFilter[{}] error.", MetadataContextHolder.get(), throwable)) - .doFinally((type) -> MetadataContextHolder.remove()); + return webFilterChain.filter(serverWebExchange); } } @@ -99,9 +97,7 @@ public class DynamicRouteScgFilter implements WebFilter, Ordered { definition.setPredicates(Arrays.asList(predicate)); dynamicRouteService.add(definition); - return webFilterChain.filter(serverWebExchange) - .doOnError(throwable -> LOG.error("handle DynamicRouteFilter[{}] error.", MetadataContextHolder.get(), throwable)) - .doFinally((type) -> MetadataContextHolder.remove()); + return webFilterChain.filter(serverWebExchange); } } \ No newline at end of file