parent
4ff4459d6b
commit
6449e313a8
@ -1,100 +1,140 @@
|
||||
/*
|
||||
* 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.rpc.enhancement.feign.plugin.reporter;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.tencent.cloud.common.constant.RouterConstant;
|
||||
import com.tencent.cloud.common.metadata.MetadataContext;
|
||||
import com.tencent.cloud.common.util.RequestLabelUtils;
|
||||
import com.tencent.polaris.api.pojo.RetStatus;
|
||||
import com.tencent.polaris.api.pojo.ServiceKey;
|
||||
import com.tencent.polaris.api.rpc.ServiceCallResult;
|
||||
import com.tencent.polaris.api.utils.CollectionUtils;
|
||||
import com.tencent.polaris.client.api.SDKContext;
|
||||
import feign.Request;
|
||||
import feign.RequestTemplate;
|
||||
import feign.Response;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
|
||||
|
||||
/**
|
||||
* Util for polaris reporter.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public final class ReporterUtils {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ReporterUtils.class);
|
||||
|
||||
private ReporterUtils() {
|
||||
}
|
||||
|
||||
public static ServiceCallResult createServiceCallResult(final SDKContext context, final Request request,
|
||||
final Response response, long delay, RetStatus retStatus, final Consumer<ServiceCallResult> consumer) {
|
||||
ServiceCallResult resultRequest = new ServiceCallResult();
|
||||
|
||||
resultRequest.setNamespace(MetadataContext.LOCAL_NAMESPACE);
|
||||
RequestTemplate requestTemplate = request.requestTemplate();
|
||||
String serviceName = requestTemplate.feignTarget().name();
|
||||
resultRequest.setService(serviceName);
|
||||
Collection<String> labels = requestTemplate.headers().get(RouterConstant.ROUTER_LABEL_HEADER);
|
||||
if (CollectionUtils.isNotEmpty(labels) && labels.iterator().hasNext()) {
|
||||
String label = labels.iterator().next();
|
||||
try {
|
||||
label = URLDecoder.decode(label, UTF_8);
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
LOGGER.error("unsupported charset exception " + UTF_8, e);
|
||||
}
|
||||
resultRequest.setLabels(RequestLabelUtils.convertLabel(label));
|
||||
}
|
||||
URI uri = URI.create(request.url());
|
||||
resultRequest.setMethod(uri.getPath());
|
||||
resultRequest.setRetCode(response.status());
|
||||
resultRequest.setRetStatus(retStatus);
|
||||
resultRequest.setDelay(delay);
|
||||
String scheme = uri.getScheme();
|
||||
if (StringUtils.isBlank(scheme)) {
|
||||
scheme = "http";
|
||||
}
|
||||
resultRequest.setProtocol(scheme);
|
||||
String sourceNamespace = MetadataContext.LOCAL_NAMESPACE;
|
||||
String sourceService = MetadataContext.LOCAL_SERVICE;
|
||||
if (StringUtils.isNotBlank(sourceNamespace) && StringUtils.isNotBlank(sourceService)) {
|
||||
resultRequest.setCallerService(new ServiceKey(sourceNamespace, sourceService));
|
||||
}
|
||||
if (Objects.nonNull(context)) {
|
||||
resultRequest.setCallerIp(context.getConfig().getGlobal().getAPI().getBindIP());
|
||||
}
|
||||
resultRequest.setHost(uri.getHost());
|
||||
// -1 means access directly by url, and use http default port number 80
|
||||
resultRequest.setPort(uri.getPort() == -1 ? 80 : uri.getPort());
|
||||
consumer.accept(resultRequest);
|
||||
return resultRequest;
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * 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.rpc.enhancement.feign.plugin.reporter;
|
||||
//
|
||||
//import java.io.UnsupportedEncodingException;
|
||||
//import java.net.URI;
|
||||
//import java.net.URLDecoder;
|
||||
//import java.util.Collection;
|
||||
//import java.util.Objects;
|
||||
//import java.util.function.Consumer;
|
||||
//
|
||||
//import com.tencent.cloud.common.constant.RouterConstant;
|
||||
//import com.tencent.cloud.common.metadata.MetadataContext;
|
||||
//import com.tencent.cloud.common.util.RequestLabelUtils;
|
||||
//import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat;
|
||||
//import com.tencent.polaris.api.plugin.circuitbreaker.entity.InstanceResource;
|
||||
//import com.tencent.polaris.api.plugin.circuitbreaker.entity.Resource;
|
||||
//import com.tencent.polaris.api.pojo.RetStatus;
|
||||
//import com.tencent.polaris.api.pojo.ServiceKey;
|
||||
//import com.tencent.polaris.api.rpc.ServiceCallResult;
|
||||
//import com.tencent.polaris.api.utils.CollectionUtils;
|
||||
//import com.tencent.polaris.client.api.SDKContext;
|
||||
//import feign.Request;
|
||||
//import feign.RequestTemplate;
|
||||
//import feign.Response;
|
||||
//import org.apache.commons.lang.StringUtils;
|
||||
//import org.slf4j.Logger;
|
||||
//import org.slf4j.LoggerFactory;
|
||||
//
|
||||
//import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
|
||||
//
|
||||
///**
|
||||
// * Util for polaris reporter.
|
||||
// *
|
||||
// * @author Haotian Zhang
|
||||
// */
|
||||
//public final class ReporterUtils {
|
||||
//
|
||||
// private static final Logger LOGGER = LoggerFactory.getLogger(ReporterUtils.class);
|
||||
//
|
||||
// private ReporterUtils() {
|
||||
// }
|
||||
//
|
||||
// public static ResourceStat createInstanceResourceStat(final Request request,
|
||||
// final Response response, long delay, RetStatus retStatus) {
|
||||
// return createInstanceResourceStat(request.requestTemplate().feignTarget().name(), URI.create(request.url()), response.status(), delay, retStatus);
|
||||
// }
|
||||
//
|
||||
// public static ResourceStat createInstanceResourceStat(final URI uri,
|
||||
// final int status, long delay, RetStatus retStatus) {
|
||||
// return createInstanceResourceStat(null, uri, status, delay, retStatus);
|
||||
// }
|
||||
//
|
||||
// private static ResourceStat createInstanceResourceStat(final String serviceName,
|
||||
// final URI uri, final int status, long delay, RetStatus retStatus) {
|
||||
// ServiceKey calleeServiceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE, serviceName);
|
||||
// ServiceKey callerServiceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE);
|
||||
// Resource resource = new InstanceResource(calleeServiceKey, uri.getHost(), getRequestPort(uri), callerServiceKey, getRequestProtocol(uri));
|
||||
// return new ResourceStat(resource, status, delay, retStatus);
|
||||
// }
|
||||
//
|
||||
// public static ServiceCallResult createServiceCallResult(final SDKContext context, final URI uri,
|
||||
// final int status, long delay, RetStatus retStatus, final Consumer<ServiceCallResult> consumer) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public static ServiceCallResult createServiceCallResult(final SDKContext context, final Request request,
|
||||
// final Response response, long delay, RetStatus retStatus, final Consumer<ServiceCallResult> consumer) {
|
||||
// ServiceCallResult resultRequest = new ServiceCallResult();
|
||||
//
|
||||
// resultRequest.setNamespace(MetadataContext.LOCAL_NAMESPACE);
|
||||
// RequestTemplate requestTemplate = request.requestTemplate();
|
||||
// String serviceName = requestTemplate.feignTarget().name();
|
||||
// resultRequest.setService(serviceName);
|
||||
// Collection<String> labels = requestTemplate.headers().get(RouterConstant.ROUTER_LABEL_HEADER);
|
||||
// if (CollectionUtils.isNotEmpty(labels) && labels.iterator().hasNext()) {
|
||||
// String label = labels.iterator().next();
|
||||
// try {
|
||||
// label = URLDecoder.decode(label, UTF_8);
|
||||
// }
|
||||
// catch (UnsupportedEncodingException e) {
|
||||
// LOGGER.error("unsupported charset exception " + UTF_8, e);
|
||||
// }
|
||||
// resultRequest.setLabels(RequestLabelUtils.convertLabel(label));
|
||||
// }
|
||||
// URI uri = URI.create(request.url());
|
||||
// resultRequest.setMethod(uri.getPath());
|
||||
// resultRequest.setRetCode(response.status());
|
||||
// resultRequest.setRetStatus(retStatus);
|
||||
// resultRequest.setDelay(delay);
|
||||
// resultRequest.setProtocol(getRequestProtocol(uri));
|
||||
// String sourceNamespace = MetadataContext.LOCAL_NAMESPACE;
|
||||
// String sourceService = MetadataContext.LOCAL_SERVICE;
|
||||
// if (StringUtils.isNotBlank(sourceNamespace) && StringUtils.isNotBlank(sourceService)) {
|
||||
// resultRequest.setCallerService(new ServiceKey(sourceNamespace, sourceService));
|
||||
// }
|
||||
// if (Objects.nonNull(context)) {
|
||||
// resultRequest.setCallerIp(context.getConfig().getGlobal().getAPI().getBindIP());
|
||||
// }
|
||||
// resultRequest.setHost(uri.getHost());
|
||||
// resultRequest.setPort(getRequestPort(uri));
|
||||
// consumer.accept(resultRequest);
|
||||
// return resultRequest;
|
||||
// }
|
||||
//
|
||||
// private static String getRequestProtocol(URI uri) {
|
||||
// String scheme = uri.getScheme();
|
||||
// if (StringUtils.isBlank(scheme)) {
|
||||
// scheme = "http";
|
||||
// }
|
||||
// return scheme;
|
||||
// }
|
||||
//
|
||||
// private static int getRequestPort(URI uri) {
|
||||
// // -1 means access directly by url, and use http default port number 80
|
||||
// return uri.getPort() == -1 ? 80 : uri.getPort();
|
||||
// }
|
||||
//
|
||||
// private static String convertLabel(String label) {
|
||||
// label = label.replaceAll("\"|\\{|\\}", "")
|
||||
// .replaceAll(",", "|");
|
||||
// return label;
|
||||
// }
|
||||
//}
|
||||
|
@ -1,235 +1,240 @@
|
||||
/*
|
||||
* 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.rpc.enhancement.resttemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.tencent.cloud.common.constant.RouterConstant;
|
||||
import com.tencent.cloud.common.metadata.MetadataContext;
|
||||
import com.tencent.cloud.common.metadata.MetadataContextHolder;
|
||||
import com.tencent.cloud.common.util.RequestLabelUtils;
|
||||
import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
|
||||
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
|
||||
import com.tencent.polaris.api.core.ConsumerAPI;
|
||||
import com.tencent.polaris.api.pojo.RetStatus;
|
||||
import com.tencent.polaris.api.pojo.ServiceKey;
|
||||
import com.tencent.polaris.api.rpc.ServiceCallResult;
|
||||
import com.tencent.polaris.api.utils.CollectionUtils;
|
||||
import com.tencent.polaris.client.api.SDKContext;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.client.DefaultResponseErrorHandler;
|
||||
import org.springframework.web.client.ResponseErrorHandler;
|
||||
|
||||
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
|
||||
|
||||
/**
|
||||
* Extend ResponseErrorHandler to get request information.
|
||||
*
|
||||
* @author wh 2022/6/21
|
||||
*/
|
||||
public class EnhancedRestTemplateReporter extends AbstractPolarisReporterAdapter implements ResponseErrorHandler, ApplicationContextAware {
|
||||
|
||||
/**
|
||||
* Polaris-CircuitBreaker-Fallback header flag.
|
||||
*/
|
||||
public static final String POLARIS_CIRCUIT_BREAKER_FALLBACK_HEADER = "X-SCT-Polaris-CircuitBreaker-Fallback";
|
||||
/**
|
||||
* response has error header flag, since EnhancedRestTemplateReporter#hasError always return true.
|
||||
*/
|
||||
public static final String HEADER_HAS_ERROR = "X-SCT-Has-Error";
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(EnhancedRestTemplateReporter.class);
|
||||
private final ConsumerAPI consumerAPI;
|
||||
private final SDKContext context;
|
||||
private ResponseErrorHandler delegateHandler;
|
||||
|
||||
public EnhancedRestTemplateReporter(RpcEnhancementReporterProperties properties, SDKContext context, ConsumerAPI consumerAPI) {
|
||||
super(properties);
|
||||
this.context = context;
|
||||
this.consumerAPI = consumerAPI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
String[] handlerBeanNames = applicationContext.getBeanNamesForType(ResponseErrorHandler.class);
|
||||
if (handlerBeanNames.length == 1) {
|
||||
if (this.delegateHandler == null) {
|
||||
this.delegateHandler = new DefaultResponseErrorHandler();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// inject user custom ResponseErrorHandler
|
||||
for (String beanName : handlerBeanNames) {
|
||||
// ignore self
|
||||
if (StringUtils.equalsIgnoreCase("enhancedRestTemplateReporter", beanName)) {
|
||||
continue;
|
||||
}
|
||||
this.delegateHandler = (ResponseErrorHandler) applicationContext.getBean(beanName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasError(@NonNull ClientHttpResponse response) throws IOException {
|
||||
if (delegateHandler != null) {
|
||||
// Preserve the delegated handler result
|
||||
boolean hasError = delegateHandler.hasError(response);
|
||||
response.getHeaders().add(HEADER_HAS_ERROR, String.valueOf(hasError));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleError(@NonNull ClientHttpResponse response) throws IOException {
|
||||
if (realHasError(response)) {
|
||||
delegateHandler.handleError(response);
|
||||
}
|
||||
|
||||
clear(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleError(@NonNull URI url, @NonNull HttpMethod method, @NonNull ClientHttpResponse response) throws IOException {
|
||||
// report result to polaris
|
||||
if (reportProperties.isEnabled()) {
|
||||
reportResult(url, response);
|
||||
}
|
||||
|
||||
// invoke delegate handler
|
||||
invokeDelegateHandler(url, method, response);
|
||||
}
|
||||
|
||||
private void reportResult(URI url, ClientHttpResponse response) {
|
||||
if (Boolean.parseBoolean(response.getHeaders().getFirst(POLARIS_CIRCUIT_BREAKER_FALLBACK_HEADER))) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ServiceCallResult resultRequest = createServiceCallResult(url, response);
|
||||
Map<String, String> loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata();
|
||||
|
||||
String targetHost = loadBalancerContext.get("host");
|
||||
String targetPort = loadBalancerContext.get("port");
|
||||
String startMillis = loadBalancerContext.get("startMillis");
|
||||
long delay = System.currentTimeMillis() - Long.parseLong(startMillis);
|
||||
|
||||
if (StringUtils.isBlank(targetHost) || StringUtils.isBlank(targetPort)) {
|
||||
LOGGER.warn("Can not get target host or port from metadata context. host = {}, port = {}", targetHost, targetPort);
|
||||
return;
|
||||
}
|
||||
|
||||
resultRequest.setHost(targetHost);
|
||||
resultRequest.setPort(Integer.parseInt(targetPort));
|
||||
resultRequest.setDelay(delay);
|
||||
|
||||
// checking response http status code
|
||||
if (apply(response.getStatusCode())) {
|
||||
resultRequest.setRetStatus(RetStatus.RetFail);
|
||||
}
|
||||
resultRequest.setRetStatus(getRetStatusFromRequest(response.getHeaders(), resultRequest.getRetStatus()));
|
||||
resultRequest.setRuleName(getActiveRuleNameFromRequest(response.getHeaders()));
|
||||
if (Objects.nonNull(context)) {
|
||||
resultRequest.setCallerIp(context.getConfig().getGlobal().getAPI().getBindIP());
|
||||
}
|
||||
|
||||
List<String> labels = response.getHeaders().get(RouterConstant.ROUTER_LABEL_HEADER);
|
||||
if (CollectionUtils.isNotEmpty(labels)) {
|
||||
String label = labels.get(0);
|
||||
try {
|
||||
label = URLDecoder.decode(label, UTF_8);
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
LOGGER.error("unsupported charset exception " + UTF_8, e);
|
||||
}
|
||||
resultRequest.setLabels(RequestLabelUtils.convertLabel(label));
|
||||
}
|
||||
|
||||
// processing report with consumerAPI .
|
||||
LOGGER.debug("Will report result of {}. Request=[{}]. Response=[{}]. Delay=[{}]ms.", resultRequest.getRetStatus()
|
||||
.name(), url, response.getStatusCode().value(), delay);
|
||||
consumerAPI.updateServiceCallResult(resultRequest);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOGGER.error("RestTemplate response reporter execute failed of {} url {}", response, url, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeDelegateHandler(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
|
||||
if (realHasError(response)) {
|
||||
delegateHandler.handleError(url, method, response);
|
||||
}
|
||||
|
||||
clear(response);
|
||||
}
|
||||
|
||||
private Boolean realHasError(ClientHttpResponse response) {
|
||||
if (delegateHandler == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String hasErrorHeader = response.getHeaders().getFirst(HEADER_HAS_ERROR);
|
||||
if (StringUtils.isBlank(hasErrorHeader)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Boolean.parseBoolean(hasErrorHeader);
|
||||
}
|
||||
|
||||
private void clear(ClientHttpResponse response) {
|
||||
response.getHeaders().remove(HEADER_HAS_ERROR);
|
||||
response.getHeaders().remove(POLARIS_CIRCUIT_BREAKER_FALLBACK_HEADER);
|
||||
}
|
||||
|
||||
private ServiceCallResult createServiceCallResult(URI uri, ClientHttpResponse response) throws IOException {
|
||||
ServiceCallResult resultRequest = new ServiceCallResult();
|
||||
String serviceName = uri.getHost();
|
||||
resultRequest.setService(serviceName);
|
||||
resultRequest.setNamespace(MetadataContext.LOCAL_NAMESPACE);
|
||||
resultRequest.setMethod(uri.getPath());
|
||||
resultRequest.setRetCode(response.getStatusCode().value());
|
||||
resultRequest.setRetStatus(RetStatus.RetSuccess);
|
||||
String sourceNamespace = MetadataContext.LOCAL_NAMESPACE;
|
||||
String sourceService = MetadataContext.LOCAL_SERVICE;
|
||||
if (StringUtils.isNotBlank(sourceNamespace) && StringUtils.isNotBlank(sourceService)) {
|
||||
resultRequest.setCallerService(new ServiceKey(sourceNamespace, sourceService));
|
||||
}
|
||||
return resultRequest;
|
||||
}
|
||||
|
||||
protected ResponseErrorHandler getDelegateHandler() {
|
||||
return this.delegateHandler;
|
||||
}
|
||||
|
||||
protected void setDelegateHandler(ResponseErrorHandler delegateHandler) {
|
||||
this.delegateHandler = delegateHandler;
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * 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.rpc.enhancement.resttemplate;
|
||||
//
|
||||
//import java.io.IOException;
|
||||
//import java.io.UnsupportedEncodingException;
|
||||
//import java.net.URI;
|
||||
//import java.net.URLDecoder;
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//import java.util.Objects;
|
||||
//
|
||||
//import com.tencent.cloud.common.constant.RouterConstant;
|
||||
//import com.tencent.cloud.common.metadata.MetadataContext;
|
||||
//import com.tencent.cloud.common.metadata.MetadataContextHolder;
|
||||
//import com.tencent.cloud.common.util.RequestLabelUtils;
|
||||
//import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
|
||||
//import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
|
||||
//import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.ReporterUtils;
|
||||
//import com.tencent.polaris.api.core.ConsumerAPI;
|
||||
//import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat;
|
||||
//import com.tencent.polaris.api.pojo.RetStatus;
|
||||
//import com.tencent.polaris.api.pojo.ServiceKey;
|
||||
//import com.tencent.polaris.api.rpc.ServiceCallResult;
|
||||
//import com.tencent.polaris.api.utils.CollectionUtils;
|
||||
//import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
|
||||
//import com.tencent.polaris.client.api.SDKContext;
|
||||
//import org.apache.commons.lang.StringUtils;
|
||||
//import org.slf4j.Logger;
|
||||
//import org.slf4j.LoggerFactory;
|
||||
//
|
||||
//import org.springframework.beans.BeansException;
|
||||
//import org.springframework.context.ApplicationContext;
|
||||
//import org.springframework.context.ApplicationContextAware;
|
||||
//import org.springframework.http.HttpMethod;
|
||||
//import org.springframework.http.client.ClientHttpResponse;
|
||||
//import org.springframework.lang.NonNull;
|
||||
//import org.springframework.web.client.DefaultResponseErrorHandler;
|
||||
//import org.springframework.web.client.ResponseErrorHandler;
|
||||
//
|
||||
//import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
|
||||
//
|
||||
///**
|
||||
// * Extend ResponseErrorHandler to get request information.
|
||||
// *
|
||||
// * @author wh 2022/6/21
|
||||
// */
|
||||
//public class EnhancedRestTemplateReporter extends AbstractPolarisReporterAdapter implements ResponseErrorHandler, ApplicationContextAware {
|
||||
//
|
||||
// /**
|
||||
// * Polaris-CircuitBreaker-Fallback header flag.
|
||||
// */
|
||||
// public static final String POLARIS_CIRCUIT_BREAKER_FALLBACK_HEADER = "X-SCT-Polaris-CircuitBreaker-Fallback";
|
||||
// /**
|
||||
// * response has error header flag, since EnhancedRestTemplateReporter#hasError always return true.
|
||||
// */
|
||||
// public static final String HEADER_HAS_ERROR = "X-SCT-Has-Error";
|
||||
// private static final Logger LOGGER = LoggerFactory.getLogger(EnhancedRestTemplateReporter.class);
|
||||
// private final ConsumerAPI consumerAPI;
|
||||
// private final SDKContext context;
|
||||
// private final CircuitBreakAPI circuitBreakAPI;
|
||||
// private ResponseErrorHandler delegateHandler;
|
||||
//
|
||||
// public EnhancedRestTemplateReporter(RpcEnhancementReporterProperties properties, SDKContext context, ConsumerAPI consumerAPI, CircuitBreakAPI circuitBreakAPI) {
|
||||
// super(properties);
|
||||
// this.context = context;
|
||||
// this.consumerAPI = consumerAPI;
|
||||
// this.circuitBreakAPI = circuitBreakAPI;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
// String[] handlerBeanNames = applicationContext.getBeanNamesForType(ResponseErrorHandler.class);
|
||||
// if (handlerBeanNames.length == 1) {
|
||||
// if (this.delegateHandler == null) {
|
||||
// this.delegateHandler = new DefaultResponseErrorHandler();
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // inject user custom ResponseErrorHandler
|
||||
// for (String beanName : handlerBeanNames) {
|
||||
// // ignore self
|
||||
// if (StringUtils.equalsIgnoreCase("enhancedRestTemplateReporter", beanName)) {
|
||||
// continue;
|
||||
// }
|
||||
// this.delegateHandler = (ResponseErrorHandler) applicationContext.getBean(beanName);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean hasError(@NonNull ClientHttpResponse response) throws IOException {
|
||||
// if (delegateHandler != null) {
|
||||
// // Preserve the delegated handler result
|
||||
// boolean hasError = delegateHandler.hasError(response);
|
||||
// response.getHeaders().add(HEADER_HAS_ERROR, String.valueOf(hasError));
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void handleError(@NonNull ClientHttpResponse response) throws IOException {
|
||||
// if (realHasError(response)) {
|
||||
// delegateHandler.handleError(response);
|
||||
// }
|
||||
//
|
||||
// clear(response);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void handleError(@NonNull URI url, @NonNull HttpMethod method, @NonNull ClientHttpResponse response) throws IOException {
|
||||
// // report result to polaris
|
||||
// if (reportProperties.isEnabled()) {
|
||||
// reportResult(url, response);
|
||||
// }
|
||||
//
|
||||
// // invoke delegate handler
|
||||
// invokeDelegateHandler(url, method, response);
|
||||
// }
|
||||
//
|
||||
// private void reportResult(URI url, ClientHttpResponse response) {
|
||||
// if (Boolean.parseBoolean(response.getHeaders().getFirst(POLARIS_CIRCUIT_BREAKER_FALLBACK_HEADER))) {
|
||||
// return;
|
||||
// }
|
||||
// try {
|
||||
// Map<String, String> loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata();
|
||||
// String targetHost = loadBalancerContext.get("host");
|
||||
// String targetPort = loadBalancerContext.get("port");
|
||||
// String startMillis = loadBalancerContext.get("startMillis");
|
||||
// long delay = System.currentTimeMillis() - Long.parseLong(startMillis);
|
||||
//
|
||||
// if (StringUtils.isBlank(targetHost) || StringUtils.isBlank(targetPort)) {
|
||||
// LOGGER.warn("Can not get target host or port from metadata context. host = {}, port = {}", targetHost, targetPort);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// ServiceCallResult resultRequest = createServiceCallResult(url, response);
|
||||
//
|
||||
// resultRequest.setHost(targetHost);
|
||||
// resultRequest.setPort(Integer.parseInt(targetPort));
|
||||
// resultRequest.setDelay(delay);
|
||||
//
|
||||
// // checking response http status code
|
||||
// if (apply(response.getStatusCode())) {
|
||||
// resultRequest.setRetStatus(RetStatus.RetFail);
|
||||
// }
|
||||
// resultRequest.setRetStatus(getRetStatusFromRequest(response.getHeaders(), resultRequest.getRetStatus()));
|
||||
// resultRequest.setRuleName(getActiveRuleNameFromRequest(response.getHeaders()));
|
||||
// if (Objects.nonNull(context)) {
|
||||
// resultRequest.setCallerIp(context.getConfig().getGlobal().getAPI().getBindIP());
|
||||
// }
|
||||
// List<String> labels = response.getHeaders().get(RouterConstant.ROUTER_LABEL_HEADER);
|
||||
// if (CollectionUtils.isNotEmpty(labels)) {
|
||||
// String label = labels.get(0);
|
||||
// try {
|
||||
// label = URLDecoder.decode(label, UTF_8);
|
||||
// }
|
||||
// catch (UnsupportedEncodingException e) {
|
||||
// LOGGER.error("unsupported charset exception " + UTF_8, e);
|
||||
// }
|
||||
// resultRequest.setLabels(RequestLabelUtils.convertLabel(label));
|
||||
// }
|
||||
//
|
||||
// // processing report with consumerAPI .
|
||||
// LOGGER.debug("Will report result of {}. Request=[{}]. Response=[{}]. Delay=[{}]ms.", resultRequest.getRetStatus()
|
||||
// .name(), url, response.getStatusCode().value(), delay);
|
||||
// consumerAPI.updateServiceCallResult(resultRequest);
|
||||
// ResourceStat resourceStat = ReporterUtils.createInstanceResourceStat(url, response.getRawStatusCode(), delay, resultRequest.getRetStatus());
|
||||
// circuitBreakAPI.report(resourceStat);
|
||||
// }
|
||||
// catch (Exception e) {
|
||||
// LOGGER.error("RestTemplate response reporter execute failed of {} url {}", response, url, e);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void invokeDelegateHandler(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
|
||||
// if (realHasError(response)) {
|
||||
// delegateHandler.handleError(url, method, response);
|
||||
// }
|
||||
//
|
||||
// clear(response);
|
||||
// }
|
||||
//
|
||||
// private Boolean realHasError(ClientHttpResponse response) {
|
||||
// if (delegateHandler == null) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// String hasErrorHeader = response.getHeaders().getFirst(HEADER_HAS_ERROR);
|
||||
// if (StringUtils.isBlank(hasErrorHeader)) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// return Boolean.parseBoolean(hasErrorHeader);
|
||||
// }
|
||||
//
|
||||
// private void clear(ClientHttpResponse response) {
|
||||
// response.getHeaders().remove(HEADER_HAS_ERROR);
|
||||
// response.getHeaders().remove(POLARIS_CIRCUIT_BREAKER_FALLBACK_HEADER);
|
||||
// }
|
||||
//
|
||||
// private ServiceCallResult createServiceCallResult(URI uri, ClientHttpResponse response) throws IOException {
|
||||
// ServiceCallResult resultRequest = new ServiceCallResult();
|
||||
// String serviceName = uri.getHost();
|
||||
// resultRequest.setService(serviceName);
|
||||
// resultRequest.setNamespace(MetadataContext.LOCAL_NAMESPACE);
|
||||
// resultRequest.setMethod(uri.getPath());
|
||||
// resultRequest.setRetCode(response.getStatusCode().value());
|
||||
// resultRequest.setRetStatus(RetStatus.RetSuccess);
|
||||
// String sourceNamespace = MetadataContext.LOCAL_NAMESPACE;
|
||||
// String sourceService = MetadataContext.LOCAL_SERVICE;
|
||||
// if (StringUtils.isNotBlank(sourceNamespace) && StringUtils.isNotBlank(sourceService)) {
|
||||
// resultRequest.setCallerService(new ServiceKey(sourceNamespace, sourceService));
|
||||
// }
|
||||
// return resultRequest;
|
||||
// }
|
||||
//
|
||||
// protected ResponseErrorHandler getDelegateHandler() {
|
||||
// return this.delegateHandler;
|
||||
// }
|
||||
//
|
||||
// protected void setDelegateHandler(ResponseErrorHandler delegateHandler) {
|
||||
// this.delegateHandler = delegateHandler;
|
||||
// }
|
||||
//}
|
||||
|
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.rpc.enhancement.resttemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.Map;
|
||||
|
||||
import com.tencent.cloud.common.constant.HeaderConstant;
|
||||
import com.tencent.cloud.common.metadata.MetadataContextHolder;
|
||||
import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
|
||||
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
|
||||
import com.tencent.polaris.api.core.ConsumerAPI;
|
||||
import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat;
|
||||
import com.tencent.polaris.api.rpc.ServiceCallResult;
|
||||
import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
|
||||
import com.tencent.polaris.client.api.SDKContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
public class PolarisRestTemplateReporter extends AbstractPolarisReporterAdapter implements ClientHttpRequestInterceptor {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PolarisRestTemplateReporter.class);
|
||||
|
||||
private final ConsumerAPI consumerAPI;
|
||||
|
||||
private final CircuitBreakAPI circuitBreakAPI;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor With {@link RpcEnhancementReporterProperties} .
|
||||
*
|
||||
* @param reportProperties instance of {@link RpcEnhancementReporterProperties}.
|
||||
*/
|
||||
public PolarisRestTemplateReporter(RpcEnhancementReporterProperties reportProperties,
|
||||
SDKContext context,
|
||||
ConsumerAPI consumerAPI,
|
||||
CircuitBreakAPI circuitBreakAPI) {
|
||||
super(reportProperties, context);
|
||||
this.consumerAPI = consumerAPI;
|
||||
this.circuitBreakAPI = circuitBreakAPI;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
|
||||
if (!reportProperties.isEnabled()) {
|
||||
return execution.execute(request, body);
|
||||
}
|
||||
|
||||
ClientHttpResponse response = null;
|
||||
IOException ex = null;
|
||||
try {
|
||||
response = execution.execute(request, body);
|
||||
} catch (SocketTimeoutException e) {
|
||||
ex = e;
|
||||
}
|
||||
HttpHeaders requestHeaders = request.getHeaders();
|
||||
HttpHeaders responseHeaders = null;
|
||||
Integer status = null;
|
||||
if (response != null) {
|
||||
responseHeaders = response.getHeaders();
|
||||
status = response.getRawStatusCode();
|
||||
}
|
||||
|
||||
Map<String, String> loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata();
|
||||
String targetHost = loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST);
|
||||
Integer targetPort = Integer.valueOf(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT));
|
||||
long delay = System.currentTimeMillis() - Long.parseLong(loadBalancerContext.get(HeaderConstant.INTERNAL_CALL_START_TIME));
|
||||
|
||||
ServiceCallResult resultRequest = createServiceCallResult(
|
||||
request.getURI().getHost(),
|
||||
targetHost,
|
||||
targetPort,
|
||||
request.getURI(),
|
||||
requestHeaders,
|
||||
responseHeaders,
|
||||
status,
|
||||
delay,
|
||||
ex
|
||||
);
|
||||
LOG.debug("Will report result of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.",
|
||||
resultRequest.getRetStatus().name(), request.getMethod(), request.getURI().getPath(), status, delay);
|
||||
consumerAPI.updateServiceCallResult(resultRequest);
|
||||
|
||||
ResourceStat resourceStat = createInstanceResourceStat(
|
||||
request.getURI().getHost(),
|
||||
targetHost,
|
||||
targetPort,
|
||||
request.getURI(),
|
||||
status,
|
||||
delay,
|
||||
ex
|
||||
);
|
||||
circuitBreakAPI.report(resourceStat);
|
||||
|
||||
if (ex != null) {
|
||||
throw ex;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
@ -1,173 +1,173 @@
|
||||
/*
|
||||
* 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.rpc.enhancement.scg;
|
||||
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import com.tencent.cloud.common.constant.HeaderConstant;
|
||||
import com.tencent.cloud.common.metadata.MetadataContext;
|
||||
import com.tencent.cloud.common.metadata.MetadataContextHolder;
|
||||
import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
|
||||
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
|
||||
import com.tencent.polaris.api.core.ConsumerAPI;
|
||||
import com.tencent.polaris.api.pojo.RetStatus;
|
||||
import com.tencent.polaris.api.pojo.ServiceKey;
|
||||
import com.tencent.polaris.api.rpc.ServiceCallResult;
|
||||
import com.tencent.polaris.client.api.SDKContext;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.netty.http.client.HttpClient;
|
||||
import reactor.netty.http.client.HttpClientConfig;
|
||||
import reactor.netty.http.client.HttpClientResponse;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
public class EnhancedPolarisHttpClient extends HttpClient {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(EnhancedPolarisHttpClient.class);
|
||||
|
||||
private final RpcEnhancementReporterProperties properties;
|
||||
private final SDKContext context;
|
||||
private final ConsumerAPI consumerAPI;
|
||||
private final Reporter adapter;
|
||||
private final BiConsumer<? super HttpClientResponse, ? super Throwable> handler = new BiConsumer<HttpClientResponse, Throwable>() {
|
||||
@Override
|
||||
public void accept(HttpClientResponse httpClientResponse, Throwable throwable) {
|
||||
if (Objects.isNull(consumerAPI)) {
|
||||
return;
|
||||
}
|
||||
HttpHeaders responseHeaders = httpClientResponse.responseHeaders();
|
||||
|
||||
ServiceCallResult result = new ServiceCallResult();
|
||||
result.setCallerService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE));
|
||||
result.setNamespace(MetadataContext.LOCAL_NAMESPACE);
|
||||
|
||||
Map<String, String> metadata = MetadataContextHolder.get().getLoadbalancerMetadata();
|
||||
result.setDelay(System.currentTimeMillis() - Long.parseLong(metadata.get("startTime")));
|
||||
result.setService(metadata.get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID));
|
||||
result.setHost(metadata.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST));
|
||||
result.setPort(Integer.parseInt(metadata.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT)));
|
||||
RetStatus status = RetStatus.RetSuccess;
|
||||
if (Objects.isNull(throwable)) {
|
||||
if (EnhancedPolarisHttpClient.this.adapter.apply(HttpStatus.valueOf(httpClientResponse.status()
|
||||
.code()))) {
|
||||
status = RetStatus.RetFail;
|
||||
}
|
||||
org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
|
||||
responseHeaders.forEach(entry -> headers.add(entry.getKey(), entry.getValue()));
|
||||
status = adapter.getRetStatusFromRequest(headers, status);
|
||||
result.setRuleName(adapter.getActiveRuleNameFromRequest(headers));
|
||||
}
|
||||
else {
|
||||
if (throwable instanceof SocketTimeoutException) {
|
||||
status = RetStatus.RetTimeout;
|
||||
}
|
||||
}
|
||||
result.setMethod(httpClientResponse.uri());
|
||||
result.setRetCode(httpClientResponse.status().code());
|
||||
result.setRetStatus(status);
|
||||
if (Objects.nonNull(context)) {
|
||||
result.setCallerIp(context.getConfig().getGlobal().getAPI().getBindIP());
|
||||
}
|
||||
try {
|
||||
consumerAPI.updateServiceCallResult(result);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
LOG.error("update service call result fail", ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
private HttpClient target;
|
||||
|
||||
public EnhancedPolarisHttpClient(
|
||||
HttpClient client,
|
||||
RpcEnhancementReporterProperties properties,
|
||||
SDKContext context,
|
||||
ConsumerAPI consumerAPI) {
|
||||
this.properties = properties;
|
||||
this.context = context;
|
||||
this.consumerAPI = consumerAPI;
|
||||
this.target = client;
|
||||
this.adapter = new Reporter(properties);
|
||||
this.registerReportHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpClientConfig configuration() {
|
||||
return target.configuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpClient duplicate() {
|
||||
return new EnhancedPolarisHttpClient(target, properties, context, consumerAPI);
|
||||
}
|
||||
|
||||
private void registerReportHandler() {
|
||||
target = target.doOnRequest((request, connection) -> {
|
||||
String serviceId = request.requestHeaders().get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID);
|
||||
String host = request.requestHeaders().get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST);
|
||||
String port = request.requestHeaders().get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT);
|
||||
if (StringUtils.isNotBlank(serviceId)) {
|
||||
MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID, serviceId);
|
||||
MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST, host);
|
||||
MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT, port);
|
||||
MetadataContextHolder.get().setLoadbalancer("startTime", System.currentTimeMillis() + "");
|
||||
}
|
||||
|
||||
request.requestHeaders().remove(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID);
|
||||
request.requestHeaders().remove(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST);
|
||||
request.requestHeaders().remove(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT);
|
||||
});
|
||||
target = target.doOnResponse((httpClientResponse, connection) -> handler.accept(httpClientResponse, null));
|
||||
target = target.doOnResponseError(handler);
|
||||
}
|
||||
|
||||
|
||||
private static class Reporter extends AbstractPolarisReporterAdapter {
|
||||
|
||||
/**
|
||||
* Constructor With {@link RpcEnhancementReporterProperties} .
|
||||
*
|
||||
* @param reportProperties instance of {@link RpcEnhancementReporterProperties}.
|
||||
*/
|
||||
protected Reporter(RpcEnhancementReporterProperties reportProperties) {
|
||||
super(reportProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(HttpStatus httpStatus) {
|
||||
return super.apply(httpStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RetStatus getRetStatusFromRequest(org.springframework.http.HttpHeaders headers, RetStatus defaultVal) {
|
||||
return super.getRetStatusFromRequest(headers, defaultVal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActiveRuleNameFromRequest(org.springframework.http.HttpHeaders headers) {
|
||||
return super.getActiveRuleNameFromRequest(headers);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * 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.rpc.enhancement.scg;
|
||||
//
|
||||
//import java.net.SocketTimeoutException;
|
||||
//import java.util.Map;
|
||||
//import java.util.Objects;
|
||||
//import java.util.function.BiConsumer;
|
||||
//
|
||||
//import com.tencent.cloud.common.constant.HeaderConstant;
|
||||
//import com.tencent.cloud.common.metadata.MetadataContext;
|
||||
//import com.tencent.cloud.common.metadata.MetadataContextHolder;
|
||||
//import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
|
||||
//import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
|
||||
//import com.tencent.polaris.api.core.ConsumerAPI;
|
||||
//import com.tencent.polaris.api.pojo.RetStatus;
|
||||
//import com.tencent.polaris.api.pojo.ServiceKey;
|
||||
//import com.tencent.polaris.api.rpc.ServiceCallResult;
|
||||
//import com.tencent.polaris.client.api.SDKContext;
|
||||
//import io.netty.handler.codec.http.HttpHeaders;
|
||||
//import org.apache.commons.lang.StringUtils;
|
||||
//import org.slf4j.Logger;
|
||||
//import org.slf4j.LoggerFactory;
|
||||
//import reactor.netty.http.client.HttpClient;
|
||||
//import reactor.netty.http.client.HttpClientConfig;
|
||||
//import reactor.netty.http.client.HttpClientResponse;
|
||||
//
|
||||
//import org.springframework.http.HttpStatus;
|
||||
//
|
||||
//public class EnhancedPolarisHttpClient extends HttpClient {
|
||||
//
|
||||
// private static final Logger LOG = LoggerFactory.getLogger(EnhancedPolarisHttpClient.class);
|
||||
//
|
||||
// private final RpcEnhancementReporterProperties properties;
|
||||
// private final SDKContext context;
|
||||
// private final ConsumerAPI consumerAPI;
|
||||
// private final Reporter adapter;
|
||||
// private final BiConsumer<? super HttpClientResponse, ? super Throwable> handler = new BiConsumer<HttpClientResponse, Throwable>() {
|
||||
// @Override
|
||||
// public void accept(HttpClientResponse httpClientResponse, Throwable throwable) {
|
||||
// if (Objects.isNull(consumerAPI)) {
|
||||
// return;
|
||||
// }
|
||||
// HttpHeaders responseHeaders = httpClientResponse.responseHeaders();
|
||||
//
|
||||
// ServiceCallResult result = new ServiceCallResult();
|
||||
// result.setCallerService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE));
|
||||
// result.setNamespace(MetadataContext.LOCAL_NAMESPACE);
|
||||
//
|
||||
// Map<String, String> metadata = MetadataContextHolder.get().getLoadbalancerMetadata();
|
||||
// result.setDelay(System.currentTimeMillis() - Long.parseLong(metadata.get("startTime")));
|
||||
// result.setService(metadata.get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID));
|
||||
// result.setHost(metadata.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST));
|
||||
// result.setPort(Integer.parseInt(metadata.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT)));
|
||||
// RetStatus status = RetStatus.RetSuccess;
|
||||
// if (Objects.isNull(throwable)) {
|
||||
// if (EnhancedPolarisHttpClient.this.adapter.apply(HttpStatus.valueOf(httpClientResponse.status()
|
||||
// .code()))) {
|
||||
// status = RetStatus.RetFail;
|
||||
// }
|
||||
// org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
|
||||
// responseHeaders.forEach(entry -> headers.add(entry.getKey(), entry.getValue()));
|
||||
// status = adapter.getRetStatusFromRequest(headers, status);
|
||||
// result.setRuleName(adapter.getActiveRuleNameFromRequest(headers));
|
||||
// }
|
||||
// else {
|
||||
// if (throwable instanceof SocketTimeoutException) {
|
||||
// status = RetStatus.RetTimeout;
|
||||
// }
|
||||
// }
|
||||
// result.setMethod(httpClientResponse.uri());
|
||||
// result.setRetCode(httpClientResponse.status().code());
|
||||
// result.setRetStatus(status);
|
||||
// if (Objects.nonNull(context)) {
|
||||
// result.setCallerIp(context.getConfig().getGlobal().getAPI().getBindIP());
|
||||
// }
|
||||
// try {
|
||||
// consumerAPI.updateServiceCallResult(result);
|
||||
// }
|
||||
// catch (Throwable ex) {
|
||||
// LOG.error("update service call result fail", ex);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// private HttpClient target;
|
||||
//
|
||||
// public EnhancedPolarisHttpClient(
|
||||
// HttpClient client,
|
||||
// RpcEnhancementReporterProperties properties,
|
||||
// SDKContext context,
|
||||
// ConsumerAPI consumerAPI) {
|
||||
// this.properties = properties;
|
||||
// this.context = context;
|
||||
// this.consumerAPI = consumerAPI;
|
||||
// this.target = client;
|
||||
// this.adapter = new Reporter(properties);
|
||||
// this.registerReportHandler();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public HttpClientConfig configuration() {
|
||||
// return target.configuration();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected HttpClient duplicate() {
|
||||
// return new EnhancedPolarisHttpClient(target, properties, context, consumerAPI);
|
||||
// }
|
||||
//
|
||||
// private void registerReportHandler() {
|
||||
// target = target.doOnRequest((request, connection) -> {
|
||||
// String serviceId = request.requestHeaders().get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID);
|
||||
// String host = request.requestHeaders().get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST);
|
||||
// String port = request.requestHeaders().get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT);
|
||||
// if (StringUtils.isNotBlank(serviceId)) {
|
||||
// MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID, serviceId);
|
||||
// MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST, host);
|
||||
// MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT, port);
|
||||
// MetadataContextHolder.get().setLoadbalancer("startTime", System.currentTimeMillis() + "");
|
||||
// }
|
||||
//
|
||||
// request.requestHeaders().remove(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID);
|
||||
// request.requestHeaders().remove(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST);
|
||||
// request.requestHeaders().remove(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT);
|
||||
// });
|
||||
// target = target.doOnResponse((httpClientResponse, connection) -> handler.accept(httpClientResponse, null));
|
||||
// target = target.doOnResponseError(handler);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private static class Reporter extends AbstractPolarisReporterAdapter {
|
||||
//
|
||||
// /**
|
||||
// * Constructor With {@link RpcEnhancementReporterProperties} .
|
||||
// *
|
||||
// * @param reportProperties instance of {@link RpcEnhancementReporterProperties}.
|
||||
// */
|
||||
// protected Reporter(RpcEnhancementReporterProperties reportProperties) {
|
||||
// super(reportProperties);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean apply(HttpStatus httpStatus) {
|
||||
// return super.apply(httpStatus);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public RetStatus getRetStatusFromRequest(org.springframework.http.HttpHeaders headers, RetStatus defaultVal) {
|
||||
// return super.getRetStatusFromRequest(headers, defaultVal);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String getActiveRuleNameFromRequest(org.springframework.http.HttpHeaders headers) {
|
||||
// return super.getActiveRuleNameFromRequest(headers);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
@ -1,43 +1,43 @@
|
||||
/*
|
||||
* 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.rpc.enhancement.scg;
|
||||
|
||||
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
|
||||
import com.tencent.polaris.api.core.ConsumerAPI;
|
||||
import com.tencent.polaris.client.api.SDKContext;
|
||||
import reactor.netty.http.client.HttpClient;
|
||||
|
||||
import org.springframework.cloud.gateway.config.HttpClientCustomizer;
|
||||
|
||||
public class EnhancedPolarisHttpClientCustomizer implements HttpClientCustomizer {
|
||||
|
||||
private final RpcEnhancementReporterProperties properties;
|
||||
private final SDKContext context;
|
||||
private final ConsumerAPI consumerAPI;
|
||||
|
||||
public EnhancedPolarisHttpClientCustomizer(RpcEnhancementReporterProperties properties, SDKContext context, ConsumerAPI consumerAPI) {
|
||||
this.properties = properties;
|
||||
this.context = context;
|
||||
this.consumerAPI = consumerAPI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpClient customize(HttpClient httpClient) {
|
||||
return new EnhancedPolarisHttpClient(httpClient, properties, context, consumerAPI);
|
||||
}
|
||||
}
|
||||
///*
|
||||
// * 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.rpc.enhancement.scg;
|
||||
//
|
||||
//import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
|
||||
//import com.tencent.polaris.api.core.ConsumerAPI;
|
||||
//import com.tencent.polaris.client.api.SDKContext;
|
||||
//import reactor.netty.http.client.HttpClient;
|
||||
//
|
||||
//import org.springframework.cloud.gateway.config.HttpClientCustomizer;
|
||||
//
|
||||
//public class EnhancedPolarisHttpClientCustomizer implements HttpClientCustomizer {
|
||||
//
|
||||
// private final RpcEnhancementReporterProperties properties;
|
||||
// private final SDKContext context;
|
||||
// private final ConsumerAPI consumerAPI;
|
||||
//
|
||||
// public EnhancedPolarisHttpClientCustomizer(RpcEnhancementReporterProperties properties, SDKContext context, ConsumerAPI consumerAPI) {
|
||||
// this.properties = properties;
|
||||
// this.context = context;
|
||||
// this.consumerAPI = consumerAPI;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public HttpClient customize(HttpClient httpClient) {
|
||||
// return new EnhancedPolarisHttpClient(httpClient, properties, context, consumerAPI);
|
||||
// }
|
||||
//}
|
||||
|
@ -0,0 +1,109 @@
|
||||
package com.tencent.cloud.rpc.enhancement.scg;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.tencent.cloud.common.constant.HeaderConstant;
|
||||
import com.tencent.cloud.common.metadata.MetadataContextHolder;
|
||||
import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
|
||||
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
|
||||
import com.tencent.polaris.api.core.ConsumerAPI;
|
||||
import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat;
|
||||
import com.tencent.polaris.api.rpc.ServiceCallResult;
|
||||
import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
|
||||
import com.tencent.polaris.client.api.SDKContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
public class PolarisGatewayReporter extends AbstractPolarisReporterAdapter implements GlobalFilter {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PolarisGatewayReporter.class);
|
||||
|
||||
private final ConsumerAPI consumerAPI;
|
||||
|
||||
private final CircuitBreakAPI circuitBreakAPI;
|
||||
|
||||
/**
|
||||
* Constructor With {@link RpcEnhancementReporterProperties} .
|
||||
*
|
||||
* @param reportProperties instance of {@link RpcEnhancementReporterProperties}.
|
||||
*/
|
||||
public PolarisGatewayReporter(RpcEnhancementReporterProperties reportProperties,
|
||||
SDKContext context,
|
||||
ConsumerAPI consumerAPI,
|
||||
CircuitBreakAPI circuitBreakAPI) {
|
||||
super(reportProperties, context);
|
||||
this.consumerAPI = consumerAPI;
|
||||
this.circuitBreakAPI = circuitBreakAPI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
if (!reportProperties.isEnabled()) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
MetadataContextHolder.get().setLoadbalancer(
|
||||
HeaderConstant.INTERNAL_CALLEE_SERVICE_ID,
|
||||
exchange.getRequest().getHeaders().getFirst(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID)
|
||||
);
|
||||
MetadataContextHolder.get().setLoadbalancer(
|
||||
HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST,
|
||||
exchange.getRequest().getHeaders().getFirst(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST)
|
||||
);
|
||||
MetadataContextHolder.get().setLoadbalancer(
|
||||
HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT,
|
||||
exchange.getRequest().getHeaders().getFirst(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT)
|
||||
);
|
||||
MetadataContextHolder.get().setLoadbalancer(
|
||||
HeaderConstant.INTERNAL_CALL_START_TIME,
|
||||
String.valueOf(System.currentTimeMillis())
|
||||
);
|
||||
return chain.filter(exchange)
|
||||
.doOnSuccess(v -> instrumentResponse(exchange, null))
|
||||
.doOnError(t -> instrumentResponse(exchange, t));
|
||||
}
|
||||
|
||||
private void instrumentResponse(ServerWebExchange exchange, Throwable t) {
|
||||
Map<String, String> loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata();
|
||||
String serviceId = loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID);
|
||||
String targetHost = loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST);
|
||||
Integer targetPort = Integer.valueOf(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT));
|
||||
long delay = System.currentTimeMillis() - Long.parseLong(loadBalancerContext.get(HeaderConstant.INTERNAL_CALL_START_TIME));
|
||||
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
|
||||
ServiceCallResult resultRequest = createServiceCallResult(
|
||||
serviceId,
|
||||
targetHost,
|
||||
targetPort,
|
||||
request.getURI(),
|
||||
request.getHeaders(),
|
||||
response.getHeaders(),
|
||||
response.getRawStatusCode(),
|
||||
delay,
|
||||
t
|
||||
);
|
||||
LOG.debug("Will report result of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.",
|
||||
resultRequest.getRetStatus().name(), request.getMethod(), request.getURI().getPath(), response.getRawStatusCode(), delay);
|
||||
consumerAPI.updateServiceCallResult(resultRequest);
|
||||
|
||||
ResourceStat resourceStat = createInstanceResourceStat(
|
||||
serviceId,
|
||||
targetHost,
|
||||
targetPort,
|
||||
request.getURI(),
|
||||
response.getRawStatusCode(),
|
||||
delay,
|
||||
t
|
||||
);
|
||||
circuitBreakAPI.report(resourceStat);
|
||||
}
|
||||
|
||||
}
|
@ -1,230 +1,231 @@
|
||||
/*
|
||||
* 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.rpc.enhancement.resttemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.tencent.cloud.common.metadata.MetadataContext;
|
||||
import com.tencent.cloud.common.metadata.MetadataContextHolder;
|
||||
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
|
||||
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
|
||||
import com.tencent.polaris.api.core.ConsumerAPI;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.client.AbstractClientHttpResponse;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.web.client.DefaultResponseErrorHandler;
|
||||
import org.springframework.web.client.ResponseErrorHandler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Test for {@link EnhancedRestTemplateReporter}.
|
||||
* @author lepdou 2022-09-06
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class EnhancedRestTemplateReporterTest {
|
||||
|
||||
private static MockedStatic<MetadataContextHolder> mockedMetadataContextHolder;
|
||||
private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
|
||||
@Mock
|
||||
private ConsumerAPI consumerAPI;
|
||||
@Mock
|
||||
private RpcEnhancementReporterProperties reporterProperties;
|
||||
@Mock
|
||||
private ResponseErrorHandler delegate;
|
||||
@InjectMocks
|
||||
private EnhancedRestTemplateReporter enhancedRestTemplateReporter;
|
||||
|
||||
@InjectMocks
|
||||
private EnhancedRestTemplateReporter enhancedRestTemplateReporter2;
|
||||
|
||||
@BeforeAll
|
||||
static void beforeAll() {
|
||||
mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
|
||||
mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
|
||||
.thenReturn("caller");
|
||||
MetadataContext metadataContext = Mockito.mock(MetadataContext.class);
|
||||
|
||||
// mock transitive metadata
|
||||
Map<String, String> loadBalancerContext = new HashMap<>();
|
||||
loadBalancerContext.put("host", "1.1.1.1");
|
||||
loadBalancerContext.put("port", "8080");
|
||||
loadBalancerContext.put("startMillis", String.valueOf(System.currentTimeMillis()));
|
||||
when(metadataContext.getLoadbalancerMetadata()).thenReturn(loadBalancerContext);
|
||||
|
||||
mockedMetadataContextHolder = Mockito.mockStatic(MetadataContextHolder.class);
|
||||
mockedMetadataContextHolder.when(MetadataContextHolder::get).thenReturn(metadataContext);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void afterAll() {
|
||||
mockedApplicationContextAwareUtils.close();
|
||||
mockedMetadataContextHolder.close();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
enhancedRestTemplateReporter.setDelegateHandler(delegate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetApplicationContext() {
|
||||
ApplicationContext applicationContext = mock(ApplicationContext.class);
|
||||
|
||||
// test no ResponseErrorHandler
|
||||
when(applicationContext.getBeanNamesForType(any(Class.class)))
|
||||
.thenReturn(new String[] {"enhancedRestTemplateReporter"});
|
||||
enhancedRestTemplateReporter2.setApplicationContext(applicationContext);
|
||||
assertThat(enhancedRestTemplateReporter2.getDelegateHandler()).isInstanceOf(DefaultResponseErrorHandler.class);
|
||||
|
||||
// test one other ResponseErrorHandler
|
||||
when(applicationContext.getBeanNamesForType(any(Class.class)))
|
||||
.thenReturn(new String[] {"enhancedRestTemplateReporter", "mockedResponseErrorHandler"});
|
||||
when(applicationContext.getBean(anyString())).thenReturn(mock(MockedResponseErrorHandler.class));
|
||||
enhancedRestTemplateReporter2.setApplicationContext(applicationContext);
|
||||
assertThat(enhancedRestTemplateReporter2.getDelegateHandler()).isInstanceOf(MockedResponseErrorHandler.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasError() throws IOException {
|
||||
when(delegate.hasError(any())).thenReturn(true);
|
||||
|
||||
MockedClientHttpResponse response = new MockedClientHttpResponse();
|
||||
assertThat(enhancedRestTemplateReporter.hasError(response)).isTrue();
|
||||
|
||||
String realHasError = response.getHeaders().getFirst(EnhancedRestTemplateReporter.HEADER_HAS_ERROR);
|
||||
assertThat(realHasError).isEqualTo("true");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleHasError() throws IOException {
|
||||
when(reporterProperties.isEnabled()).thenReturn(true);
|
||||
when(delegate.hasError(any())).thenReturn(true);
|
||||
|
||||
MockedClientHttpResponse response = new MockedClientHttpResponse();
|
||||
enhancedRestTemplateReporter.hasError(response);
|
||||
|
||||
URI uri = mock(URI.class);
|
||||
enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response);
|
||||
|
||||
verify(consumerAPI, times(1)).updateServiceCallResult(any());
|
||||
verify(delegate).handleError(uri, HttpMethod.GET, response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleHasNotError() throws IOException {
|
||||
when(reporterProperties.isEnabled()).thenReturn(true);
|
||||
when(delegate.hasError(any())).thenReturn(false);
|
||||
|
||||
MockedClientHttpResponse response = new MockedClientHttpResponse();
|
||||
enhancedRestTemplateReporter.hasError(response);
|
||||
|
||||
URI uri = mock(URI.class);
|
||||
enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response);
|
||||
|
||||
verify(consumerAPI, times(1)).updateServiceCallResult(any());
|
||||
verify(delegate, times(0)).handleError(uri, HttpMethod.GET, response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReportSwitchOff() throws IOException {
|
||||
when(reporterProperties.isEnabled()).thenReturn(false);
|
||||
when(delegate.hasError(any())).thenReturn(true);
|
||||
|
||||
MockedClientHttpResponse response = new MockedClientHttpResponse();
|
||||
enhancedRestTemplateReporter.hasError(response);
|
||||
|
||||
URI uri = mock(URI.class);
|
||||
enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response);
|
||||
|
||||
verify(consumerAPI, times(0)).updateServiceCallResult(any());
|
||||
verify(delegate).handleError(uri, HttpMethod.GET, response);
|
||||
}
|
||||
|
||||
static class MockedClientHttpResponse extends AbstractClientHttpResponse {
|
||||
|
||||
private final HttpHeaders headers;
|
||||
|
||||
MockedClientHttpResponse() {
|
||||
this.headers = new HttpHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRawStatusCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatusText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBody() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpStatus getStatusCode() throws IOException {
|
||||
return HttpStatus.OK;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MockedResponseErrorHandler extends DefaultResponseErrorHandler {
|
||||
|
||||
@Override
|
||||
public void handleError(@NonNull ClientHttpResponse response) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
///*
|
||||
// * 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.rpc.enhancement.resttemplate;
|
||||
//
|
||||
//import java.io.IOException;
|
||||
//import java.io.InputStream;
|
||||
//import java.net.URI;
|
||||
//import java.util.HashMap;
|
||||
//import java.util.Map;
|
||||
//
|
||||
//import com.tencent.cloud.common.metadata.MetadataContext;
|
||||
//import com.tencent.cloud.common.metadata.MetadataContextHolder;
|
||||
//import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
|
||||
//import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
|
||||
//import com.tencent.polaris.api.core.ConsumerAPI;
|
||||
//import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
//import org.junit.jupiter.api.AfterAll;
|
||||
//import org.junit.jupiter.api.BeforeAll;
|
||||
//import org.junit.jupiter.api.BeforeEach;
|
||||
//import org.junit.jupiter.api.Test;
|
||||
//import org.junit.jupiter.api.extension.ExtendWith;
|
||||
//import org.mockito.InjectMocks;
|
||||
//import org.mockito.Mock;
|
||||
//import org.mockito.MockedStatic;
|
||||
//import org.mockito.Mockito;
|
||||
//import org.mockito.junit.jupiter.MockitoExtension;
|
||||
//
|
||||
//import org.springframework.context.ApplicationContext;
|
||||
//import org.springframework.http.HttpHeaders;
|
||||
//import org.springframework.http.HttpMethod;
|
||||
//import org.springframework.http.HttpStatus;
|
||||
//import org.springframework.http.client.AbstractClientHttpResponse;
|
||||
//import org.springframework.http.client.ClientHttpResponse;
|
||||
//import org.springframework.web.client.DefaultResponseErrorHandler;
|
||||
//import org.springframework.web.client.ResponseErrorHandler;
|
||||
//
|
||||
//import static org.assertj.core.api.Assertions.assertThat;
|
||||
//import static org.mockito.ArgumentMatchers.any;
|
||||
//import static org.mockito.ArgumentMatchers.anyString;
|
||||
//import static org.mockito.Mockito.mock;
|
||||
//import static org.mockito.Mockito.times;
|
||||
//import static org.mockito.Mockito.verify;
|
||||
//import static org.mockito.Mockito.when;
|
||||
//
|
||||
///**
|
||||
// * Test for {@link EnhancedRestTemplateReporter}.
|
||||
// *
|
||||
// * @author lepdou 2022-09-06
|
||||
// */
|
||||
//@ExtendWith(MockitoExtension.class)
|
||||
//public class EnhancedRestTemplateReporterTest {
|
||||
//
|
||||
// private static MockedStatic<MetadataContextHolder> mockedMetadataContextHolder;
|
||||
// private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
|
||||
// @Mock
|
||||
// private ConsumerAPI consumerAPI;
|
||||
// @Mock
|
||||
// private RpcEnhancementReporterProperties reporterProperties;
|
||||
// @Mock
|
||||
// private ResponseErrorHandler delegate;
|
||||
// @InjectMocks
|
||||
// private EnhancedRestTemplateReporter enhancedRestTemplateReporter;
|
||||
//
|
||||
// @InjectMocks
|
||||
// private EnhancedRestTemplateReporter enhancedRestTemplateReporter2;
|
||||
//
|
||||
// @BeforeAll
|
||||
// static void beforeAll() {
|
||||
// mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
|
||||
// mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
|
||||
// .thenReturn("caller");
|
||||
// MetadataContext metadataContext = Mockito.mock(MetadataContext.class);
|
||||
//
|
||||
// // mock transitive metadata
|
||||
// Map<String, String> loadBalancerContext = new HashMap<>();
|
||||
// loadBalancerContext.put("host", "1.1.1.1");
|
||||
// loadBalancerContext.put("port", "8080");
|
||||
// loadBalancerContext.put("startMillis", String.valueOf(System.currentTimeMillis()));
|
||||
// when(metadataContext.getLoadbalancerMetadata()).thenReturn(loadBalancerContext);
|
||||
//
|
||||
// mockedMetadataContextHolder = Mockito.mockStatic(MetadataContextHolder.class);
|
||||
// mockedMetadataContextHolder.when(MetadataContextHolder::get).thenReturn(metadataContext);
|
||||
// }
|
||||
//
|
||||
// @AfterAll
|
||||
// static void afterAll() {
|
||||
// mockedApplicationContextAwareUtils.close();
|
||||
// mockedMetadataContextHolder.close();
|
||||
// }
|
||||
//
|
||||
// @BeforeEach
|
||||
// void setUp() {
|
||||
// enhancedRestTemplateReporter.setDelegateHandler(delegate);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testSetApplicationContext() {
|
||||
// ApplicationContext applicationContext = mock(ApplicationContext.class);
|
||||
//
|
||||
// // test no ResponseErrorHandler
|
||||
// when(applicationContext.getBeanNamesForType(any(Class.class)))
|
||||
// .thenReturn(new String[] {"enhancedRestTemplateReporter"});
|
||||
// enhancedRestTemplateReporter2.setApplicationContext(applicationContext);
|
||||
// assertThat(enhancedRestTemplateReporter2.getDelegateHandler()).isInstanceOf(DefaultResponseErrorHandler.class);
|
||||
//
|
||||
// // test one other ResponseErrorHandler
|
||||
// when(applicationContext.getBeanNamesForType(any(Class.class)))
|
||||
// .thenReturn(new String[] {"enhancedRestTemplateReporter", "mockedResponseErrorHandler"});
|
||||
// when(applicationContext.getBean(anyString())).thenReturn(mock(MockedResponseErrorHandler.class));
|
||||
// enhancedRestTemplateReporter2.setApplicationContext(applicationContext);
|
||||
// assertThat(enhancedRestTemplateReporter2.getDelegateHandler()).isInstanceOf(MockedResponseErrorHandler.class);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testHasError() throws IOException {
|
||||
// when(delegate.hasError(any())).thenReturn(true);
|
||||
//
|
||||
// MockedClientHttpResponse response = new MockedClientHttpResponse();
|
||||
// assertThat(enhancedRestTemplateReporter.hasError(response)).isTrue();
|
||||
//
|
||||
// String realHasError = response.getHeaders().getFirst(EnhancedRestTemplateReporter.HEADER_HAS_ERROR);
|
||||
// assertThat(realHasError).isEqualTo("true");
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testHandleHasError() throws IOException {
|
||||
// when(reporterProperties.isEnabled()).thenReturn(true);
|
||||
// when(delegate.hasError(any())).thenReturn(true);
|
||||
//
|
||||
// MockedClientHttpResponse response = new MockedClientHttpResponse();
|
||||
// enhancedRestTemplateReporter.hasError(response);
|
||||
//
|
||||
// URI uri = mock(URI.class);
|
||||
// enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response);
|
||||
//
|
||||
// verify(consumerAPI, times(1)).updateServiceCallResult(any());
|
||||
// verify(delegate).handleError(uri, HttpMethod.GET, response);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testHandleHasNotError() throws IOException {
|
||||
// when(reporterProperties.isEnabled()).thenReturn(true);
|
||||
// when(delegate.hasError(any())).thenReturn(false);
|
||||
//
|
||||
// MockedClientHttpResponse response = new MockedClientHttpResponse();
|
||||
// enhancedRestTemplateReporter.hasError(response);
|
||||
//
|
||||
// URI uri = mock(URI.class);
|
||||
// enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response);
|
||||
//
|
||||
// verify(consumerAPI, times(1)).updateServiceCallResult(any());
|
||||
// verify(delegate, times(0)).handleError(uri, HttpMethod.GET, response);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testReportSwitchOff() throws IOException {
|
||||
// when(reporterProperties.isEnabled()).thenReturn(false);
|
||||
// when(delegate.hasError(any())).thenReturn(true);
|
||||
//
|
||||
// MockedClientHttpResponse response = new MockedClientHttpResponse();
|
||||
// enhancedRestTemplateReporter.hasError(response);
|
||||
//
|
||||
// URI uri = mock(URI.class);
|
||||
// enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response);
|
||||
//
|
||||
// verify(consumerAPI, times(0)).updateServiceCallResult(any());
|
||||
// verify(delegate).handleError(uri, HttpMethod.GET, response);
|
||||
// }
|
||||
//
|
||||
// static class MockedClientHttpResponse extends AbstractClientHttpResponse {
|
||||
//
|
||||
// private final HttpHeaders headers;
|
||||
//
|
||||
// MockedClientHttpResponse() {
|
||||
// this.headers = new HttpHeaders();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getRawStatusCode() {
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String getStatusText() {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void close() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public InputStream getBody() throws IOException {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public HttpHeaders getHeaders() {
|
||||
// return headers;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public HttpStatus getStatusCode() throws IOException {
|
||||
// return HttpStatus.OK;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private static class MockedResponseErrorHandler extends DefaultResponseErrorHandler {
|
||||
//
|
||||
// @Override
|
||||
// public void handleError(@NonNull ClientHttpResponse response) {
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//}
|
||||
|
@ -1,49 +1,49 @@
|
||||
/*
|
||||
* 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.rpc.enhancement.scg;
|
||||
|
||||
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
|
||||
import com.tencent.polaris.api.core.ConsumerAPI;
|
||||
import com.tencent.polaris.client.api.SDKContext;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import reactor.netty.http.client.HttpClient;
|
||||
|
||||
public class EnhancedPolarisHttpClientCustomizerTest {
|
||||
|
||||
@Test
|
||||
public void testCustomize() {
|
||||
RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties();
|
||||
properties.setEnabled(true);
|
||||
properties.getStatuses().clear();
|
||||
properties.getSeries().clear();
|
||||
|
||||
SDKContext context = Mockito.mock(SDKContext.class);
|
||||
ConsumerAPI consumerAPI = Mockito.mock(ConsumerAPI.class);
|
||||
|
||||
EnhancedPolarisHttpClientCustomizer clientCustomizer = new EnhancedPolarisHttpClientCustomizer(properties, context, consumerAPI);
|
||||
|
||||
HttpClient client = HttpClient.create();
|
||||
HttpClient proxyClient = clientCustomizer.customize(client);
|
||||
|
||||
Assertions.assertNotNull(proxyClient);
|
||||
Assertions.assertEquals(EnhancedPolarisHttpClient.class.getName(), proxyClient.getClass().getName());
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * 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.rpc.enhancement.scg;
|
||||
//
|
||||
//import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
|
||||
//import com.tencent.polaris.api.core.ConsumerAPI;
|
||||
//import com.tencent.polaris.client.api.SDKContext;
|
||||
//import org.junit.jupiter.api.Assertions;
|
||||
//import org.junit.jupiter.api.Test;
|
||||
//import org.mockito.Mockito;
|
||||
//import reactor.netty.http.client.HttpClient;
|
||||
//
|
||||
//public class EnhancedPolarisHttpClientCustomizerTest {
|
||||
//
|
||||
// @Test
|
||||
// public void testCustomize() {
|
||||
// RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties();
|
||||
// properties.setEnabled(true);
|
||||
// properties.getStatuses().clear();
|
||||
// properties.getSeries().clear();
|
||||
//
|
||||
// SDKContext context = Mockito.mock(SDKContext.class);
|
||||
// ConsumerAPI consumerAPI = Mockito.mock(ConsumerAPI.class);
|
||||
//
|
||||
// EnhancedPolarisHttpClientCustomizer clientCustomizer = new EnhancedPolarisHttpClientCustomizer(properties, context, consumerAPI);
|
||||
//
|
||||
// HttpClient client = HttpClient.create();
|
||||
// HttpClient proxyClient = clientCustomizer.customize(client);
|
||||
//
|
||||
// Assertions.assertNotNull(proxyClient);
|
||||
// Assertions.assertEquals(EnhancedPolarisHttpClient.class.getName(), proxyClient.getClass().getName());
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
Loading…
Reference in new issue