提交 e6578fc3 编写于 作者: M mxd

支持swagger

上级 5270b969
......@@ -75,57 +75,5 @@
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
</dependency>
</dependencies>
</project>
......@@ -115,7 +115,7 @@ import java.util.function.BiFunction;
@Configuration
@ConditionalOnClass({RequestMappingHandlerMapping.class})
@EnableConfigurationProperties(MagicAPIProperties.class)
@Import({MagicRedisAutoConfiguration.class, MagicElasticSearchAutoConfiguration.class, MagicMongoAutoConfiguration.class, MagicJsonAutoConfiguration.class, ApplicationUriPrinter.class})
@Import({MagicRedisAutoConfiguration.class, MagicElasticSearchAutoConfiguration.class, MagicMongoAutoConfiguration.class, MagicSwaggerConfiguration.class, MagicJsonAutoConfiguration.class, ApplicationUriPrinter.class})
@EnableWebSocket
public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketConfigurer {
......
......@@ -147,6 +147,9 @@ public class MagicAPIProperties {
@NestedConfigurationProperty
private DebugConfig debugConfig = new DebugConfig();
@NestedConfigurationProperty
private SwaggerConfig swaggerConfig = new SwaggerConfig();
@NestedConfigurationProperty
private ResourceConfig resource = new ResourceConfig();
......@@ -413,4 +416,12 @@ public class MagicAPIProperties {
public void setPersistenceResponseBody(boolean persistenceResponseBody) {
this.persistenceResponseBody = persistenceResponseBody;
}
public SwaggerConfig getSwaggerConfig() {
return swaggerConfig;
}
public void setSwaggerConfig(SwaggerConfig swaggerConfig) {
this.swaggerConfig = swaggerConfig;
}
}
package org.ssssssss.magicapi.spring.boot.starter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.ssssssss.magicapi.core.service.MagicResourceService;
import org.ssssssss.magicapi.core.service.impl.RequestMagicDynamicRegistry;
import org.ssssssss.magicapi.swagger.SwaggerEntity;
import org.ssssssss.magicapi.swagger.SwaggerProvider;
import org.ssssssss.magicapi.utils.Mapping;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
import javax.servlet.ServletContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Configuration
@AutoConfigureAfter({MagicAPIAutoConfiguration.class})
@EnableConfigurationProperties(MagicAPIProperties.class)
@ConditionalOnClass(name = "springfox.documentation.swagger.web.SwaggerResourcesProvider")
public class MagicSwaggerConfiguration {
private final MagicAPIProperties properties;
private final ApplicationContext applicationContext;
@Autowired
@Lazy
private RequestMappingHandlerMapping requestMappingHandlerMapping;
public MagicSwaggerConfiguration(MagicAPIProperties properties, ApplicationContext applicationContext) {
this.properties = properties;
this.applicationContext = applicationContext;
}
@Bean
@Primary
public SwaggerResourcesProvider magicSwaggerResourcesProvider(RequestMagicDynamicRegistry requestMagicDynamicRegistry, MagicResourceService magicResourceService, ServletContext servletContext) throws NoSuchMethodException {
SwaggerConfig config = properties.getSwaggerConfig();
Mapping mapping = Mapping.create(requestMappingHandlerMapping);
RequestMappingInfo requestMappingInfo = mapping.paths(config.getLocation()).build();
SwaggerEntity.License license = new SwaggerEntity.License("MIT", "https://gitee.com/ssssssss-team/magic-api/blob/master/LICENSE");
SwaggerEntity.Info info = new SwaggerEntity.Info(config.getDescription(), config.getVersion(), config.getTitle(), license, config.getConcat());
// 构建文档信息
SwaggerProvider swaggerProvider = new SwaggerProvider(requestMagicDynamicRegistry, magicResourceService, servletContext.getContextPath(), info, properties.isPersistenceResponseBody());
// 注册swagger.json
mapping.register(requestMappingInfo, swaggerProvider, SwaggerProvider.class.getDeclaredMethod("swaggerJson"));
return () -> {
List<SwaggerResource> resources = new ArrayList<>();
// 追加Magic Swagger信息
resources.add(swaggerResource(config.getName(), config.getLocation()));
Map<String, SwaggerResourcesProvider> beans = applicationContext.getBeansOfType(SwaggerResourcesProvider.class);
// 获取已定义的文档信息
for (Map.Entry<String, SwaggerResourcesProvider> entry : beans.entrySet()) {
if (!"magicSwaggerResourcesProvider".equalsIgnoreCase(entry.getKey())) {
resources.addAll(entry.getValue().get());
}
}
return resources;
};
}
/**
* 构建 SwaggerResource
*
* @param name 名字
* @param location 位置
*/
private SwaggerResource swaggerResource(String name, String location) {
SwaggerResource resource = new SwaggerResource();
resource.setName(name);
resource.setLocation(location);
resource.setSwaggerVersion("2.0");
return resource;
}
}
package org.ssssssss.magicapi.spring.boot.starter;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.ssssssss.magicapi.swagger.SwaggerEntity;
/**
* Swagger 配置
*
* @author mxd
*/
public class SwaggerConfig {
/**
* 资源名称
*/
private String name = "MagicAPI接口";
/**
* 资源位置
*/
private String location = "/v2/api-docs/magic-api/swagger2.json";
/**
* 文档标题
*/
private String title = "MagicAPI Swagger Docs";
/**
* 文档描述
*/
private String description = "MagicAPI 接口信息";
@NestedConfigurationProperty
private SwaggerEntity.Concat concat = new SwaggerEntity.Concat();
/**
* 文档版本
*/
private String version = "1.0";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public SwaggerEntity.Concat getConcat() {
return concat;
}
public void setConcat(SwaggerEntity.Concat concat) {
this.concat = concat;
}
}
......@@ -11,21 +11,6 @@ public class Constants {
public static final String CONST_STRING_TRUE = "true";
/**
* 接口文件夹名
*/
public static final String PATH_API = "api";
/**
* 函数文件夹名
*/
public static final String PATH_FUNCTION = "function";
/**
* websocket文件夹名
*/
public static final String PATH_WEBSOCKET = "websocket";
/**
* 空值
*/
......@@ -65,6 +50,11 @@ public class Constants {
* 脚本中header的变量名
*/
public static final String VAR_NAME_HEADER = "header";
/**
* 脚本中query的变量名
*/
public static final String VAR_NAME_QUERY = "query";
/**
/**
......@@ -72,6 +62,16 @@ public class Constants {
*/
public static final String VAR_NAME_REQUEST_BODY = "body";
/**
* 脚本中RequestBody的变量值字段类型
*/
public static final String VAR_NAME_REQUEST_BODY_VALUE_TYPE_OBJECT = "object";
/**
* 脚本中RequestBody的变量名字段类型
*/
public static final String VAR_NAME_REQUEST_BODY_VALUE_TYPE_ARRAY = "array";
public static final String HEADER_REQUEST_SCRIPT_ID = "Magic-Request-Script-Id";
public static final String HEADER_REQUEST_CLIENT_ID = "Magic-Request-Client-Id";
......@@ -126,106 +126,10 @@ public class Constants {
*/
public static int RESPONSE_CODE_INVALID = 0;
/**
* 通知新增
*/
public static final int NOTIFY_ACTION_ADD = 1;
/**
* 通知修改
*/
public static final int NOTIFY_ACTION_UPDATE = 2;
/**
* 通知删除
*/
public static final int NOTIFY_ACTION_DELETE = 3;
/**
* 通知更新全部
*/
public static final int NOTIFY_ACTION_ALL = 0;
/**
* 通知接口刷新
*/
public static final int NOTIFY_ACTION_API = 1;
/**
* 通知分组刷新
*/
public static final int NOTIFY_ACTION_GROUP = 2;
/**
* 通知函数刷新
*/
public static final int NOTIFY_ACTION_FUNCTION = 3;
/**
* 通知数据源刷新
*/
public static final int NOTIFY_ACTION_DATASOURCE = 4;
/**
* 通知WebSocket刷新
*/
public static final int NOTIFY_ACTION_WEBSOCKET = 5;
/**
* 通知 C -> S 的WebSocket消息
*/
public static final int NOTIFY_WS_C_S = 100;
/**
* 通知 S -> C 的WebSocket消息
*/
public static final int NOTIFY_WS_S_C = 200;
/**
* 空数组
*/
public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
/**
* 数据库日期类型
*/
public static final List<String> DBTYPE_DATE = Arrays.asList("datetime", "time", "date", "timestamp");
/**
* 数据库数值类型
*/
public static final List<String> DBTYPE_NUMBER = Arrays.asList("tinyint", "smallint", "mediumint", "int", "number", "integer", "bit", "bigint");
/**
* 数据库数值类型
*/
public static final List<String> DBTYPE_DECIMAL = Arrays.asList("float", "double", "decimal");
/**
* String类型
*/
public static final String JAVA_TYPE_STRING = "String";
/**
* Date类型
*/
public static final String JAVA_TYPE_DATE = "Date";
/**
* int类型
*/
public static final String JAVA_TYPE_INTEGER = "Integer";
/**
* long类型
*/
public static final String JAVA_TYPE_LONG = "Long";
/**
* BigDecimal类型
*/
public static final String JAVA_TYPE_BIGDECIMAL = "BigDecimal";
}
......@@ -9,9 +9,11 @@ import org.ssssssss.magicapi.core.exception.MagicAPIException;
import org.ssssssss.magicapi.core.model.MagicEntity;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
public abstract class AbstractMagicDynamicRegistry<T extends MagicEntity> implements MagicDynamicRegistry<T> {
......@@ -115,6 +117,10 @@ public abstract class AbstractMagicDynamicRegistry<T extends MagicEntity> implem
}
public List<T> mappings(){
return this.mappings.values().stream().map(MappingNode::getEntity).collect(Collectors.toList());
}
protected MappingNode<T> buildMappingNode(T entity) {
MappingNode<T> mappingNode = new MappingNode<>(entity);
mappingNode.setMappingKey(this.magicResourceStorage.buildKey(entity));
......
package org.ssssssss.magicapi.swagger;
import java.util.*;
/**
* Swagger接口信息
*
* @author mxd
*/
public class SwaggerEntity {
private String swagger = "2.0";
private String host;
private String basePath;
private Info info;
private final Set<Tag> tags = new TreeSet<>(Comparator.comparing(Tag::getName));
private final Map<String, Object> definitions = new HashMap<>();
private final Map<String, Map<String, Path>> paths = new HashMap<>();
private static Map<String, Object> doProcessSchema(Object target) {
Map<String, Object> result = new HashMap<>(3);
result.put("type", getType(target));
if (target instanceof List) {
List<?> targetList = (List<?>) target;
if (targetList.size() > 0) {
result.put("items", doProcessSchema(targetList.get(0)));
} else {
result.put("items", Collections.emptyList());
}
} else if (target instanceof Map) {
Set<Map.Entry> entries = ((Map) target).entrySet();
Map<String, Map<String, Object>> properties = new HashMap<>(entries.size());
for (Map.Entry entry : entries) {
properties.put(Objects.toString(entry.getKey()), doProcessSchema(entry.getValue()));
}
result.put("properties", properties);
} else {
result.put("example", target == null ? "" : target);
result.put("description", target == null ? "" : target);
}
return result;
}
private static String getType(Object object) {
if (object instanceof Number) {
return "number";
}
if (object instanceof String) {
return "string";
}
if (object instanceof Boolean) {
return "boolean";
}
if (object instanceof List) {
return "array";
}
if (object instanceof Map) {
return "object";
}
return "string";
}
public static Map<String, Object> createParameter(boolean required, String name, String in, String type, String description, Object example) {
Map<String, Object> parameter = new HashMap<>();
parameter.put("required", required);
parameter.put("name", name);
parameter.put("in", in);
parameter.put("description", description);
if ("body".equalsIgnoreCase(in)) {
Map<String, Object> schema = new HashMap<>();
schema.put("type", type);
schema.put("example", example);
parameter.put("schema", schema);
} else {
parameter.put("x-example", example);
parameter.put("type", type);
}
return parameter;
}
public Info getInfo() {
return info;
}
public void setInfo(Info info) {
this.info = info;
}
public void addPath(String path, String method, Path pathInfo) {
Map<String, Path> map = paths.computeIfAbsent(path, k -> new HashMap<>());
map.put(method.toLowerCase(), pathInfo);
}
public void addTag(String name, String description) {
this.tags.add(new Tag(name, description));
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getSwagger() {
return swagger;
}
public void setSwagger(String swagger) {
this.swagger = swagger;
}
public String getBasePath() {
return basePath;
}
public void setBasePath(String basePath) {
this.basePath = basePath;
}
public Map<String, Object> getDefinitions() {
return definitions;
}
public void addDefinitions(String path, Object definition) {
definitions.put(path, definition);
}
public Set<Tag> getTags() {
return tags;
}
public Map<String, Map<String, Path>> getPaths() {
return paths;
}
public static class Concat {
private String name;
private String url;
private String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
public static class Info {
private String description;
private String version;
private String title;
private License license;
private Concat concat;
public Info(String description, String version, String title, License license, Concat concat) {
this.description = description;
this.version = version;
this.title = title;
this.license = license;
this.concat = concat;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public License getLicense() {
return license;
}
public void setLicense(License license) {
this.license = license;
}
public Concat getConcat() {
return concat;
}
public void setConcat(Concat concat) {
this.concat = concat;
}
}
public static class Path {
private List<String> tags = new ArrayList<>();
private String summary;
private String description;
private final String operationId;
private List<String> produces = new ArrayList<>();
private List<String> consumes = new ArrayList<>();
private List<Map<String, Object>> parameters = new ArrayList<>();
private Map<String, Object> responses = new HashMap<>();
public Path(String operationId) {
this.operationId = operationId;
}
public void addProduce(String produce) {
this.produces.add(produce);
}
public void addConsume(String consume) {
this.consumes.add(consume);
}
public void addParameter(Map<String, Object> parameter) {
this.parameters.add(parameter);
}
public String getOperationId() {
return operationId;
}
public void addResponse(String status, Object object) {
Map<String, Object> response = new HashMap<>();
response.put("description", "OK");
response.put("schema", doProcessSchema(object));
response.put("example", object);
this.responses.put(status, response);
}
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
public void addTag(String tag) {
this.tags.add(tag);
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public List<String> getProduces() {
return produces;
}
public void setProduces(List<String> produces) {
this.produces = produces;
}
public List<String> getConsumes() {
return consumes;
}
public void setConsumes(List<String> consumes) {
this.consumes = consumes;
}
public List<Map<String, Object>> getParameters() {
return parameters;
}
public void setParameters(List<Map<String, Object>> parameters) {
this.parameters = parameters;
}
public Map<String, Object> getResponses() {
return responses;
}
public void setResponses(Map<String, Object> responses) {
this.responses = responses;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
public static class Parameter {
private String name;
private String in;
private boolean required = false;
private String type;
private Object schema;
private String description;
private Object example;
public Parameter(boolean required, String name, String in, String type, String description, Object example) {
this.name = name;
this.in = in;
this.type = type;
this.description = description;
this.required = required;
if ("body".equalsIgnoreCase(in)) {
this.schema = "";
} else {
this.example = example;
/*
* fix swagger文档使用knife4j时无法显示接口详情的问题(query类型参数)
* schema 需设置为空字符串,否则请求参数中数据类型字段显示不正确
*/
this.schema = "";
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIn() {
return in;
}
public void setIn(String in) {
this.in = in;
}
public boolean isRequired() {
return required;
}
public void setRequired(boolean required) {
this.required = required;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Object getSchema() {
return schema;
}
public void setSchema(Object schema) {
this.schema = schema;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Object getExample() {
return example;
}
public void setExample(Object example) {
this.example = example;
}
}
public static class Tag {
private String name;
private String description;
public Tag(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Tag tag = (Tag) o;
return Objects.equals(name, tag.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
public static class License {
private String name;
private String url;
public License(String name, String url) {
this.name = name;
this.url = url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
}
package org.ssssssss.magicapi.swagger;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.ssssssss.magicapi.core.config.MagicConfiguration;
import org.ssssssss.magicapi.core.model.ApiInfo;
import org.ssssssss.magicapi.core.model.BaseDefinition;
import org.ssssssss.magicapi.core.model.DataType;
import org.ssssssss.magicapi.core.model.Path;
import org.ssssssss.magicapi.core.service.MagicResourceService;
import org.ssssssss.magicapi.core.service.impl.RequestMagicDynamicRegistry;
import org.ssssssss.magicapi.utils.JsonUtils;
import org.ssssssss.magicapi.utils.PathUtils;
import org.ssssssss.script.parsing.ast.literal.BooleanLiteral;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static org.ssssssss.magicapi.core.config.Constants.*;
/**
* 生成swagger用的json
*
* @author mxd
*/
public class SwaggerProvider {
/**
* swagger Model定义路径前缀
*/
private static final String DEFINITION = "#/definitions/";
/**
* body空对象
*/
private static final String BODY_EMPTY = "{}";
private final Map<String, Object> DEFINITION_MAP = new ConcurrentHashMap<>();
private final RequestMagicDynamicRegistry requestMagicDynamicRegistry;
private final MagicResourceService magicResourceService;
/**
* 基础路径
*/
private final String basePath;
private final SwaggerEntity.Info info;
private final boolean persistenceResponseBody;
public SwaggerProvider(RequestMagicDynamicRegistry requestMagicDynamicRegistry, MagicResourceService magicResourceService, String basePath, SwaggerEntity.Info info, boolean persistenceResponseBody) {
this.requestMagicDynamicRegistry = requestMagicDynamicRegistry;
this.magicResourceService = magicResourceService;
this.basePath = basePath;
this.info = info;
this.persistenceResponseBody = persistenceResponseBody;
}
@ResponseBody
public SwaggerEntity swaggerJson() {
this.DEFINITION_MAP.clear();
List<ApiInfo> infos = requestMagicDynamicRegistry.mappings();
SwaggerEntity swaggerEntity = new SwaggerEntity();
swaggerEntity.setInfo(info);
swaggerEntity.setBasePath(this.basePath);
for (ApiInfo info : infos) {
String groupName = magicResourceService.getGroupName(info.getGroupId()).replace("/", "-");
String requestPath = PathUtils.replaceSlash("/" + magicResourceService.getGroupPath(info.getGroupId()) + "/" + info.getPath());
SwaggerEntity.Path path = new SwaggerEntity.Path(info.getId());
path.addTag(groupName);
boolean hasBody = false;
try {
List<Map<String, Object>> parameters = parseParameters(info);
hasBody = parameters.stream().anyMatch(it -> VAR_NAME_REQUEST_BODY.equals(it.get("in")));
BaseDefinition baseDefinition = info.getRequestBodyDefinition();
if (hasBody && baseDefinition != null) {
doProcessDefinition(baseDefinition, info, groupName, "root_", "request", 0);
}
parameters.forEach(path::addParameter);
if (this.persistenceResponseBody) {
baseDefinition = info.getResponseBodyDefinition();
if (baseDefinition != null) {
Map responseMap = parseResponse(info);
if (!responseMap.isEmpty()) {
path.setResponses(responseMap);
doProcessDefinition(baseDefinition, info, groupName, "root_" + baseDefinition.getName(), "response", 0);
}
} else {
path.addResponse("200", JsonUtils.readValue(Objects.toString(info.getResponseBody(), BODY_EMPTY), Object.class));
}
}
} catch (Exception ignored) {
}
if (hasBody) {
path.addConsume("application/json");
} else {
path.addConsume("*/*");
}
path.addProduce("application/json");
path.setSummary(info.getName());
path.setDescription(StringUtils.defaultIfBlank(info.getDescription(), info.getName()));
swaggerEntity.addPath(requestPath, info.getMethod(), path);
}
if (this.DEFINITION_MAP.size() > 0) {
Set<Map.Entry> entries = ((Map) this.DEFINITION_MAP).entrySet();
for (Map.Entry entry : entries) {
swaggerEntity.addDefinitions(Objects.toString(entry.getKey()), entry.getValue());
}
}
return swaggerEntity;
}
private List<Map<String, Object>> parseParameters(ApiInfo info) {
List<Map<String, Object>> parameters = new ArrayList<>();
info.getParameters().forEach(it -> parameters.add(SwaggerEntity.createParameter(it.isRequired(), it.getName(), VAR_NAME_QUERY, it.getDataType().getJavascriptType(), it.getDescription(), it.getValue())));
info.getHeaders().forEach(it -> parameters.add(SwaggerEntity.createParameter(it.isRequired(), it.getName(), VAR_NAME_HEADER, it.getDataType().getJavascriptType(), it.getDescription(), it.getValue())));
List<Path> paths = new ArrayList<>(info.getPaths());
MagicConfiguration.getMagicResourceService().getGroupsByFileId(info.getId())
.stream()
.flatMap(it -> it.getPaths().stream())
.filter(it -> !paths.contains(it))
.forEach(paths::add);
paths.forEach(it -> parameters.add(SwaggerEntity.createParameter(it.isRequired(), it.getName(), VAR_NAME_PATH_VARIABLE, it.getDataType().getJavascriptType(), it.getDescription(), it.getValue())));
try {
BaseDefinition baseDefinition = info.getRequestBodyDefinition();
if (baseDefinition != null && !CollectionUtils.isEmpty(baseDefinition.getChildren())) {
Map<String, Object> parameter = SwaggerEntity.createParameter(baseDefinition.isRequired(), StringUtils.isNotBlank(baseDefinition.getName()) ? baseDefinition.getName() : VAR_NAME_REQUEST_BODY, VAR_NAME_REQUEST_BODY, baseDefinition.getDataType().getJavascriptType(), baseDefinition.getDescription(), baseDefinition);
Map<String, Object> schema = new HashMap<>(2);
String groupName = magicResourceService.getGroupName(info.getGroupId()).replace("/", "-");
String voName = groupName + "«" + info.getPath().replaceFirst("/", "").replaceAll("/", "_") + "«request«";
if (DataType.Array == baseDefinition.getDataType()) {
voName += "root_" + (StringUtils.isNotBlank(baseDefinition.getName()) ? baseDefinition.getName() + "_" : "_") + "»»»";
Map<String, Object> items = new HashMap<>(2);
items.put("originalRef", voName);
items.put("$ref", DEFINITION + voName);
schema.put("items", items);
schema.put("type", VAR_NAME_REQUEST_BODY_VALUE_TYPE_ARRAY);
} else {
voName += "root_" + baseDefinition.getName() + "»»»";
schema.put("originalRef", voName);
schema.put("$ref", DEFINITION + voName);
}
parameter.put("schema", schema);
parameters.add(parameter);
} else {
Object object = JsonUtils.readValue(info.getRequestBody(), Object.class);
boolean isListOrMap = (object instanceof List || object instanceof Map);
if (isListOrMap && BooleanLiteral.isTrue(object)) {
parameters.add(SwaggerEntity.createParameter(false, VAR_NAME_REQUEST_BODY, VAR_NAME_REQUEST_BODY, object instanceof List ? VAR_NAME_REQUEST_BODY_VALUE_TYPE_ARRAY : VAR_NAME_REQUEST_BODY_VALUE_TYPE_OBJECT, null, object));
}
}
} catch (Exception ignored) {
}
return parameters;
}
private Map<String, Object> parseResponse(ApiInfo info) {
Map<String, Object> result = new HashMap<>();
BaseDefinition baseDefinition = info.getResponseBodyDefinition();
if (!CollectionUtils.isEmpty(baseDefinition.getChildren())) {
String groupName = magicResourceService.getGroupName(info.getGroupId()).replace("/", "-");
String voName = groupName + "«" + info.getPath().replaceFirst("/", "").replaceAll("/", "_") + "«response«";
voName += "root_" + baseDefinition.getName() + "»»»";
Map<String, Object> schema = new HashMap<>(2);
schema.put("originalRef", voName);
schema.put("$ref", DEFINITION + voName);
Map<String, Object> response = new HashMap<>(2);
response.put("description", "OK");
response.put("schema", schema);
result.put("200", response);
}
return result;
}
private Map<String, Object> doProcessDefinition(BaseDefinition target, ApiInfo info, String groupName, String parentName, String definitionType, int level) {
Map<String, Object> result = new HashMap<>(4);
result.put("description", target.getDescription());
if (DataType.Array == target.getDataType()) {
if (!CollectionUtils.isEmpty(target.getChildren())) {
result.put("items", doProcessDefinition(target.getChildren().get(0), info, groupName, parentName + target.getName() + "_", definitionType, level + 1));
} else {
result.put("items", Collections.emptyList());
}
result.put("type", target.getDataType().getJavascriptType());
} else if (DataType.Object == target.getDataType()) {
String voName = groupName + "«" + info.getPath().replaceFirst("/", "").replaceAll("/", "_") + (StringUtils.equals("response", definitionType) ? "«response«" : "«request«") + parentName + target.getName() + "»»»";
Map<String, Object> definition = new HashMap<>(4);
Map<String, Map<String, Object>> properties = new HashMap<>(target.getChildren().size());
Set<String> requiredSet = new HashSet<>(target.getChildren().size());
for (BaseDefinition obj : target.getChildren()) {
properties.put(obj.getName(), doProcessDefinition(obj, info, groupName, parentName + target.getName() + "_", definitionType, level + 1));
if (obj.isRequired()) {
requiredSet.add(obj.getName());
}
}
definition.put("properties", properties);
definition.put("description", target.getDescription());
definition.put("type", target.getDataType().getJavascriptType());
definition.put("required", requiredSet);
if (this.DEFINITION_MAP.containsKey(voName)) {
// TODO 应该不会出现名字都一样的
voName = voName.replace("»»»", "_" + level + "»»»");
}
this.DEFINITION_MAP.put(voName, definition);
result.put("originalRef", voName);
result.put("$ref", DEFINITION + voName);
} else {
result.put("example", target.getValue());
result.put("type", target.getDataType().getJavascriptType());
}
return result;
}
}
......@@ -80,7 +80,9 @@ public class TaskMagicDynamicRegistry extends AbstractMagicDynamicRegistry<TaskI
if(scheduledFuture != null){
try {
scheduledFuture.cancel(true);
} catch (Exception ignored) {
} catch (Exception e) {
String scriptName = MagicConfiguration.getMagicResourceService().getScriptName(info);
logger.warn("定时任务:[{}]取消失败", scriptName, e);
}
}
}
......
......@@ -36,6 +36,10 @@ public class Mapping {
this.prefix = StringUtils.defaultIfBlank(prefix, "");
}
public static Mapping create(RequestMappingHandlerMapping mapping) {
return create(mapping, null, null);
}
public static Mapping create(RequestMappingHandlerMapping mapping, String base, String prefix) {
if (HAS_GET_PATTERN_PARSER) {
RequestMappingInfo.BuilderConfiguration config = new RequestMappingInfo.BuilderConfiguration();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册