feat:support service contract reporting. (#1139)

pull/1146/head
Haotian Zhang 1 year ago committed by GitHub
parent e4ac09c8d6
commit 5cf3640867
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -16,7 +16,7 @@ header:
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
paths:
- "**/java/**"
- "**/tencent/**"
language:
Java:
extensions:

@ -7,4 +7,5 @@
- [Refactoring:remove invalid @AutoConfigureAfter and @AutoConfigureBefore from discovery client automatic configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1115)
- [feat: support log path configuration parameters.](https://github.com/Tencent/spring-cloud-tencent/pull/1128)
- [refactor:optimize the order and condition matching of service registration automatic configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1129)
- [feat: add circuit breaker actuator.](https://github.com/Tencent/spring-cloud-tencent/pull/1136)
- [feat: add circuit breaker actuator.](https://github.com/Tencent/spring-cloud-tencent/pull/1136)
- [feat:support service contract reporting.](https://github.com/Tencent/spring-cloud-tencent/pull/1139)

@ -47,6 +47,7 @@
<module>spring-cloud-starter-tencent-polaris-ratelimit</module>
<module>spring-cloud-starter-tencent-polaris-circuitbreaker</module>
<module>spring-cloud-starter-tencent-polaris-router</module>
<module>spring-cloud-starter-tencent-polaris-contract</module>
<module>spring-cloud-tencent-plugin-starters</module>
<module>spring-cloud-tencent-dependencies</module>
<module>spring-cloud-starter-tencent-all</module>

@ -45,6 +45,11 @@
<artifactId>spring-cloud-starter-tencent-metadata-transfer</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-contract</artifactId>
</dependency>
<!-- Spring Cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
@ -88,12 +93,19 @@
<configuration>
<createSourcesJar>true</createSourcesJar>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports</resource>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports</resource>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
</resource>
</transformer>
</transformers>
</configuration>

@ -101,7 +101,7 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
private void initCustomPolarisConfigExtensionFiles(CompositePropertySource compositePropertySource) {
if (polarisConfigCustomExtensionLayer == null) {
LOGGER.debug("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps");
LOGGER.debug("[SCT Config] PolarisConfigCustomExtensionLayer is not init, ignore the following execution steps");
return;
}
polarisConfigCustomExtensionLayer.initConfigFiles(environment, compositePropertySource, polarisPropertySourceManager, configFileService);
@ -109,7 +109,7 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
private void afterLocatePolarisConfigExtension(CompositePropertySource compositePropertySource) {
if (polarisConfigCustomExtensionLayer == null) {
LOGGER.debug("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps");
LOGGER.debug("[SCT Config] PolarisConfigCustomExtensionLayer is not init, ignore the following execution steps");
return;
}
polarisConfigCustomExtensionLayer.executeAfterLocateConfigReturning(compositePropertySource);

@ -89,7 +89,7 @@ public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationL
private void customInitRegisterPolarisConfig(PolarisConfigPropertyAutoRefresher polarisConfigPropertyAutoRefresher) {
if (polarisConfigCustomExtensionLayer == null) {
LOGGER.debug("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps");
LOGGER.debug("[SCT Config] PolarisConfigCustomExtensionLayer is not init, ignore the following execution steps");
return;
}
polarisConfigCustomExtensionLayer.initRegisterConfig(polarisConfigPropertyAutoRefresher);
@ -139,7 +139,7 @@ public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationL
private void customRegisterPolarisConfigPublishChangeListener(PolarisPropertySource polarisPropertySource) {
if (polarisConfigCustomExtensionLayer == null) {
LOGGER.debug("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps");
LOGGER.debug("[SCT Config] PolarisConfigCustomExtensionLayer is not init, ignore the following execution steps");
return;
}
polarisConfigCustomExtensionLayer.executeRegisterPublishChangeListener(polarisPropertySource);

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-tencent</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-starter-tencent-polaris-contract</artifactId>
<name>Spring Cloud Starter Tencent Polaris Contract</name>
<dependencies>
<!-- Spring Cloud Tencent dependencies start -->
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<!-- Spring Cloud Tencent dependencies end -->
<!-- Spring cloud dependencies start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring cloud dependencies start -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<exclusions>
<exclusion>
<artifactId>swagger-models</artifactId>
<groupId>io.swagger</groupId>
</exclusion>
<exclusion>
<artifactId>swagger-annotations</artifactId>
<groupId>io.swagger</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,150 @@
/*
* 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.contract;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
import com.tencent.polaris.api.core.ProviderAPI;
import com.tencent.polaris.api.plugin.server.InterfaceDescriptor;
import com.tencent.polaris.api.plugin.server.ReportServiceContractRequest;
import com.tencent.polaris.api.plugin.server.ReportServiceContractResponse;
import io.swagger.models.HttpMethod;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import springfox.documentation.service.Documentation;
import springfox.documentation.spring.web.DocumentationCache;
import springfox.documentation.spring.web.json.JsonSerializer;
import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.lang.NonNull;
import org.springframework.util.CollectionUtils;
public class PolarisContractReporter implements ApplicationListener<ApplicationReadyEvent> {
private final Logger LOG = LoggerFactory.getLogger(PolarisContractReporter.class);
private final ServiceModelToSwagger2Mapper swagger2Mapper;
private final DocumentationCache documentationCache;
private final JsonSerializer jsonSerializer;
private final String groupName;
private final ProviderAPI providerAPI;
private final PolarisDiscoveryProperties polarisDiscoveryProperties;
public PolarisContractReporter(DocumentationCache documentationCache, ServiceModelToSwagger2Mapper swagger2Mapper,
JsonSerializer jsonSerializer, String groupName, ProviderAPI providerAPI,
PolarisDiscoveryProperties polarisDiscoveryProperties) {
this.swagger2Mapper = swagger2Mapper;
this.documentationCache = documentationCache;
this.jsonSerializer = jsonSerializer;
this.groupName = groupName;
this.providerAPI = providerAPI;
this.polarisDiscoveryProperties = polarisDiscoveryProperties;
}
@Override
public void onApplicationEvent(@NonNull ApplicationReadyEvent applicationReadyEvent) {
try {
Documentation documentation = documentationCache.documentationByGroup(groupName);
Swagger swagger = swagger2Mapper.mapDocumentation(documentation);
if (swagger != null) {
ReportServiceContractRequest request = new ReportServiceContractRequest();
request.setName(polarisDiscoveryProperties.getService());
request.setNamespace(polarisDiscoveryProperties.getNamespace());
request.setService(polarisDiscoveryProperties.getService());
request.setProtocol("http");
request.setVersion(polarisDiscoveryProperties.getVersion());
List<InterfaceDescriptor> interfaceDescriptorList = getInterfaceDescriptorFromSwagger(swagger);
request.setInterfaceDescriptors(interfaceDescriptorList);
ReportServiceContractResponse response = providerAPI.reportServiceContract(request);
LOG.info("Service contract [Namespace: {}. Name: {}. Service: {}. Protocol:{}. Version: {}. API counter: {}] is reported.",
request.getNamespace(), request.getName(), request.getService(), request.getProtocol(),
request.getVersion(), request.getInterfaceDescriptors().size());
if (LOG.isDebugEnabled()) {
String jsonValue = JacksonUtils.serialize2Json(swagger);
LOG.debug("OpenApi json data: {}", jsonValue);
}
}
else {
LOG.warn("Swagger or json is null, documentationCache keys:{}, group:{}", documentationCache.all()
.keySet(), groupName);
}
}
catch (Throwable t) {
LOG.error("Report contract failed.", t);
}
}
private List<InterfaceDescriptor> getInterfaceDescriptorFromSwagger(Swagger swagger) {
List<InterfaceDescriptor> interfaceDescriptorList = new ArrayList<>();
Map<String, Path> paths = swagger.getPaths();
for (Map.Entry<String, Path> p : paths.entrySet()) {
Path path = p.getValue();
Map<String, Operation> operationMap = getOperationMapFromPath(path);
if (CollectionUtils.isEmpty(operationMap)) {
continue;
}
for (Map.Entry<String, Operation> o : operationMap.entrySet()) {
InterfaceDescriptor interfaceDescriptor = new InterfaceDescriptor();
interfaceDescriptor.setPath(p.getKey());
interfaceDescriptor.setMethod(o.getKey());
interfaceDescriptor.setContent(JacksonUtils.serialize2Json(p.getValue()));
interfaceDescriptorList.add(interfaceDescriptor);
}
}
return interfaceDescriptorList;
}
private Map<String, Operation> getOperationMapFromPath(Path path) {
Map<String, Operation> operationMap = new HashMap<>();
if (path.getGet() != null) {
operationMap.put(HttpMethod.GET.name(), path.getGet());
}
if (path.getPut() != null) {
operationMap.put(HttpMethod.PUT.name(), path.getPut());
}
if (path.getPost() != null) {
operationMap.put(HttpMethod.POST.name(), path.getPost());
}
if (path.getHead() != null) {
operationMap.put(HttpMethod.HEAD.name(), path.getHead());
}
if (path.getDelete() != null) {
operationMap.put(HttpMethod.DELETE.name(), path.getDelete());
}
if (path.getPatch() != null) {
operationMap.put(HttpMethod.PATCH.name(), path.getPatch());
}
if (path.getOptions() != null) {
operationMap.put(HttpMethod.OPTIONS.name(), path.getOptions());
}
return operationMap;
}
}

@ -0,0 +1,35 @@
/*
* 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.contract;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener;
public class PolarisSwaggerApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent startingEvent) {
SpringApplication application = startingEvent.getSpringApplication();
Class<?> mainClass = application.getMainApplicationClass();
if (mainClass == null) {
return;
}
SwaggerContext.setAttribute(String.format("$%s", "MainClass"), mainClass);
}
}

@ -0,0 +1,36 @@
/*
* 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.contract;
import java.util.concurrent.ConcurrentHashMap;
public final class SwaggerContext {
private static final ConcurrentHashMap<String, Object> attribute = new ConcurrentHashMap<>();
private SwaggerContext() {
}
public static void setAttribute(String key, Object value) {
attribute.put(key, value);
}
public static Object getAttribute(String key) {
return attribute.get(key);
}
}

@ -0,0 +1,46 @@
/*
* 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.contract.config;
/**
* Interface for contract properties.
*
* @author Haotian Zhang
*/
public interface ContractProperties {
boolean isEnabled();
void setEnabled(boolean enabled);
String getBasePackage();
void setBasePackage(String basePackage);
String getExcludePath();
void setExcludePath(String excludePath);
String getGroup();
void setGroup(String group);
String getBasePath();
void setBasePath(String basePath);
}

@ -0,0 +1,26 @@
/*
* 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.contract.config;
/**
* Extend contract properties.
*
* @author Haotian Zhang
*/
public interface ExtendedContractProperties extends ContractProperties {
}

@ -0,0 +1,52 @@
/*
* 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.contract.config;
import java.util.List;
import com.tencent.cloud.common.constant.OrderConstant;
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
import com.tencent.polaris.factory.config.ConfigurationImpl;
import com.tencent.polaris.factory.config.provider.RegisterConfigImpl;
/**
* Modifier of service contract.
*
* @author Haotian Zhang
*/
public class PolarisContractModifier implements PolarisConfigModifier {
private final PolarisContractProperties polarisContractProperties;
public PolarisContractModifier(PolarisContractProperties polarisContractProperties) {
this.polarisContractProperties = polarisContractProperties;
}
@Override
public void modify(ConfigurationImpl configuration) {
List<RegisterConfigImpl> registerConfigs = configuration.getProvider().getRegisters();
for (RegisterConfigImpl registerConfig : registerConfigs) {
registerConfig.setReportServiceContractEnable(polarisContractProperties.isEnabled());
}
}
@Override
public int getOrder() {
return OrderConstant.Modifier.SERVICE_CONTRACT_ORDER;
}
}

@ -0,0 +1,122 @@
/*
* 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.contract.config;
import java.util.Objects;
import javax.annotation.Nullable;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Properties for Polaris contract.
*
* @author Haotian Zhang
*/
@ConfigurationProperties("spring.cloud.polaris.contract")
public class PolarisContractProperties implements ContractProperties {
private final ExtendedContractProperties extendContractProperties;
private boolean enabled = true;
/**
* Packages to be scanned. Split by ",".
*/
private String basePackage;
/**
* Paths to be excluded. Split by ",".
*/
private String excludePath;
/**
* Group to create swagger docket.
*/
private String group = "default";
/**
* Base paths to be scanned. Split by ",".
*/
private String basePath = "/**";
public PolarisContractProperties(@Nullable ExtendedContractProperties extendContractProperties) {
this.extendContractProperties = extendContractProperties;
}
@Override
public boolean isEnabled() {
if (Objects.nonNull(extendContractProperties)) {
return extendContractProperties.isEnabled();
}
return enabled;
}
@Override
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@Override
public String getBasePackage() {
if (Objects.nonNull(extendContractProperties)) {
return extendContractProperties.getBasePackage();
}
return basePackage;
}
@Override
public void setBasePackage(String basePackage) {
this.basePackage = basePackage;
}
@Override
public String getExcludePath() {
if (Objects.nonNull(extendContractProperties)) {
return extendContractProperties.getExcludePath();
}
return excludePath;
}
@Override
public void setExcludePath(String excludePath) {
this.excludePath = excludePath;
}
@Override
public String getGroup() {
if (Objects.nonNull(extendContractProperties)) {
return extendContractProperties.getGroup();
}
return group;
}
@Override
public void setGroup(String group) {
this.group = group;
}
@Override
public String getBasePath() {
if (Objects.nonNull(extendContractProperties)) {
return extendContractProperties.getBasePath();
}
return basePath;
}
@Override
public void setBasePath(String basePath) {
this.basePath = basePath;
}
}

@ -0,0 +1,48 @@
/*
* 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.contract.config;
import javax.annotation.Nullable;
import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Auto configuration for Polaris contract properties.
*
* @author Haotian Zhang
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnPolarisEnabled
public class PolarisContractPropertiesAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public PolarisContractProperties polarisContractProperties(@Nullable ExtendedContractProperties extendedContractProperties) {
return new PolarisContractProperties(extendedContractProperties);
}
@Bean
@ConditionalOnMissingBean
public PolarisContractModifier polarisContractModifier(PolarisContractProperties polarisContractProperties) {
return new PolarisContractModifier(polarisContractProperties);
}
}

@ -0,0 +1,34 @@
/*
* 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.contract.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* Bootstrap configuration for Polaris contract properties.
*
* @author Haotian Zhang
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty("spring.cloud.polaris.enabled")
@Import(PolarisContractPropertiesAutoConfiguration.class)
public class PolarisContractPropertiesBootstrapConfiguration {
}

@ -0,0 +1,147 @@
/*
* 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.contract.config;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.function.Predicate;
import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled;
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
import com.tencent.cloud.polaris.contract.PolarisContractReporter;
import com.tencent.cloud.polaris.contract.PolarisSwaggerApplicationListener;
import com.tencent.cloud.polaris.contract.utils.PackageUtil;
import springfox.boot.starter.autoconfigure.OpenApiAutoConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.DocumentationCache;
import springfox.documentation.spring.web.json.JsonSerializer;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration(proxyBeanMethods = false)
@ConditionalOnPolarisEnabled
@ConditionalOnProperty(name = "spring.cloud.polaris.contract.enabled", havingValue = "true", matchIfMissing = true)
@Import(OpenApiAutoConfiguration.class)
public class PolarisSwaggerAutoConfiguration {
static {
// After springboot2.6.x, the default path matching strategy of spring MVC is changed from ANT_PATH_MATCHER
// mode to PATH_PATTERN_PARSER mode, causing an error. The solution is to switch to the original ANT_PATH_MATCHER mode.
System.setProperty("spring.mvc.pathmatch.matching-strategy", "ant-path-matcher");
}
@Bean
public Docket polarisDocket(PolarisContractProperties polarisContractProperties) {
List<Predicate<String>> excludePathList = PackageUtil.getExcludePathPredicates(polarisContractProperties.getExcludePath());
List<Predicate<String>> basePathList = PackageUtil.getBasePathPredicates(polarisContractProperties.getBasePath());
String basePackage = PackageUtil.scanPackage(polarisContractProperties.getBasePackage());
Predicate<String> basePathListOr = null;
for (Predicate<String> basePathPredicate : basePathList) {
if (basePathListOr == null) {
basePathListOr = basePathPredicate;
}
else {
basePathListOr = basePathListOr.or(basePathPredicate);
}
}
Predicate<String> excludePathListOr = null;
for (Predicate<String> excludePathPredicate : excludePathList) {
if (excludePathListOr == null) {
excludePathListOr = excludePathPredicate;
}
else {
excludePathListOr = excludePathListOr.or(excludePathPredicate);
}
}
Predicate<String> pathsPredicate = basePathListOr;
if (excludePathListOr != null) {
excludePathListOr = excludePathListOr.negate();
pathsPredicate = pathsPredicate.and(excludePathListOr);
}
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(PackageUtil.basePackage(basePackage))
.paths(pathsPredicate)
.build()
.groupName(polarisContractProperties.getGroup())
.enable(polarisContractProperties.isEnabled())
.directModelSubstitute(LocalDate.class, Date.class)
.apiInfo(new ApiInfoBuilder()
.title("Polaris Swagger API")
.description("This is to show polaris api description.")
.license("BSD-3-Clause")
.licenseUrl("https://opensource.org/licenses/BSD-3-Clause")
.termsOfServiceUrl("")
.version("1.0.0")
.contact(new Contact("", "", ""))
.build());
}
@Bean
@ConditionalOnBean(Docket.class)
@ConditionalOnMissingBean
public PolarisContractReporter polarisApiMetadataGrapher(DocumentationCache documentationCache,
ServiceModelToSwagger2Mapper swagger2Mapper, JsonSerializer jsonSerializer,
PolarisContractProperties polarisContractProperties, PolarisSDKContextManager polarisSDKContextManager,
PolarisDiscoveryProperties polarisDiscoveryProperties) {
return new PolarisContractReporter(documentationCache, swagger2Mapper, jsonSerializer,
polarisContractProperties.getGroup(), polarisSDKContextManager.getProviderAPI(), polarisDiscoveryProperties);
}
@Bean
@ConditionalOnMissingBean
public PolarisSwaggerApplicationListener polarisSwaggerApplicationListener() {
return new PolarisSwaggerApplicationListener();
}
/**
* Create when web application type is SERVLET.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
protected static class SwaggerServletConfig {
}
/**
* Create when web application type is REACTIVE.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
protected static class SwaggerReactiveConfig {
}
}

@ -0,0 +1,214 @@
/*
* 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.contract.utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.tencent.cloud.polaris.contract.SwaggerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.PathSelectors;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.util.StringUtils;
import static com.google.common.base.Optional.fromNullable;
/**
* Util for package processing.
*
* @author Haotian Zhang
*/
public final class PackageUtil {
private static final Logger LOG = LoggerFactory.getLogger(PackageUtil.class);
private static final String SPLITTER = ",";
private PackageUtil() {
}
public static Predicate<RequestHandler> basePackage(String basePackage) {
return input -> declaringClass(input).transform(handlerPackage(basePackage, SPLITTER)).or(false);
}
public static Optional<Class<?>> declaringClass(RequestHandler input) {
if (input == null) {
return Optional.absent();
}
return fromNullable(input.declaringClass());
}
public static Function<Class<?>, Boolean> handlerPackage(String basePackage, String splitter) {
return input -> {
try {
if (StringUtils.isEmpty(basePackage)) {
return false;
}
String[] packages = basePackage.trim().split(splitter);
// Loop to determine matching
for (String strPackage : packages) {
if (input == null) {
continue;
}
Package pkg = input.getPackage();
if (pkg == null) {
continue;
}
String name = pkg.getName();
if (StringUtils.isEmpty(name)) {
continue;
}
boolean isMatch = name.startsWith(strPackage);
if (isMatch) {
return true;
}
}
}
catch (Exception e) {
LOG.error("handler package error", e);
}
return false;
};
}
public static List<Predicate<String>> getExcludePathPredicates(String excludePath) {
List<Predicate<String>> excludePathList = new ArrayList<>();
if (StringUtils.isEmpty(excludePath)) {
return excludePathList;
}
String[] exs = excludePath.split(SPLITTER);
for (String ex : exs) {
if (!StringUtils.isEmpty(ex)) {
excludePathList.add(PathSelectors.ant(ex));
}
}
return excludePathList;
}
public static List<Predicate<String>> getBasePathPredicates(String basePath) {
List<Predicate<String>> basePathList = new ArrayList<>();
if (!StringUtils.isEmpty(basePath)) {
String[] bps = basePath.split(SPLITTER);
for (String bp : bps) {
if (!StringUtils.isEmpty(bp)) {
basePathList.add(PathSelectors.ant(bp));
}
}
}
if (basePathList.isEmpty()) {
basePathList.add(PathSelectors.ant("/**"));
}
return basePathList;
}
public static String scanPackage(String configBasePackage) {
String validScanPackage;
// Externally configured scan package
Set<String> configPackageSet = new HashSet<>();
if (!StringUtils.isEmpty(configBasePackage)) {
configPackageSet.addAll(Arrays.asList(configBasePackage.split(SPLITTER)));
}
Object mainClz = SwaggerContext.getAttribute(String.format("$%s", "MainClass"));
// Verification of the valid path of MainClass
if (mainClz != null) {
Set<String> autoDetectPackageSet = parseDefaultScanPackage((Class<?>) mainClz);
if (LOG.isInfoEnabled() && !autoDetectPackageSet.isEmpty()) {
LOG.info("Auto detect default swagger scan packages: {}",
String.join(SPLITTER, autoDetectPackageSet).trim());
}
Set<String> validScanPackageSet = merge(configPackageSet, autoDetectPackageSet);
validScanPackage = String.join(SPLITTER, validScanPackageSet).trim();
if (LOG.isInfoEnabled() && !StringUtils.isEmpty(validScanPackage)) {
LOG.info("Swagger scan valid packages: {}", validScanPackage);
}
}
else {
// If there is no MainClass, the configured path is used for scanning
validScanPackage = String.join(SPLITTER, configPackageSet);
if (LOG.isWarnEnabled()) {
LOG.warn("Cannot detect main class, swagger scanning packages is set to: {}",
validScanPackage);
}
}
return validScanPackage;
}
public static Set<String> merge(Set<String> configPackageSet, Set<String> autoDetectPackageSet) {
if (configPackageSet == null || configPackageSet.size() == 0) {
return autoDetectPackageSet;
}
return configPackageSet;
}
public static Set<String> parseDefaultScanPackage(Class<?> mainClass) {
Set<String> packageSets = new HashSet<>();
String defaultPackage = mainClass.getPackage().getName();
try {
boolean springBootEnv = true;
try {
Class.forName("org.springframework.boot.autoconfigure.SpringBootApplication");
}
catch (Throwable t) {
LOG.info("Can not load annotation @SpringBootApplication, " +
"current environment is not in spring boot framework. ");
springBootEnv = false;
}
if (!springBootEnv) {
packageSets.add(defaultPackage);
return packageSets;
}
SpringBootApplication bootAnnotation = mainClass.getAnnotation(SpringBootApplication.class);
Class<?>[] baseClassPackages;
String[] basePackages;
if (bootAnnotation == null) {
packageSets.add(defaultPackage);
}
else {
// baseClassPackages annotation
baseClassPackages = bootAnnotation.scanBasePackageClasses();
for (Class<?> clz : baseClassPackages) {
packageSets.add(clz.getPackage().getName());
}
// basePackage annotation
basePackages = bootAnnotation.scanBasePackages();
packageSets.addAll(Arrays.asList(basePackages));
// When basePackage and baseClassPackages are both empty, the package path where the MainClass class is located is used by default.
if (packageSets.isEmpty()) {
packageSets.add(defaultPackage);
}
}
}
catch (Throwable t) {
LOG.warn("Swagger scan package is empty and auto detect main class occur exception: {}",
t.getMessage());
}
return packageSets;
}
}

@ -0,0 +1,90 @@
/*
*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 springfox.documentation.spring.web;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import static springfox.documentation.spring.web.paths.Paths.maybeChompLeadingSlash;
import static springfox.documentation.spring.web.paths.Paths.maybeChompTrailingSlash;
/**
* Modified to be compatible with spring-boot-actuator.
*/
public class WebMvcPatternsRequestConditionWrapper
implements springfox.documentation.spring.wrapper.PatternsRequestCondition<PatternsRequestCondition> {
private final String contextPath;
private final PatternsRequestCondition condition;
public WebMvcPatternsRequestConditionWrapper(
String contextPath,
PatternsRequestCondition condition) {
this.contextPath = contextPath;
this.condition = condition;
}
@Override
public springfox.documentation.spring.wrapper.PatternsRequestCondition combine(
springfox.documentation.spring.wrapper.PatternsRequestCondition<PatternsRequestCondition> other) {
if (other instanceof WebMvcPatternsRequestConditionWrapper && !this.equals(other)) {
return new WebMvcPatternsRequestConditionWrapper(
contextPath,
condition.combine(((WebMvcPatternsRequestConditionWrapper) other).condition));
}
return this;
}
@Override
public Set<String> getPatterns() {
// polaris add start
if (this.condition == null) {
return new HashSet<>();
}
// polaris add end
return this.condition.getPatterns().stream()
.map(p -> String.format("%s/%s", maybeChompTrailingSlash(contextPath), maybeChompLeadingSlash(p)))
.collect(Collectors.toSet());
}
@Override
public boolean equals(Object o) {
if (o instanceof WebMvcPatternsRequestConditionWrapper) {
return this.condition.equals(((WebMvcPatternsRequestConditionWrapper) o).condition);
}
return false;
}
@Override
public int hashCode() {
return this.condition.hashCode();
}
@Override
public String toString() {
return this.condition.toString();
}
}

@ -0,0 +1,175 @@
/*
*
* Copyright 2016-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 springfox.documentation.spring.web;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;
import com.fasterxml.classmate.ResolvedType;
import springfox.documentation.RequestHandler;
import springfox.documentation.RequestHandlerKey;
import springfox.documentation.service.ResolvedMethodParameter;
import springfox.documentation.spring.web.readers.operation.HandlerMethodResolver;
import springfox.documentation.spring.wrapper.NameValueExpression;
import springfox.documentation.spring.wrapper.PatternsRequestCondition;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import static java.util.Optional.ofNullable;
/**
* Modified to be compatible with spring-boot-actuator.
*/
public class WebMvcRequestHandler implements RequestHandler {
private final String contextPath;
private final HandlerMethodResolver methodResolver;
private final RequestMappingInfo requestMapping;
private final HandlerMethod handlerMethod;
public WebMvcRequestHandler(
String contextPath,
HandlerMethodResolver methodResolver,
RequestMappingInfo requestMapping,
HandlerMethod handlerMethod) {
this.contextPath = contextPath;
this.methodResolver = methodResolver;
this.requestMapping = requestMapping;
this.handlerMethod = handlerMethod;
}
@Override
public HandlerMethod getHandlerMethod() {
return handlerMethod;
}
@Override
public RequestHandler combine(RequestHandler other) {
return this;
}
@Override
public Class<?> declaringClass() {
return handlerMethod.getBeanType();
}
@Override
public boolean isAnnotatedWith(Class<? extends Annotation> annotation) {
return null != AnnotationUtils.findAnnotation(handlerMethod.getMethod(), annotation);
}
@Override
public PatternsRequestCondition getPatternsCondition() {
return new WebMvcPatternsRequestConditionWrapper(
contextPath,
requestMapping.getPatternsCondition());
}
@Override
public String groupName() {
return ControllerNamingUtils.controllerNameAsGroup(handlerMethod);
}
@Override
public String getName() {
return handlerMethod.getMethod().getName();
}
@Override
public Set<RequestMethod> supportedMethods() {
return requestMapping.getMethodsCondition().getMethods();
}
@Override
public Set<MediaType> produces() {
return requestMapping.getProducesCondition().getProducibleMediaTypes();
}
@Override
public Set<MediaType> consumes() {
return requestMapping.getConsumesCondition().getConsumableMediaTypes();
}
@Override
public Set<NameValueExpression<String>> headers() {
return WebMvcNameValueExpressionWrapper.from(requestMapping.getHeadersCondition().getExpressions());
}
@Override
public Set<NameValueExpression<String>> params() {
return WebMvcNameValueExpressionWrapper.from(requestMapping.getParamsCondition().getExpressions());
}
@Override
public <T extends Annotation> Optional<T> findAnnotation(Class<T> annotation) {
return ofNullable(AnnotationUtils.findAnnotation(handlerMethod.getMethod(), annotation));
}
@Override
public RequestHandlerKey key() {
// polaris add start
Set<String> patterns = new HashSet<>();
if (requestMapping.getPatternsCondition() != null && requestMapping.getPatternsCondition()
.getPatterns() != null) {
patterns = requestMapping.getPatternsCondition().getPatterns();
}
// polaris add end
return new RequestHandlerKey(
patterns,
requestMapping.getMethodsCondition().getMethods(),
requestMapping.getConsumesCondition().getConsumableMediaTypes(),
requestMapping.getProducesCondition().getProducibleMediaTypes());
}
@Override
public springfox.documentation.spring.wrapper.RequestMappingInfo<?> getRequestMapping() {
return new WebMvcRequestMappingInfoWrapper(requestMapping);
}
@Override
public List<ResolvedMethodParameter> getParameters() {
return methodResolver.methodParameters(handlerMethod);
}
@Override
public ResolvedType getReturnType() {
return methodResolver.methodReturnType(handlerMethod);
}
@Override
public <T extends Annotation> Optional<T> findControllerAnnotation(Class<T> annotation) {
return ofNullable(AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), annotation));
}
@Override
public String toString() {
return new StringJoiner(", ", WebMvcRequestHandler.class.getSimpleName() + "{", "}")
.add("requestMapping=" + requestMapping)
.add("handlerMethod=" + handlerMethod)
.add("key=" + key())
.toString();
}
}

@ -0,0 +1,7 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.tencent.cloud.polaris.contract.config.PolarisSwaggerAutoConfiguration,\
com.tencent.cloud.polaris.contract.config.PolarisContractProperties
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.tencent.cloud.polaris.contract.config.PolarisContractPropertiesAutoConfiguration
org.springframework.context.ApplicationListener=\
com.tencent.cloud.polaris.contract.PolarisSwaggerApplicationListener

@ -64,7 +64,7 @@ public class PolarisDiscoveryProperties {
/**
* Version number.
*/
private String version;
private String version = "1.0.0";
/**
* Protocol name such as http, https.

@ -171,5 +171,10 @@ public class OrderConstant {
* Order of stat reporter configuration modifier.
*/
public static Integer STAT_REPORTER_ORDER = 1;
/**
* Order of service contract configuration modifier.
*/
public static Integer SERVICE_CONTRACT_ORDER = Integer.MAX_VALUE - 9;
}
}

@ -64,10 +64,14 @@
<artifactId>spring-cloud-starter-tencent-polaris-config</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-contract</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-discovery-adapter-plugin</artifactId>
<version>${revision}</version>
</dependency>
<dependency>

@ -76,6 +76,8 @@
<polaris.version>1.15.0-SNAPSHOT</polaris.version>
<guava.version>32.0.1-jre</guava.version>
<logback.version>1.2.11</logback.version>
<springfox.swagger2.version>3.0.0</springfox.swagger2.version>
<io.swagger.version>1.5.24</io.swagger.version>
<mocktio.version>4.5.1</mocktio.version>
<byte-buddy.version>1.12.10</byte-buddy.version>
<protobuf-java.version>3.21.7</protobuf-java.version>
@ -154,6 +156,12 @@
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-contract</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-all</artifactId>
@ -212,6 +220,24 @@
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${springfox.swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>${io.swagger.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${io.swagger.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>

@ -28,6 +28,11 @@
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-contract</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.tencent.polaris</groupId>-->
<!-- <artifactId>connector-consul</artifactId>-->

@ -45,7 +45,7 @@ public class DiscoveryCallerController {
* @param value2 value 2
* @return sum
*/
@GetMapping("/feign")
@RequestMapping("/feign")
public int feign(@RequestParam int value1, @RequestParam int value2) {
return discoveryCalleeService.sum(value1, value2);
}

@ -30,12 +30,6 @@ import com.tencent.cloud.rpc.enhancement.filter.EnhancedServletFilter;
import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientExceptionHook;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPostHook;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPreHook;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerExceptionHook;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPostHook;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPreHook;
import com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter;
import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter;
import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateInterceptor;
@ -115,36 +109,6 @@ public class RpcEnhancementAutoConfiguration {
return new ExceptionPolarisReporter(properties, polarisSDKContextManager.getConsumerAPI());
}
@Bean
public AssemblyClientExceptionHook assemblyClientExceptionHook(PolarisSDKContextManager polarisSDKContextManager, InstanceTransformer instanceTransformer) {
return new AssemblyClientExceptionHook(polarisSDKContextManager.getAssemblyAPI(), instanceTransformer);
}
@Bean
public AssemblyClientPostHook assemblyClientPostHook(PolarisSDKContextManager polarisSDKContextManager, InstanceTransformer instanceTransformer) {
return new AssemblyClientPostHook(polarisSDKContextManager.getAssemblyAPI(), instanceTransformer);
}
@Bean
public AssemblyClientPreHook assemblyClientPreHook(PolarisSDKContextManager polarisSDKContextManager) {
return new AssemblyClientPreHook(polarisSDKContextManager.getAssemblyAPI());
}
@Bean
public AssemblyServerExceptionHook assemblyServerExceptionHook(PolarisSDKContextManager polarisSDKContextManager) {
return new AssemblyServerExceptionHook(polarisSDKContextManager.getAssemblyAPI());
}
@Bean
public AssemblyServerPostHook assemblyServerPostHook(PolarisSDKContextManager polarisSDKContextManager) {
return new AssemblyServerPostHook(polarisSDKContextManager.getAssemblyAPI());
}
@Bean
public AssemblyServerPreHook assemblyServerPreHook(PolarisSDKContextManager polarisSDKContextManager) {
return new AssemblyServerPreHook(polarisSDKContextManager.getAssemblyAPI());
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
protected static class RpcEnhancementServletFilterConfig {

@ -44,27 +44,5 @@ public class PluginOrderConstant {
* {@link com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter}.
*/
public static final int CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 2;
/**
* order for
* {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPreHook}
* and
* {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPostHook}
* and
* {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientExceptionHook}.
*/
public static final int ASSEMBLY_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 3;
}
public static class ServerPluginOrder {
/**
* order for
* {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPreHook}
* and
* {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPostHook}
* and
* {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerExceptionHook}.
*/
public static final int ASSEMBLY_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 1;
}
}

@ -1,56 +0,0 @@
/*
* 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.plugin.assembly;
import com.tencent.polaris.api.pojo.ServiceKey;
import com.tencent.polaris.api.rpc.MetadataProvider;
import org.springframework.cloud.client.ServiceInstance;
/**
* AssemblyMetadataProvider.
*
* @author sean yu
*/
public class AssemblyMetadataProvider implements MetadataProvider {
private final ServiceInstance serviceInstance;
private final String namespace;
public AssemblyMetadataProvider(ServiceInstance localServiceInstance, String namespace) {
this.serviceInstance = localServiceInstance;
this.namespace = namespace;
}
@Override
public String getMetadata(String key) {
return serviceInstance.getMetadata().get(key);
}
@Override
public ServiceKey getLocalService() {
return new ServiceKey(namespace, serviceInstance.getServiceId());
}
@Override
public String getLocalIp() {
return serviceInstance.getHost();
}
}

@ -1,126 +0,0 @@
/*
* 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.plugin.assembly;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import com.google.common.net.HttpHeaders;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
import com.tencent.polaris.api.pojo.ServiceKey;
import com.tencent.polaris.api.rpc.RequestContext;
import org.springframework.http.HttpMethod;
/**
* AssemblyRequestContext.
*
* @author sean yu
*/
public class AssemblyRequestContext implements RequestContext {
private final EnhancedRequestContext requestContext;
private final ServiceKey callerService;
private final String callerIp;
private final Map<String, String> cookies;
public AssemblyRequestContext(EnhancedRequestContext requestContext, ServiceKey callerService, String callerIp) {
this.requestContext = requestContext;
this.callerService = callerService;
this.callerIp = callerIp;
this.cookies = new HashMap<>();
List<String> allCookies =
Optional.ofNullable(requestContext.getHttpHeaders().get(HttpHeaders.COOKIE))
.orElse(new ArrayList<>())
.stream()
.flatMap(it -> Arrays.stream(it.split(";")))
.collect(Collectors.toList());
allCookies.forEach(cookie -> {
String[] cookieKV = cookie.split("=");
if (cookieKV.length == 2) {
cookies.put(cookieKV[0], cookieKV[1]);
}
});
}
@Override
public String getMethod() {
return requestContext.getHttpMethod().name();
}
@Override
public void setMethod(String method) {
requestContext.setHttpMethod(HttpMethod.valueOf(method));
}
@Override
public String getHeader(String key) {
return requestContext.getHttpHeaders().getFirst(key);
}
@Override
public void setHeader(String key, String value) {
requestContext.getHttpHeaders().set(key, value);
}
@Override
public Collection<String> listHeaderKeys() {
return requestContext.getHttpHeaders().keySet();
}
@Override
public String getCookie(String key) {
return this.cookies.get(key);
}
@Override
public void setCookie(String key, String value) {
this.cookies.put(key, value);
}
@Override
public Collection<String> listCookieKeys() {
return this.cookies.keySet();
}
@Override
public String getCallerIp() {
return callerIp;
}
@Override
public ServiceKey getCallerService() {
return callerService;
}
@Override
public URI getURI() {
return requestContext.getUrl();
}
}

@ -1,87 +0,0 @@
/*
* 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.plugin.assembly;
import java.util.Collection;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils;
import com.tencent.polaris.api.pojo.RetStatus;
import com.tencent.polaris.api.rpc.ResponseContext;
import org.springframework.lang.Nullable;
/**
* AssemblyResponseContext.
*
* @author sean yu
*/
public class AssemblyResponseContext implements ResponseContext {
private final EnhancedResponseContext responseContext;
private final Throwable throwable;
private final RetStatus retStatus;
public AssemblyResponseContext(@Nullable EnhancedResponseContext responseContext, @Nullable Throwable throwable) {
this.responseContext = responseContext;
this.throwable = throwable;
if (responseContext == null) {
this.retStatus = PolarisEnhancedPluginUtils.getRetStatusFromRequest(null, null, throwable);
}
else {
this.retStatus = PolarisEnhancedPluginUtils.getRetStatusFromRequest(responseContext.getHttpHeaders(), responseContext.getHttpStatus(), throwable);
}
}
@Override
public Object getRetCode() {
if (responseContext == null) {
return null;
}
return this.responseContext.getHttpStatus();
}
@Override
public String getHeader(String key) {
if (responseContext == null) {
return null;
}
return this.responseContext.getHttpHeaders().getFirst(key);
}
@Override
public Collection<String> listHeaders() {
if (responseContext == null) {
return null;
}
return this.responseContext.getHttpHeaders().keySet();
}
@Override
public Throwable getThrowable() {
return this.throwable;
}
@Override
public RetStatus getRetStatus() {
return this.retStatus;
}
}

@ -1,82 +0,0 @@
/*
* 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.plugin.assembly.client;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyResponseContext;
import com.tencent.cloud.rpc.enhancement.transformer.InstanceTransformer;
import com.tencent.polaris.api.pojo.ServiceKey;
import com.tencent.polaris.assembly.api.AssemblyAPI;
import com.tencent.polaris.assembly.api.pojo.AfterRequest;
import com.tencent.polaris.assembly.api.pojo.Capability;
import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.ASSEMBLY_PLUGIN_ORDER;
/**
* AssemblyClientExceptionHook.
*
* @author sean yu
*/
public class AssemblyClientExceptionHook implements EnhancedPlugin {
private final AssemblyAPI assemblyAPI;
private final InstanceTransformer instanceTransformer;
public AssemblyClientExceptionHook(AssemblyAPI assemblyAPI, InstanceTransformer instanceTransformer) {
this.assemblyAPI = assemblyAPI;
this.instanceTransformer = instanceTransformer;
}
@Override
public EnhancedPluginType getType() {
return EnhancedPluginType.Client.EXCEPTION;
}
@Override
public void run(EnhancedPluginContext context) {
AfterRequest afterRequest = new AfterRequest();
afterRequest.setCapabilities(new Capability[]{Capability.ALL});
afterRequest.setRequestContext(new AssemblyRequestContext(
context.getRequest(),
new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getLocalServiceInstance().getServiceId()),
context.getLocalServiceInstance().getHost()
));
afterRequest.setResponseContext(new AssemblyResponseContext(null, context.getThrowable()));
afterRequest.setMetadataProvider(new AssemblyMetadataProvider(context.getLocalServiceInstance(), MetadataContext.LOCAL_NAMESPACE));
afterRequest.setDelay(context.getDelay());
afterRequest.setRouteLabels(PolarisEnhancedPluginUtils.getLabelMap(context.getRequest().getHttpHeaders()));
// TargetService and TargetInstance only exist in client side
afterRequest.setTargetService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getTargetServiceInstance().getServiceId()));
afterRequest.setTargetInstance(instanceTransformer.transform(context.getTargetServiceInstance()));
assemblyAPI.afterCallService(afterRequest);
}
@Override
public int getOrder() {
return ASSEMBLY_PLUGIN_ORDER;
}
}

@ -1,83 +0,0 @@
/*
* 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.plugin.assembly.client;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyResponseContext;
import com.tencent.cloud.rpc.enhancement.transformer.InstanceTransformer;
import com.tencent.polaris.api.pojo.ServiceKey;
import com.tencent.polaris.assembly.api.AssemblyAPI;
import com.tencent.polaris.assembly.api.pojo.AfterRequest;
import com.tencent.polaris.assembly.api.pojo.Capability;
import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.ASSEMBLY_PLUGIN_ORDER;
/**
* AssemblyClientPostHook.
*
* @author sean yu
*/
public class AssemblyClientPostHook implements EnhancedPlugin {
private final AssemblyAPI assemblyAPI;
private final InstanceTransformer instanceTransformer;
public AssemblyClientPostHook(AssemblyAPI assemblyAPI, InstanceTransformer instanceTransformer) {
this.assemblyAPI = assemblyAPI;
this.instanceTransformer = instanceTransformer;
}
@Override
public EnhancedPluginType getType() {
return EnhancedPluginType.Client.POST;
}
@Override
public void run(EnhancedPluginContext context) {
AfterRequest afterRequest = new AfterRequest();
afterRequest.setCapabilities(new Capability[]{Capability.ALL});
afterRequest.setRequestContext(new AssemblyRequestContext(
context.getRequest(),
new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getLocalServiceInstance().getServiceId()),
context.getLocalServiceInstance().getHost()
));
afterRequest.setResponseContext(new AssemblyResponseContext(context.getResponse(), null));
afterRequest.setMetadataProvider(new AssemblyMetadataProvider(context.getLocalServiceInstance(), MetadataContext.LOCAL_NAMESPACE));
afterRequest.setDelay(context.getDelay());
afterRequest.setRouteLabels(PolarisEnhancedPluginUtils.getLabelMap(context.getRequest().getHttpHeaders()));
// TargetService and TargetInstance only exist in client side
afterRequest.setTargetService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getTargetServiceInstance().getServiceId()));
afterRequest.setTargetInstance(instanceTransformer.transform(context.getTargetServiceInstance()));
assemblyAPI.afterCallService(afterRequest);
}
@Override
public int getOrder() {
return ASSEMBLY_PLUGIN_ORDER;
}
}

@ -1,73 +0,0 @@
/*
* 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.plugin.assembly.client;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext;
import com.tencent.polaris.api.pojo.ServiceKey;
import com.tencent.polaris.assembly.api.AssemblyAPI;
import com.tencent.polaris.assembly.api.pojo.BeforeRequest;
import com.tencent.polaris.assembly.api.pojo.Capability;
import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.ASSEMBLY_PLUGIN_ORDER;
/**
* AssemblyClientPreHook.
*
* @author sean yu
*/
public class AssemblyClientPreHook implements EnhancedPlugin {
private final AssemblyAPI assemblyAPI;
public AssemblyClientPreHook(AssemblyAPI assemblyAPI) {
this.assemblyAPI = assemblyAPI;
}
@Override
public EnhancedPluginType getType() {
return EnhancedPluginType.Client.PRE;
}
@Override
public void run(EnhancedPluginContext context) {
BeforeRequest beforeRequest = new BeforeRequest();
beforeRequest.setCapabilities(new Capability[]{Capability.ALL});
beforeRequest.setRequestContext(new AssemblyRequestContext(
context.getRequest(),
new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getLocalServiceInstance().getServiceId()),
context.getLocalServiceInstance().getHost()
));
beforeRequest.setMetadataProvider(new AssemblyMetadataProvider(context.getLocalServiceInstance(), MetadataContext.LOCAL_NAMESPACE));
// TargetService only exist in client side
beforeRequest.setTargetService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getTargetServiceInstance().getServiceId()));
assemblyAPI.beforeCallService(beforeRequest);
}
@Override
public int getOrder() {
return ASSEMBLY_PLUGIN_ORDER;
}
}

@ -1,76 +0,0 @@
/*
* 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.plugin.assembly.server;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyResponseContext;
import com.tencent.polaris.api.pojo.ServiceKey;
import com.tencent.polaris.assembly.api.AssemblyAPI;
import com.tencent.polaris.assembly.api.pojo.AfterRequest;
import com.tencent.polaris.assembly.api.pojo.Capability;
import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ServerPluginOrder.ASSEMBLY_PLUGIN_ORDER;
/**
* AssemblyServerExceptionHook.
*
* @author sean yu
*/
public class AssemblyServerExceptionHook implements EnhancedPlugin {
private final AssemblyAPI assemblyAPI;
public AssemblyServerExceptionHook(AssemblyAPI assemblyAPI) {
this.assemblyAPI = assemblyAPI;
}
@Override
public EnhancedPluginType getType() {
return EnhancedPluginType.Server.EXCEPTION;
}
@Override
public void run(EnhancedPluginContext context) {
AfterRequest afterRequest = new AfterRequest();
afterRequest.setCapabilities(new Capability[]{Capability.ALL});
afterRequest.setRequestContext(new AssemblyRequestContext(
context.getRequest(),
new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getLocalServiceInstance().getServiceId()),
context.getLocalServiceInstance().getHost()
));
afterRequest.setResponseContext(new AssemblyResponseContext(null, context.getThrowable()));
afterRequest.setMetadataProvider(new AssemblyMetadataProvider(context.getLocalServiceInstance(), MetadataContext.LOCAL_NAMESPACE));
afterRequest.setDelay(context.getDelay());
afterRequest.setRouteLabels(PolarisEnhancedPluginUtils.getLabelMap(context.getRequest().getHttpHeaders()));
assemblyAPI.afterProcess(afterRequest);
}
@Override
public int getOrder() {
return ASSEMBLY_PLUGIN_ORDER;
}
}

@ -1,75 +0,0 @@
/*
* 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.plugin.assembly.server;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyResponseContext;
import com.tencent.polaris.api.pojo.ServiceKey;
import com.tencent.polaris.assembly.api.AssemblyAPI;
import com.tencent.polaris.assembly.api.pojo.AfterRequest;
import com.tencent.polaris.assembly.api.pojo.Capability;
import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ServerPluginOrder.ASSEMBLY_PLUGIN_ORDER;
/**
* AssemblyServerPostHook.
*
* @author sean yu
*/
public class AssemblyServerPostHook implements EnhancedPlugin {
private final AssemblyAPI assemblyAPI;
public AssemblyServerPostHook(AssemblyAPI assemblyAPI) {
this.assemblyAPI = assemblyAPI;
}
@Override
public EnhancedPluginType getType() {
return EnhancedPluginType.Server.POST;
}
@Override
public void run(EnhancedPluginContext context) {
AfterRequest afterRequest = new AfterRequest();
afterRequest.setCapabilities(new Capability[]{Capability.ALL});
afterRequest.setRequestContext(new AssemblyRequestContext(
context.getRequest(),
new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getLocalServiceInstance().getServiceId()),
context.getLocalServiceInstance().getHost()
));
afterRequest.setResponseContext(new AssemblyResponseContext(context.getResponse(), null));
afterRequest.setMetadataProvider(new AssemblyMetadataProvider(context.getLocalServiceInstance(), MetadataContext.LOCAL_NAMESPACE));
afterRequest.setDelay(context.getDelay());
afterRequest.setRouteLabels(PolarisEnhancedPluginUtils.getLabelMap(context.getRequest().getHttpHeaders()));
assemblyAPI.afterProcess(afterRequest);
}
@Override
public int getOrder() {
return ASSEMBLY_PLUGIN_ORDER;
}
}

@ -1,70 +0,0 @@
/*
* 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.plugin.assembly.server;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext;
import com.tencent.polaris.api.pojo.ServiceKey;
import com.tencent.polaris.assembly.api.AssemblyAPI;
import com.tencent.polaris.assembly.api.pojo.BeforeRequest;
import com.tencent.polaris.assembly.api.pojo.Capability;
import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ServerPluginOrder.ASSEMBLY_PLUGIN_ORDER;
/**
* AssemblyServerPreHook.
*
* @author sean yu
*/
public class AssemblyServerPreHook implements EnhancedPlugin {
private final AssemblyAPI assemblyAPI;
public AssemblyServerPreHook(AssemblyAPI assemblyAPI) {
this.assemblyAPI = assemblyAPI;
}
@Override
public EnhancedPluginType getType() {
return EnhancedPluginType.Server.PRE;
}
@Override
public void run(EnhancedPluginContext context) {
BeforeRequest beforeRequest = new BeforeRequest();
beforeRequest.setCapabilities(new Capability[]{Capability.ALL});
beforeRequest.setRequestContext(new AssemblyRequestContext(
context.getRequest(),
new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getLocalServiceInstance().getServiceId()),
context.getLocalServiceInstance().getHost()
));
beforeRequest.setMetadataProvider(new AssemblyMetadataProvider(context.getLocalServiceInstance(), MetadataContext.LOCAL_NAMESPACE));
assemblyAPI.beforeProcess(beforeRequest);
}
@Override
public int getOrder() {
return ASSEMBLY_PLUGIN_ORDER;
}
}

@ -1,146 +0,0 @@
/*
* 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.plugin;
import java.net.URI;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientExceptionHook;
import com.tencent.cloud.rpc.enhancement.transformer.InstanceTransformer;
import com.tencent.polaris.assembly.api.AssemblyAPI;
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.cloud.client.DefaultServiceInstance;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
/**
* AssemblyClientExceptionHookTest.
*
* @author sean yu
*/
@ExtendWith(MockitoExtension.class)
public class AssemblyClientExceptionHookTest {
private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
@InjectMocks
private AssemblyClientExceptionHook assemblyClientExceptionHook;
@Mock
private AssemblyAPI assemblyAPI;
@Mock
private InstanceTransformer instanceTransformer;
@BeforeAll
static void beforeAll() {
mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
.thenReturn("unit-test");
ApplicationContext applicationContext = mock(ApplicationContext.class);
RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class);
doReturn(reporterProperties)
.when(applicationContext).getBean(RpcEnhancementReporterProperties.class);
mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext)
.thenReturn(applicationContext);
}
@AfterAll
static void afterAll() {
mockedApplicationContextAwareUtils.close();
}
@BeforeEach
void setUp() {
MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
}
@Test
public void testGetName() {
assertThat(assemblyClientExceptionHook.getName()).isEqualTo(AssemblyClientExceptionHook.class.getName());
}
@Test
public void testType() {
assertThat(assemblyClientExceptionHook.getType()).isEqualTo(EnhancedPluginType.Client.EXCEPTION);
}
@Test
public void testRun() {
EnhancedPluginContext pluginContext = new EnhancedPluginContext();
EnhancedRequestContext request = EnhancedRequestContext.builder()
.httpMethod(HttpMethod.GET)
.url(URI.create("http://0.0.0.0/"))
.httpHeaders(new HttpHeaders())
.build();
request.toString();
EnhancedResponseContext response = EnhancedResponseContext.builder()
.httpStatus(200)
.build();
response.toString();
DefaultServiceInstance targetServiceInstance = new DefaultServiceInstance();
targetServiceInstance.setServiceId(SERVICE_PROVIDER);
DefaultServiceInstance localServiceInstance = new DefaultServiceInstance();
localServiceInstance.setServiceId(SERVICE_PROVIDER);
pluginContext.setRequest(request);
pluginContext.setResponse(response);
pluginContext.setTargetServiceInstance(targetServiceInstance, null);
pluginContext.setLocalServiceInstance(localServiceInstance);
pluginContext.setThrowable(new RuntimeException());
assemblyClientExceptionHook.run(pluginContext);
assemblyClientExceptionHook.getOrder();
assemblyClientExceptionHook.getName();
assemblyClientExceptionHook.getType();
}
@Test
public void testHandlerThrowable() {
// mock request
EnhancedRequestContext request = mock(EnhancedRequestContext.class);
// mock response
EnhancedResponseContext response = mock(EnhancedResponseContext.class);
EnhancedPluginContext context = new EnhancedPluginContext();
context.setRequest(request);
context.setResponse(response);
assemblyClientExceptionHook.handlerThrowable(context, new RuntimeException("Mock exception."));
}
}

@ -1,146 +0,0 @@
/*
* 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.plugin;
import java.net.URI;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPostHook;
import com.tencent.cloud.rpc.enhancement.transformer.InstanceTransformer;
import com.tencent.polaris.assembly.api.AssemblyAPI;
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.cloud.client.DefaultServiceInstance;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
/**
* AssemblyClientPostHookTest.
*
* @author sean yu
*/
@ExtendWith(MockitoExtension.class)
public class AssemblyClientPostHookTest {
private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
@InjectMocks
private AssemblyClientPostHook assemblyClientPostHook;
@Mock
private AssemblyAPI assemblyAPI;
@Mock
private InstanceTransformer instanceTransformer;
@BeforeAll
static void beforeAll() {
mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
.thenReturn("unit-test");
ApplicationContext applicationContext = mock(ApplicationContext.class);
RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class);
doReturn(reporterProperties)
.when(applicationContext).getBean(RpcEnhancementReporterProperties.class);
mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext)
.thenReturn(applicationContext);
}
@AfterAll
static void afterAll() {
mockedApplicationContextAwareUtils.close();
}
@BeforeEach
void setUp() {
MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
}
@Test
public void testGetName() {
assertThat(assemblyClientPostHook.getName()).isEqualTo(AssemblyClientPostHook.class.getName());
}
@Test
public void testType() {
assertThat(assemblyClientPostHook.getType()).isEqualTo(EnhancedPluginType.Client.POST);
}
@Test
public void testRun() {
EnhancedPluginContext pluginContext = new EnhancedPluginContext();
EnhancedRequestContext request = EnhancedRequestContext.builder()
.httpMethod(HttpMethod.GET)
.url(URI.create("http://0.0.0.0/"))
.httpHeaders(new HttpHeaders())
.build();
request.toString();
EnhancedResponseContext response = EnhancedResponseContext.builder()
.httpStatus(200)
.build();
response.toString();
DefaultServiceInstance targetServiceInstance = new DefaultServiceInstance();
targetServiceInstance.setServiceId(SERVICE_PROVIDER);
DefaultServiceInstance localServiceInstance = new DefaultServiceInstance();
localServiceInstance.setServiceId(SERVICE_PROVIDER);
pluginContext.setRequest(request);
pluginContext.setResponse(response);
pluginContext.setTargetServiceInstance(targetServiceInstance, null);
pluginContext.setLocalServiceInstance(localServiceInstance);
pluginContext.setThrowable(new RuntimeException());
assemblyClientPostHook.run(pluginContext);
assemblyClientPostHook.getOrder();
assemblyClientPostHook.getName();
assemblyClientPostHook.getType();
}
@Test
public void testHandlerThrowable() {
// mock request
EnhancedRequestContext request = mock(EnhancedRequestContext.class);
// mock response
EnhancedResponseContext response = mock(EnhancedResponseContext.class);
EnhancedPluginContext context = new EnhancedPluginContext();
context.setRequest(request);
context.setResponse(response);
assemblyClientPostHook.handlerThrowable(context, new RuntimeException("Mock exception."));
}
}

@ -1,143 +0,0 @@
/*
* 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.plugin;
import java.net.URI;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPreHook;
import com.tencent.polaris.assembly.api.AssemblyAPI;
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.cloud.client.DefaultServiceInstance;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
/**
* AssemblyClientPreHookTest.
*
* @author sean yu
*/
@ExtendWith(MockitoExtension.class)
public class AssemblyClientPreHookTest {
private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
@InjectMocks
private AssemblyClientPreHook assemblyClientPreHook;
@Mock
private AssemblyAPI assemblyAPI;
@BeforeAll
static void beforeAll() {
mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
.thenReturn("unit-test");
ApplicationContext applicationContext = mock(ApplicationContext.class);
RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class);
doReturn(reporterProperties)
.when(applicationContext).getBean(RpcEnhancementReporterProperties.class);
mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext)
.thenReturn(applicationContext);
}
@AfterAll
static void afterAll() {
mockedApplicationContextAwareUtils.close();
}
@BeforeEach
void setUp() {
MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
}
@Test
public void testGetName() {
assertThat(assemblyClientPreHook.getName()).isEqualTo(AssemblyClientPreHook.class.getName());
}
@Test
public void testType() {
assertThat(assemblyClientPreHook.getType()).isEqualTo(EnhancedPluginType.Client.PRE);
}
@Test
public void testRun() {
EnhancedPluginContext pluginContext = new EnhancedPluginContext();
EnhancedRequestContext request = EnhancedRequestContext.builder()
.httpMethod(HttpMethod.GET)
.url(URI.create("http://0.0.0.0/"))
.httpHeaders(new HttpHeaders())
.build();
request.toString();
EnhancedResponseContext response = EnhancedResponseContext.builder()
.httpStatus(200)
.build();
response.toString();
DefaultServiceInstance targetServiceInstance = new DefaultServiceInstance();
targetServiceInstance.setServiceId(SERVICE_PROVIDER);
DefaultServiceInstance localServiceInstance = new DefaultServiceInstance();
localServiceInstance.setServiceId(SERVICE_PROVIDER);
pluginContext.setRequest(request);
pluginContext.setResponse(response);
pluginContext.setTargetServiceInstance(targetServiceInstance, null);
pluginContext.setLocalServiceInstance(localServiceInstance);
pluginContext.setThrowable(new RuntimeException());
assemblyClientPreHook.run(pluginContext);
assemblyClientPreHook.getOrder();
assemblyClientPreHook.getName();
assemblyClientPreHook.getType();
}
@Test
public void testHandlerThrowable() {
// mock request
EnhancedRequestContext request = mock(EnhancedRequestContext.class);
// mock response
EnhancedResponseContext response = mock(EnhancedResponseContext.class);
EnhancedPluginContext context = new EnhancedPluginContext();
context.setRequest(request);
context.setResponse(response);
assemblyClientPreHook.handlerThrowable(context, new RuntimeException("Mock exception."));
}
}

@ -1,57 +0,0 @@
/*
* 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.plugin;
import java.util.HashMap;
import java.util.Map;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider;
import com.tencent.polaris.api.pojo.ServiceKey;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.cloud.client.ServiceInstance;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.doReturn;
/**
* AssemblyMetadataProviderTest.
*
* @author sean yu
*/
@ExtendWith(MockitoExtension.class)
public class AssemblyMetadataProviderTest {
@Test
public void testAssemblyMetadataProvider() {
ServiceInstance serviceInstance = Mockito.mock(ServiceInstance.class);
Map<String, String> metadata = new HashMap<String, String>() {{
put("k", "v");
}};
doReturn(metadata).when(serviceInstance).getMetadata();
doReturn("0.0.0.0").when(serviceInstance).getHost();
doReturn("test").when(serviceInstance).getServiceId();
AssemblyMetadataProvider assemblyMetadataProvider = new AssemblyMetadataProvider(serviceInstance, "test");
assertThat(assemblyMetadataProvider.getMetadata("k")).isEqualTo("v");
assertThat(assemblyMetadataProvider.getLocalIp()).isEqualTo("0.0.0.0");
assertThat(assemblyMetadataProvider.getLocalService()).isEqualTo(new ServiceKey("test", "test"));
}
}

@ -1,83 +0,0 @@
/*
* 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.plugin;
import java.net.URI;
import java.util.Arrays;
import java.util.HashSet;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext;
import com.tencent.polaris.api.pojo.ServiceKey;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import static org.assertj.core.api.Assertions.assertThat;
/**
* AssemblyRequestContextTest.
*
* @author sean yu
*/
@ExtendWith(MockitoExtension.class)
public class AssemblyRequestContextTest {
@Test
public void testAssemblyRequestContext() {
URI uri = URI.create("http://0.0.0.0/");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("a", "a");
httpHeaders.add(HttpHeaders.COOKIE, "cookies-k1=cookies-v1;cookies-k2=cookies-v2");
EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder()
.httpMethod(HttpMethod.GET)
.url(uri)
.httpHeaders(httpHeaders)
.build();
ServiceKey callerService = new ServiceKey("test", "test");
AssemblyRequestContext assemblyRequestContext = new AssemblyRequestContext(
enhancedRequestContext,
callerService,
"0.0.0.0"
);
assertThat(assemblyRequestContext.getURI()).isEqualTo(uri);
assertThat(assemblyRequestContext.getHeader("a")).isEqualTo("a");
assemblyRequestContext.setHeader("b", "b");
assertThat(assemblyRequestContext.listHeaderKeys()).isEqualTo(new HashSet<>(Arrays.asList(HttpHeaders.COOKIE, "a", "b")));
assertThat(assemblyRequestContext.getMethod()).isEqualTo(HttpMethod.GET.toString());
assemblyRequestContext.setMethod(HttpMethod.OPTIONS.name());
assertThat(assemblyRequestContext.getMethod()).isEqualTo(HttpMethod.OPTIONS.toString());
assertThat(assemblyRequestContext.getCookie("cookies-k1")).isEqualTo("cookies-v1");
assertThat(assemblyRequestContext.getCookie("cookies-k2")).isEqualTo("cookies-v2");
assemblyRequestContext.setCookie("cookies-k3", "cookies-v3");
assertThat(assemblyRequestContext.listCookieKeys()).isEqualTo(new HashSet<>(Arrays.asList("cookies-k1", "cookies-k2", "cookies-k3")));
assertThat(assemblyRequestContext.getCallerService()).isEqualTo(callerService);
assertThat(assemblyRequestContext.getCallerIp()).isEqualTo("0.0.0.0");
}
}

@ -1,101 +0,0 @@
/*
* 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.plugin;
import java.net.SocketTimeoutException;
import java.util.Arrays;
import java.util.HashSet;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyResponseContext;
import com.tencent.polaris.api.pojo.RetStatus;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.HttpStatus;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
/**
* AssemblyResponseContextTest.
*
* @author sean yu
*/
@ExtendWith(MockitoExtension.class)
public class AssemblyResponseContextTest {
private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
@BeforeAll
static void beforeAll() {
mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
.thenReturn("unit-test");
ApplicationContext applicationContext = mock(ApplicationContext.class);
RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class);
doReturn(reporterProperties)
.when(applicationContext).getBean(RpcEnhancementReporterProperties.class);
mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext)
.thenReturn(applicationContext);
}
@AfterAll
static void afterAll() {
mockedApplicationContextAwareUtils.close();
}
@Test
public void testAssemblyResponseContext() {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("a", "a");
EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder()
.httpHeaders(httpHeaders)
.httpStatus(HttpStatus.OK.value())
.build();
AssemblyResponseContext assemblyResponseContext = new AssemblyResponseContext(enhancedResponseContext, null);
assertThat(assemblyResponseContext.getHeader("a")).isEqualTo("a");
assertThat(assemblyResponseContext.getRetCode()).isEqualTo(HttpStatus.OK.value());
assertThat(assemblyResponseContext.getThrowable()).isEqualTo(null);
assertThat(assemblyResponseContext.getRetStatus()).isEqualTo(RetStatus.RetSuccess);
assertThat(assemblyResponseContext.listHeaders()).isEqualTo(new HashSet<>(Arrays.asList("a")));
Throwable e = new SocketTimeoutException();
assemblyResponseContext = new AssemblyResponseContext(null, e);
assertThat(assemblyResponseContext.getHeader("a")).isEqualTo(null);
assertThat(assemblyResponseContext.getRetCode()).isEqualTo(null);
assertThat(assemblyResponseContext.getThrowable()).isEqualTo(e);
assertThat(assemblyResponseContext.getRetStatus()).isEqualTo(RetStatus.RetTimeout);
assertThat(assemblyResponseContext.listHeaders()).isEqualTo(null);
}
}

@ -1,143 +0,0 @@
/*
* 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.plugin;
import java.net.URI;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerExceptionHook;
import com.tencent.polaris.assembly.api.AssemblyAPI;
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.cloud.client.DefaultServiceInstance;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
/**
* AssemblyServerExceptionHookTest.
*
* @author sean yu
*/
@ExtendWith(MockitoExtension.class)
public class AssemblyServerExceptionHookTest {
private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
@InjectMocks
private AssemblyServerExceptionHook assemblyServerExceptionHook;
@Mock
private AssemblyAPI assemblyAPI;
@BeforeAll
static void beforeAll() {
mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
.thenReturn("unit-test");
ApplicationContext applicationContext = mock(ApplicationContext.class);
RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class);
doReturn(reporterProperties)
.when(applicationContext).getBean(RpcEnhancementReporterProperties.class);
mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext)
.thenReturn(applicationContext);
}
@AfterAll
static void afterAll() {
mockedApplicationContextAwareUtils.close();
}
@BeforeEach
void setUp() {
MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
}
@Test
public void testGetName() {
assertThat(assemblyServerExceptionHook.getName()).isEqualTo(AssemblyServerExceptionHook.class.getName());
}
@Test
public void testType() {
assertThat(assemblyServerExceptionHook.getType()).isEqualTo(EnhancedPluginType.Server.EXCEPTION);
}
@Test
public void testRun() {
EnhancedPluginContext pluginContext = new EnhancedPluginContext();
EnhancedRequestContext request = EnhancedRequestContext.builder()
.httpMethod(HttpMethod.GET)
.url(URI.create("http://0.0.0.0/"))
.httpHeaders(new HttpHeaders())
.build();
request.toString();
EnhancedResponseContext response = EnhancedResponseContext.builder()
.httpStatus(200)
.build();
response.toString();
DefaultServiceInstance targetServiceInstance = new DefaultServiceInstance();
targetServiceInstance.setServiceId(SERVICE_PROVIDER);
DefaultServiceInstance localServiceInstance = new DefaultServiceInstance();
localServiceInstance.setServiceId(SERVICE_PROVIDER);
pluginContext.setRequest(request);
pluginContext.setResponse(response);
pluginContext.setTargetServiceInstance(targetServiceInstance, null);
pluginContext.setLocalServiceInstance(localServiceInstance);
pluginContext.setThrowable(new RuntimeException());
assemblyServerExceptionHook.run(pluginContext);
assemblyServerExceptionHook.getOrder();
assemblyServerExceptionHook.getName();
assemblyServerExceptionHook.getType();
}
@Test
public void testHandlerThrowable() {
// mock request
EnhancedRequestContext request = mock(EnhancedRequestContext.class);
// mock response
EnhancedResponseContext response = mock(EnhancedResponseContext.class);
EnhancedPluginContext context = new EnhancedPluginContext();
context.setRequest(request);
context.setResponse(response);
assemblyServerExceptionHook.handlerThrowable(context, new RuntimeException("Mock exception."));
}
}

@ -1,143 +0,0 @@
/*
* 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.plugin;
import java.net.URI;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPostHook;
import com.tencent.polaris.assembly.api.AssemblyAPI;
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.cloud.client.DefaultServiceInstance;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
/**
* AssemblyServerPostHookTest.
*
* @author sean yu
*/
@ExtendWith(MockitoExtension.class)
public class AssemblyServerPostHookTest {
private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
@InjectMocks
private AssemblyServerPostHook assemblyServerPostHook;
@Mock
private AssemblyAPI assemblyAPI;
@BeforeAll
static void beforeAll() {
mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
.thenReturn("unit-test");
ApplicationContext applicationContext = mock(ApplicationContext.class);
RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class);
doReturn(reporterProperties)
.when(applicationContext).getBean(RpcEnhancementReporterProperties.class);
mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext)
.thenReturn(applicationContext);
}
@AfterAll
static void afterAll() {
mockedApplicationContextAwareUtils.close();
}
@BeforeEach
void setUp() {
MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
}
@Test
public void testGetName() {
assertThat(assemblyServerPostHook.getName()).isEqualTo(AssemblyServerPostHook.class.getName());
}
@Test
public void testType() {
assertThat(assemblyServerPostHook.getType()).isEqualTo(EnhancedPluginType.Server.POST);
}
@Test
public void testRun() {
EnhancedPluginContext pluginContext = new EnhancedPluginContext();
EnhancedRequestContext request = EnhancedRequestContext.builder()
.httpMethod(HttpMethod.GET)
.url(URI.create("http://0.0.0.0/"))
.httpHeaders(new HttpHeaders())
.build();
request.toString();
EnhancedResponseContext response = EnhancedResponseContext.builder()
.httpStatus(200)
.build();
response.toString();
DefaultServiceInstance targetServiceInstance = new DefaultServiceInstance();
targetServiceInstance.setServiceId(SERVICE_PROVIDER);
DefaultServiceInstance localServiceInstance = new DefaultServiceInstance();
localServiceInstance.setServiceId(SERVICE_PROVIDER);
pluginContext.setRequest(request);
pluginContext.setResponse(response);
pluginContext.setTargetServiceInstance(targetServiceInstance, null);
pluginContext.setLocalServiceInstance(localServiceInstance);
pluginContext.setThrowable(new RuntimeException());
assemblyServerPostHook.run(pluginContext);
assemblyServerPostHook.getOrder();
assemblyServerPostHook.getName();
assemblyServerPostHook.getType();
}
@Test
public void testHandlerThrowable() {
// mock request
EnhancedRequestContext request = mock(EnhancedRequestContext.class);
// mock response
EnhancedResponseContext response = mock(EnhancedResponseContext.class);
EnhancedPluginContext context = new EnhancedPluginContext();
context.setRequest(request);
context.setResponse(response);
assemblyServerPostHook.handlerThrowable(context, new RuntimeException("Mock exception."));
}
}

@ -1,143 +0,0 @@
/*
* 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.plugin;
import java.net.URI;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
import com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPreHook;
import com.tencent.polaris.assembly.api.AssemblyAPI;
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.cloud.client.DefaultServiceInstance;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
/**
* AssemblyServerPreHookTest.
*
* @author sean yu
*/
@ExtendWith(MockitoExtension.class)
public class AssemblyServerPreHookTest {
private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
@InjectMocks
private AssemblyServerPreHook assemblyServerPreHook;
@Mock
private AssemblyAPI assemblyAPI;
@BeforeAll
static void beforeAll() {
mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
.thenReturn("unit-test");
ApplicationContext applicationContext = mock(ApplicationContext.class);
RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class);
doReturn(reporterProperties)
.when(applicationContext).getBean(RpcEnhancementReporterProperties.class);
mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext)
.thenReturn(applicationContext);
}
@AfterAll
static void afterAll() {
mockedApplicationContextAwareUtils.close();
}
@BeforeEach
void setUp() {
MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
}
@Test
public void testGetName() {
assertThat(assemblyServerPreHook.getName()).isEqualTo(AssemblyServerPreHook.class.getName());
}
@Test
public void testType() {
assertThat(assemblyServerPreHook.getType()).isEqualTo(EnhancedPluginType.Server.PRE);
}
@Test
public void testRun() {
EnhancedPluginContext pluginContext = new EnhancedPluginContext();
EnhancedRequestContext request = EnhancedRequestContext.builder()
.httpMethod(HttpMethod.GET)
.url(URI.create("http://0.0.0.0/"))
.httpHeaders(new HttpHeaders())
.build();
request.toString();
EnhancedResponseContext response = EnhancedResponseContext.builder()
.httpStatus(200)
.build();
response.toString();
DefaultServiceInstance targetServiceInstance = new DefaultServiceInstance();
targetServiceInstance.setServiceId(SERVICE_PROVIDER);
DefaultServiceInstance localServiceInstance = new DefaultServiceInstance();
localServiceInstance.setServiceId(SERVICE_PROVIDER);
pluginContext.setRequest(request);
pluginContext.setResponse(response);
pluginContext.setTargetServiceInstance(targetServiceInstance, null);
pluginContext.setLocalServiceInstance(localServiceInstance);
pluginContext.setThrowable(new RuntimeException());
assemblyServerPreHook.run(pluginContext);
assemblyServerPreHook.getOrder();
assemblyServerPreHook.getName();
assemblyServerPreHook.getType();
}
@Test
public void testHandlerThrowable() {
// mock request
EnhancedRequestContext request = mock(EnhancedRequestContext.class);
// mock response
EnhancedResponseContext response = mock(EnhancedResponseContext.class);
EnhancedPluginContext context = new EnhancedPluginContext();
context.setRequest(request);
context.setResponse(response);
assemblyServerPreHook.handlerThrowable(context, new RuntimeException("Mock exception."));
}
}
Loading…
Cancel
Save