-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #548 from HXSecurity/beta
bump version to 1.12.0-beta1
- Loading branch information
Showing
76 changed files
with
4,368 additions
and
440 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>dongtai-api-gather</artifactId> | ||
<groupId>io.dongtai.iast</groupId> | ||
<version>${revision}</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>dongtai-api-gather-dubbo-api</artifactId> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.apache.dubbo</groupId> | ||
<artifactId>dubbo</artifactId> | ||
<!-- 不要修改这个依赖版本,如果必须改动需要保证在 [2.7.13, 3.0.0) 区间 --> | ||
<version>2.7.21</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.alibaba</groupId> | ||
<artifactId>dubbo</artifactId> | ||
<version>2.6.12</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>io.dongtai.iast</groupId> | ||
<artifactId>dongtai-api-gather-openapi</artifactId> | ||
<version>${project.version}</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.dongtai.iast</groupId> | ||
<artifactId>dongtai-log</artifactId> | ||
<version>${project.version}</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
109 changes: 109 additions & 0 deletions
109
...r-dubbo-api/src/main/java/io/dongtai/iast/api/gather/dubbo/convertor/MethodConvertor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package io.dongtai.iast.api.gather.dubbo.convertor; | ||
|
||
import io.dongtai.iast.api.openapi.convertor.OpenApiSchemaConvertorManager; | ||
import io.dongtai.iast.api.openapi.domain.MediaType; | ||
import io.dongtai.iast.api.openapi.domain.Operation; | ||
import io.dongtai.iast.api.openapi.domain.Parameter; | ||
import io.dongtai.iast.api.openapi.domain.Response; | ||
import io.dongtai.log.DongTaiLog; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.*; | ||
|
||
/** | ||
* 用于把Dubbo的Service的方法转为Open API的Operation结构 | ||
* | ||
* @author CC11001100 | ||
* @since v1.12.0 | ||
*/ | ||
public class MethodConvertor { | ||
|
||
private OpenApiSchemaConvertorManager manager; | ||
private Method reflectionMethod; | ||
|
||
/** | ||
* @param manager | ||
* @param reflectionMethod 要转换的Method,一个Method对应着一个Operation | ||
*/ | ||
public MethodConvertor(OpenApiSchemaConvertorManager manager, Method reflectionMethod) { | ||
this.manager = manager; | ||
this.reflectionMethod = reflectionMethod; | ||
} | ||
|
||
public Operation convert() { | ||
Operation o = new Operation(); | ||
|
||
try { | ||
o.mergeParameters(this.parseParameters()); | ||
} catch (Throwable e) { | ||
DongTaiLog.debug("MethodConvertor.convert parseParameters exception", e); | ||
} | ||
|
||
try { | ||
o.setResponses(this.parseResponse()); | ||
} catch (Throwable e) { | ||
DongTaiLog.debug("MethodConvertor.convert parseResponse exception", e); | ||
} | ||
|
||
// 设置这两个字段 | ||
o.setOperationId(UUID.randomUUID().toString()); | ||
// 把类名设置为标签 | ||
o.setTags(Collections.singletonList(reflectionMethod.getDeclaringClass().getName())); | ||
|
||
return o; | ||
} | ||
|
||
/** | ||
* 把Dubbo的Service的方法返回值转换为Open API的Response | ||
* | ||
* @return | ||
*/ | ||
private Map<String, Response> parseResponse() { | ||
|
||
Class<?> returnType = this.reflectionMethod.getReturnType(); | ||
// 这里需要注意,可能会有返回值为空的情况,这种情况就认为是没有响应值 | ||
if (Void.TYPE == returnType) { | ||
return null; | ||
} | ||
|
||
// 把函数的返回值对应到HTTP的响应体上 | ||
Response r = new Response(); | ||
Map<String, MediaType> contentMap = new HashMap<>(); | ||
MediaType mediaType = new MediaType(); | ||
mediaType.setSchema(this.manager.convertClass(returnType)); | ||
contentMap.put(MediaType.APPLICATION_JSON, mediaType); | ||
r.setContent(contentMap); | ||
|
||
// 这里只处理正常返回的情况,认为是200的情况,至于throws抛出异常500的情况就不再处理了 | ||
Map<String, Response> responseMap = new HashMap<>(); | ||
r.setDescription(Response.MSG_OK); | ||
responseMap.put(Response.CODE_OK, r); | ||
|
||
return responseMap; | ||
} | ||
|
||
/** | ||
* 解析Method上的参数为OpenAPI的Parameter | ||
* | ||
* @return | ||
*/ | ||
private List<Parameter> parseParameters() { | ||
java.lang.reflect.Parameter[] reflectionParameterArray = this.reflectionMethod.getParameters(); | ||
if (reflectionParameterArray == null || reflectionParameterArray.length == 0) { | ||
return Collections.emptyList(); | ||
} | ||
List<Parameter> parameterList = new ArrayList<>(); | ||
for (java.lang.reflect.Parameter reflectionParameter : reflectionParameterArray) { | ||
try { | ||
Parameter convert = new ParameterConvertor(this.manager, reflectionParameter).convert(); | ||
if (convert != null) { | ||
parameterList.add(convert); | ||
} | ||
} catch (Throwable e) { | ||
DongTaiLog.debug("MethodConvertor.parseParameters ParameterConvertor exception", e); | ||
} | ||
} | ||
return parameterList; | ||
} | ||
|
||
} |
46 changes: 46 additions & 0 deletions
46
...ubbo-api/src/main/java/io/dongtai/iast/api/gather/dubbo/convertor/ParameterConvertor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package io.dongtai.iast.api.gather.dubbo.convertor; | ||
|
||
import io.dongtai.iast.api.openapi.convertor.OpenApiSchemaConvertorManager; | ||
import io.dongtai.iast.api.openapi.domain.Parameter; | ||
import io.dongtai.iast.api.openapi.domain.ParameterIn; | ||
import io.dongtai.iast.api.openapi.domain.Schema; | ||
|
||
/** | ||
* 方法参数级别的转换,把Dubbo的Service上的Method的Parameter转为Open API的Parameter的格式 | ||
* | ||
* @author CC11001100 | ||
* @since v1.12.0 | ||
*/ | ||
public class ParameterConvertor { | ||
|
||
private final OpenApiSchemaConvertorManager manager; | ||
private final java.lang.reflect.Parameter reflectionParameter; | ||
|
||
/** | ||
* @param manager | ||
* @param reflectionParameter 要转换的方法参数 | ||
*/ | ||
public ParameterConvertor(OpenApiSchemaConvertorManager manager, java.lang.reflect.Parameter reflectionParameter) { | ||
this.manager = manager; | ||
this.reflectionParameter = reflectionParameter; | ||
} | ||
|
||
public Parameter convert() { | ||
|
||
Parameter openApiParameter = new Parameter(); | ||
|
||
// 2023-6-25 18:23:17 以后得空的时候也许可以把这里优化一下,用asm拿到真正的参数名字,这样前端页面上用户看着心情会好一些 | ||
openApiParameter.setName(reflectionParameter.getName()); | ||
|
||
// 洞态开发人员内部约定:dubbo的参数固定认为是放在query上的,同时是必传的 | ||
openApiParameter.setIn(ParameterIn.Query); | ||
openApiParameter.setRequired(true); | ||
|
||
// 参数的类型转为Open API的类型,如果有涉及到复合类型的话存储到Open API的组件库中 | ||
Schema schema = this.manager.convertClass(this.reflectionParameter.getType()); | ||
openApiParameter.setSchema(schema); | ||
|
||
return openApiParameter; | ||
} | ||
|
||
} |
95 changes: 95 additions & 0 deletions
95
...-dubbo-api/src/main/java/io/dongtai/iast/api/gather/dubbo/convertor/ServiceConvertor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package io.dongtai.iast.api.gather.dubbo.convertor; | ||
|
||
import io.dongtai.iast.api.openapi.convertor.OpenApiSchemaConvertorManager; | ||
import io.dongtai.iast.api.openapi.domain.Operation; | ||
import io.dongtai.iast.api.openapi.domain.Path; | ||
import io.dongtai.log.DongTaiLog; | ||
|
||
import java.lang.reflect.Method; | ||
import java.lang.reflect.Parameter; | ||
import java.util.*; | ||
|
||
/** | ||
* 类级别的转换,将dubbo的Service接口转换为open api的格式 | ||
* | ||
* @author CC11001100 | ||
* @since v1.12.0 | ||
*/ | ||
public class ServiceConvertor { | ||
|
||
private OpenApiSchemaConvertorManager manager; | ||
private Class interfaceClass; | ||
|
||
public ServiceConvertor(OpenApiSchemaConvertorManager manager, Class interfaceClass) { | ||
this.manager = manager; | ||
this.interfaceClass = interfaceClass; | ||
} | ||
|
||
public Map<String, Path> convert() { | ||
Map<String, Path> pathMap = new HashMap<>(); | ||
for (Method parseServiceMethod : this.parseServiceMethods()) { | ||
try { | ||
Operation convert = new MethodConvertor(this.manager, parseServiceMethod).convert(); | ||
Path path = new Path(); | ||
path.setDubbo(convert); | ||
pathMap.put(this.buildSign(parseServiceMethod), path); | ||
} catch (Throwable e) { | ||
DongTaiLog.debug("ServiceConvertor.convert exception", e); | ||
} | ||
} | ||
return pathMap; | ||
} | ||
|
||
/** | ||
* 解析Service上提供的接口 | ||
* | ||
* @return | ||
*/ | ||
private List<Method> parseServiceMethods() { | ||
List<Method> methodList = new ArrayList<>(); | ||
Set<String> distinctSet = new HashSet<>(); | ||
Queue<Class> needProcessClassQueue = new LinkedList<>(); | ||
needProcessClassQueue.add(this.interfaceClass); | ||
while (!needProcessClassQueue.isEmpty()) { | ||
Class poll = needProcessClassQueue.poll(); | ||
|
||
// 收集当前类上的方法 | ||
Method[] declaredMethods = poll.getDeclaredMethods(); | ||
for (Method declaredMethod : declaredMethods) { | ||
String s = this.buildSign(declaredMethod); | ||
if (distinctSet.contains(s)) { | ||
continue; | ||
} | ||
distinctSet.add(s); | ||
methodList.add(declaredMethod); | ||
} | ||
|
||
// 收集父接口,以便等下处理父接口上的方法 | ||
needProcessClassQueue.addAll(Arrays.asList(poll.getInterfaces())); | ||
} | ||
|
||
return methodList; | ||
} | ||
|
||
/** | ||
* 方法的签名需要统一,签名的格式与dubbo流量采集那里保持一致,在server端要靠这个作为path把它们关联到一起 | ||
* | ||
* @param method | ||
* @return Example: /app.iast.common.dubbo.vul.VulService/runtimeExec(java.lang.String,java.lang.StringBuilder,byte[]) | ||
*/ | ||
private String buildSign(Method method) { | ||
StringBuilder sign = new StringBuilder(); | ||
sign.append("/").append(method.getDeclaringClass().getName()).append("/").append(method.getName()).append("("); | ||
Parameter[] parameters = method.getParameters(); | ||
if (parameters != null && parameters.length != 0) { | ||
for (int i = 0; i < parameters.length; i++) { | ||
sign.append(parameters[i].getType().getCanonicalName()); | ||
if (i + 1 < parameters.length) { | ||
sign.append(","); | ||
} | ||
} | ||
} | ||
return sign.append(")").toString(); | ||
} | ||
|
||
} |
Oops, something went wrong.