博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
聊聊springcloud的GatewayControllerEndpoint
阅读量:7017 次
发布时间:2019-06-28

本文共 12218 字,大约阅读时间需要 40 分钟。

  hot3.png

本文主要研究一下springcloud的GatewayControllerEndpoint

GatewayAutoConfiguration

spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java

@Configuration@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)@EnableConfigurationProperties@AutoConfigureBefore(HttpHandlerAutoConfiguration.class)@AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class})@ConditionalOnClass(DispatcherHandler.class)public class GatewayAutoConfiguration {	//......		@Bean	public AfterRoutePredicateFactory afterRoutePredicateFactory() {		return new AfterRoutePredicateFactory();	}	@Bean	public BeforeRoutePredicateFactory beforeRoutePredicateFactory() {		return new BeforeRoutePredicateFactory();	}	@Bean	public BetweenRoutePredicateFactory betweenRoutePredicateFactory() {		return new BetweenRoutePredicateFactory();	}	@Bean	public CookieRoutePredicateFactory cookieRoutePredicateFactory() {		return new CookieRoutePredicateFactory();	}	@Bean	public HeaderRoutePredicateFactory headerRoutePredicateFactory() {		return new HeaderRoutePredicateFactory();	}	@Bean	public HostRoutePredicateFactory hostRoutePredicateFactory() {		return new HostRoutePredicateFactory();	}	@Bean	public MethodRoutePredicateFactory methodRoutePredicateFactory() {		return new MethodRoutePredicateFactory();	}	@Bean	public PathRoutePredicateFactory pathRoutePredicateFactory() {		return new PathRoutePredicateFactory();	}	@Bean	public QueryRoutePredicateFactory queryRoutePredicateFactory() {		return new QueryRoutePredicateFactory();	}	@Bean	public ReadBodyPredicateFactory readBodyPredicateFactory(ServerCodecConfigurer codecConfigurer) {		return new ReadBodyPredicateFactory(codecConfigurer);	}	//......	@Configuration	@ConditionalOnClass(Health.class)	protected static class GatewayActuatorConfiguration {		@Bean		@ConditionalOnEnabledEndpoint		public GatewayControllerEndpoint gatewayControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator, List
globalFilters, List
GatewayFilters, RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator) { return new GatewayControllerEndpoint(routeDefinitionLocator, globalFilters, GatewayFilters, routeDefinitionWriter, routeLocator); } }}

可以看到最后有一个GatewayActuatorConfiguration,在有actuator类库的前提下则会配置,配置的是GatewayControllerEndpoint

GatewayControllerEndpoint

spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/actuate/GatewayControllerEndpoint.java

@RestControllerEndpoint(id = "gateway")public class GatewayControllerEndpoint implements ApplicationEventPublisherAware {	private static final Log log = LogFactory.getLog(GatewayControllerEndpoint.class);	private RouteDefinitionLocator routeDefinitionLocator;	private List
globalFilters; private List
GatewayFilters; private RouteDefinitionWriter routeDefinitionWriter; private RouteLocator routeLocator; private ApplicationEventPublisher publisher; public GatewayControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator, List
globalFilters, List
GatewayFilters, RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator) { this.routeDefinitionLocator = routeDefinitionLocator; this.globalFilters = globalFilters; this.GatewayFilters = GatewayFilters; this.routeDefinitionWriter = routeDefinitionWriter; this.routeLocator = routeLocator; } @Override public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { this.publisher = publisher; } // TODO: Add uncommited or new but not active routes endpoint @PostMapping("/refresh") public Mono
refresh() { this.publisher.publishEvent(new RefreshRoutesEvent(this)); return Mono.empty(); } @GetMapping("/globalfilters") public Mono
> globalfilters() { return getNamesToOrders(this.globalFilters); } @GetMapping("/routefilters") public Mono
> routefilers() { return getNamesToOrders(this.GatewayFilters); } private
Mono
> getNamesToOrders(List
list) { return Flux.fromIterable(list).reduce(new HashMap<>(), this::putItem); } private HashMap
putItem(HashMap
map, Object o) { Integer order = null; if (o instanceof Ordered) { order = ((Ordered)o).getOrder(); } //filters.put(o.getClass().getName(), order); map.put(o.toString(), order); return map; } // TODO: Flush out routes without a definition @GetMapping("/routes") public Mono
>> routes() { Mono
> routeDefs = this.routeDefinitionLocator.getRouteDefinitions() .collectMap(RouteDefinition::getId); Mono
> routes = this.routeLocator.getRoutes().collectList(); return Mono.zip(routeDefs, routes).map(tuple -> { Map
defs = tuple.getT1(); List
routeList = tuple.getT2(); List
> allRoutes = new ArrayList<>(); routeList.forEach(route -> { HashMap
r = new HashMap<>(); r.put("route_id", route.getId()); r.put("order", route.getOrder()); if (defs.containsKey(route.getId())) { r.put("route_definition", defs.get(route.getId())); } else { HashMap
obj = new HashMap<>(); obj.put("predicate", route.getPredicate().toString()); if (!route.getFilters().isEmpty()) { ArrayList
filters = new ArrayList<>(); for (GatewayFilter filter : route.getFilters()) { filters.add(filter.toString()); } obj.put("filters", filters); } if (!obj.isEmpty()) { r.put("route_object", obj); } } allRoutes.add(r); }); return allRoutes; }); }/*http POST :8080/admin/gateway/routes/apiaddreqhead uri=http://httpbin.org:80 predicates:='["Host=**.apiaddrequestheader.org", "Path=/headers"]' filters:='["AddRequestHeader=X-Request-ApiFoo, ApiBar"]'*/ @PostMapping("/routes/{id}") @SuppressWarnings("unchecked") public Mono
> save(@PathVariable String id, @RequestBody Mono
route) { return this.routeDefinitionWriter.save(route.map(r -> { r.setId(id); log.debug("Saving route: " + route); return r; })).then(Mono.defer(() -> Mono.just(ResponseEntity.created(URI.create("/routes/"+id)).build()) )); } @DeleteMapping("/routes/{id}") public Mono
> delete(@PathVariable String id) { return this.routeDefinitionWriter.delete(Mono.just(id)) .then(Mono.defer(() -> Mono.just(ResponseEntity.ok().build()))) .onErrorResume(t -> t instanceof NotFoundException, t -> Mono.just(ResponseEntity.notFound().build())); } @GetMapping("/routes/{id}") public Mono
> route(@PathVariable String id) { //TODO: missing RouteLocator return this.routeDefinitionLocator.getRouteDefinitions() .filter(route -> route.getId().equals(id)) .singleOrEmpty() .map(route -> ResponseEntity.ok(route)) .switchIfEmpty(Mono.just(ResponseEntity.notFound().build())); } @GetMapping("/routes/{id}/combinedfilters") public Mono
> combinedfilters(@PathVariable String id) { //TODO: missing global filters return this.routeLocator.getRoutes() .filter(route -> route.getId().equals(id)) .reduce(new HashMap<>(), this::putItem); }}

可以看到提供了如下几个rest api

  • POST /refresh
  • GET /globalfilters
  • GET /routefilters
  • GET /routes
  • POST /routes/{id}
  • GET /routes/{id}
  • GET /routes/{id}/combinedfilters

实例

/actuator/gateway/routes

[  {    "route_id": "CompositeDiscoveryClient_DISCOVERY-SERVICE",    "route_definition": {      "id": "CompositeDiscoveryClient_DISCOVERY-SERVICE",      "predicates": [        {          "name": "Path",          "args": {            "pattern": "/DISCOVERY-SERVICE/**"          }        }      ],      "filters": [        {          "name": "RewritePath",          "args": {            "regexp": "/DISCOVERY-SERVICE/(?
.*)", "replacement": "/${remaining}" } } ], "uri": "lb://DISCOVERY-SERVICE", "order": 0 }, "order": 0 }, { "route_id": "CompositeDiscoveryClient_GATEWAY-SERVICE", "route_definition": { "id": "CompositeDiscoveryClient_GATEWAY-SERVICE", "predicates": [ { "name": "Path", "args": { "pattern": "/GATEWAY-SERVICE/**" } } ], "filters": [ { "name": "RewritePath", "args": { "regexp": "/GATEWAY-SERVICE/(?
.*)", "replacement": "/${remaining}" } } ], "uri": "lb://GATEWAY-SERVICE", "order": 0 }, "order": 0 }]

/actuator/gateway/globalfilters

{  "org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@f425231": 10100,  "org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@5cbd94b2": -1,  "org.springframework.cloud.gateway.filter.NettyRoutingFilter@506aabf6": 2147483647,  "org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@756aadfc": 10000,  "org.springframework.cloud.gateway.filter.ForwardRoutingFilter@705a8dbc": 2147483647,  "org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@6824b913": 2147483637,  "org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@40729f01": 2147483646}

/actuator/gateway/routefilters

{  "[RedirectToGatewayFilterFactory@32f96bba configClass = RedirectToGatewayFilterFactory.Config]": null,  "[StripPrefixGatewayFilterFactory@4a481728 configClass = StripPrefixGatewayFilterFactory.Config]": null,  "[RemoveResponseHeaderGatewayFilterFactory@67e25252 configClass = AbstractGatewayFilterFactory.NameConfig]": null,  "[RequestHeaderToRequestUriGatewayFilterFactory@4ace284d configClass = AbstractGatewayFilterFactory.NameConfig]": null,  "[ModifyRequestBodyGatewayFilterFactory@b3e86d5 configClass = ModifyRequestBodyGatewayFilterFactory.Config]": null,  "[RemoveRequestHeaderGatewayFilterFactory@611640f0 configClass = AbstractGatewayFilterFactory.NameConfig]": null,  "[SetStatusGatewayFilterFactory@3fd05b3e configClass = SetStatusGatewayFilterFactory.Config]": null,  "[PreserveHostHeaderGatewayFilterFactory@4d0e54e0 configClass = Object]": null,  "[SetResponseHeaderGatewayFilterFactory@1682c08c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,  "[SecureHeadersGatewayFilterFactory@76ececd configClass = Object]": null,  "[SaveSessionGatewayFilterFactory@4eb9f2af configClass = Object]": null,  "[AddResponseHeaderGatewayFilterFactory@75b6dd5b configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,  "[PrefixPathGatewayFilterFactory@e111c7c configClass = PrefixPathGatewayFilterFactory.Config]": null,  "[SetRequestHeaderGatewayFilterFactory@7affc159 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,  "[RewritePathGatewayFilterFactory@58f4b31a configClass = RewritePathGatewayFilterFactory.Config]": null,  "[SetPathGatewayFilterFactory@72eb6200 configClass = SetPathGatewayFilterFactory.Config]": null,  "[RetryGatewayFilterFactory@21a9a705 configClass = RetryGatewayFilterFactory.Retry]": null,  "[AddRequestHeaderGatewayFilterFactory@1f1cddf3 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,  "[ModifyResponseBodyGatewayFilterFactory@72b43104 configClass = ModifyResponseBodyGatewayFilterFactory.Config]": null,  "[AddRequestParameterGatewayFilterFactory@228bda54 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null}

/actuator/gateway/routes/CompositeDiscoveryClient_DISCOVERY-SERVICE

{  "id": "CompositeDiscoveryClient_DISCOVERY-SERVICE",  "predicates": [    {      "name": "Path",      "args": {        "pattern": "/DISCOVERY-SERVICE/**"      }    }  ],  "filters": [    {      "name": "RewritePath",      "args": {        "regexp": "/DISCOVERY-SERVICE/(?
.*)", "replacement": "/${remaining}" } } ], "uri": "lb://DISCOVERY-SERVICE", "order": 0}

/actuator/gateway/routes/CompositeDiscoveryClient_DISCOVERY-SERVICE/combinedfilters

{  "Route{id='CompositeDiscoveryClient_DISCOVERY-SERVICE', uri=lb://DISCOVERY-SERVICE, order=0, predicate=org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$769/1774209584@7d9639ad, gatewayFilters=[OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory$$Lambda$771/1052389952@528c8627, order=1}]}": 0}

小结

springcloud gateway提供了一个gateway actuator,该endpiont提供了关于filter及routes的信息查询以及指定route信息更新的rest api,这给web界面提供管理配置功能提供了极大的便利。

doc

转载于:https://my.oschina.net/go4it/blog/1805179

你可能感兴趣的文章
Windows远程桌面漏洞Esteemaudit(CVE-2017-9073)补丁简要分析
查看>>
Arbor Networks凭借业界全面的 DDoS 防御组合为各类客户提供可用性保护
查看>>
达沃时代帮助VSAN提供NAS方案
查看>>
买服务器网络设备时该考虑哪些因素?
查看>>
悲催的CISO:数据泄露事故的替罪羊
查看>>
2015年十大安全故事回顾
查看>>
数据挖掘与预测分析术语总结
查看>>
寻找“高级威胁”防御的答案
查看>>
“有本事就来抓我呀!”企业发现APT攻击平均需要205天
查看>>
女兒,今天是你的生日
查看>>
机器学习零基础?手把手教你用TensorFlow搭建图像识别系统(二)
查看>>
韩国美女黑客是怎样的一种存在?
查看>>
利用无人机或吸尘器黑掉企业无线打印机
查看>>
Linux基础命令介绍九:进程与内存
查看>>
实现翻转卡片的动画效果
查看>>
即时通信增长持续放缓,差异化与多元化成为趋势
查看>>
《Linux内核精髓:精通Linux内核必会的75个绝技》一第2章 资源管理
查看>>
《认知设计:提升学习体验的艺术》——与学习者进行交流
查看>>
Facebook、亚马逊等巨头是如何建造自己的数据库的?| 全球聚焦
查看>>
默认OpenStack安全组:如何更改规则?
查看>>