feat:add metadata init filter in SCG

pull/15/head
SkyeBeFreeman 3 years ago
parent b9ebbcdada
commit 4f13128597

@ -17,6 +17,8 @@
package com.tencent.cloud.metadata.context; package com.tencent.cloud.metadata.context;
import com.tencent.cloud.metadata.util.JacksonUtils;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -74,4 +76,12 @@ public class MetadataContext {
public void putAllSystemMetadata(Map<String, String> systemMetadata) { public void putAllSystemMetadata(Map<String, String> systemMetadata) {
this.systemMetadata.putAll(systemMetadata); this.systemMetadata.putAll(systemMetadata);
} }
@Override
public String toString() {
return "MetadataContext{" +
"transitiveCustomMetadata=" + JacksonUtils.serialize2Json(transitiveCustomMetadata) +
", systemMetadata=" + JacksonUtils.serialize2Json(systemMetadata) +
'}';
}
} }

@ -70,25 +70,21 @@ public class MetadataReactiveFilter implements WebFilter, Ordered {
LOG.debug("Get upstream metadata string: {}", customMetadataStr); LOG.debug("Get upstream metadata string: {}", customMetadataStr);
// create custom metadata. // create custom metadata.
Map<String, String> upstreamCustomMetadataMap = JacksonUtils.deserializeMetadataMap(customMetadataStr); Map<String, String> upstreamCustomMetadataMap = JacksonUtils.deserialize2Map(customMetadataStr);
// create system metadata. // create system metadata.
Map<String, String> systemMetadataMap = new HashMap<>(); Map<String, String> systemMetadataMap = new HashMap<>();
systemMetadataMap.put(LOCAL_NAMESPACE, MetadataContextHolder.LOCAL_NAMESPACE); systemMetadataMap.put(LOCAL_NAMESPACE, MetadataContextHolder.LOCAL_NAMESPACE);
systemMetadataMap.put(LOCAL_SERVICE, MetadataContextHolder.LOCAL_SERVICE); systemMetadataMap.put(LOCAL_SERVICE, MetadataContextHolder.LOCAL_SERVICE);
systemMetadataMap.put(LOCAL_PATH, serverHttpRequest.getURI().getRawPath()); systemMetadataMap.put(LOCAL_PATH, serverHttpRequest.getURI().getPath());
try { MetadataContextHolder.init(upstreamCustomMetadataMap, systemMetadataMap);
MetadataContextHolder.init(upstreamCustomMetadataMap, systemMetadataMap);
// Save to ServerWebExchange. // Save to ServerWebExchange.
serverWebExchange.getAttributes() serverWebExchange.getAttributes()
.put(MetadataConstant.HeaderName.METADATA_CONTEXT, MetadataContextHolder.get()); .put(MetadataConstant.HeaderName.METADATA_CONTEXT, MetadataContextHolder.get());
return webFilterChain.filter(serverWebExchange).doFinally((type) -> MetadataContextHolder.remove()); return webFilterChain.filter(serverWebExchange)
} catch (RuntimeException e) { .doOnError(throwable -> LOG.error("handle metadata[{}] error.", MetadataContextHolder.get()))
throw e; .doFinally((type) -> MetadataContextHolder.remove());
} finally {
MetadataContextHolder.remove();
}
} }
} }

@ -64,7 +64,7 @@ public class MetadataServletFilter extends OncePerRequestFilter {
LOG.debug("Get upstream metadata string: {}", customMetadataStr); LOG.debug("Get upstream metadata string: {}", customMetadataStr);
// create custom metadata. // create custom metadata.
Map<String, String> upstreamCustomMetadataMap = JacksonUtils.deserializeMetadataMap(customMetadataStr); Map<String, String> upstreamCustomMetadataMap = JacksonUtils.deserialize2Map(customMetadataStr);
// create system metadata. // create system metadata.
Map<String, String> systemMetadataMap = new HashMap<>(); Map<String, String> systemMetadataMap = new HashMap<>();

@ -57,7 +57,7 @@ public class Metadata2HeaderFeignInterceptor implements RequestInterceptor, Orde
if (!CollectionUtils.isEmpty(requestTemplate.headers()) if (!CollectionUtils.isEmpty(requestTemplate.headers())
&& !CollectionUtils.isEmpty(requestTemplate.headers().get(CUSTOM_METADATA))) { && !CollectionUtils.isEmpty(requestTemplate.headers().get(CUSTOM_METADATA))) {
for (String headerMetadataStr : requestTemplate.headers().get(CUSTOM_METADATA)) { for (String headerMetadataStr : requestTemplate.headers().get(CUSTOM_METADATA)) {
Map<String, String> headerMetadataMap = JacksonUtils.deserializeMetadataMap(headerMetadataStr); Map<String, String> headerMetadataMap = JacksonUtils.deserialize2Map(headerMetadataStr);
for (String key : headerMetadataMap.keySet()) { for (String key : headerMetadataMap.keySet()) {
metadataContext.putTransitiveCustomMetadata(key, headerMetadataMap.get(key)); metadataContext.putTransitiveCustomMetadata(key, headerMetadataMap.get(key));
} }
@ -66,7 +66,7 @@ public class Metadata2HeaderFeignInterceptor implements RequestInterceptor, Orde
Map<String, String> customMetadata = metadataContext.getAllTransitiveCustomMetadata(); Map<String, String> customMetadata = metadataContext.getAllTransitiveCustomMetadata();
if (!CollectionUtils.isEmpty(customMetadata)) { if (!CollectionUtils.isEmpty(customMetadata)) {
String metadataStr = JacksonUtils.serializeToJson(customMetadata); String metadataStr = JacksonUtils.serialize2Json(customMetadata);
requestTemplate.removeHeader(CUSTOM_METADATA); requestTemplate.removeHeader(CUSTOM_METADATA);
try { try {
requestTemplate.header(CUSTOM_METADATA, requestTemplate.header(CUSTOM_METADATA,

@ -59,14 +59,14 @@ public class MetadataRestTemplateInterceptor implements ClientHttpRequestInterce
// add new metadata and cover old // add new metadata and cover old
String metadataStr = httpRequest.getHeaders().getFirst(MetadataConstant.HeaderName.CUSTOM_METADATA); String metadataStr = httpRequest.getHeaders().getFirst(MetadataConstant.HeaderName.CUSTOM_METADATA);
if (!StringUtils.isEmpty(metadataStr)) { if (!StringUtils.isEmpty(metadataStr)) {
Map<String, String> headerMetadataMap = JacksonUtils.deserializeMetadataMap(metadataStr); Map<String, String> headerMetadataMap = JacksonUtils.deserialize2Map(metadataStr);
for (String key : headerMetadataMap.keySet()) { for (String key : headerMetadataMap.keySet()) {
metadataContext.putTransitiveCustomMetadata(key, headerMetadataMap.get(key)); metadataContext.putTransitiveCustomMetadata(key, headerMetadataMap.get(key));
} }
} }
Map<String, String> customMetadata = metadataContext.getAllTransitiveCustomMetadata(); Map<String, String> customMetadata = metadataContext.getAllTransitiveCustomMetadata();
if (!CollectionUtils.isEmpty(customMetadata)) { if (!CollectionUtils.isEmpty(customMetadata)) {
metadataStr = JacksonUtils.serializeToJson(customMetadata); metadataStr = JacksonUtils.serialize2Json(customMetadata);
try { try {
httpRequest.getHeaders().set(MetadataConstant.HeaderName.CUSTOM_METADATA, httpRequest.getHeaders().set(MetadataConstant.HeaderName.CUSTOM_METADATA,
URLEncoder.encode(metadataStr, "UTF-8")); URLEncoder.encode(metadataStr, "UTF-8"));

@ -45,7 +45,7 @@ public class JacksonUtils {
* @param <T> type of object * @param <T> type of object
* @return Json String * @return Json String
*/ */
public static <T> String serializeToJson(T object) { public static <T> String serialize2Json(T object) {
try { try {
return OM.writeValueAsString(object); return OM.writeValueAsString(object);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
@ -60,7 +60,7 @@ public class JacksonUtils {
* @param jsonStr Json String * @param jsonStr Json String
* @return Map * @return Map
*/ */
public static Map<String, String> deserializeMetadataMap(String jsonStr) { public static Map<String, String> deserialize2Map(String jsonStr) {
try { try {
if (StringUtils.hasText(jsonStr)) { if (StringUtils.hasText(jsonStr)) {
return OM.readValue(jsonStr, Map.class); return OM.readValue(jsonStr, Map.class);

@ -47,7 +47,7 @@ public class MetadataUtils {
// Transfer string to map. // Transfer string to map.
if (StringUtils.hasText(newMetadataStr)) { if (StringUtils.hasText(newMetadataStr)) {
Map<String, String> requestMetadataMap = JacksonUtils.deserializeMetadataMap(newMetadataStr); Map<String, String> requestMetadataMap = JacksonUtils.deserialize2Map(newMetadataStr);
// metadata from upstream cover local metadata for this thread. // metadata from upstream cover local metadata for this thread.
for (String key : requestMetadataMap.keySet()) { for (String key : requestMetadataMap.keySet()) {

@ -80,7 +80,7 @@ public class Metadata2HeaderFeignInterceptorTest {
@RequestMapping("/test") @RequestMapping("/test")
public String test(@RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String customMetadataStr) public String test(@RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String customMetadataStr)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
String systemMetadataStr = JacksonUtils.serializeToJson(MetadataContextHolder.get().getAllSystemMetadata()); String systemMetadataStr = JacksonUtils.serialize2Json(MetadataContextHolder.get().getAllSystemMetadata());
return URLDecoder.decode(customMetadataStr, "UTF-8") + systemMetadataStr; return URLDecoder.decode(customMetadataStr, "UTF-8") + systemMetadataStr;
} }

@ -93,7 +93,7 @@ public class MetadataRestTemplateInterceptorTest {
public String test(@RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String customMetadataStr) public String test(@RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String customMetadataStr)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
String systemMetadataStr = String systemMetadataStr =
JacksonUtils.serializeToJson(MetadataContextHolder.get().getAllSystemMetadata()); JacksonUtils.serialize2Json(MetadataContextHolder.get().getAllSystemMetadata());
return URLDecoder.decode(customMetadataStr, "UTF-8") + systemMetadataStr; return URLDecoder.decode(customMetadataStr, "UTF-8") + systemMetadataStr;
} }

@ -20,6 +20,7 @@ package com.tencent.cloud.polaris.gateway.config;
import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.http.ZuulServlet; import com.netflix.zuul.http.ZuulServlet;
import com.tencent.cloud.polaris.gateway.core.scg.filter.Metadata2HeaderScgFilter; 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.zuul.filter.Metadata2HeaderZuulFilter; import com.tencent.cloud.polaris.gateway.core.zuul.filter.Metadata2HeaderZuulFilter;
import com.tencent.cloud.polaris.gateway.core.zuul.filter.MetadataFirstZuulFilter; import com.tencent.cloud.polaris.gateway.core.zuul.filter.MetadataFirstZuulFilter;
import com.tencent.cloud.polaris.gateway.core.zuul.filter.RateLimitZuulFilter; import com.tencent.cloud.polaris.gateway.core.zuul.filter.RateLimitZuulFilter;
@ -57,6 +58,11 @@ public class PolarisGatewayAutoConfiguration {
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ConditionalOnClass(GlobalFilter.class) @ConditionalOnClass(GlobalFilter.class)
static class PolarisGatewayScgAutoConfiguration { static class PolarisGatewayScgAutoConfiguration {
@Bean
public GlobalFilter metadataFirstScgFilter() {
return new MetadataFirstScgFilter();
}
@Bean @Bean
public GlobalFilter metadata2HeaderScgFilter() { public GlobalFilter metadata2HeaderScgFilter() {
return new Metadata2HeaderScgFilter(); return new Metadata2HeaderScgFilter();

@ -64,7 +64,7 @@ public class Metadata2HeaderScgFilter extends AbstractGlobalFilter {
} }
Map<String, String> customMetadata = metadataContext.getAllTransitiveCustomMetadata(); Map<String, String> customMetadata = metadataContext.getAllTransitiveCustomMetadata();
if (!CollectionUtils.isEmpty(customMetadata)) { if (!CollectionUtils.isEmpty(customMetadata)) {
String metadataStr = JacksonUtils.serializeToJson(customMetadata); String metadataStr = JacksonUtils.serialize2Json(customMetadata);
try { try {
builder.header(MetadataConstant.HeaderName.CUSTOM_METADATA, URLEncoder.encode(metadataStr, "UTF-8")); builder.header(MetadataConstant.HeaderName.CUSTOM_METADATA, URLEncoder.encode(metadataStr, "UTF-8"));
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {

@ -0,0 +1,66 @@
/*
* 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.MetadataContext;
import com.tencent.cloud.metadata.context.MetadataContextHolder;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import static org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter.ROUTE_TO_URL_FILTER_ORDER;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
/**
* @author Haotian Zhang
*/
public class MetadataFirstScgFilter extends AbstractGlobalFilter {
@Override
public int getOrder() {
return ROUTE_TO_URL_FILTER_ORDER + 1;
}
@Override
public boolean shouldFilter(ServerWebExchange exchange, GatewayFilterChain chain) {
return true;
}
@Override
public Mono<Void> doFilter(ServerWebExchange exchange, GatewayFilterChain chain) {
// get request context
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// get metadata of current thread
MetadataContext metadataContext = exchange.getAttribute(MetadataConstant.HeaderName.METADATA_CONTEXT);
// TODO 对端命名空间暂时与本地命名空间相同
metadataContext.putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_NAMESPACE,
MetadataContextHolder.get().getSystemMetadata(MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE));
metadataContext.putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_SERVICE, route.getId());
metadataContext.putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_PATH,
exchange.getRequest().getURI().getPath());
exchange.getAttributes().put(MetadataConstant.HeaderName.METADATA_CONTEXT, metadataContext);
return chain.filter(exchange);
}
}

@ -66,7 +66,7 @@ public class Metadata2HeaderZuulFilter extends ZuulFilter {
// add new metadata and cover old // add new metadata and cover old
Map<String, String> customMetadata = metadataContext.getAllTransitiveCustomMetadata(); Map<String, String> customMetadata = metadataContext.getAllTransitiveCustomMetadata();
if (!CollectionUtils.isEmpty(customMetadata)) { if (!CollectionUtils.isEmpty(customMetadata)) {
String metadataStr = JacksonUtils.serializeToJson(customMetadata); String metadataStr = JacksonUtils.serialize2Json(customMetadata);
try { try {
requestContext.addZuulRequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA, requestContext.addZuulRequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA,
URLEncoder.encode(metadataStr, "UTF-8")); URLEncoder.encode(metadataStr, "UTF-8"));

Loading…
Cancel
Save