@@ -5,10 +5,39 @@ import com.nsgk.agentcentersdk.api.NSSDK; | |||||
import com.nsgk.agentcentersdk.api.NSSDKClient; | import com.nsgk.agentcentersdk.api.NSSDKClient; | ||||
import com.nsgk.agentcentersdk.core.NSProtocol; | import com.nsgk.agentcentersdk.core.NSProtocol; | ||||
import com.nsgk.agentcentersdk.entity.NSContractionEntity; | import com.nsgk.agentcentersdk.entity.NSContractionEntity; | ||||
import com.nsgk.agentcentersdk.utility.NSReflect; | |||||
public final class NSMain | public final class NSMain | ||||
{ | { | ||||
public static void main(String[] args) | |||||
public static void main(String[] args) throws Exception | |||||
{ | |||||
//Test(); | |||||
Test_reflect(); | |||||
} | |||||
public static void Test_reflect() throws InstantiationException, IllegalAccessException | |||||
{ | |||||
Class<?> NSContractionEntity_class = NSReflect.Class("com.nsgk.agentcentersdk.entity.NSContractionEntity"); | |||||
Class<?> NSSDK_class = NSReflect.Class("com.nsgk.agentcentersdk.api.NSSDK"); | |||||
Object client; | |||||
Object entity; | |||||
Object result; | |||||
NSReflect.CallStatic_s(NSSDK_class, "InitClient", String.class, "http://localhost", short.class, (short) 8081, String.class, "test", String.class, "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=="); | |||||
client = NSReflect.CallStatic(NSSDK_class, "InstanceClient"); | |||||
entity = NSContractionEntity_class.newInstance(); | |||||
NSReflect.Call(entity, "setBuildingTime", "2000-12-23"); | |||||
NSReflect.Call(entity, "setName", "测试合同"); | |||||
NSReflect.Call(entity, "setDeptId", 187L); | |||||
NSReflect.Call(entity, "setBookId", 166L); | |||||
NSReflect.Call(entity, "setOutId", 250L); | |||||
result = NSReflect.Call_s(client, "Send", int.class, NSProtocol.NS_PROTOCOL_CONTRACTION, NSReflect.Class("com.nsgk.agentcentersdk.entity.NSEntityBase"), entity); | |||||
System.err.println(result); | |||||
} | |||||
public static void Test() | |||||
{ | { | ||||
NSSDKClient client; | NSSDKClient client; | ||||
NSContractionEntity entity; | NSContractionEntity entity; | ||||
@@ -19,9 +48,10 @@ public final class NSMain | |||||
entity = new NSContractionEntity(); | entity = new NSContractionEntity(); | ||||
entity.setBuildingTime("2000-12-23") | entity.setBuildingTime("2000-12-23") | ||||
.setName("测试合同") | |||||
.setDeptId(187L) | |||||
.setBookId(166L) | |||||
.setName("测试合同") | |||||
.setDeptId(187L) | |||||
.setBookId(166L) | |||||
.setOutId(999L) | |||||
; | ; | ||||
result = client.Send(NSProtocol.NS_PROTOCOL_CONTRACTION, entity); | result = client.Send(NSProtocol.NS_PROTOCOL_CONTRACTION, entity); | ||||
System.err.println(result); | System.err.println(result); | ||||
@@ -2,22 +2,49 @@ package com.nsgk.agentcentersdk.api; | |||||
import com.alibaba.fastjson2.JSON; | import com.alibaba.fastjson2.JSON; | ||||
import com.alibaba.fastjson2.JSONObject; | import com.alibaba.fastjson2.JSONObject; | ||||
import com.nsgk.agentcentersdk.err.NSErrno; | |||||
import lombok.Data; | import lombok.Data; | ||||
// 服务端返回对象 | // 服务端返回对象 | ||||
@Data | @Data | ||||
public class NSApiResult | |||||
public final class NSApiResult | |||||
{ | { | ||||
public static final int NS_RESULT_SUCCESS = 200; | |||||
public static final int NS_RESULT_ERROR = 500; | |||||
public final int code; | public final int code; | ||||
public final String msg; | public final String msg; | ||||
public final Object data; | public final Object data; | ||||
public final long timestamp = System.currentTimeMillis(); | |||||
public final Long timestamp; | |||||
public final int errno; | |||||
NSApiResult(int code, String msg, Object data) | NSApiResult(int code, String msg, Object data) | ||||
{ | |||||
this(code, msg, data, NSErrno.ERRNO_OK); | |||||
} | |||||
NSApiResult(int code, String msg, Object data, int errno) | |||||
{ | |||||
this(code, msg, data, System.currentTimeMillis(), errno); | |||||
} | |||||
NSApiResult(int code, String msg, Object data, Long timestamp, int errno) | |||||
{ | { | ||||
this.code = code; | this.code = code; | ||||
this.msg = msg; | this.msg = msg; | ||||
this.data = data; | this.data = data; | ||||
this.timestamp = timestamp; | |||||
this.errno = errno; | |||||
} | |||||
static NSApiResult Success(String msg, Object data) | |||||
{ | |||||
return new NSApiResult(NS_RESULT_SUCCESS, msg, data); | |||||
} | |||||
static NSApiResult Error(int errno, String msg, Object data) | |||||
{ | |||||
return new NSApiResult(NS_RESULT_ERROR, msg, data, errno); | |||||
} | } | ||||
static NSApiResult FromJSON(String str) | static NSApiResult FromJSON(String str) | ||||
@@ -25,6 +52,12 @@ public class NSApiResult | |||||
JSONObject jsonObject; | JSONObject jsonObject; | ||||
jsonObject = JSON.parseObject(str); | jsonObject = JSON.parseObject(str); | ||||
return new NSApiResult(jsonObject.getInteger("code"), jsonObject.getString("msg"), jsonObject.get("data")); | |||||
return new NSApiResult( | |||||
jsonObject.getInteger("code"), | |||||
jsonObject.getString("msg"), | |||||
jsonObject.containsKey("data") ? jsonObject.get("data") : null, | |||||
jsonObject.containsKey("data") ? jsonObject.getLong("timestamp") : null, | |||||
jsonObject.containsKey("errno") ? jsonObject.getInteger("errno") : null | |||||
); | |||||
} | } | ||||
} | } |
@@ -1,11 +1,19 @@ | |||||
package com.nsgk.agentcentersdk.api; | package com.nsgk.agentcentersdk.api; | ||||
import cn.hutool.core.util.URLUtil; | import cn.hutool.core.util.URLUtil; | ||||
import com.nsgk.agentcentersdk.core.NSProtocol; | |||||
import com.nsgk.agentcentersdk.core.NSReportObject; | import com.nsgk.agentcentersdk.core.NSReportObject; | ||||
import com.nsgk.agentcentersdk.entity.NSEntityBase; | import com.nsgk.agentcentersdk.entity.NSEntityBase; | ||||
import com.nsgk.agentcentersdk.err.NSAssert; | |||||
import com.nsgk.agentcentersdk.err.NSErrGlobal; | |||||
import com.nsgk.agentcentersdk.err.NSErrno; | |||||
import com.nsgk.agentcentersdk.network.NSNetworkManager; | import com.nsgk.agentcentersdk.network.NSNetworkManager; | ||||
import com.nsgk.agentcentersdk.network.NSNetworkRequest; | import com.nsgk.agentcentersdk.network.NSNetworkRequest; | ||||
import com.nsgk.agentcentersdk.network.NSNetworkResponse; | import com.nsgk.agentcentersdk.network.NSNetworkResponse; | ||||
import com.nsgk.agentcentersdk.utility.NSCrypto; | |||||
import com.nsgk.agentcentersdk.utility.NSStr; | |||||
import java.util.Objects; | |||||
// SDK客户端 | // SDK客户端 | ||||
/* | /* | ||||
@@ -42,12 +50,16 @@ public final class NSSDKClient | |||||
NSReportObject<T> reportObject; | NSReportObject<T> reportObject; | ||||
NSNetworkRequest request; | NSNetworkRequest request; | ||||
NSAssert.NotNull(object, NSErrno.ERRNO_CLI_DATA_MISSING); | |||||
NSAssert.NotEmpty(identifier, NSErrno.ERRNO_CLI_PARAMETER_MISSING); | |||||
NSErrGlobal.ASSERT(NSProtocol.IsValid(protocol), NSErrno.ERRNO_SYS_INVALID_PROTOCOL); | |||||
url = NSApi.NS_API_REPORT; | url = NSApi.NS_API_REPORT; | ||||
reportObject = new NSReportObject<>(identifier, protocol, object); | reportObject = new NSReportObject<>(identifier, protocol, object); | ||||
request = new NSNetworkRequest(); | request = new NSNetworkRequest(); | ||||
request.setUrl(BuildUrl(url)); | request.setUrl(BuildUrl(url)); | ||||
request.WriteDataObject(reportObject, publicKey); | |||||
WriteDataObject(request, reportObject); | |||||
NSNetworkResponse response = NSNetworkManager.Post(request); | NSNetworkResponse response = NSNetworkManager.Post(request); | ||||
NSErrGlobal.ASSERT(response.IsSuccess(), NSErrno.ERRNO_SYS_HTTP); | |||||
String json = response.getData(); | String json = response.getData(); | ||||
return NSApiResult.FromJSON(json); | return NSApiResult.FromJSON(json); | ||||
} | } | ||||
@@ -56,4 +68,28 @@ public final class NSSDKClient | |||||
{ | { | ||||
return URLUtil.completeUrl(host + ":" + port, url); | return URLUtil.completeUrl(host + ":" + port, url); | ||||
} | } | ||||
private <T> void WriteDataObject(NSNetworkRequest request, NSReportObject<T> object) | |||||
{ | |||||
String dataStr; | |||||
request.ClearHeaders().AddHeader("sign", object.getSign()); | |||||
request.ClearQueries().AddQuery("identifier", object.getIdentifier()) | |||||
.AddQuery("protocol", object.getProtocol()) | |||||
.AddQuery("timestamp", object.getTimestamp()) | |||||
; | |||||
dataStr = object.getDataStr(); | |||||
try | |||||
{ | |||||
dataStr = NSCrypto.RSAEncrypt(dataStr, publicKey); | |||||
NSAssert.NotEmpty(dataStr, NSErrno.ERRNO_SYS_ENCRYPT_FAIL); | |||||
} | |||||
catch(Exception e) | |||||
{ | |||||
e.printStackTrace(); | |||||
NSErrGlobal.Throw(NSErrno.ERRNO_SYS_ENCRYPT_FAIL); | |||||
return; | |||||
} | |||||
request.setData(dataStr); | |||||
} | |||||
} | } |
@@ -2,12 +2,14 @@ package com.nsgk.agentcentersdk.api; | |||||
import com.nsgk.agentcentersdk.core.NSReportObject; | import com.nsgk.agentcentersdk.core.NSReportObject; | ||||
import com.nsgk.agentcentersdk.entity.NSEntityBase; | import com.nsgk.agentcentersdk.entity.NSEntityBase; | ||||
import com.nsgk.agentcentersdk.err.NSAssert; | |||||
import com.nsgk.agentcentersdk.err.NSErrGlobal; | |||||
import com.nsgk.agentcentersdk.err.NSErrno; | |||||
import com.nsgk.agentcentersdk.utility.NSArr; | import com.nsgk.agentcentersdk.utility.NSArr; | ||||
import com.nsgk.agentcentersdk.utility.NSCrypto; | import com.nsgk.agentcentersdk.utility.NSCrypto; | ||||
import com.nsgk.agentcentersdk.utility.NSHttp; | import com.nsgk.agentcentersdk.utility.NSHttp; | ||||
import javax.servlet.http.HttpServletRequest; | import javax.servlet.http.HttpServletRequest; | ||||
import java.util.Map; | |||||
// SDK服务端 | // SDK服务端 | ||||
public final class NSSDKServer | public final class NSSDKServer | ||||
@@ -27,24 +29,47 @@ public final class NSSDKServer | |||||
String data; | String data; | ||||
sign = request.getHeader("sign"); | sign = request.getHeader("sign"); | ||||
NSAssert.NotEmpty(sign, NSErrno.ERRNO_CLI_SIGN_MISSING); | |||||
data = NSHttp.GetRequestBody(request); | data = NSHttp.GetRequestBody(request); | ||||
NSAssert.NotEmpty(data, NSErrno.ERRNO_CLI_DATA_MISSING); | |||||
res = new NSReportObject<>(); | res = new NSReportObject<>(); | ||||
res.SetTimestampStr(request.getParameter("timestamp")) | res.SetTimestampStr(request.getParameter("timestamp")) | ||||
.setIdentifier(request.getParameter("identifier")) | .setIdentifier(request.getParameter("identifier")) | ||||
.SetProtocolStr(request.getParameter("protocol")) | .SetProtocolStr(request.getParameter("protocol")) | ||||
.SetDataStr(NSCrypto.RSADecrypt(data, privateKey), clazz) | |||||
; | ; | ||||
try | |||||
{ | |||||
data = NSCrypto.RSADecrypt(data, privateKey); | |||||
NSAssert.NotEmpty(data, NSErrno.ERRNO_SYS_DECRYPT_FAIL); | |||||
res.SetDataStr(data, clazz); | |||||
} | |||||
catch(Exception e) | |||||
{ | |||||
e.printStackTrace(); | |||||
return NSErrGlobal.ThrowAndReturnNull(NSErrno.ERRNO_SYS_DECRYPT_FAIL); | |||||
} | |||||
if(!res.CheckSign(sign)) | if(!res.CheckSign(sign)) | ||||
{ | { | ||||
return null; | |||||
return NSErrGlobal.ThrowAndReturn(NSErrno.ERRNO_SYS_INVALID_SIGN, null); | |||||
} | } | ||||
res.setSign(sign); | res.setSign(sign); | ||||
return res; | return res; | ||||
} | } | ||||
// 响应客户端 | // 响应客户端 | ||||
public NSApiResult Resp(int code, String msg, Object...data) | |||||
public static NSApiResult Resp(int code, String msg, Object...data) | |||||
{ | { | ||||
return new NSApiResult(code, msg, NSArr.DefParms(data)); | |||||
return new NSApiResult(code, msg, NSArr.DefParm(data)); | |||||
} | } | ||||
public static NSApiResult Success(String msg, Object...data) | |||||
{ | |||||
return NSApiResult.Success(msg, NSArr.DefParm(data)); | |||||
} | |||||
public static NSApiResult Fail(int errno, String msg, Object...data) | |||||
{ | |||||
return NSApiResult.Error(errno, msg, NSArr.DefParm(data)); | |||||
} | |||||
} | } |
@@ -13,5 +13,10 @@ public final class NSProtocol | |||||
return Math.abs(i); | return Math.abs(i); | ||||
} | } | ||||
public static boolean IsValid(int protocol) | |||||
{ | |||||
return protocol > 0; // TODO: full check | |||||
} | |||||
private NSProtocol() {} | private NSProtocol() {} | ||||
} | } |
@@ -2,6 +2,8 @@ package com.nsgk.agentcentersdk.core; | |||||
import cn.hutool.core.bean.BeanUtil; | import cn.hutool.core.bean.BeanUtil; | ||||
import com.alibaba.fastjson2.JSON; | import com.alibaba.fastjson2.JSON; | ||||
import com.nsgk.agentcentersdk.err.NSErrGlobal; | |||||
import com.nsgk.agentcentersdk.err.NSErrno; | |||||
import com.nsgk.agentcentersdk.utility.NSSignTool; | import com.nsgk.agentcentersdk.utility.NSSignTool; | ||||
import com.nsgk.agentcentersdk.utility.NSStr; | import com.nsgk.agentcentersdk.utility.NSStr; | ||||
import lombok.Data; | import lombok.Data; | ||||
@@ -14,11 +16,12 @@ import java.util.Map; | |||||
@Accessors(chain = true) | @Accessors(chain = true) | ||||
public class NSReportObject<T> | public class NSReportObject<T> | ||||
{ | { | ||||
protected static final String[] SIGN_FIELDS = { | |||||
"identifier", "protocol", "timestamp", "dataLength", | |||||
protected static final String[] SIGN_FIELDS = { // 字母顺序 | |||||
"identifier", "protocol", "timestamp", "length", | |||||
}; | }; | ||||
private String identifier; // 识别ID | private String identifier; // 识别ID | ||||
private String sign; // 签名 | private String sign; // 签名 | ||||
// md5(identifier=<客户端身份标识ID>&length=<data长度(加密前明文)>&protocol=<协议>×tamp=<毫秒时间戳>) | |||||
private int protocol = NSProtocol.NS_PROTOCOL_INVALID; // 协议 | private int protocol = NSProtocol.NS_PROTOCOL_INVALID; // 协议 | ||||
private Long timestamp; // 客户端时间戳 | private Long timestamp; // 客户端时间戳 | ||||
private T data; | private T data; | ||||
@@ -60,16 +63,26 @@ public class NSReportObject<T> | |||||
public boolean IsValid() | public boolean IsValid() | ||||
{ | { | ||||
return NSStr.IsNotEmpty(identifier) && null != timestamp && protocol > 0; | |||||
return NSStr.IsNotEmpty(identifier) && null != timestamp && timestamp > 0 && NSProtocol.IsValid(protocol); | |||||
} | } | ||||
//"d10457fb8d1ae32b27f9eb9c0a107c75" | |||||
public String Sign() | public String Sign() | ||||
{ | { | ||||
Map<String, Object> map; | Map<String, Object> map; | ||||
map = BeanUtil.beanToMap(this); | |||||
map.put("dataLength", NSStr.Length(dataStr)); | |||||
return NSSignTool.Sign(map, SIGN_FIELDS); | |||||
NSErrGlobal.ASSERT(IsValid(), NSErrno.ERRNO_CLI_PARAMETER_MISSING); | |||||
try | |||||
{ | |||||
map = BeanUtil.beanToMap(this); | |||||
map.put("length", NSStr.Length(dataStr)); | |||||
return NSSignTool.Sign(map, SIGN_FIELDS); | |||||
} | |||||
catch(Exception e) | |||||
{ | |||||
e.printStackTrace(); | |||||
return NSErrGlobal.ThrowAndReturnNull(NSErrno.ERRNO_SYS_INVALID_SIGN); | |||||
} | |||||
} | } | ||||
public boolean CheckSign(String src) | public boolean CheckSign(String src) | ||||
@@ -1,9 +1,12 @@ | |||||
package com.nsgk.agentcentersdk.entity; | package com.nsgk.agentcentersdk.entity; | ||||
import com.nsgk.agentcentersdk.utility.NSArr; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.experimental.Accessors; | import lombok.experimental.Accessors; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.util.LinkedHashMap; | |||||
import java.util.Map; | |||||
// 基本实体 | // 基本实体 | ||||
@Data | @Data | ||||
@@ -19,5 +22,47 @@ public abstract class NSEntityBase implements Serializable | |||||
protected Long deptId; | protected Long deptId; | ||||
/** 外部ID */ | /** 外部ID */ | ||||
private Long outId; | |||||
protected Long outId; | |||||
protected Map<String, Object> parms; | |||||
protected Map<String, Object> PARMS() | |||||
{ | |||||
if(null == parms) | |||||
parms = new LinkedHashMap<>(); | |||||
return parms; | |||||
} | |||||
@SuppressWarnings("unchecked") | |||||
public <T extends NSEntityBase> T Parm(String name, Object val) | |||||
{ | |||||
PARMS().put(name, val); | |||||
return (T)this; | |||||
} | |||||
@SuppressWarnings("unchecked") | |||||
public <T extends NSEntityBase> T DelParm(String...name) | |||||
{ | |||||
if(null != parms && NSArr.IsNotEmpty(name)) | |||||
{ | |||||
NSArr.Stream(name).forEach(parms::remove); | |||||
} | |||||
return (T)this; | |||||
} | |||||
public boolean HasParm(String name) | |||||
{ | |||||
if(null == parms) | |||||
return false; | |||||
return parms.containsKey(name); | |||||
} | |||||
@SuppressWarnings("unchecked") | |||||
public <T> T ParmT(String name, T...val) | |||||
{ | |||||
T def = NSArr.DefParm(val); | |||||
if(null == parms) | |||||
return def; | |||||
return (T)parms.getOrDefault(name, def); | |||||
} | |||||
} | } |
@@ -0,0 +1,28 @@ | |||||
package com.nsgk.agentcentersdk.err; | |||||
import cn.hutool.core.collection.CollectionUtil; | |||||
import com.nsgk.agentcentersdk.utility.NSStr; | |||||
import java.util.Collection; | |||||
import java.util.Objects; | |||||
// 断言 | |||||
public final class NSAssert | |||||
{ | |||||
public static void NotNull(Object obj, Integer...err) | |||||
{ | |||||
NSErrGlobal.ASSERT(Objects.nonNull(obj), err); | |||||
} | |||||
public static void NotEmpty(String obj, Integer...err) | |||||
{ | |||||
NSErrGlobal.ASSERT(NSStr.IsNotEmpty(obj), err); | |||||
} | |||||
public static void NotEmpty(Collection<?> obj, Integer...err) | |||||
{ | |||||
NSErrGlobal.ASSERT(CollectionUtil.isNotEmpty(obj), err); | |||||
} | |||||
private NSAssert() {} | |||||
} |
@@ -0,0 +1,98 @@ | |||||
package com.nsgk.agentcentersdk.err; | |||||
import com.nsgk.agentcentersdk.utility.NSArr; | |||||
import java.io.Serializable; | |||||
// 全局错误记录 | |||||
public final class NSErrGlobal | |||||
{ | |||||
private static final ThreadLocal<Integer> errno = new ThreadLocal<>(); | |||||
public static int Err(int newErr) | |||||
{ | |||||
int err; | |||||
err = errno.get(); | |||||
errno.set(newErr); | |||||
return err; | |||||
} | |||||
public static void Throw(int err) | |||||
{ | |||||
if(err == NSErrno.ERRNO_OK) | |||||
return; | |||||
throw new NSException(err); | |||||
} | |||||
public static void Throw() | |||||
{ | |||||
Throw(Errno()); | |||||
} | |||||
public static <T> T ThrowAndReturnNull(int err) | |||||
{ | |||||
return ThrowAndReturn(err, null); | |||||
} | |||||
public static <T> T ThrowAndReturnNull() | |||||
{ | |||||
return ThrowAndReturn(null); | |||||
} | |||||
public static <T> T ThrowAndReturn(int err, T t) | |||||
{ | |||||
if(err == NSErrno.ERRNO_OK) | |||||
return t; | |||||
throw new NSException(err); | |||||
} | |||||
public static <T> T ThrowAndReturn(T t) | |||||
{ | |||||
return ThrowAndReturn(Errno(), t); | |||||
} | |||||
public static <T> T Return(int err, T t) | |||||
{ | |||||
if(err != NSErrno.ERRNO_OK) | |||||
Err(err); | |||||
return t; | |||||
} | |||||
public static <T> T Return(T t) | |||||
{ | |||||
return Return(Errno(), t); | |||||
} | |||||
// 默认清除 | |||||
public static int Errno(boolean...clear) | |||||
{ | |||||
int err; | |||||
err = errno.get(); | |||||
if(null == clear || clear.length == 0 || clear[0]) | |||||
errno.set(NSErrno.ERRNO_OK); | |||||
return err; | |||||
} | |||||
public static boolean HasError(boolean...clear) | |||||
{ | |||||
return Errno(clear) != NSErrno.ERRNO_OK; | |||||
} | |||||
public static String Error(boolean...clear) | |||||
{ | |||||
return NSErrno.ErrStr(Errno(clear)); | |||||
} | |||||
public static void ASSERT(boolean expression, Integer...err) | |||||
{ | |||||
int e; | |||||
e = NSArr.GetParm(NSErrno.ERRNO_ERROR, err); | |||||
if(!expression) | |||||
Throw(e); | |||||
} | |||||
private NSErrGlobal() {} | |||||
} |
@@ -0,0 +1,43 @@ | |||||
package com.nsgk.agentcentersdk.err; | |||||
// 错误码 | |||||
public final class NSErrno | |||||
{ | |||||
public static final int ERRNO_OK = 0; | |||||
public static final int ERRNO_ERROR = 0x00001; | |||||
public static final int ERRNO_SYS_INVALID_SIGN = 0x01001; | |||||
public static final int ERRNO_SYS_ENCRYPT_FAIL = 0x01002; | |||||
public static final int ERRNO_SYS_DECRYPT_FAIL = 0x01003; | |||||
public static final int ERRNO_SYS_INVALID_PROTOCOL = 0x01004; | |||||
public static final int ERRNO_SYS_SIGN_FAIL = 0x01005; | |||||
public static final int ERRNO_SYS_HTTP = 0x01006; | |||||
public static final int ERRNO_CLI_PARAMETER_MISSING = 0x03001; | |||||
public static final int ERRNO_CLI_DATA_MISSING = 0x03002; | |||||
public static final int ERRNO_CLI_SIGN_MISSING = 0x03003; | |||||
public static final int ERRNO_SRV_HTTP = 0x04001; | |||||
private NSErrno() {} | |||||
public static String ErrStr(int errno) | |||||
{ | |||||
switch(errno) | |||||
{ | |||||
case ERRNO_SYS_INVALID_SIGN: return "签名无效"; | |||||
case ERRNO_SYS_ENCRYPT_FAIL: return "加密失败"; | |||||
case ERRNO_SYS_DECRYPT_FAIL: return "解密失败"; | |||||
case ERRNO_SYS_INVALID_PROTOCOL: return "无效协议"; | |||||
case ERRNO_SYS_SIGN_FAIL: return "签名失败"; | |||||
case ERRNO_SYS_HTTP: return "Http请求错误"; | |||||
case ERRNO_CLI_PARAMETER_MISSING: return "参数缺失"; | |||||
case ERRNO_CLI_DATA_MISSING: return "数据缺失"; | |||||
case ERRNO_CLI_SIGN_MISSING: return "签名缺失"; | |||||
case ERRNO_ERROR: default: return "错误"; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,21 @@ | |||||
package com.nsgk.agentcentersdk.err; | |||||
import lombok.Data; | |||||
@Data | |||||
public final class NSException extends RuntimeException | |||||
{ | |||||
private final int errno; | |||||
public NSException(int errno) | |||||
{ | |||||
super(NSErrno.ErrStr(errno)); | |||||
this.errno = errno; | |||||
} | |||||
public NSException(int errno, String error) | |||||
{ | |||||
super(error); | |||||
this.errno = errno; | |||||
} | |||||
} |
@@ -10,16 +10,4 @@ import lombok.experimental.Accessors; | |||||
@Accessors(chain = true) | @Accessors(chain = true) | ||||
public class NSNetworkRequest extends NSNetworkTransport | public class NSNetworkRequest extends NSNetworkTransport | ||||
{ | { | ||||
public <T> void WriteDataObject(NSReportObject<T> object, String publicKey) | |||||
{ | |||||
String dataStr; | |||||
ClearHeaders().AddHeader("sign", object.getSign()); | |||||
ClearQueries().AddQuery("identifier", object.getIdentifier()) | |||||
.AddQuery("protocol", object.getProtocol()) | |||||
.AddQuery("timestamp", object.getTimestamp()) | |||||
; | |||||
dataStr = object.getDataStr(); | |||||
setData(NSCrypto.RSAEncrypt(dataStr, publicKey)); | |||||
} | |||||
} | } |
@@ -5,7 +5,6 @@ import com.nsgk.agentcentersdk.utility.NSStr; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.experimental.Accessors; | import lombok.experimental.Accessors; | ||||
import java.util.HashMap; | |||||
import java.util.LinkedHashMap; | import java.util.LinkedHashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
@@ -40,7 +39,7 @@ public class NSNetworkTransport | |||||
public String Header(String name, String...value) | public String Header(String name, String...value) | ||||
{ | { | ||||
return headers.getOrDefault(name, NSArr.DefParms(value)); | |||||
return headers.getOrDefault(name, NSArr.DefParm(value)); | |||||
} | } | ||||
public NSNetworkTransport ClearQueries() | public NSNetworkTransport ClearQueries() | ||||
@@ -57,6 +56,6 @@ public class NSNetworkTransport | |||||
public Object Query(String name, Object...value) | public Object Query(String name, Object...value) | ||||
{ | { | ||||
return query.getOrDefault(name, NSArr.DefParms(value)); | |||||
return query.getOrDefault(name, NSArr.DefParm(value)); | |||||
} | } | ||||
} | } |
@@ -1,14 +1,39 @@ | |||||
package com.nsgk.agentcentersdk.utility; | package com.nsgk.agentcentersdk.utility; | ||||
import java.util.ArrayList; | |||||
import java.util.stream.Stream; | |||||
// 数组工具 | // 数组工具 | ||||
public final class NSArr | public final class NSArr | ||||
{ | { | ||||
public static <T> T DefParms(T...args) | |||||
public static <T> T DefParm(T...args) | |||||
{ | { | ||||
if(null == args || args.length == 0) | if(null == args || args.length == 0) | ||||
return null; | return null; | ||||
return args[0]; | return args[0]; | ||||
} | } | ||||
public static <T> T GetParm(T def, T[] args) | |||||
{ | |||||
if(null == args || args.length == 0) | |||||
return def; | |||||
return args[0]; | |||||
} | |||||
public static <T> boolean IsEmpty(T...args) | |||||
{ | |||||
return(null == args || args.length == 0); | |||||
} | |||||
public static <T> boolean IsNotEmpty(T...args) | |||||
{ | |||||
return !IsEmpty(args); | |||||
} | |||||
public static <T> Stream<T> Stream(T...args) | |||||
{ | |||||
return IsEmpty(args) ? new ArrayList<T>().stream() : Stream.of(args); | |||||
} | |||||
private NSArr() {} | private NSArr() {} | ||||
} | } |
@@ -0,0 +1,144 @@ | |||||
package com.nsgk.agentcentersdk.utility; | |||||
import java.lang.reflect.Method; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
// 反射工具 | |||||
public final class NSReflect | |||||
{ | |||||
public static Class<?> Class(String className) | |||||
{ | |||||
try | |||||
{ | |||||
return Class.forName(className); | |||||
} | |||||
catch(ClassNotFoundException e) | |||||
{ | |||||
e.printStackTrace(); | |||||
throw new RuntimeException("SDK版本不匹配"); | |||||
} | |||||
} | |||||
@SuppressWarnings("unchecked") | |||||
public static <T> T CallStaticT(Class<?> classObject, String methodName, Object...args) | |||||
{ | |||||
return (T)CallStatic(classObject, methodName, args); | |||||
} | |||||
@SuppressWarnings("unchecked") | |||||
public static <T> T CallStaticT_s(Class<?> classObject, String methodName, Object...args) | |||||
{ | |||||
return (T)CallStatic_s(classObject, methodName, args); | |||||
} | |||||
public static Object CallStatic(Class<?> classObject, String methodName, Object...args) | |||||
{ | |||||
if(null == args || args.length == 0) | |||||
return CallStatic_s(classObject, methodName); | |||||
Object[] objs = new Object[args.length * 2]; | |||||
for(int i = 0; i < args.length; i++) | |||||
{ | |||||
objs[i * 2] = args[i].getClass(); | |||||
objs[i * 2 + 1] = args[i]; | |||||
} | |||||
return CallStatic_s(classObject, methodName, objs); | |||||
} | |||||
public static Object CallStatic_s(Class<?> classObject, String methodName, Object...args) | |||||
{ | |||||
List<Class<?>> classes = new ArrayList<>(); | |||||
List<Object> params = new ArrayList<>(); | |||||
if(null != args && args.length > 0) | |||||
{ | |||||
for(int i = 0; i < args.length; i += 2) | |||||
{ | |||||
Class<?> clazz; | |||||
Object c = args[i]; | |||||
if(null != c) | |||||
clazz = (Class<?>) c; | |||||
else | |||||
clazz = args[i + 1].getClass(); | |||||
classes.add(clazz); | |||||
params.add(args[i + 1]); | |||||
} | |||||
} | |||||
try | |||||
{ | |||||
Method method = classObject.getMethod(methodName, classes.toArray(new Class<?>[0])); | |||||
return method.invoke(null, params.toArray(new Object[0])); | |||||
} | |||||
catch(NoSuchMethodException | IllegalAccessException | IllegalArgumentException e) | |||||
{ | |||||
e.printStackTrace(); | |||||
throw new RuntimeException("SDK版本不匹配"); | |||||
} | |||||
catch(Exception e) | |||||
{ | |||||
e.printStackTrace(); | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
@SuppressWarnings("unchecked") | |||||
public static <T> T CallT(Object object, String methodName, Object...args) | |||||
{ | |||||
return (T)Call(object, methodName, args); | |||||
} | |||||
@SuppressWarnings("unchecked") | |||||
public static <T> T CallT_s(Object object, String methodName, Object...args) | |||||
{ | |||||
return (T)Call_s(object, methodName, args); | |||||
} | |||||
public static Object Call(Object object, String methodName, Object...args) | |||||
{ | |||||
if(null == args || args.length == 0) | |||||
return Call_s(object, methodName); | |||||
Object[] objs = new Object[args.length * 2]; | |||||
for(int i = 0; i < args.length; i++) | |||||
{ | |||||
objs[i * 2] = args[i].getClass(); | |||||
objs[i * 2 + 1] = args[i]; | |||||
} | |||||
return Call_s(object, methodName, objs); | |||||
} | |||||
public static Object Call_s(Object object, String methodName, Object...args) | |||||
{ | |||||
List<Class<?>> classes = new ArrayList<>(); | |||||
List<Object> params = new ArrayList<>(); | |||||
if(null != args && args.length > 0) | |||||
{ | |||||
for(int i = 0; i < args.length; i += 2) | |||||
{ | |||||
Class<?> clazz; | |||||
Object c = args[i]; | |||||
if(null != c) | |||||
clazz = (Class<?>) c; | |||||
else | |||||
clazz = args[i + 1].getClass(); | |||||
classes.add(clazz); | |||||
params.add(args[i + 1]); | |||||
} | |||||
} | |||||
try | |||||
{ | |||||
Method method = object.getClass().getMethod(methodName, classes.toArray(new Class<?>[0])); | |||||
return method.invoke(object, params.toArray(new Object[0])); | |||||
} | |||||
catch(NoSuchMethodException | IllegalAccessException | IllegalArgumentException e) | |||||
{ | |||||
e.printStackTrace(); | |||||
throw new RuntimeException("SDK版本不匹配"); | |||||
} | |||||
catch(Exception e) | |||||
{ | |||||
e.printStackTrace(); | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
private NSReflect() {} | |||||
} |
@@ -24,7 +24,7 @@ public final class NSSignTool | |||||
fields = Arrays.stream(signFields).sorted(String::compareTo).collect(Collectors.toList()); | fields = Arrays.stream(signFields).sorted(String::compareTo).collect(Collectors.toList()); | ||||
sb = new StringBuilder(); | sb = new StringBuilder(); | ||||
for(int i = 0; i < fields.size(); i++) | for(int i = 0; i < fields.size(); i++) | ||||
{//dataLength=69&identifier=test&protocol=1×tamp=1683442648774 | |||||
{ | |||||
if(i > 0) | if(i > 0) | ||||
sb.append("&"); | sb.append("&"); | ||||
String key = fields.get(i); | String key = fields.get(i); | ||||
@@ -3,10 +3,17 @@ package com.ruoyi.web.controller.agentcenter; | |||||
import com.nsgk.agentcentersdk.api.NSApiResult; | import com.nsgk.agentcentersdk.api.NSApiResult; | ||||
import com.nsgk.agentcentersdk.api.NSSDK; | import com.nsgk.agentcentersdk.api.NSSDK; | ||||
import com.nsgk.agentcentersdk.api.NSSDKServer; | import com.nsgk.agentcentersdk.api.NSSDKServer; | ||||
import com.nsgk.agentcentersdk.core.NSProtocol; | |||||
import com.nsgk.agentcentersdk.core.NSReportObject; | import com.nsgk.agentcentersdk.core.NSReportObject; | ||||
import com.nsgk.agentcentersdk.entity.NSContractionEntity; | import com.nsgk.agentcentersdk.entity.NSContractionEntity; | ||||
import com.nsgk.agentcentersdk.err.NSErrGlobal; | |||||
import com.nsgk.agentcentersdk.err.NSErrno; | |||||
import com.nsgk.agentcentersdk.err.NSException; | |||||
import com.ruoyi.agentcenter.object.ContractionMessage; | |||||
import com.ruoyi.agentcenter.object.Message; | |||||
import com.ruoyi.common.config.RuoYiConfig; | import com.ruoyi.common.config.RuoYiConfig; | ||||
import com.ruoyi.common.core.controller.BaseController; | import com.ruoyi.common.core.controller.BaseController; | ||||
import com.ruoyi.common.utils.EventBusEngine; | |||||
import org.springframework.web.bind.annotation.PostMapping; | import org.springframework.web.bind.annotation.PostMapping; | ||||
import org.springframework.web.bind.annotation.RequestMapping; | import org.springframework.web.bind.annotation.RequestMapping; | ||||
import org.springframework.web.bind.annotation.RestController; | import org.springframework.web.bind.annotation.RestController; | ||||
@@ -32,7 +39,7 @@ public class AgentCenterController extends BaseController | |||||
server = NSSDK.InstanceServer(); | server = NSSDK.InstanceServer(); | ||||
recv = server.Recv(request, NSContractionEntity.class); | recv = server.Recv(request, NSContractionEntity.class); | ||||
return server.Resp(200, "测试成功", recv.getDataStr()); | |||||
return server.Resp(0, "测试成功", recv.getDataStr()); | |||||
} | } | ||||
@PostMapping("/report") | @PostMapping("/report") | ||||
@@ -42,9 +49,36 @@ public class AgentCenterController extends BaseController | |||||
NSReportObject<NSContractionEntity> recv; | NSReportObject<NSContractionEntity> recv; | ||||
NSSDK.InitServer(RuoYiConfig.Secret.privateKey); | NSSDK.InitServer(RuoYiConfig.Secret.privateKey); | ||||
server = NSSDK.InstanceServer(); | |||||
recv = server.Recv(request, NSContractionEntity.class); | |||||
try | |||||
{ | |||||
server = NSSDK.InstanceServer(); | |||||
recv = server.Recv(request, NSContractionEntity.class); | |||||
EventBusEngine.Post(convMsg(recv)); | |||||
return NSSDKServer.Success("上报成功"); | |||||
} | |||||
catch(NSException e) | |||||
{ | |||||
return NSSDKServer.Fail(e.getErrno(), e.getMessage()); | |||||
} | |||||
} | |||||
private Message<?> convMsg(NSReportObject<?> reportObject) | |||||
{ | |||||
Message<?> msg; | |||||
int protocol; | |||||
return server.Resp(200, "上报成功", recv.getDataStr()); | |||||
protocol = reportObject.getProtocol(); | |||||
switch(reportObject.getProtocol()) | |||||
{ | |||||
case NSProtocol.NS_PROTOCOL_CONTRACTION: | |||||
msg = new ContractionMessage(protocol, reportObject.getIdentifier(), reportObject.getTimestamp(), (NSContractionEntity)reportObject.getData()); | |||||
break; | |||||
default: | |||||
NSErrGlobal.Err(NSErrno.ERRNO_SYS_INVALID_PROTOCOL); | |||||
throw new RuntimeException(String.format("未知的协议类型: 0x%x", protocol)); | |||||
} | |||||
return msg; | |||||
} | } | ||||
} | } |
@@ -0,0 +1,26 @@ | |||||
package com.ruoyi.agentcenter.listener; | |||||
import com.alibaba.fastjson2.JSONObject; | |||||
import com.google.common.eventbus.Subscribe; | |||||
import com.ruoyi.agentcenter.object.ContractionMessage; | |||||
import com.ruoyi.common.utils.EventBusEngine; | |||||
import org.springframework.stereotype.Component; | |||||
import javax.annotation.PostConstruct; | |||||
@Component | |||||
public class ContractionListener | |||||
{ | |||||
@PostConstruct | |||||
public void init() | |||||
{ | |||||
EventBusEngine.Register(this); | |||||
} | |||||
@Subscribe | |||||
//@AllowConcurrentEvents | |||||
public void handle(ContractionMessage msg) | |||||
{ | |||||
System.err.println(JSONObject.toJSONString(msg)); | |||||
} | |||||
} |
@@ -1,8 +1,7 @@ | |||||
package com.ruoyi.agentcenter.listener; | package com.ruoyi.agentcenter.listener; | ||||
import com.google.common.eventbus.AllowConcurrentEvents; | |||||
import com.google.common.eventbus.Subscribe; | import com.google.common.eventbus.Subscribe; | ||||
import com.ruoyi.common.object.Message; | |||||
import com.ruoyi.agentcenter.object.Message; | |||||
import com.ruoyi.common.utils.EventBusEngine; | import com.ruoyi.common.utils.EventBusEngine; | ||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
@@ -14,13 +13,13 @@ public class TestListener | |||||
@PostConstruct | @PostConstruct | ||||
public void init() | public void init() | ||||
{ | { | ||||
EventBusEngine.Register(this); | |||||
//EventBusEngine.Register(this); | |||||
} | } | ||||
@Subscribe | @Subscribe | ||||
//@AllowConcurrentEvents | //@AllowConcurrentEvents | ||||
public void handle(Message msg) | public void handle(Message msg) | ||||
{ | { | ||||
System.err.println("LLL " + msg.data + " " + Thread.currentThread().getId()); | |||||
System.err.println("LLL " + msg.getData() + " " + Thread.currentThread().getId()); | |||||
} | } | ||||
} | } |
@@ -0,0 +1,11 @@ | |||||
package com.ruoyi.agentcenter.object; | |||||
import com.nsgk.agentcentersdk.entity.NSContractionEntity; | |||||
public class ContractionMessage extends Message<NSContractionEntity> | |||||
{ | |||||
public ContractionMessage(int protocol, String identifier, Long timestamp, NSContractionEntity data) | |||||
{ | |||||
super(protocol, identifier, timestamp, data); | |||||
} | |||||
} |
@@ -0,0 +1,31 @@ | |||||
package com.ruoyi.agentcenter.object; | |||||
import com.nsgk.agentcentersdk.core.NSProtocol; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public abstract class Message<T> | |||||
{ | |||||
private final int protocol; // 协议 | |||||
private final String identifier; // 识别ID | |||||
private final Long timestamp; // 客户端时间戳 | |||||
private final T data; | |||||
public Message() | |||||
{ | |||||
this.protocol = NSProtocol.NS_PROTOCOL_INVALID; | |||||
this.identifier = ""; | |||||
this.timestamp = 0L; | |||||
this.data = null; | |||||
} | |||||
public Message(int protocol, String identifier, Long timestamp, T data) | |||||
{ | |||||
this.protocol = protocol; | |||||
this.identifier = identifier; | |||||
this.timestamp = timestamp; | |||||
this.data = data; | |||||
} | |||||
} |
@@ -1,14 +0,0 @@ | |||||
package com.ruoyi.common.object; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public final class Message | |||||
{ | |||||
public static final int PROTOCOL_INVALID = 0; | |||||
public int protocol = PROTOCOL_INVALID; | |||||
public Object data; | |||||
} |