Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:add zero protection. #1278

Merged
merged 11 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
- [fix:fix nearby router properties loading bug.](https://github.com/Tencent/spring-cloud-tencent/pull/1273)
- [refactor:let the configuration SDK context stand alone.](https://github.com/Tencent/spring-cloud-tencent/pull/1275)
- [fix: fix grammar issues for lane router example & optimize the gateway dependency](https://github.com/Tencent/spring-cloud-tencent/pull/1276)
- [feat:add zero protection.](https://github.com/Tencent/spring-cloud-tencent/pull/1278)
- [fix: fix lossless deregister failed when no healthcheck configured](https://github.com/Tencent/spring-cloud-tencent/pull/1281)
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ public ConfigurationModifier(PolarisConfigProperties polarisConfigProperties,

@Override
public void modify(ConfigurationImpl configuration) {
configuration.getGlobal().getAPI().setReportEnable(false);

if (!polarisContextProperties.getEnabled() || !polarisConfigProperties.isEnabled()) {
return;
}
if (StringUtils.equalsIgnoreCase(polarisConfigProperties.getDataSource(), DATA_SOURCE_POLARIS)) {
initByPolarisDataSource(configuration);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,26 @@ public PolarisConfigFileLocator(PolarisConfigProperties polarisConfigProperties,

@Override
public PropertySource<?> locate(Environment environment) {
CompositePropertySource compositePropertySource = new CompositePropertySource(POLARIS_CONFIG_PROPERTY_SOURCE_NAME);
try {
// load custom config extension files
initCustomPolarisConfigExtensionFiles(compositePropertySource);
// load spring boot default config files
initInternalConfigFiles(compositePropertySource);
// load custom config files
List<ConfigFileGroup> configFileGroups = polarisConfigProperties.getGroups();
if (CollectionUtils.isEmpty(configFileGroups)) {
if (polarisConfigProperties.isEnabled()) {
CompositePropertySource compositePropertySource = new CompositePropertySource(POLARIS_CONFIG_PROPERTY_SOURCE_NAME);
try {
// load custom config extension files
initCustomPolarisConfigExtensionFiles(compositePropertySource);
// load spring boot default config files
initInternalConfigFiles(compositePropertySource);
// load custom config files
List<ConfigFileGroup> configFileGroups = polarisConfigProperties.getGroups();
if (CollectionUtils.isEmpty(configFileGroups)) {
return compositePropertySource;
}
initCustomPolarisConfigFiles(compositePropertySource, configFileGroups);
return compositePropertySource;
}
initCustomPolarisConfigFiles(compositePropertySource, configFileGroups);
return compositePropertySource;
}
finally {
afterLocatePolarisConfigExtension(compositePropertySource);
finally {
afterLocatePolarisConfigExtension(compositePropertySource);
}
}
return null;
}

private void initCustomPolarisConfigExtensionFiles(CompositePropertySource compositePropertySource) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,16 @@ public boolean isResolvable(ConfigDataLocationResolverContext context, ConfigDat
if (!location.hasPrefix(PREFIX)) {
return false;
}
return context.getBinder()

boolean contextEnabled = context.getBinder()
.bind("spring.cloud.polaris.enabled", Boolean.class)
.orElse(true);

boolean configEnabled = context.getBinder()
.bind("spring.cloud.polaris.config.enabled", Boolean.class)
.orElse(true);

return contextEnabled && configEnabled;
}

@Override
Expand Down Expand Up @@ -138,9 +145,24 @@ public List<PolarisConfigDataResource> resolveProfileSpecific(
polarisContextProperties = new PolarisContextProperties();
}

// prepare and init earlier Polaris SDKContext to pull config files from remote.
prepareAndInitEarlierPolarisSdkContext(resolverContext, polarisConfigProperties, polarisCryptoConfigProperties, polarisContextProperties);
if (!polarisContextProperties.getEnabled() || !polarisConfigProperties.isEnabled()) {
return Collections.emptyList();
}

// prepare and init earlier Polaris SDKContext to pull config files from remote.
try {
prepareAndInitEarlierPolarisSdkContext(resolverContext, polarisConfigProperties, polarisCryptoConfigProperties, polarisContextProperties);
}
catch (Throwable throwable) {
if (location.isOptional()) {
log.warn("create earlier polaris SDK context failed.", throwable);
return new ArrayList<>();
}
else {
log.error("create earlier polaris SDK context failed.", throwable);
throw throwable;
}
}
bootstrapContext.registerIfAbsent(PolarisConfigProperties.class,
BootstrapRegistry.InstanceSupplier.of(polarisConfigProperties));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public void testLoadApplicationPropertiesFile() {
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yml")).thenReturn(emptyConfigFile);
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yaml")).thenReturn(emptyConfigFile);

when(polarisConfigProperties.isEnabled()).thenReturn(true);
when(polarisConfigProperties.getGroups()).thenReturn(null);
when(environment.getActiveProfiles()).thenReturn(new String[] {});

Expand Down Expand Up @@ -136,6 +137,7 @@ public void testActiveProfileFilesPriorityBiggerThanDefault() {
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap-dev.yml")).thenReturn(emptyConfigFile);
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap-dev.yaml")).thenReturn(emptyConfigFile);

when(polarisConfigProperties.isEnabled()).thenReturn(true);
when(polarisConfigProperties.getGroups()).thenReturn(null);
when(environment.getActiveProfiles()).thenReturn(new String[] {"dev"});

Expand Down Expand Up @@ -173,6 +175,7 @@ public void testGetCustomFiles() {
configFileGroup.setFiles(Lists.newArrayList(customFile1, customFile2));
customFiles.add(configFileGroup);

when(polarisConfigProperties.isEnabled()).thenReturn(true);
when(polarisConfigProperties.getGroups()).thenReturn(customFiles);
when(environment.getActiveProfiles()).thenReturn(new String[] {});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,22 @@

package com.tencent.cloud.polaris.contract;

import java.io.IOException;
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.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.contract.config.PolarisContractProperties;
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 com.tencent.polaris.api.utils.StringUtils;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
Expand All @@ -37,6 +41,7 @@
import org.slf4j.LoggerFactory;
import org.springdoc.api.AbstractOpenApiResource;
import org.springdoc.api.AbstractOpenApiResourceUtil;
import org.springdoc.core.providers.ObjectMapperProvider;
import org.springdoc.webflux.api.OpenApiWebFluxUtil;
import org.springdoc.webmvc.api.OpenApiWebMvcUtil;

Expand All @@ -62,15 +67,18 @@ public class PolarisContractReporter implements ApplicationListener<ApplicationR

private final PolarisDiscoveryProperties polarisDiscoveryProperties;

private final ObjectMapperProvider springdocObjectMapperProvider;

public PolarisContractReporter(org.springdoc.webmvc.api.MultipleOpenApiResource multipleOpenApiWebMvcResource,
org.springdoc.webflux.api.MultipleOpenApiResource multipleOpenApiWebFluxResource,
PolarisContractProperties polarisContractProperties, ProviderAPI providerAPI,
PolarisDiscoveryProperties polarisDiscoveryProperties) {
PolarisDiscoveryProperties polarisDiscoveryProperties, ObjectMapperProvider springdocObjectMapperProvider) {
this.multipleOpenApiWebMvcResource = multipleOpenApiWebMvcResource;
this.multipleOpenApiWebFluxResource = multipleOpenApiWebFluxResource;
this.polarisContractProperties = polarisContractProperties;
this.providerAPI = providerAPI;
this.polarisDiscoveryProperties = polarisDiscoveryProperties;
this.springdocObjectMapperProvider = springdocObjectMapperProvider;
}

@Override
Expand All @@ -90,20 +98,35 @@ else if (multipleOpenApiWebFluxResource != null) {
}
if (openAPI != null) {
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.setService(polarisDiscoveryProperties.getService());
request.setProtocol("http");
request.setVersion(polarisDiscoveryProperties.getVersion());
List<InterfaceDescriptor> interfaceDescriptorList = getInterfaceDescriptorFromSwagger(openAPI);
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);
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(openAPI);
LOG.debug("OpenApi json data: {}", jsonValue);
LOG.debug("OpenApi json base64 data: {}", serviceApiMeta);
}
}
else {
Expand All @@ -129,7 +152,21 @@ private List<InterfaceDescriptor> getInterfaceDescriptorFromSwagger(OpenAPI open
InterfaceDescriptor interfaceDescriptor = new InterfaceDescriptor();
interfaceDescriptor.setPath(p.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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,8 @@ public interface ContractProperties {
boolean isReportEnabled();

void setReportEnabled(boolean reportEnabled);

String getName();

void setName(String name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public PolarisContractModifier(PolarisContractProperties polarisContractProperti
public void modify(ConfigurationImpl configuration) {
List<RegisterConfigImpl> registerConfigs = configuration.getProvider().getRegisters();
for (RegisterConfigImpl registerConfig : registerConfigs) {
registerConfig.setReportServiceContractEnable(polarisContractProperties.isEnabled());
registerConfig.setReportServiceContractEnable(
polarisContractProperties.isEnabled() && polarisContractProperties.isReportEnabled());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public class PolarisContractProperties implements ContractProperties {
@Value("${spring.cloud.polaris.contract.report.enabled:true}")
private boolean reportEnabled = true;

private String name;

public PolarisContractProperties(@Nullable ExtendedContractProperties extendContractProperties) {
this.extendContractProperties = extendContractProperties;
}
Expand All @@ -71,6 +73,9 @@ public boolean isEnabled() {

@Override
public void setEnabled(boolean enabled) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setEnabled(enabled);
}
this.enabled = enabled;
}

Expand All @@ -84,6 +89,9 @@ public String getBasePackage() {

@Override
public void setBasePackage(String basePackage) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setBasePackage(basePackage);
}
this.basePackage = basePackage;
}

Expand All @@ -97,6 +105,9 @@ public String getExcludePath() {

@Override
public void setExcludePath(String excludePath) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setExcludePath(excludePath);
}
this.excludePath = excludePath;
}

Expand All @@ -110,6 +121,9 @@ public String getGroup() {

@Override
public void setGroup(String group) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setGroup(group);
}
this.group = group;
}

Expand All @@ -123,6 +137,9 @@ public String getBasePath() {

@Override
public void setBasePath(String basePath) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setBasePath(basePath);
}
this.basePath = basePath;
}

Expand All @@ -136,16 +153,40 @@ public boolean isExposure() {

@Override
public void setExposure(boolean exposure) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setExposure(exposure);
}
this.exposure = exposure;
}

@Override
public boolean isReportEnabled() {
if (Objects.nonNull(extendContractProperties)) {
return extendContractProperties.isReportEnabled();
}
return reportEnabled;
}

@Override
public void setReportEnabled(boolean reportEnabled) {
if (Objects.nonNull(extendContractProperties)) {
extendContractProperties.setReportEnabled(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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import io.swagger.v3.oas.models.info.License;
import org.springdoc.core.configuration.SpringDocConfiguration;
import org.springdoc.core.models.GroupedOpenApi;
import org.springdoc.core.providers.ObjectMapperProvider;
import org.springdoc.webflux.api.MultipleOpenApiWebFluxResource;
import org.springdoc.webmvc.api.MultipleOpenApiWebMvcResource;

Expand Down Expand Up @@ -85,8 +86,8 @@ public GroupedOpenApi polarisGroupedOpenApi(PolarisContractProperties polarisCon
public OpenAPI polarisOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("Polaris Swagger API")
.description("This is to show polaris api description.")
.title("Polaris Contract")
.description("This is to show polaris contract description.")
.license(new License().name("BSD-3-Clause").url("https://opensource.org/licenses/BSD-3-Clause"))
.version("1.0.0"));
}
Expand All @@ -98,9 +99,9 @@ public PolarisContractReporter polarisContractReporter(
@Nullable MultipleOpenApiWebMvcResource multipleOpenApiWebMvcResource,
@Nullable MultipleOpenApiWebFluxResource multipleOpenApiWebFluxResource,
PolarisContractProperties polarisContractProperties, PolarisSDKContextManager polarisSDKContextManager,
PolarisDiscoveryProperties polarisDiscoveryProperties) {
PolarisDiscoveryProperties polarisDiscoveryProperties, ObjectMapperProvider springdocObjectMapperProvider) {
return new PolarisContractReporter(multipleOpenApiWebMvcResource, multipleOpenApiWebFluxResource,
polarisContractProperties, polarisSDKContextManager.getProviderAPI(), polarisDiscoveryProperties);
polarisContractProperties, polarisSDKContextManager.getProviderAPI(), polarisDiscoveryProperties, springdocObjectMapperProvider);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.tencent.cloud.polaris.contract.config.PolarisContractPropertiesAutoConfiguration
com.tencent.cloud.polaris.contract.config.PolarisContractPropertiesBootstrapConfiguration
org.springframework.context.ApplicationListener=\
com.tencent.cloud.polaris.contract.PolarisSwaggerApplicationListener
Loading
Loading