Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
ssssssss-team
magic-api
提交
e6578fc3
M
magic-api
项目概览
ssssssss-team
/
magic-api
12 个月 前同步成功
通知
41
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
magic-api
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
e6578fc3
编写于
1月 20, 2022
作者:
M
mxd
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
支持swagger
上级
5270b969
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
952 addition
and
165 deletion
+952
-165
magic-api-spring-boot-starter/pom.xml
magic-api-spring-boot-starter/pom.xml
+0
-52
magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicAPIAutoConfiguration.java
...gicapi/spring/boot/starter/MagicAPIAutoConfiguration.java
+1
-1
magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicAPIProperties.java
...ssss/magicapi/spring/boot/starter/MagicAPIProperties.java
+11
-0
magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicSwaggerConfiguration.java
...gicapi/spring/boot/starter/MagicSwaggerConfiguration.java
+89
-0
magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/SwaggerConfig.java
.../ssssssss/magicapi/spring/boot/starter/SwaggerConfig.java
+88
-0
magic-api/src/main/java/org/ssssssss/magicapi/core/config/Constants.java
...ain/java/org/ssssssss/magicapi/core/config/Constants.java
+15
-111
magic-api/src/main/java/org/ssssssss/magicapi/core/service/AbstractMagicDynamicRegistry.java
...s/magicapi/core/service/AbstractMagicDynamicRegistry.java
+6
-0
magic-api/src/main/java/org/ssssssss/magicapi/swagger/SwaggerEntity.java
...ain/java/org/ssssssss/magicapi/swagger/SwaggerEntity.java
+510
-0
magic-api/src/main/java/org/ssssssss/magicapi/swagger/SwaggerProvider.java
...n/java/org/ssssssss/magicapi/swagger/SwaggerProvider.java
+225
-0
magic-api/src/main/java/org/ssssssss/magicapi/task/service/TaskMagicDynamicRegistry.java
...sssss/magicapi/task/service/TaskMagicDynamicRegistry.java
+3
-1
magic-api/src/main/java/org/ssssssss/magicapi/utils/Mapping.java
...pi/src/main/java/org/ssssssss/magicapi/utils/Mapping.java
+4
-0
未找到文件。
magic-api-spring-boot-starter/pom.xml
浏览文件 @
e6578fc3
...
...
@@ -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>
magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicAPIAutoConfiguration.java
浏览文件 @
e6578fc3
...
...
@@ -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
,
Magic
SwaggerConfiguration
.
class
,
Magic
JsonAutoConfiguration
.
class
,
ApplicationUriPrinter
.
class
})
@EnableWebSocket
public
class
MagicAPIAutoConfiguration
implements
WebMvcConfigurer
,
WebSocketConfigurer
{
...
...
magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicAPIProperties.java
浏览文件 @
e6578fc3
...
...
@@ -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
;
}
}
magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicSwaggerConfiguration.java
0 → 100644
浏览文件 @
e6578fc3
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
;
}
}
magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/SwaggerConfig.java
0 → 100644
浏览文件 @
e6578fc3
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
;
}
}
magic-api/src/main/java/org/ssssssss/magicapi/core/config/Constants.java
浏览文件 @
e6578fc3
...
...
@@ -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"
;
}
magic-api/src/main/java/org/ssssssss/magicapi/core/service/AbstractMagicDynamicRegistry.java
浏览文件 @
e6578fc3
...
...
@@ -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
));
...
...
magic-api/src/main/java/org/ssssssss/magicapi/swagger/SwaggerEntity.java
0 → 100644
浏览文件 @
e6578fc3
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
;
}
}
}
magic-api/src/main/java/org/ssssssss/magicapi/swagger/SwaggerProvider.java
0 → 100644
浏览文件 @
e6578fc3
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
;
}
}
magic-api/src/main/java/org/ssssssss/magicapi/task/service/TaskMagicDynamicRegistry.java
浏览文件 @
e6578fc3
...
...
@@ -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
);
}
}
}
...
...
magic-api/src/main/java/org/ssssssss/magicapi/utils/Mapping.java
浏览文件 @
e6578fc3
...
...
@@ -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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录