diff --git a/did-common/src/main/java/io/github/ehlxr/did/common/Constants.java b/did-common/src/main/java/io/github/ehlxr/did/common/Constants.java
index 3844ebf..74c6d1d 100644
--- a/did-common/src/main/java/io/github/ehlxr/did/common/Constants.java
+++ b/did-common/src/main/java/io/github/ehlxr/did/common/Constants.java
@@ -45,6 +45,7 @@ public class Constants {
* 编码解码 byte 数组固定长度
*/
public static int DECODER_FRAMELENGTH = 100;
+
private Constants() {
}
diff --git a/did-common/src/main/java/io/github/ehlxr/did/common/NettyUtil.java b/did-common/src/main/java/io/github/ehlxr/did/common/NettyUtil.java
index 86e1ba7..284e141 100644
--- a/did-common/src/main/java/io/github/ehlxr/did/common/NettyUtil.java
+++ b/did-common/src/main/java/io/github/ehlxr/did/common/NettyUtil.java
@@ -5,7 +5,6 @@ import io.netty.channel.ChannelFutureListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.*;
import java.net.SocketAddress;
/**
@@ -40,31 +39,4 @@ public class NettyUtil {
logger.info("closeChannel: close the connection to remote address[{}] result: {}",
addrRemote, future.isSuccess()));
}
-
- public static byte[] toBytes(Object obj) throws IOException {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(bos);
- oos.writeObject(obj);
- oos.flush();
-
- // if (bytes.length > Constants.DECODER_FRAMELENGTH) {
- // logger.error("bytes length should not bigger than {}", Constants.DECODER_FRAMELENGTH);
- // return null;
- // } else if (bytes.length < Constants.DECODER_FRAMELENGTH) {
- // byte[] result = new byte[Constants.DECODER_FRAMELENGTH];
- //
- // // 如果长度不足,填充
- // System.arraycopy(bytes, 0, result, 0, bytes.length);
- // return result;
- // }
-
- return bos.toByteArray();
- }
-
- public static Object toObject(byte[] bts) throws IOException, ClassNotFoundException {
- ByteArrayInputStream bis = new ByteArrayInputStream(bts);
- ObjectInputStream ois = new ObjectInputStream(bis);
-
- return ois.readObject();
- }
}
diff --git a/did-core/pom.xml b/did-core/pom.xml
new file mode 100644
index 0000000..eabaa92
--- /dev/null
+++ b/did-core/pom.xml
@@ -0,0 +1,43 @@
+
+
+
+ did-parent
+ io.github.ehlxr
+ 1.0.2-SNAPSHOT
+
+ 4.0.0
+
+ did-core
+
+
+
+ io.github.ehlxr
+ did-common
+
+
+
+ io.protostuff
+ protostuff-core
+
+
+ io.protostuff
+ protostuff-runtime
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+
+ com.github.github
+ site-maven-plugin
+
+
+
+
\ No newline at end of file
diff --git a/did-common/src/main/java/io/github/ehlxr/did/common/SdkProto.java b/did-core/src/main/java/io/github/ehlxr/did/SdkProto.java
similarity index 74%
rename from did-common/src/main/java/io/github/ehlxr/did/common/SdkProto.java
rename to did-core/src/main/java/io/github/ehlxr/did/SdkProto.java
index 1dc9e88..0120af1 100644
--- a/did-common/src/main/java/io/github/ehlxr/did/common/SdkProto.java
+++ b/did-core/src/main/java/io/github/ehlxr/did/SdkProto.java
@@ -1,4 +1,6 @@
-package io.github.ehlxr.did.common;
+package io.github.ehlxr.did;
+
+import io.github.ehlxr.did.common.JsonUtils;
import java.io.Serializable;
import java.util.concurrent.atomic.AtomicInteger;
@@ -20,13 +22,6 @@ public class SdkProto implements Serializable {
private long did;
public SdkProto() {
- rqid = REQUEST_ID.incrementAndGet();
- did = 0;
- }
-
- public SdkProto(int rqid, long did) {
- this.rqid = rqid;
- this.did = did;
}
public static SdkProtoBuilder newBuilder() {
@@ -37,10 +32,9 @@ public class SdkProto implements Serializable {
return rqid;
}
- public void setRqid(int rqid) {
- if (rqid > 0) {
- this.rqid = rqid;
- }
+ public int rqid() {
+ rqid = REQUEST_ID.incrementAndGet();
+ return rqid;
}
public long getDid() {
@@ -57,17 +51,11 @@ public class SdkProto implements Serializable {
}
public static final class SdkProtoBuilder {
- private int rqid;
private long did;
private SdkProtoBuilder() {
}
- public SdkProtoBuilder rqid(int rqid) {
- this.rqid = rqid;
- return this;
- }
-
public SdkProtoBuilder did(long did) {
this.did = did;
return this;
@@ -75,7 +63,6 @@ public class SdkProto implements Serializable {
public SdkProto build() {
SdkProto sdkProto = new SdkProto();
- sdkProto.setRqid(rqid);
sdkProto.setDid(did);
return sdkProto;
}
diff --git a/did-common/src/main/java/io/github/ehlxr/did/netty/MyProtocolBean.java b/did-core/src/main/java/io/github/ehlxr/did/adapter/Message.java
similarity index 51%
rename from did-common/src/main/java/io/github/ehlxr/did/netty/MyProtocolBean.java
rename to did-core/src/main/java/io/github/ehlxr/did/adapter/Message.java
index 6996382..b9f1827 100644
--- a/did-common/src/main/java/io/github/ehlxr/did/netty/MyProtocolBean.java
+++ b/did-core/src/main/java/io/github/ehlxr/did/adapter/Message.java
@@ -22,35 +22,53 @@
* THE SOFTWARE.
*/
-package io.github.ehlxr.did.netty;
+package io.github.ehlxr.did.adapter;
-import io.github.ehlxr.did.common.NettyUtil;
import io.github.ehlxr.did.common.Try;
+import io.github.ehlxr.did.serializer.SerializerHolder;
+
+import java.io.Serializable;
/**
* @author ehlxr
* @since 2021-02-08 22:07.
*/
-public class MyProtocolBean {
- // 类型(系统编号 0xA 表示A系统,0xB 表示B系统)
+public class Message implements Serializable {
+ private static final long serialVersionUID = 2419320297359425651L;
+
+ /**
+ * 类型(例如:0xA 表示 A 系统;0xB 表示 B 系统)
+ */
private byte type;
- // 信息标志 0xA 表示心跳包 0xB 表示超时包 0xC 业务信息包
+ /**
+ * 信息标志(例如:0xA 表示心跳包;0xB 表示超时包;0xC 业务信息包)
+ */
private byte flag;
- // 内容长度
+ /**
+ * 内容长度(通过 content 计算而来)
+ */
private int length;
- // 内容
- private byte[] content;
+ /**
+ * 消息内容
+ */
+ private T content;
- public MyProtocolBean(byte type, byte flag, int length, byte[] content) {
+ public Message(byte type, byte flag, T content) {
this.type = type;
this.flag = flag;
- this.length = length;
this.content = content;
}
+ public Message() {
+ }
+
+ public static MessageBuilder newBuilder() {
+ return new MessageBuilder<>();
+ }
+
public byte getType() {
return type;
}
@@ -68,28 +86,60 @@ public class MyProtocolBean {
}
public int getLength() {
- return length;
- }
-
- public void setLength(int length) {
- this.length = length;
+ return getContent().length;
}
public byte[] getContent() {
- return content;
+ return Try.of(SerializerHolder.get()::serializer).apply(content).get();
}
- public void setContent(byte[] content) {
+ public void setContent(T content) {
this.content = content;
}
+ public T content(Class clazz) {
+ return SerializerHolder.get().deserializer(getContent(), clazz);
+ }
+
@Override
public String toString() {
- return "MyProtocolBean{" +
+ return "Message{" +
"type=" + type +
", flag=" + flag +
", length=" + length +
- ", content=" + Try.of(NettyUtil::toObject).apply(content).get() +
+ ", content=" + content +
'}';
}
+
+ public static final class MessageBuilder {
+ private byte type;
+ private byte flag;
+ private T content;
+
+ private MessageBuilder() {
+ }
+
+ public MessageBuilder type(byte type) {
+ this.type = type;
+ return this;
+ }
+
+ public MessageBuilder flag(byte flag) {
+ this.flag = flag;
+ return this;
+ }
+
+ public MessageBuilder content(T content) {
+ this.content = content;
+ return this;
+ }
+
+ public Message build() {
+ Message message = new Message<>();
+ message.setType(type);
+ message.setFlag(flag);
+ message.setContent(content);
+ return message;
+ }
+ }
}
\ No newline at end of file
diff --git a/did-common/src/main/java/io/github/ehlxr/did/netty/MyProtocolDecoder.java b/did-core/src/main/java/io/github/ehlxr/did/adapter/MessageDecoder.java
similarity index 52%
rename from did-common/src/main/java/io/github/ehlxr/did/netty/MyProtocolDecoder.java
rename to did-core/src/main/java/io/github/ehlxr/did/adapter/MessageDecoder.java
index ef17dc2..0f16b5c 100644
--- a/did-common/src/main/java/io/github/ehlxr/did/netty/MyProtocolDecoder.java
+++ b/did-core/src/main/java/io/github/ehlxr/did/adapter/MessageDecoder.java
@@ -22,58 +22,83 @@
* THE SOFTWARE.
*/
-package io.github.ehlxr.did.netty;
+package io.github.ehlxr.did.adapter;
+import io.github.ehlxr.did.SdkProto;
+import io.github.ehlxr.did.common.Constants;
+import io.github.ehlxr.did.common.NettyUtil;
+import io.github.ehlxr.did.serializer.SerializerHolder;
import io.netty.buffer.ByteBuf;
+import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* @author ehlxr
* @since 2021-02-08 22:09.
*/
-public class MyProtocolDecoder extends LengthFieldBasedFrameDecoder {
+public class MessageDecoder extends LengthFieldBasedFrameDecoder {
private static final int HEADER_SIZE = 6;
+ private static final Logger logger = LoggerFactory.getLogger(MessageDecoder.class);
/**
* @param maxFrameLength 帧的最大长度
- * @param lengthFieldOffset length字段偏移的地址
- * @param lengthFieldLength length字段所占的字节长
+ * @param lengthFieldOffset length 字段偏移的地址
+ * @param lengthFieldLength length 字段所占的字节长
* @param lengthAdjustment 修改帧数据长度字段中定义的值,可以为负数 因为有时候我们习惯把头部记入长度,若为负数,则说明要推后多少个字段
* @param initialBytesToStrip 解析时候跳过多少个长度
- * @param failFast 为true,当frame长度超过maxFrameLength时立即报TooLongFrameException异常,为false,读取完整个帧再报异
+ * @param failFast true,当 frame 长度超过 maxFrameLength 时立即报 TooLongFrameException 异常,
+ * false,读取完整个帧再报异
*/
- public MyProtocolDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength,
- int lengthAdjustment, int initialBytesToStrip, boolean failFast) {
+ public MessageDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength,
+ int lengthAdjustment, int initialBytesToStrip, boolean failFast) {
super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip, failFast);
}
+ public MessageDecoder() {
+ super(Constants.MAX_FRAME_LENGTH, Constants.LENGTH_FIELD_OFFSET, Constants.LENGTH_FIELD_LENGTH,
+ Constants.LENGTH_ADJUSTMENT, Constants.INITIAL_BYTES_TO_STRIP, false);
+ }
+
@Override
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
- //在这里调用父类的方法,实现指得到想要的部分,我在这里全部都要,也可以只要body部分
+ // 在这里调用父类的方法,实现指得到想要的部分,我在这里全部都要,也可以只要 body 部分
in = (ByteBuf) super.decode(ctx, in);
if (in == null) {
return null;
}
if (in.readableBytes() < HEADER_SIZE) {
- throw new Exception("字节数不足");
+ throw new IllegalArgumentException("decode failed 'cause of insufficient readable bytes");
}
- //读取type字段
+ // 读取 type 字段
byte type = in.readByte();
- //读取flag字段
+ // 读取 flag 字段
byte flag = in.readByte();
- //读取length字段
+ // 读取 length 字段
int length = in.readInt();
if (in.readableBytes() != length) {
- throw new Exception("标记的长度不符合实际长度");
+ throw new IllegalArgumentException("the length of the readable bytes does not match the actual length");
}
- //读取body
+ // 读取 body
byte[] bytes = new byte[in.readableBytes()];
in.readBytes(bytes);
- return new MyProtocolBean(type, flag, length, bytes);
+ return Message.newBuilder()
+ .type(type)
+ .flag(flag)
+ .content(SerializerHolder.get().deserializer(bytes, SdkProto.class))
+ .build();
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+ Channel channel = ctx.channel();
+ logger.error("channel {} will be closed, 'cause of ", NettyUtil.parseRemoteAddr(channel), cause);
+ NettyUtil.closeChannel(channel);
}
}
\ No newline at end of file
diff --git a/did-common/src/main/java/io/github/ehlxr/did/netty/MyProtocolEncoder.java b/did-core/src/main/java/io/github/ehlxr/did/adapter/MessageEncoder.java
similarity index 80%
rename from did-common/src/main/java/io/github/ehlxr/did/netty/MyProtocolEncoder.java
rename to did-core/src/main/java/io/github/ehlxr/did/adapter/MessageEncoder.java
index d7a1dc0..ab557ec 100644
--- a/did-common/src/main/java/io/github/ehlxr/did/netty/MyProtocolEncoder.java
+++ b/did-core/src/main/java/io/github/ehlxr/did/adapter/MessageEncoder.java
@@ -22,23 +22,25 @@
* THE SOFTWARE.
*/
-package io.github.ehlxr.did.netty;
+package io.github.ehlxr.did.adapter;
+import io.github.ehlxr.did.SdkProto;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
+import java.util.Objects;
+
/**
* @author ehlxr
* @since 2021-02-08 22:12.
*/
-public class MyProtocolEncoder extends MessageToByteEncoder {
+public class MessageEncoder extends MessageToByteEncoder> {
@Override
- protected void encode(ChannelHandlerContext ctx, MyProtocolBean msg, ByteBuf out) throws Exception {
- if (msg == null) {
- throw new Exception("msg is null");
- }
+ protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) {
+ Objects.requireNonNull(msg, "encode failed 'cause of recive message is null");
+
out.writeByte(msg.getType());
out.writeByte(msg.getFlag());
out.writeInt(msg.getLength());
diff --git a/did-core/src/main/java/io/github/ehlxr/did/extension/Activate.java b/did-core/src/main/java/io/github/ehlxr/did/extension/Activate.java
new file mode 100644
index 0000000..ed6efff
--- /dev/null
+++ b/did-core/src/main/java/io/github/ehlxr/did/extension/Activate.java
@@ -0,0 +1,80 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright © 2020 xrv
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package io.github.ehlxr.did.extension;
+
+import java.lang.annotation.*;
+
+/**
+ * Activate
+ *
+ * 对于可以被框架中自动激活加载扩展,此Annotation用于配置扩展被自动激活加载条件。
+ * 比如,过滤扩展,有多个实现,使用Activate Annotation的扩展可以根据条件被自动加载。
+ *
+ *
+ * 底层框架SPI提供者通过{@link ExtensionLoader}的{@link ExtensionLoader#getActivateExtensions}方法
+ * 获得条件的扩展。
+ *
+ * @see SPI
+ * @see ExtensionLoader
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD})
+public @interface Activate {
+ /**
+ * Group过滤条件。
+ *
+ * 包含{@link ExtensionLoader#getActivateExtensions}的group参数给的值,则返回扩展。
+ *
+ * 如没有Group设置,则不过滤。
+ */
+ String[] group() default {};
+
+ /**
+ * Key过滤条件。包含{@link ExtensionLoader#getActivateExtensions}的URL的参数Key中有,则返回扩展。
+ *
+ * 示例:
+ * 注解的值 @Activate("cache,validatioin")
,
+ * 则{@link ExtensionLoader#getActivateExtensions}的URL的参数有cache
Key,或是validatioin
则返回扩展。
+ *
+ * 如没有设置,则不过滤。
+ */
+ String[] value() default {};
+
+ /**
+ * 排序信息,可以不提供。
+ */
+ String[] before() default {};
+
+ /**
+ * 排序信息,可以不提供。
+ */
+ String[] after() default {};
+
+ /**
+ * 排序信息,可以不提供。
+ */
+ int order() default 0;
+}
\ No newline at end of file
diff --git a/did-core/src/main/java/io/github/ehlxr/did/extension/ActivateComparator.java b/did-core/src/main/java/io/github/ehlxr/did/extension/ActivateComparator.java
new file mode 100644
index 0000000..6d86f41
--- /dev/null
+++ b/did-core/src/main/java/io/github/ehlxr/did/extension/ActivateComparator.java
@@ -0,0 +1,90 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright © 2020 xrv
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package io.github.ehlxr.did.extension;
+
+import java.util.Comparator;
+
+/**
+ * Order Comparetor
+ *
+ * @author ehlxr
+ */
+public class ActivateComparator implements Comparator