This commit is contained in:
Redkale
2020-05-30 19:55:07 +08:00
parent a1fdfc9cc9
commit a1501af7a7
23 changed files with 219 additions and 28 deletions

View File

@@ -24,6 +24,8 @@ import org.redkale.util.*;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public abstract class ClusterAgent {

View File

@@ -8,12 +8,13 @@ package org.redkale.mq;
import org.redkale.net.http.*;
/**
*
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public class HttpMessageRequest extends HttpRequest {

View File

@@ -19,6 +19,8 @@ import org.redkale.util.ObjectPool;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public class HttpMessageResponse extends HttpResponse {

View File

@@ -0,0 +1,130 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.mq;
import java.net.HttpCookie;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import org.redkale.convert.*;
import org.redkale.convert.json.JsonConvert;
import static org.redkale.mq.MessageCoder.*;
import org.redkale.net.http.HttpResult;
import org.redkale.util.Utility;
/**
* HttpResult的MessageCoder实现
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public class HttpResultCoder implements MessageCoder<HttpResult> {
private static final HttpResultCoder instance = new HttpResultCoder();
public static HttpResultCoder getInstance() {
return instance;
}
@Override
public byte[] encode(HttpResult data) {
if (data == null) return null;
byte[] contentType = MessageCoder.getBytes(data.getContentType());
byte[] headers = MessageCoder.getBytes(data.getHeaders());
byte[] cookies = getBytes(data.getCookies());
byte[] content;
if (data.getResult() == null) {
content = new byte[0]; //""
} else if (data.getResult() instanceof CharSequence) {
content = MessageCoder.getBytes(data.getResult().toString());
} else {
Convert cc = data.convert();
if (cc == null || !(cc instanceof TextConvert)) cc = JsonConvert.root();
content = cc.convertToBytes(data.getResult());
}
int count = 4 + 2 + contentType.length + headers.length + cookies.length + 4 + (content == null ? 0 : content.length);
final byte[] bs = new byte[count];
ByteBuffer buffer = ByteBuffer.wrap(bs);
buffer.putInt(data.getStatus());
buffer.putChar((char) contentType.length);
if (contentType.length > 0) buffer.put(contentType);
buffer.put(headers);
buffer.put(cookies);
if (content == null || content.length == 0) {
buffer.putInt(0);
} else {
buffer.putInt(content.length);
buffer.put(content);
}
return bs;
}
@Override
public HttpResult<byte[]> decode(byte[] data) {
if (data == null) return null;
ByteBuffer buffer = ByteBuffer.wrap(data);
HttpResult result = new HttpResult();
result.setStatus(buffer.getInt());
result.setContentType(MessageCoder.getShortString(buffer));
result.setHeaders(MessageCoder.getMap(buffer));
result.setCookies(getCookieList(buffer));
int len = buffer.getInt();
if (len > 0) {
byte[] bs = new byte[len];
buffer.get(bs);
result.setResult(bs);
}
return result;
}
public static byte[] getBytes(final List<HttpCookie> list) {
if (list == null || list.isEmpty()) return new byte[2];
final AtomicInteger len = new AtomicInteger(2);
list.forEach(cookie -> {
len.addAndGet(2 + (cookie.getName() == null ? 0 : Utility.encodeUTF8Length(cookie.getName())));
len.addAndGet(2 + (cookie.getValue() == null ? 0 : Utility.encodeUTF8Length(cookie.getValue())));
len.addAndGet(2 + (cookie.getDomain() == null ? 0 : Utility.encodeUTF8Length(cookie.getDomain())));
len.addAndGet(2 + (cookie.getPath() == null ? 0 : Utility.encodeUTF8Length(cookie.getPath())));
len.addAndGet(2 + (cookie.getPortlist() == null ? 0 : Utility.encodeUTF8Length(cookie.getPortlist())));
len.addAndGet(4 + 1 + 1); //maxage Secure HttpOnly
});
final byte[] bs = new byte[len.get()];
final ByteBuffer buffer = ByteBuffer.wrap(bs);
buffer.putChar((char) list.size());
list.forEach(cookie -> {
putShortString(buffer, cookie.getName());
putShortString(buffer, cookie.getValue());
putShortString(buffer, cookie.getDomain());
putShortString(buffer, cookie.getPath());
putShortString(buffer, cookie.getPortlist());
buffer.putLong(cookie.getMaxAge());
buffer.put(cookie.getSecure() ? (byte) 1 : (byte) 0);
buffer.put(cookie.isHttpOnly() ? (byte) 1 : (byte) 0);
});
return bs;
}
public static List<HttpCookie> getCookieList(ByteBuffer buffer) {
int len = buffer.getChar();
if (len == 0) return null;
final List<HttpCookie> list = new ArrayList<>(len);
for (int i = 0; i < len; i++) {
HttpCookie cookie = new HttpCookie(getShortString(buffer), getShortString(buffer));
cookie.setDomain(getShortString(buffer));
cookie.setPath(getShortString(buffer));
cookie.setPortlist(getShortString(buffer));
cookie.setMaxAge(buffer.getLong());
cookie.setSecure(buffer.get() == 1);
cookie.setHttpOnly(buffer.get() == 1);
list.add(cookie);
}
return list;
}
}

View File

@@ -16,6 +16,8 @@ import org.redkale.net.http.HttpSimpleRequest;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public class HttpSimpleRequestCoder implements MessageCoder<HttpSimpleRequest> {

View File

@@ -21,6 +21,8 @@ import org.redkale.util.*;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public abstract class MessageAgent {

View File

@@ -19,6 +19,9 @@ import org.redkale.util.Utility;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*
* @param <T> 泛型
*/
public interface MessageCoder<T> {

View File

@@ -14,7 +14,10 @@ import java.util.logging.Logger;
* <p>
* 详情见: https://redkale.org
*
*
* @author zhangjx
*
* @since 2.1.0
*/
public abstract class MessageConsumer extends Thread {

View File

@@ -11,6 +11,8 @@ package org.redkale.mq;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public interface MessageProcessor {

View File

@@ -14,6 +14,8 @@ import java.util.logging.Logger;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public abstract class MessageProducer extends Thread {

View File

@@ -18,6 +18,8 @@ import org.redkale.util.Comment;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public class MessageRecord implements Serializable {

View File

@@ -15,6 +15,8 @@ import org.redkale.convert.ConvertType;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public class MessageRecordCoder implements MessageCoder<MessageRecord> {

View File

@@ -11,6 +11,8 @@ package org.redkale.mq;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public interface MessageResponse {

View File

@@ -14,6 +14,8 @@ import org.redkale.net.sncp.*;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public class SncpMessageRequest extends SncpRequest {

View File

@@ -19,6 +19,8 @@ import org.redkale.util.ObjectPool;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public class SncpMessageResponse extends SncpResponse {

View File

@@ -1013,7 +1013,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
if (defaultCookie.getDomain() != null && cookie.getDomain() == null) cookie.setDomain(defaultCookie.getDomain());
if (defaultCookie.getPath() != null && cookie.getPath() == null) cookie.setPath(defaultCookie.getPath());
}
buffer.put(("Set-Cookie: " + genString(cookie) + "\r\n").getBytes());
buffer.put(("Set-Cookie: " + cookieString(cookie) + "\r\n").getBytes());
}
}
buffer.put(LINE);
@@ -1022,7 +1022,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
return buffer;
}
private CharSequence genString(HttpCookie cookie) {
private CharSequence cookieString(HttpCookie cookie) {
StringBuilder sb = new StringBuilder();
sb.append(cookie.getName()).append("=").append(cookie.getValue()).append("; Version=1");
if (cookie.getDomain() != null) sb.append("; Domain=").append(cookie.getDomain());

View File

@@ -23,17 +23,20 @@ public class HttpResult<T> {
public static final String SESSIONID_COOKIENAME = HttpRequest.SESSIONID_NAME;
protected Map<String, String> headers;
protected List<HttpCookie> cookies;
protected String contentType;
protected T result;
@ConvertColumn(index = 1)
protected int status = 0; //不设置则为 200
protected String message;
@ConvertColumn(index = 2)
protected String contentType;
@ConvertColumn(index = 3)
protected Map<String, String> headers;
@ConvertColumn(index = 4)
protected List<HttpCookie> cookies;
@ConvertColumn(index = 5)
protected T result;
protected Convert convert;
@@ -85,11 +88,6 @@ public class HttpResult<T> {
return this;
}
public HttpResult<T> message(String message) {
this.message = message;
return this;
}
public Convert convert() {
return convert;
}
@@ -138,14 +136,6 @@ public class HttpResult<T> {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);

View File

@@ -17,6 +17,8 @@ import org.redkale.util.Comment;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public class HttpSimpleRequest implements java.io.Serializable {

View File

@@ -100,6 +100,12 @@ public abstract class Sncp {
return service.getClass().getAnnotation(SncpDyn.class) != null;
}
public static int getVersion(Service service) {
if (service == null) return -1;
Version ver = service.getClass().getAnnotation(Version.class);
return ver == null ? -1 : ver.value();
}
public static String getResourceName(Service service) {
if (service == null) return null;
Resource res = service.getClass().getAnnotation(Resource.class);

View File

@@ -75,12 +75,13 @@ public final class SncpClient {
this.remote = remote;
this.executor = factory.getExecutor();
this.bufferSupplier = factory.getBufferSupplier();
Class<?> tn = serviceTypeOrImplClass;
Version ver = tn.getAnnotation(Version.class);
this.serviceClass = serviceClass;
this.serviceversion = 0;
this.serviceversion = ver == null ? 0 : ver.value();
this.clientSncpAddress = clientSncpAddress;
this.name = serviceName;
Class tn = serviceTypeOrImplClass;
ResourceType rt = (ResourceType) tn.getAnnotation(ResourceType.class);
ResourceType rt = tn.getAnnotation(ResourceType.class);
if (rt != null) tn = rt.value();
this.serviceid = Sncp.hash(tn.getName() + ':' + serviceName);
final List<SncpAction> methodens = new ArrayList<>();

View File

@@ -15,6 +15,8 @@ import org.redkale.util.Attribute;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
* @param <T> 对象类型
* @param <F> 字段类型
*/

View File

@@ -16,6 +16,8 @@ import org.redkale.util.Attribute;
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public class RpcCallAttribute implements Attribute<Object, Serializable> {

View File

@@ -0,0 +1,29 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.util;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 版本, 可用于标记Service的接口版本变化
*
* <p>
* 详情见: https://redkale.org
*
* @since 2.1.0
*
* @author zhangjx
*/
@Inherited
@Documented
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface Version {
int value();
}