|
|
@ -29,15 +29,16 @@ 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 io.swagger.models.HttpMethod;
|
|
|
|
import io.swagger.v3.oas.models.OpenAPI;
|
|
|
|
import io.swagger.models.Operation;
|
|
|
|
import io.swagger.v3.oas.models.Operation;
|
|
|
|
import io.swagger.models.Path;
|
|
|
|
import io.swagger.v3.oas.models.PathItem;
|
|
|
|
import io.swagger.models.Swagger;
|
|
|
|
import io.swagger.v3.oas.models.Paths;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import springfox.documentation.service.Documentation;
|
|
|
|
import org.springdoc.api.AbstractOpenApiResource;
|
|
|
|
import springfox.documentation.spring.web.DocumentationCache;
|
|
|
|
import org.springdoc.api.AbstractOpenApiResourceUtil;
|
|
|
|
import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper;
|
|
|
|
import org.springdoc.webflux.api.OpenApiWebFluxUtil;
|
|
|
|
|
|
|
|
import org.springdoc.webmvc.api.OpenApiWebMvcUtil;
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
|
|
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
|
|
|
import org.springframework.context.ApplicationListener;
|
|
|
|
import org.springframework.context.ApplicationListener;
|
|
|
@ -52,18 +53,21 @@ import org.springframework.util.CollectionUtils;
|
|
|
|
public class PolarisContractReporter implements ApplicationListener<ApplicationReadyEvent> {
|
|
|
|
public class PolarisContractReporter implements ApplicationListener<ApplicationReadyEvent> {
|
|
|
|
|
|
|
|
|
|
|
|
private final Logger LOG = LoggerFactory.getLogger(PolarisContractReporter.class);
|
|
|
|
private final Logger LOG = LoggerFactory.getLogger(PolarisContractReporter.class);
|
|
|
|
private final ServiceModelToSwagger2Mapper swagger2Mapper;
|
|
|
|
|
|
|
|
private final DocumentationCache documentationCache;
|
|
|
|
private final org.springdoc.webmvc.api.MultipleOpenApiResource multipleOpenApiWebMvcResource;
|
|
|
|
|
|
|
|
private final org.springdoc.webflux.api.MultipleOpenApiResource multipleOpenApiWebFluxResource;
|
|
|
|
private final PolarisContractProperties polarisContractProperties;
|
|
|
|
private final PolarisContractProperties polarisContractProperties;
|
|
|
|
|
|
|
|
|
|
|
|
private final ProviderAPI providerAPI;
|
|
|
|
private final ProviderAPI providerAPI;
|
|
|
|
|
|
|
|
|
|
|
|
private final PolarisDiscoveryProperties polarisDiscoveryProperties;
|
|
|
|
private final PolarisDiscoveryProperties polarisDiscoveryProperties;
|
|
|
|
|
|
|
|
|
|
|
|
public PolarisContractReporter(DocumentationCache documentationCache, ServiceModelToSwagger2Mapper swagger2Mapper,
|
|
|
|
public PolarisContractReporter(org.springdoc.webmvc.api.MultipleOpenApiResource multipleOpenApiWebMvcResource,
|
|
|
|
PolarisContractProperties polarisContractProperties, ProviderAPI providerAPI, PolarisDiscoveryProperties polarisDiscoveryProperties) {
|
|
|
|
org.springdoc.webflux.api.MultipleOpenApiResource multipleOpenApiWebFluxResource,
|
|
|
|
this.swagger2Mapper = swagger2Mapper;
|
|
|
|
PolarisContractProperties polarisContractProperties, ProviderAPI providerAPI,
|
|
|
|
this.documentationCache = documentationCache;
|
|
|
|
PolarisDiscoveryProperties polarisDiscoveryProperties) {
|
|
|
|
|
|
|
|
this.multipleOpenApiWebMvcResource = multipleOpenApiWebMvcResource;
|
|
|
|
|
|
|
|
this.multipleOpenApiWebFluxResource = multipleOpenApiWebFluxResource;
|
|
|
|
this.polarisContractProperties = polarisContractProperties;
|
|
|
|
this.polarisContractProperties = polarisContractProperties;
|
|
|
|
this.providerAPI = providerAPI;
|
|
|
|
this.providerAPI = providerAPI;
|
|
|
|
this.polarisDiscoveryProperties = polarisDiscoveryProperties;
|
|
|
|
this.polarisDiscoveryProperties = polarisDiscoveryProperties;
|
|
|
@ -73,29 +77,37 @@ public class PolarisContractReporter implements ApplicationListener<ApplicationR
|
|
|
|
public void onApplicationEvent(@NonNull ApplicationReadyEvent applicationReadyEvent) {
|
|
|
|
public void onApplicationEvent(@NonNull ApplicationReadyEvent applicationReadyEvent) {
|
|
|
|
if (polarisContractProperties.isReportEnabled()) {
|
|
|
|
if (polarisContractProperties.isReportEnabled()) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
Documentation documentation = documentationCache.documentationByGroup(polarisContractProperties.getGroup());
|
|
|
|
AbstractOpenApiResource openApiResource = null;
|
|
|
|
Swagger swagger = swagger2Mapper.mapDocumentation(documentation);
|
|
|
|
if (multipleOpenApiWebMvcResource != null) {
|
|
|
|
if (swagger != null) {
|
|
|
|
openApiResource = OpenApiWebMvcUtil.getOpenApiResourceOrThrow(multipleOpenApiWebMvcResource, polarisContractProperties.getGroup());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (multipleOpenApiWebFluxResource != null) {
|
|
|
|
|
|
|
|
openApiResource = OpenApiWebFluxUtil.getOpenApiResourceOrThrow(multipleOpenApiWebFluxResource, polarisContractProperties.getGroup());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
OpenAPI openAPI = null;
|
|
|
|
|
|
|
|
if (openApiResource != null) {
|
|
|
|
|
|
|
|
openAPI = AbstractOpenApiResourceUtil.getOpenApi(openApiResource);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (openAPI != null) {
|
|
|
|
ReportServiceContractRequest request = new ReportServiceContractRequest();
|
|
|
|
ReportServiceContractRequest request = new ReportServiceContractRequest();
|
|
|
|
request.setName(polarisDiscoveryProperties.getService());
|
|
|
|
request.setName(polarisDiscoveryProperties.getService());
|
|
|
|
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(swagger);
|
|
|
|
List<InterfaceDescriptor> interfaceDescriptorList = getInterfaceDescriptorFromSwagger(openAPI);
|
|
|
|
request.setInterfaceDescriptors(interfaceDescriptorList);
|
|
|
|
request.setInterfaceDescriptors(interfaceDescriptorList);
|
|
|
|
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(swagger);
|
|
|
|
String jsonValue = JacksonUtils.serialize2Json(openAPI);
|
|
|
|
LOG.debug("OpenApi json data: {}", jsonValue);
|
|
|
|
LOG.debug("OpenApi json data: {}", jsonValue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
LOG.warn("Swagger or json is null, documentationCache keys:{}, group:{}", documentationCache.all()
|
|
|
|
LOG.warn("OpenAPI or json is null, group:{}", polarisContractProperties.getGroup());
|
|
|
|
.keySet(), polarisContractProperties.getGroup());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Throwable t) {
|
|
|
|
catch (Throwable t) {
|
|
|
@ -104,11 +116,11 @@ public class PolarisContractReporter implements ApplicationListener<ApplicationR
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private List<InterfaceDescriptor> getInterfaceDescriptorFromSwagger(Swagger swagger) {
|
|
|
|
private List<InterfaceDescriptor> getInterfaceDescriptorFromSwagger(OpenAPI openAPI) {
|
|
|
|
List<InterfaceDescriptor> interfaceDescriptorList = new ArrayList<>();
|
|
|
|
List<InterfaceDescriptor> interfaceDescriptorList = new ArrayList<>();
|
|
|
|
Map<String, Path> paths = swagger.getPaths();
|
|
|
|
Paths paths = openAPI.getPaths();
|
|
|
|
for (Map.Entry<String, Path> p : paths.entrySet()) {
|
|
|
|
for (Map.Entry<String, PathItem> p : paths.entrySet()) {
|
|
|
|
Path path = p.getValue();
|
|
|
|
PathItem path = p.getValue();
|
|
|
|
Map<String, Operation> operationMap = getOperationMapFromPath(path);
|
|
|
|
Map<String, Operation> operationMap = getOperationMapFromPath(path);
|
|
|
|
if (CollectionUtils.isEmpty(operationMap)) {
|
|
|
|
if (CollectionUtils.isEmpty(operationMap)) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
@ -124,29 +136,29 @@ public class PolarisContractReporter implements ApplicationListener<ApplicationR
|
|
|
|
return interfaceDescriptorList;
|
|
|
|
return interfaceDescriptorList;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Map<String, Operation> getOperationMapFromPath(Path path) {
|
|
|
|
private Map<String, Operation> getOperationMapFromPath(PathItem path) {
|
|
|
|
Map<String, Operation> operationMap = new HashMap<>();
|
|
|
|
Map<String, Operation> operationMap = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
|
|
if (path.getGet() != null) {
|
|
|
|
if (path.getGet() != null) {
|
|
|
|
operationMap.put(HttpMethod.GET.name(), path.getGet());
|
|
|
|
operationMap.put(PathItem.HttpMethod.GET.name(), path.getGet());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (path.getPut() != null) {
|
|
|
|
if (path.getPut() != null) {
|
|
|
|
operationMap.put(HttpMethod.PUT.name(), path.getPut());
|
|
|
|
operationMap.put(PathItem.HttpMethod.PUT.name(), path.getPut());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (path.getPost() != null) {
|
|
|
|
if (path.getPost() != null) {
|
|
|
|
operationMap.put(HttpMethod.POST.name(), path.getPost());
|
|
|
|
operationMap.put(PathItem.HttpMethod.POST.name(), path.getPost());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (path.getHead() != null) {
|
|
|
|
if (path.getHead() != null) {
|
|
|
|
operationMap.put(HttpMethod.HEAD.name(), path.getHead());
|
|
|
|
operationMap.put(PathItem.HttpMethod.HEAD.name(), path.getHead());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (path.getDelete() != null) {
|
|
|
|
if (path.getDelete() != null) {
|
|
|
|
operationMap.put(HttpMethod.DELETE.name(), path.getDelete());
|
|
|
|
operationMap.put(PathItem.HttpMethod.DELETE.name(), path.getDelete());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (path.getPatch() != null) {
|
|
|
|
if (path.getPatch() != null) {
|
|
|
|
operationMap.put(HttpMethod.PATCH.name(), path.getPatch());
|
|
|
|
operationMap.put(PathItem.HttpMethod.PATCH.name(), path.getPatch());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (path.getOptions() != null) {
|
|
|
|
if (path.getOptions() != null) {
|
|
|
|
operationMap.put(HttpMethod.OPTIONS.name(), path.getOptions());
|
|
|
|
operationMap.put(PathItem.HttpMethod.OPTIONS.name(), path.getOptions());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return operationMap;
|
|
|
|
return operationMap;
|
|
|
|