mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
5.0
This commit is contained in:
86
sop-support/sop-service-support/pom.xml
Normal file
86
sop-support/sop-service-support/pom.xml
Normal file
@@ -0,0 +1,86 @@
|
||||
<?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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-service-support</artifactId>
|
||||
<version>5.0.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<version>3.2.10</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.34</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.3</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<configuration>
|
||||
<skipTests>true</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
<configuration>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@@ -0,0 +1,39 @@
|
||||
package com.gitee.sop.support.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
@Inherited
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Open {
|
||||
|
||||
/**
|
||||
* 接口名,如:member.user.get
|
||||
*/
|
||||
String value();
|
||||
|
||||
/**
|
||||
* 版本号,默认版本号是"1.0"
|
||||
*/
|
||||
String version() default "1.0";
|
||||
|
||||
/**
|
||||
* 指定接口是否需要授权才能访问,可在admin中进行修改
|
||||
*/
|
||||
boolean permission() default false;
|
||||
|
||||
/**
|
||||
* 是否需要appAuthToken,设置为true,网关端会校验token是否存在
|
||||
*/
|
||||
boolean needToken() default false;
|
||||
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
package com.gitee.sop.support.context;
|
||||
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public class OpenContext {
|
||||
|
||||
/** 分配给开发者的应用ID */
|
||||
private static final String APP_ID_NAME = "client.app_id";
|
||||
/** 接口名称 */
|
||||
private static final String API_NAME = "client.method";
|
||||
/** 调用的接口版本 */
|
||||
private static final String VERSION_NAME = "client.version";
|
||||
/** 开放平台主动通知商户服务器里指定的页面http/https路径 */
|
||||
private static final String NOTIFY_URL_NAME = "client.notify_url";
|
||||
/** OAuth 2.0授权token */
|
||||
private static final String APP_AUTH_TOKEN_NAME = "client.app_auth_token";
|
||||
private static final String CLIENT_IP = "client.ip";
|
||||
private static final String TRACE_ID = "client.trace_id";
|
||||
|
||||
/**
|
||||
* 获取appId
|
||||
*/
|
||||
public static String getAppId() {
|
||||
return RpcContext.getServerAttachment().getAttachment(APP_ID_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取apiName
|
||||
*/
|
||||
public static String getApiName() {
|
||||
return RpcContext.getServerAttachment().getAttachment(API_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取version
|
||||
*/
|
||||
public static String getVersion() {
|
||||
return RpcContext.getServerAttachment().getAttachment(VERSION_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token,没有返回null
|
||||
*/
|
||||
public static String getAppAuthToken() {
|
||||
return RpcContext.getServerAttachment().getAttachment(APP_AUTH_TOKEN_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端ip
|
||||
*/
|
||||
public static String getClientIp() {
|
||||
return RpcContext.getServerAttachment().getAttachment(CLIENT_IP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取回调地址
|
||||
*/
|
||||
public static String getNotifyUrl() {
|
||||
return RpcContext.getServerAttachment().getAttachment(NOTIFY_URL_NAME);
|
||||
}
|
||||
|
||||
public static String getTraceId() {
|
||||
return RpcContext.getServerAttachment().getAttachment(TRACE_ID);
|
||||
}
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
package com.gitee.sop.support.register;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.gitee.sop.support.annotation.Open;
|
||||
import com.gitee.sop.support.service.ApiRegisterService;
|
||||
import com.gitee.sop.support.service.dto.RegisterDTO;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public class ApiRegister {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(ApiRegister.class);
|
||||
|
||||
private final ApiRegisterService apiRegisterService;
|
||||
|
||||
public ApiRegister(ApiRegisterService apiRegisterService) {
|
||||
this.apiRegisterService = apiRegisterService;
|
||||
}
|
||||
|
||||
public void reg(String appName, Collection<Object> objects) {
|
||||
if (objects == null || objects.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Object serviceObj : objects) {
|
||||
Class<?> objClass = serviceObj.getClass();
|
||||
if (objClass.getAnnotation(DubboService.class) == null) {
|
||||
continue;
|
||||
}
|
||||
checkClass(objClass);
|
||||
|
||||
doWithMethod(objClass, (interfaceClass, method, open) ->
|
||||
this.regApi(appName, interfaceClass, method, open));
|
||||
}
|
||||
}
|
||||
|
||||
protected void doWithMethod(Class<?> objClass, RegisterCallback callback) {
|
||||
for (Method method : objClass.getMethods()) {
|
||||
Class<?> declaringClass = method.getDeclaringClass();
|
||||
if (declaringClass == Object.class) {
|
||||
continue;
|
||||
}
|
||||
for (Class<?> anInterface : declaringClass.getInterfaces()) {
|
||||
try {
|
||||
Method parentMethod = anInterface.getMethod(method.getName(), method.getParameterTypes());
|
||||
Open open = method.getAnnotation(Open.class);
|
||||
if (open == null) {
|
||||
open = parentMethod.getAnnotation(Open.class);
|
||||
}
|
||||
if (open != null) {
|
||||
callback.callback(anInterface, parentMethod, open);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void regApi(String appName, Class<?> interfaceClass, Method method, Open open) {
|
||||
List<ParamInfo> paramInfos = buildParamInfo(method);
|
||||
RegisterDTO registerDTO = new RegisterDTO();
|
||||
registerDTO.setApplication(appName);
|
||||
registerDTO.setApiName(open.value());
|
||||
registerDTO.setApiVersion(open.version());
|
||||
registerDTO.setInterfaceClassName(interfaceClass.getName());
|
||||
registerDTO.setMethodName(method.getName());
|
||||
registerDTO.setParamInfo(JSON.toJSONString(paramInfos));
|
||||
registerDTO.setIsPermission(parseBoolean(open.permission()));
|
||||
registerDTO.setIsNeedToken(parseBoolean(open.needToken()));
|
||||
LOG.info("注册开放接口, apiInfo=" + registerDTO);
|
||||
try {
|
||||
apiRegisterService.register(registerDTO);
|
||||
} catch (Exception e) {
|
||||
LOG.error("接口注册失败, registerDTO=" + registerDTO + ", method=" + method, e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ParamInfo> buildParamInfo(Method method) {
|
||||
Parameter[] parameters = method.getParameters();
|
||||
if (parameters.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Stream.of(parameters)
|
||||
.map(parameter -> {
|
||||
ParamInfo paramInfo = new ParamInfo();
|
||||
paramInfo.setName(parameter.getName());
|
||||
paramInfo.setType(parameter.getType().getName());
|
||||
Type parameterizedType = parameter.getParameterizedType();
|
||||
// 如果是集合
|
||||
if (parameterizedType instanceof ParameterizedType) {
|
||||
if (!Collection.class.isAssignableFrom(parameter.getType())) {
|
||||
throw new IllegalArgumentException("开放接口参数不正确,只支持集合泛型, method={}" + method);
|
||||
}
|
||||
ParameterizedType genericType = (ParameterizedType) parameterizedType;
|
||||
Type[] actualTypeArguments = genericType.getActualTypeArguments();
|
||||
Type actualTypeArgument = actualTypeArguments[0];
|
||||
paramInfo.setActualType(actualTypeArgument.getTypeName());
|
||||
}
|
||||
return paramInfo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
private int parseBoolean(boolean b) {
|
||||
return b ? 1 : 0;
|
||||
}
|
||||
|
||||
private void checkClass(Class<?> objClass) {
|
||||
Class<?>[] interfaces = objClass.getInterfaces();
|
||||
if (interfaces.length == 0) {
|
||||
throw new RuntimeException("Dubbo接口必须要实现接口, class=" + objClass.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Data
|
||||
private static class ParamInfo implements Serializable {
|
||||
private static final long serialVersionUID = -404173450677698875L;
|
||||
|
||||
private String name;
|
||||
private String type;
|
||||
private String actualType;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
package com.gitee.sop.support.register;
|
||||
|
||||
import com.gitee.sop.support.annotation.Open;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface RegisterCallback {
|
||||
void callback(Class<?> interfaceClass, Method method, Open open);
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
package com.gitee.sop.support.request;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Setter
|
||||
public class CommonFileData implements FileData, Serializable {
|
||||
private static final long serialVersionUID = -7737314661756983260L;
|
||||
|
||||
/**
|
||||
* 上传文件表单名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 原始文件名称,可能为null
|
||||
*/
|
||||
private String originalFilename;
|
||||
|
||||
/**
|
||||
* 文件的contentType,可能为null
|
||||
*/
|
||||
private String contentType;
|
||||
|
||||
/**
|
||||
* 文件内容
|
||||
*/
|
||||
private byte[] data;
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginalFilename() {
|
||||
return originalFilename;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return data == null || data.length == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
return data == null ? 0 : data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes() {
|
||||
return data;
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
package com.gitee.sop.support.request;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public interface FileData {
|
||||
|
||||
/**
|
||||
* 返回表单字段名
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* 返回文件原始名称.
|
||||
*/
|
||||
String getOriginalFilename();
|
||||
|
||||
/**
|
||||
* 返回文件Content type,没有指定返回null
|
||||
*/
|
||||
String getContentType();
|
||||
|
||||
/**
|
||||
* 文件内容是否为空
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* 返回文件内容大小单位byte,没有返回0
|
||||
*/
|
||||
long getSize();
|
||||
|
||||
/**
|
||||
* 返回文字字节内容
|
||||
*/
|
||||
byte[] getBytes();
|
||||
|
||||
/**
|
||||
* 返回文件流
|
||||
*/
|
||||
default InputStream getInputStream() {
|
||||
return new ByteArrayInputStream(getBytes());
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package com.gitee.sop.support.service;
|
||||
|
||||
import com.gitee.sop.support.service.dto.RegisterDTO;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public interface ApiRegisterService {
|
||||
/**
|
||||
* 接口注册
|
||||
*
|
||||
* @param registerDTO 接口信息
|
||||
*/
|
||||
void register(RegisterDTO registerDTO);
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
package com.gitee.sop.support.service;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public interface IsvService {
|
||||
void refresh(String appId);
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package com.gitee.sop.support.service.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class RegisterDTO implements Serializable {
|
||||
private static final long serialVersionUID = 2183251167679411550L;
|
||||
|
||||
private String application;
|
||||
|
||||
private String apiName;
|
||||
|
||||
private String apiVersion;
|
||||
|
||||
private String interfaceClassName;
|
||||
|
||||
private String methodName;
|
||||
|
||||
/**
|
||||
* 字段信息
|
||||
*
|
||||
* [{"name":"id": "type":"java.lang.Integer"}]
|
||||
*/
|
||||
private String paramInfo;
|
||||
|
||||
private Integer isPermission;
|
||||
|
||||
private Integer isNeedToken;
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1 @@
|
||||
com.gitee.sop.support.request.CommonFileData
|
@@ -0,0 +1,84 @@
|
||||
package com.gitee.sop.support;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public class FindTest extends TestCase {
|
||||
|
||||
@Test
|
||||
public void testFind() {
|
||||
ServiceImpl service = new ServiceImpl();
|
||||
Class<?> aClass = service.getClass();
|
||||
for (Method method : aClass.getMethods()) {
|
||||
Class<?> declaringClass = method.getDeclaringClass();
|
||||
if (declaringClass == Object.class) {
|
||||
continue;
|
||||
}
|
||||
//System.out.println(method);
|
||||
// System.out.println(method.getDeclaringClass().isInterface());
|
||||
for (Class<?> anInterface : declaringClass.getInterfaces()) {
|
||||
try {
|
||||
Method parentMethod = anInterface.getMethod(method.getName(), method.getParameterTypes());
|
||||
if (method.getName().equals(parentMethod.getName())) {
|
||||
System.out.println("same:" + method);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Service {
|
||||
void h();
|
||||
|
||||
String say();
|
||||
|
||||
void hello(int i);
|
||||
|
||||
String hello2(int i, List list);
|
||||
|
||||
String hello3(int i, int... j);
|
||||
|
||||
}
|
||||
|
||||
static class ServiceImpl implements Service {
|
||||
@Override
|
||||
public void h() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String say() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hello(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String hello2(int i, List list) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String hello3(int i, int... j) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public int add() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user