feat:add zero protection. (#1386)

Co-authored-by: Haotian Zhang <skyebefreeman@qq.com>
pull/1389/head
Fishtail 3 months ago committed by GitHub
parent cfea9906db
commit ce0ce68b2f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -13,3 +13,5 @@
- [fix: fix grammar issues for lane router example & optimize the gateway dependency](https://github.com/Tencent/spring-cloud-tencent/pull/1382) - [fix: fix grammar issues for lane router example & optimize the gateway dependency](https://github.com/Tencent/spring-cloud-tencent/pull/1382)
- [refactor:let the configuration SDK context stand alone.](https://github.com/Tencent/spring-cloud-tencent/pull/1383) - [refactor:let the configuration SDK context stand alone.](https://github.com/Tencent/spring-cloud-tencent/pull/1383)
- [fix: fix lossless deregister failed when no healthcheck configured](https://github.com/Tencent/spring-cloud-tencent/pull/1385) - [fix: fix lossless deregister failed when no healthcheck configured](https://github.com/Tencent/spring-cloud-tencent/pull/1385)
- [fix:fix ApplicationContextAwareUtils NPE bug.](https://github.com/Tencent/spring-cloud-tencent/pull/1386)
- [feat:add zero protection.](https://github.com/Tencent/spring-cloud-tencent/pull/1386)

@ -63,6 +63,11 @@ public class ConfigurationModifier implements PolarisConfigurationConfigModifier
@Override @Override
public void modify(ConfigurationImpl configuration) { public void modify(ConfigurationImpl configuration) {
configuration.getGlobal().getAPI().setReportEnable(false);
if (!polarisContextProperties.getEnabled() || !polarisConfigProperties.isEnabled()) {
return;
}
if (StringUtils.equalsIgnoreCase(polarisConfigProperties.getDataSource(), DATA_SOURCE_POLARIS)) { if (StringUtils.equalsIgnoreCase(polarisConfigProperties.getDataSource(), DATA_SOURCE_POLARIS)) {
initByPolarisDataSource(configuration); initByPolarisDataSource(configuration);
} }

@ -78,6 +78,7 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
@Override @Override
public PropertySource<?> locate(Environment environment) { public PropertySource<?> locate(Environment environment) {
if (polarisConfigProperties.isEnabled()) {
CompositePropertySource compositePropertySource = new CompositePropertySource(POLARIS_CONFIG_PROPERTY_SOURCE_NAME); CompositePropertySource compositePropertySource = new CompositePropertySource(POLARIS_CONFIG_PROPERTY_SOURCE_NAME);
try { try {
// load custom config extension files // load custom config extension files
@ -96,6 +97,8 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
afterLocatePolarisConfigExtension(compositePropertySource); afterLocatePolarisConfigExtension(compositePropertySource);
} }
} }
return null;
}
private void initCustomPolarisConfigExtensionFiles(CompositePropertySource compositePropertySource) { private void initCustomPolarisConfigExtensionFiles(CompositePropertySource compositePropertySource) {
if (polarisConfigCustomExtensionLayer == null) { if (polarisConfigCustomExtensionLayer == null) {

@ -90,6 +90,7 @@ public class PolarisConfigFileLocatorTest {
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yml")).thenReturn(emptyConfigFile); when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yml")).thenReturn(emptyConfigFile);
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yaml")).thenReturn(emptyConfigFile); when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yaml")).thenReturn(emptyConfigFile);
when(polarisConfigProperties.isEnabled()).thenReturn(true);
when(polarisConfigProperties.getGroups()).thenReturn(null); when(polarisConfigProperties.getGroups()).thenReturn(null);
when(environment.getActiveProfiles()).thenReturn(new String[] {}); when(environment.getActiveProfiles()).thenReturn(new String[] {});
@ -137,6 +138,7 @@ public class PolarisConfigFileLocatorTest {
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap-dev.yml")).thenReturn(emptyConfigFile); when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap-dev.yml")).thenReturn(emptyConfigFile);
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap-dev.yaml")).thenReturn(emptyConfigFile); when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap-dev.yaml")).thenReturn(emptyConfigFile);
when(polarisConfigProperties.isEnabled()).thenReturn(true);
when(polarisConfigProperties.getGroups()).thenReturn(null); when(polarisConfigProperties.getGroups()).thenReturn(null);
when(environment.getActiveProfiles()).thenReturn(new String[] {"dev"}); when(environment.getActiveProfiles()).thenReturn(new String[] {"dev"});
@ -174,6 +176,7 @@ public class PolarisConfigFileLocatorTest {
configFileGroup.setFiles(Lists.newArrayList(customFile1, customFile2)); configFileGroup.setFiles(Lists.newArrayList(customFile1, customFile2));
customFiles.add(configFileGroup); customFiles.add(configFileGroup);
when(polarisConfigProperties.isEnabled()).thenReturn(true);
when(polarisConfigProperties.getGroups()).thenReturn(customFiles); when(polarisConfigProperties.getGroups()).thenReturn(customFiles);
when(environment.getActiveProfiles()).thenReturn(new String[] {}); when(environment.getActiveProfiles()).thenReturn(new String[] {});

@ -17,18 +17,22 @@
package com.tencent.cloud.polaris.contract; package com.tencent.cloud.polaris.contract;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.tencent.cloud.common.util.JacksonUtils; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tencent.cloud.common.util.GzipUtil;
import com.tencent.cloud.polaris.PolarisDiscoveryProperties; import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
import com.tencent.cloud.polaris.contract.config.PolarisContractProperties; import com.tencent.cloud.polaris.contract.config.PolarisContractProperties;
import com.tencent.polaris.api.core.ProviderAPI; import com.tencent.polaris.api.core.ProviderAPI;
import com.tencent.polaris.api.plugin.server.InterfaceDescriptor; import com.tencent.polaris.api.plugin.server.InterfaceDescriptor;
import com.tencent.polaris.api.plugin.server.ReportServiceContractRequest; import com.tencent.polaris.api.plugin.server.ReportServiceContractRequest;
import com.tencent.polaris.api.plugin.server.ReportServiceContractResponse; import com.tencent.polaris.api.plugin.server.ReportServiceContractResponse;
import com.tencent.polaris.api.utils.StringUtils;
import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.PathItem;
@ -37,6 +41,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springdoc.api.AbstractOpenApiResource; import org.springdoc.api.AbstractOpenApiResource;
import org.springdoc.api.AbstractOpenApiResourceUtil; import org.springdoc.api.AbstractOpenApiResourceUtil;
import org.springdoc.core.providers.ObjectMapperProvider;
import org.springdoc.webflux.api.OpenApiWebFluxUtil; import org.springdoc.webflux.api.OpenApiWebFluxUtil;
import org.springdoc.webmvc.api.OpenApiWebMvcUtil; import org.springdoc.webmvc.api.OpenApiWebMvcUtil;
@ -62,15 +67,18 @@ public class PolarisContractReporter implements ApplicationListener<ApplicationR
private final PolarisDiscoveryProperties polarisDiscoveryProperties; private final PolarisDiscoveryProperties polarisDiscoveryProperties;
private final ObjectMapperProvider springdocObjectMapperProvider;
public PolarisContractReporter(org.springdoc.webmvc.api.MultipleOpenApiResource multipleOpenApiWebMvcResource, public PolarisContractReporter(org.springdoc.webmvc.api.MultipleOpenApiResource multipleOpenApiWebMvcResource,
org.springdoc.webflux.api.MultipleOpenApiResource multipleOpenApiWebFluxResource, org.springdoc.webflux.api.MultipleOpenApiResource multipleOpenApiWebFluxResource,
PolarisContractProperties polarisContractProperties, ProviderAPI providerAPI, PolarisContractProperties polarisContractProperties, ProviderAPI providerAPI,
PolarisDiscoveryProperties polarisDiscoveryProperties) { PolarisDiscoveryProperties polarisDiscoveryProperties, ObjectMapperProvider springdocObjectMapperProvider) {
this.multipleOpenApiWebMvcResource = multipleOpenApiWebMvcResource; this.multipleOpenApiWebMvcResource = multipleOpenApiWebMvcResource;
this.multipleOpenApiWebFluxResource = multipleOpenApiWebFluxResource; this.multipleOpenApiWebFluxResource = multipleOpenApiWebFluxResource;
this.polarisContractProperties = polarisContractProperties; this.polarisContractProperties = polarisContractProperties;
this.providerAPI = providerAPI; this.providerAPI = providerAPI;
this.polarisDiscoveryProperties = polarisDiscoveryProperties; this.polarisDiscoveryProperties = polarisDiscoveryProperties;
this.springdocObjectMapperProvider = springdocObjectMapperProvider;
} }
@Override @Override
@ -90,20 +98,35 @@ public class PolarisContractReporter implements ApplicationListener<ApplicationR
} }
if (openAPI != null) { if (openAPI != null) {
ReportServiceContractRequest request = new ReportServiceContractRequest(); ReportServiceContractRequest request = new ReportServiceContractRequest();
request.setName(polarisDiscoveryProperties.getService()); String name = polarisContractProperties.getName();
if (StringUtils.isBlank(name)) {
name = polarisDiscoveryProperties.getService();
}
request.setName(name);
request.setNamespace(polarisDiscoveryProperties.getNamespace()); request.setNamespace(polarisDiscoveryProperties.getNamespace());
request.setService(polarisDiscoveryProperties.getService()); request.setService(polarisDiscoveryProperties.getService());
request.setProtocol("http"); request.setProtocol("http");
request.setVersion(polarisDiscoveryProperties.getVersion()); request.setVersion(polarisDiscoveryProperties.getVersion());
List<InterfaceDescriptor> interfaceDescriptorList = getInterfaceDescriptorFromSwagger(openAPI); List<InterfaceDescriptor> interfaceDescriptorList = getInterfaceDescriptorFromSwagger(openAPI);
request.setInterfaceDescriptors(interfaceDescriptorList); request.setInterfaceDescriptors(interfaceDescriptorList);
String jsonValue;
if (springdocObjectMapperProvider != null && springdocObjectMapperProvider.jsonMapper() != null) {
jsonValue = springdocObjectMapperProvider.jsonMapper().writeValueAsString(openAPI);
}
else {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
jsonValue = mapper.writeValueAsString(openAPI);
}
String serviceApiMeta = GzipUtil.compressBase64Encode(jsonValue, "utf-8");
request.setContent(serviceApiMeta);
ReportServiceContractResponse response = providerAPI.reportServiceContract(request); ReportServiceContractResponse response = providerAPI.reportServiceContract(request);
LOG.info("Service contract [Namespace: {}. Name: {}. Service: {}. Protocol:{}. Version: {}. API counter: {}] is reported.", LOG.info("Service contract [Namespace: {}. Name: {}. Service: {}. Protocol:{}. Version: {}. API counter: {}] is reported.",
request.getNamespace(), request.getName(), request.getService(), request.getProtocol(), request.getNamespace(), request.getName(), request.getService(), request.getProtocol(),
request.getVersion(), request.getInterfaceDescriptors().size()); request.getVersion(), request.getInterfaceDescriptors().size());
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
String jsonValue = JacksonUtils.serialize2Json(openAPI);
LOG.debug("OpenApi json data: {}", jsonValue); LOG.debug("OpenApi json data: {}", jsonValue);
LOG.debug("OpenApi json base64 data: {}", serviceApiMeta);
} }
} }
else { else {
@ -129,7 +152,21 @@ public class PolarisContractReporter implements ApplicationListener<ApplicationR
InterfaceDescriptor interfaceDescriptor = new InterfaceDescriptor(); InterfaceDescriptor interfaceDescriptor = new InterfaceDescriptor();
interfaceDescriptor.setPath(p.getKey()); interfaceDescriptor.setPath(p.getKey());
interfaceDescriptor.setMethod(o.getKey()); interfaceDescriptor.setMethod(o.getKey());
interfaceDescriptor.setContent(JacksonUtils.serialize2Json(p.getValue())); try {
String jsonValue;
if (springdocObjectMapperProvider != null && springdocObjectMapperProvider.jsonMapper() != null) {
jsonValue = springdocObjectMapperProvider.jsonMapper().writeValueAsString(o.getValue());
}
else {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
jsonValue = mapper.writeValueAsString(o.getValue());
}
interfaceDescriptor.setContent(GzipUtil.compressBase64Encode(jsonValue, "utf-8"));
}
catch (IOException ioe) {
LOG.warn("Encode operation [{}] failed.", o.getValue(), ioe);
}
interfaceDescriptorList.add(interfaceDescriptor); interfaceDescriptorList.add(interfaceDescriptor);
} }
} }

@ -51,4 +51,8 @@ public interface ContractProperties {
boolean isReportEnabled(); boolean isReportEnabled();
void setReportEnabled(boolean reportEnabled); void setReportEnabled(boolean reportEnabled);
String getName();
void setName(String name);
} }

@ -41,7 +41,8 @@ public class PolarisContractModifier implements PolarisConfigModifier {
public void modify(ConfigurationImpl configuration) { public void modify(ConfigurationImpl configuration) {
List<RegisterConfigImpl> registerConfigs = configuration.getProvider().getRegisters(); List<RegisterConfigImpl> registerConfigs = configuration.getProvider().getRegisters();
for (RegisterConfigImpl registerConfig : registerConfigs) { for (RegisterConfigImpl registerConfig : registerConfigs) {
registerConfig.setReportServiceContractEnable(polarisContractProperties.isEnabled()); registerConfig.setReportServiceContractEnable(
polarisContractProperties.isEnabled() && polarisContractProperties.isReportEnabled());
} }
} }

@ -57,6 +57,8 @@ public class PolarisContractProperties implements ContractProperties {
@Value("${spring.cloud.polaris.contract.report.enabled:true}") @Value("${spring.cloud.polaris.contract.report.enabled:true}")
private boolean reportEnabled = true; private boolean reportEnabled = true;
private String name;
public PolarisContractProperties(@Nullable ExtendedContractProperties extendContractProperties) { public PolarisContractProperties(@Nullable ExtendedContractProperties extendContractProperties) {
this.extendContractProperties = extendContractProperties; this.extendContractProperties = extendContractProperties;
} }
@ -71,6 +73,9 @@ public class PolarisContractProperties implements ContractProperties {
@Override @Override
public void setEnabled(boolean enabled) { public void setEnabled(boolean enabled) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setEnabled(enabled);
}
this.enabled = enabled; this.enabled = enabled;
} }
@ -84,6 +89,9 @@ public class PolarisContractProperties implements ContractProperties {
@Override @Override
public void setBasePackage(String basePackage) { public void setBasePackage(String basePackage) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setBasePackage(basePackage);
}
this.basePackage = basePackage; this.basePackage = basePackage;
} }
@ -97,6 +105,9 @@ public class PolarisContractProperties implements ContractProperties {
@Override @Override
public void setExcludePath(String excludePath) { public void setExcludePath(String excludePath) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setExcludePath(excludePath);
}
this.excludePath = excludePath; this.excludePath = excludePath;
} }
@ -110,6 +121,9 @@ public class PolarisContractProperties implements ContractProperties {
@Override @Override
public void setGroup(String group) { public void setGroup(String group) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setGroup(group);
}
this.group = group; this.group = group;
} }
@ -123,6 +137,9 @@ public class PolarisContractProperties implements ContractProperties {
@Override @Override
public void setBasePath(String basePath) { public void setBasePath(String basePath) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setBasePath(basePath);
}
this.basePath = basePath; this.basePath = basePath;
} }
@ -136,16 +153,40 @@ public class PolarisContractProperties implements ContractProperties {
@Override @Override
public void setExposure(boolean exposure) { public void setExposure(boolean exposure) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setExposure(exposure);
}
this.exposure = exposure; this.exposure = exposure;
} }
@Override @Override
public boolean isReportEnabled() { public boolean isReportEnabled() {
if (Objects.nonNull(extendContractProperties)) {
return extendContractProperties.isReportEnabled();
}
return reportEnabled; return reportEnabled;
} }
@Override @Override
public void setReportEnabled(boolean reportEnabled) { public void setReportEnabled(boolean reportEnabled) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setReportEnabled(reportEnabled);
}
this.reportEnabled = reportEnabled; this.reportEnabled = reportEnabled;
} }
public String getName() {
if (Objects.nonNull(extendContractProperties)) {
return extendContractProperties.getName();
}
return name;
}
@Override
public void setName(String name) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setName(name);
}
this.name = name;
}
} }

@ -30,6 +30,7 @@ import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License; import io.swagger.v3.oas.models.info.License;
import org.springdoc.core.GroupedOpenApi; import org.springdoc.core.GroupedOpenApi;
import org.springdoc.core.SpringDocConfiguration; import org.springdoc.core.SpringDocConfiguration;
import org.springdoc.core.providers.ObjectMapperProvider;
import org.springdoc.webflux.api.MultipleOpenApiWebFluxResource; import org.springdoc.webflux.api.MultipleOpenApiWebFluxResource;
import org.springdoc.webmvc.api.MultipleOpenApiWebMvcResource; import org.springdoc.webmvc.api.MultipleOpenApiWebMvcResource;
@ -56,6 +57,12 @@ import static com.tencent.cloud.polaris.contract.utils.PackageUtil.SPLITTER;
@Import(SpringDocConfiguration.class) @Import(SpringDocConfiguration.class)
public class PolarisSwaggerAutoConfiguration { 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 @Bean
public GroupedOpenApi polarisGroupedOpenApi(PolarisContractProperties polarisContractProperties) { public GroupedOpenApi polarisGroupedOpenApi(PolarisContractProperties polarisContractProperties) {
String basePackage = PackageUtil.scanPackage(polarisContractProperties.getBasePackage()); String basePackage = PackageUtil.scanPackage(polarisContractProperties.getBasePackage());
@ -79,8 +86,8 @@ public class PolarisSwaggerAutoConfiguration {
public OpenAPI polarisOpenAPI() { public OpenAPI polarisOpenAPI() {
return new OpenAPI() return new OpenAPI()
.info(new Info() .info(new Info()
.title("Polaris Swagger API") .title("Polaris Contract")
.description("This is to show polaris api description.") .description("This is to show polaris contract description.")
.license(new License().name("BSD-3-Clause").url("https://opensource.org/licenses/BSD-3-Clause")) .license(new License().name("BSD-3-Clause").url("https://opensource.org/licenses/BSD-3-Clause"))
.version("1.0.0")); .version("1.0.0"));
} }
@ -92,9 +99,9 @@ public class PolarisSwaggerAutoConfiguration {
@Nullable MultipleOpenApiWebMvcResource multipleOpenApiWebMvcResource, @Nullable MultipleOpenApiWebMvcResource multipleOpenApiWebMvcResource,
@Nullable MultipleOpenApiWebFluxResource multipleOpenApiWebFluxResource, @Nullable MultipleOpenApiWebFluxResource multipleOpenApiWebFluxResource,
PolarisContractProperties polarisContractProperties, PolarisSDKContextManager polarisSDKContextManager, PolarisContractProperties polarisContractProperties, PolarisSDKContextManager polarisSDKContextManager,
PolarisDiscoveryProperties polarisDiscoveryProperties) { PolarisDiscoveryProperties polarisDiscoveryProperties, ObjectMapperProvider springdocObjectMapperProvider) {
return new PolarisContractReporter(multipleOpenApiWebMvcResource, multipleOpenApiWebFluxResource, return new PolarisContractReporter(multipleOpenApiWebMvcResource, multipleOpenApiWebFluxResource,
polarisContractProperties, polarisSDKContextManager.getProviderAPI(), polarisDiscoveryProperties); polarisContractProperties, polarisSDKContextManager.getProviderAPI(), polarisDiscoveryProperties, springdocObjectMapperProvider);
} }
@Bean @Bean

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

@ -51,6 +51,10 @@ public class DiscoveryConfigModifier implements PolarisConfigModifier {
// Set ServiceRefreshInterval // Set ServiceRefreshInterval
configuration.getConsumer().getLocalCache() configuration.getConsumer().getLocalCache()
.setServiceListRefreshInterval(polarisDiscoveryProperties.getServiceListRefreshInterval()); .setServiceListRefreshInterval(polarisDiscoveryProperties.getServiceListRefreshInterval());
configuration.getConsumer().getZeroProtection().setEnable(polarisDiscoveryProperties.isZeroProtectionEnabled());
configuration.getConsumer().getZeroProtection()
.setNeedTestConnectivity(polarisDiscoveryProperties.isZeroProtectionNeedTestConnectivity());
} }
@Override @Override

@ -101,6 +101,18 @@ public class PolarisDiscoveryProperties {
*/ */
private Long serviceListRefreshInterval = 60000L; private Long serviceListRefreshInterval = 60000L;
/**
* Zero protection switch.
*/
@Value("${spring.cloud.polaris.discovery.zero-protection.enabled:false}")
private boolean zeroProtectionEnabled = false;
/**
* Zero protection test connectivity switch.
*/
@Value("${spring.cloud.polaris.discovery.zero-protection.is-need-test-connectivity:false}")
private boolean zeroProtectionNeedTestConnectivity = false;
public String getInstanceId() { public String getInstanceId() {
return instanceId; return instanceId;
} }
@ -192,6 +204,22 @@ public class PolarisDiscoveryProperties {
this.heartbeatInterval = heartbeatInterval; this.heartbeatInterval = heartbeatInterval;
} }
public boolean isZeroProtectionEnabled() {
return zeroProtectionEnabled;
}
public void setZeroProtectionEnabled(boolean zeroProtectionEnabled) {
this.zeroProtectionEnabled = zeroProtectionEnabled;
}
public boolean isZeroProtectionNeedTestConnectivity() {
return zeroProtectionNeedTestConnectivity;
}
public void setZeroProtectionNeedTestConnectivity(boolean zeroProtectionNeedTestConnectivity) {
this.zeroProtectionNeedTestConnectivity = zeroProtectionNeedTestConnectivity;
}
public Boolean getEnabled() { public Boolean getEnabled() {
return enabled; return enabled;
} }
@ -227,6 +255,8 @@ public class PolarisDiscoveryProperties {
", heartbeatInterval=" + heartbeatInterval + ", heartbeatInterval=" + heartbeatInterval +
", healthCheckUrl='" + healthCheckUrl + '\'' + ", healthCheckUrl='" + healthCheckUrl + '\'' +
", serviceListRefreshInterval=" + serviceListRefreshInterval + ", serviceListRefreshInterval=" + serviceListRefreshInterval +
", zeroProtectionEnabled=" + zeroProtectionEnabled +
", zeroProtectionNeedTestConnectivity=" + zeroProtectionNeedTestConnectivity +
'}'; '}';
} }
} }

@ -90,6 +90,9 @@ public class ConsulConfigModifier implements PolarisConfigModifier {
if (StringUtils.isNotBlank(consulContextProperties.getInstanceId())) { if (StringUtils.isNotBlank(consulContextProperties.getInstanceId())) {
metadata.put(ConsulConstant.MetadataMapKey.INSTANCE_ID_KEY, consulContextProperties.getInstanceId()); metadata.put(ConsulConstant.MetadataMapKey.INSTANCE_ID_KEY, consulContextProperties.getInstanceId());
} }
if (StringUtils.isNotBlank(consulContextProperties.getAclToken())) {
serverConnectorConfig.setToken(consulContextProperties.getAclToken());
}
if (consulContextProperties.isPreferIpAddress() if (consulContextProperties.isPreferIpAddress()
&& StringUtils.isNotBlank(consulContextProperties.getIpAddress())) { && StringUtils.isNotBlank(consulContextProperties.getIpAddress())) {
metadata.put(ConsulConstant.MetadataMapKey.PREFER_IP_ADDRESS_KEY, metadata.put(ConsulConstant.MetadataMapKey.PREFER_IP_ADDRESS_KEY,

@ -55,6 +55,9 @@ public class ConsulContextProperties {
@Value("${spring.cloud.consul.discovery.prefer-ip-address:#{'false'}}") @Value("${spring.cloud.consul.discovery.prefer-ip-address:#{'false'}}")
private boolean preferIpAddress; private boolean preferIpAddress;
@Value("${consul.token:${CONSUL_TOKEN:${spring.cloud.consul.token:${SPRING_CLOUD_CONSUL_TOKEN:${spring.cloud.consul.discovery.acl-token:}}}}}")
private String aclToken;
public String getHost() { public String getHost() {
return host; return host;
} }
@ -83,14 +86,14 @@ public class ConsulContextProperties {
return register; return register;
} }
public boolean isDiscoveryEnabled() {
return discoveryEnabled;
}
public void setRegister(boolean register) { public void setRegister(boolean register) {
this.register = register; this.register = register;
} }
public boolean isDiscoveryEnabled() {
return discoveryEnabled;
}
public void setDiscoveryEnabled(boolean discoveryEnabled) { public void setDiscoveryEnabled(boolean discoveryEnabled) {
this.discoveryEnabled = discoveryEnabled; this.discoveryEnabled = discoveryEnabled;
} }
@ -126,4 +129,12 @@ public class ConsulContextProperties {
public void setPreferIpAddress(boolean preferIpAddress) { public void setPreferIpAddress(boolean preferIpAddress) {
this.preferIpAddress = preferIpAddress; this.preferIpAddress = preferIpAddress;
} }
public String getAclToken() {
return aclToken;
}
public void setAclToken(String aclToken) {
this.aclToken = aclToken;
}
} }

@ -67,6 +67,7 @@ public class PolarisRegistration implements Registration {
private final List<PolarisRegistrationCustomizer> customizers; private final List<PolarisRegistrationCustomizer> customizers;
private boolean registerEnabled = false; private boolean registerEnabled = false;
private Map<String, String> metadata; private Map<String, String> metadata;
private Map<String, Map<String, String>> extendedMetadata;
private int port; private int port;
private String instanceId; private String instanceId;
@ -132,6 +133,8 @@ public class PolarisRegistration implements Registration {
this.metadata = instanceMetadata; this.metadata = instanceMetadata;
} }
this.extendedMetadata = new HashMap<>();
// generate registerEnabled // generate registerEnabled
if (null != polarisDiscoveryProperties) { if (null != polarisDiscoveryProperties) {
registerEnabled = polarisDiscoveryProperties.isRegisterEnabled(); registerEnabled = polarisDiscoveryProperties.isRegisterEnabled();
@ -217,6 +220,13 @@ public class PolarisRegistration implements Registration {
return metadata; return metadata;
} }
public Map<String, Map<String, String>> getExtendedMetadata() {
if (extendedMetadata == null) {
extendedMetadata = new HashMap<>();
}
return extendedMetadata;
}
@Override @Override
public String getInstanceId() { public String getInstanceId() {
return instanceId; return instanceId;

@ -117,6 +117,7 @@ public class PolarisServiceRegistry implements ServiceRegistry<PolarisRegistrati
instanceRegisterRequest.setCampus(staticMetadataManager.getCampus()); instanceRegisterRequest.setCampus(staticMetadataManager.getCampus());
instanceRegisterRequest.setTtl(polarisDiscoveryProperties.getHeartbeatInterval()); instanceRegisterRequest.setTtl(polarisDiscoveryProperties.getHeartbeatInterval());
instanceRegisterRequest.setMetadata(registration.getMetadata()); instanceRegisterRequest.setMetadata(registration.getMetadata());
instanceRegisterRequest.setExtendedMetadata(registration.getExtendedMetadata());
instanceRegisterRequest.setProtocol(polarisDiscoveryProperties.getProtocol()); instanceRegisterRequest.setProtocol(polarisDiscoveryProperties.getProtocol());
instanceRegisterRequest.setVersion(polarisDiscoveryProperties.getVersion()); instanceRegisterRequest.setVersion(polarisDiscoveryProperties.getVersion());
instanceRegisterRequest.setInstanceId(polarisDiscoveryProperties.getInstanceId()); instanceRegisterRequest.setInstanceId(polarisDiscoveryProperties.getInstanceId());

@ -67,16 +67,16 @@
"description": "Millis interval of refresh of service info list. Default: 60000." "description": "Millis interval of refresh of service info list. Default: 60000."
}, },
{ {
"name": "spring.cloud.polaris.loadbalancer.enabled", "name": "spring.cloud.polaris.discovery.zero-protection.enabled",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
"defaultValue": "true", "defaultValue": false,
"description": "polaris loadbalancer." "description": "Zero protection switch. Default: false."
}, },
{ {
"name": "spring.cloud.polaris.loadbalancer.strategy", "name": "spring.cloud.polaris.discovery.zero-protection.is-need-test-connectivity",
"type": "java.lang.String", "type": "java.lang.Boolean",
"defaultValue": "roundRobin", "defaultValue": false,
"description": "loadbalancer strategy." "description": "Zero protection test connectivity switch. Default: false."
}, },
{ {
"name": "spring.cloud.nacos.discovery.enabled", "name": "spring.cloud.nacos.discovery.enabled",

@ -101,6 +101,8 @@ public class PolarisDiscoveryPropertiesTest {
+ ", registerEnabled=true" + ", registerEnabled=true"
+ ", heartbeatInterval=20" + ", heartbeatInterval=20"
+ ", healthCheckUrl='/health'" + ", healthCheckUrl='/health'"
+ ", serviceListRefreshInterval=1000}"); + ", serviceListRefreshInterval=1000"
+ ", zeroProtectionEnabled=false"
+ ", zeroProtectionNeedTestConnectivity=false}");
} }
} }

@ -125,7 +125,7 @@ public class OrderConstant {
/** /**
* Address modifier order. * Address modifier order.
*/ */
public static Integer ADDRESS_ORDER = Integer.MIN_VALUE; public static Integer ADDRESS_ORDER = Integer.MIN_VALUE + 10;
/** /**
* Discovery config modifier order. * Discovery config modifier order.

@ -0,0 +1,88 @@
/*
* 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.common.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author kysonli
*/
public final class GzipUtil {
private static final Logger LOG = LoggerFactory.getLogger(GzipUtil.class);
private GzipUtil() {
}
public static byte[] compress(String data, String charsetName) throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); GZIPOutputStream gzip = new GZIPOutputStream(bos)) {
gzip.write(data.getBytes(charsetName));
gzip.finish();
return bos.toByteArray();
}
catch (IOException e) {
LOG.error("compress data [{}] error", data, e);
throw e;
}
}
public static String compressBase64Encode(String data, String charsetName) throws IOException {
byte[] compressData = compress(data, charsetName);
return new String(Base64.getEncoder().encode(compressData), charsetName);
}
public static String compressBase64Encode(byte[] byteData, String charsetName) throws IOException {
byte[] compressData = compress(new String(byteData, charsetName), charsetName);
return Base64.getEncoder().encodeToString(compressData);
}
public static byte[] decompress(byte[] zipData) throws IOException {
try (ByteArrayInputStream bis = new ByteArrayInputStream(zipData); GZIPInputStream gzip = new GZIPInputStream(bis); ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
byte[] buf = new byte[256];
int num;
while ((num = gzip.read(buf)) != -1) {
bos.write(buf, 0, num);
}
bos.flush();
return bos.toByteArray();
}
catch (IOException e) {
LOG.error("decompress zip data error", e);
throw e;
}
}
public static String base64DecodeDecompress(String data, String charsetName) throws IOException {
byte[] base64DecodeData = Base64.getDecoder().decode(data);
return new String(decompress(base64DecodeData), charsetName);
}
public static String base64DecodeDecompress(String data) throws IOException {
return base64DecodeDecompress(data, "utf-8");
}
}

@ -14,6 +14,9 @@ spring:
heartbeat: heartbeat:
enabled: true enabled: true
health-check-url: /quickstart/caller/healthCheck health-check-url: /quickstart/caller/healthCheck
zero-protection:
enabled: true
is-need-test-connectivity: true
contract: contract:
exposure: true exposure: true
report: report:

@ -18,6 +18,7 @@
package com.tencent.cloud.polaris.context; package com.tencent.cloud.polaris.context;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.tencent.cloud.common.constant.OrderConstant; import com.tencent.cloud.common.constant.OrderConstant;
@ -26,6 +27,8 @@ import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.polaris.factory.config.ConfigurationImpl; import com.tencent.polaris.factory.config.ConfigurationImpl;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;
/** /**
* Modify polaris server address. * Modify polaris server address.
* *
@ -48,6 +51,13 @@ public class ModifyAddress implements PolarisConfigModifier {
List<String> addresses = AddressUtils.parseAddressList(properties.getAddress()); List<String> addresses = AddressUtils.parseAddressList(properties.getAddress());
configuration.getGlobal().getServerConnector().setAddresses(addresses); configuration.getGlobal().getServerConnector().setAddresses(addresses);
if (CollectionUtils.isEmpty(configuration.getGlobal().getServerConnectors())) {
configuration.getGlobal().setServerConnectors(new ArrayList<>());
}
if (CollectionUtils.isEmpty(configuration.getGlobal().getServerConnectors())
&& null != configuration.getGlobal().getServerConnector()) {
configuration.getGlobal().getServerConnectors().add(configuration.getGlobal().getServerConnector());
}
} }
@Override @Override

@ -65,7 +65,7 @@ public class PolarisContextProperties {
* If polaris enabled. * If polaris enabled.
*/ */
@Value("${spring.cloud.polaris.enabled:#{'true'}}") @Value("${spring.cloud.polaris.enabled:#{'true'}}")
private Boolean enabled; private Boolean enabled = true;
/** /**
* polaris namespace. * polaris namespace.

@ -62,7 +62,7 @@ public class StatConfigModifier implements PolarisConfigModifier {
// pull metrics // pull metrics
prometheusHandlerConfig.setType("pull"); prometheusHandlerConfig.setType("pull");
if (!StringUtils.hasText(polarisStatProperties.getHost())) { if (!StringUtils.hasText(polarisStatProperties.getHost())) {
polarisStatProperties.setHost(environment.getProperty("spring.cloud.client.ip-address")); polarisStatProperties.setHost("0.0.0.0");
} }
prometheusHandlerConfig.setHost(polarisStatProperties.getHost()); prometheusHandlerConfig.setHost(polarisStatProperties.getHost());
prometheusHandlerConfig.setPort(polarisStatProperties.getPort()); prometheusHandlerConfig.setPort(polarisStatProperties.getPort());

Loading…
Cancel
Save