This commit is contained in:
crusader 2018-05-03 23:20:42 +09:00
parent 7525b0b8fe
commit 2716b28c1d
11 changed files with 293 additions and 11 deletions

View File

@ -0,0 +1,11 @@
package com.loafle.commons.rpc.protocol;
import com.loafle.commons.rpc.RPCException;
/**
* RPCClientCodec
*/
public interface RPCClientCodec {
byte[] request(String method, Object[] params, Object id) throws RPCException;
RPCClientResponseCodec response(byte[] buf) throws RPCException;
}

View File

@ -0,0 +1,8 @@
package com.loafle.commons.rpc.protocol;
/**
* RPCClientNotificationCodec
*/
public interface RPCClientNotificationCodec extends RPCRegistryCodec {
}

View File

@ -0,0 +1,14 @@
package com.loafle.commons.rpc.protocol;
import com.loafle.commons.rpc.RPCException;
/**
* RPCClientResponseCodec
*/
public interface RPCClientResponseCodec {
boolean isNotification();
RPCClientNotificationCodec notification() throws RPCException;
<T> T result(Class<T> resultType) throws RPCException;
RPCError error();
Object id();
}

View File

@ -0,0 +1,11 @@
package com.loafle.commons.rpc.protocol.json;
import java.util.List;
/**
* JSONClientNotification
*/
public class JSONClientNotification {
public String method;
public List<String> params;
}

View File

@ -0,0 +1,23 @@
package com.loafle.commons.rpc.protocol.json;
import java.util.List;
import org.codehaus.jackson.annotate.JsonProperty;
/**
* JSONClientRequest
*/
public class JSONClientRequest {
@JsonProperty("jsonrpc")
public String version;
public String method;
public Object[] params;
public Object id;
JSONClientRequest(String version, String method, Object[] params, Object id) {
this.version = version;
this.method = method;
this.params = params;
this.id = id;
}
}

View File

@ -0,0 +1,19 @@
package com.loafle.commons.rpc.protocol.json;
import com.loafle.commons.rpc.protocol.RPCError;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.annotate.JsonRawValue;
/**
* JSONClientResponse
*/
public class JSONClientResponse {
@JsonProperty("jsonrpc")
public String version;
@JsonRawValue
public Object result;
public RPCError error;
public Object id;
}

View File

@ -0,0 +1,38 @@
package com.loafle.commons.rpc.protocol.json;
import java.io.IOException;
import com.loafle.commons.rpc.RPCException;
import com.loafle.commons.rpc.protocol.RPCClientCodec;
import com.loafle.commons.rpc.protocol.RPCClientResponseCodec;
import org.codehaus.jackson.map.ObjectMapper;
/**
* JSONRPCClientCodec
*/
public class JSONRPCClientCodec extends JSONRPCCodec implements RPCClientCodec {
public JSONRPCClientCodec() {
}
public JSONRPCClientCodec(ObjectMapper objectMapper) {
super(objectMapper);
}
@Override
public byte[] request(String method, Object[] params, Object id) throws RPCException {
JSONClientRequest request = new JSONClientRequest(JSONRPC.version, method, params, id);
try {
String json = this.objectMapper.writeValueAsString(request);
return json.getBytes();
} catch (IOException e) {
throw new RPCException("cannot marsharling", e);
}
}
@Override
public RPCClientResponseCodec response(byte[] buf) throws RPCException {
return new JSONRPCClientResponseCodec(this.objectMapper, buf);
}
}

View File

@ -0,0 +1,68 @@
package com.loafle.commons.rpc.protocol.json;
import java.io.IOException;
import java.lang.reflect.Type;
import com.google.gson.internal.Primitives;
import com.loafle.commons.rpc.RPCException;
import com.loafle.commons.rpc.protocol.RPCClientNotificationCodec;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.JavaType;
/**
* JSONRPCClientNotificationCodec
*/
public class JSONRPCClientNotificationCodec implements RPCClientNotificationCodec {
private ObjectMapper objectMapper;
private JSONClientNotification notification;
public JSONRPCClientNotificationCodec(ObjectMapper objectMapper, byte[] buff) throws RPCException {
this.objectMapper = objectMapper;
try {
this.notification = this.objectMapper.readValue(buff, JSONClientNotification.class);
} catch (IOException e) {
throw new RPCException("cannot unmarsharling", e);
}
}
@Override
public String method() {
return this.notification.method;
}
@Override
public Object[] params(Type[] paramTypes) throws RPCException {
if (null == paramTypes && null == this.notification.params) {
return null;
}
if ((null != paramTypes && null == this.notification.params) || null == paramTypes && null != this.notification.params) {
throw new RPCException("params is not valied");
}
if (paramTypes.length != this.notification.params.size()) {
throw new RPCException(String.format("The size of params[%d] and types[%d] is not same",
this.notification.params.size(), paramTypes.length));
}
Object[] result = new Object[paramTypes.length];
for (int i = 0; i < paramTypes.length; i++) {
Type paramType = paramTypes[i];
String param = this.notification.params.get(i);
JavaType targetType = objectMapper.getTypeFactory().constructType(paramType);
if (!Primitives.isPrimitive(paramType) && !paramType.getTypeName().equals(String.class.getName())) {
try {
result[i] = objectMapper.readValue(param, targetType);
} catch (IOException e) {
throw new IllegalArgumentException();
}
}
result[i] = objectMapper.convertValue(param, targetType);
}
return result;
}
}

View File

@ -0,0 +1,75 @@
package com.loafle.commons.rpc.protocol.json;
import java.io.IOException;
import com.google.gson.internal.Primitives;
import com.loafle.commons.rpc.RPCException;
import com.loafle.commons.rpc.protocol.RPCClientNotificationCodec;
import com.loafle.commons.rpc.protocol.RPCClientResponseCodec;
import com.loafle.commons.rpc.protocol.RPCError;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.JavaType;
/**
* JSONRPCClientResponseCodec
*/
public class JSONRPCClientResponseCodec implements RPCClientResponseCodec {
private ObjectMapper objectMapper;
private JSONClientResponse response;
public JSONRPCClientResponseCodec(ObjectMapper objectMapper, byte[] buff) throws RPCException {
this.objectMapper = objectMapper;
try {
this.response = this.objectMapper.readValue(buff, JSONClientResponse.class);
} catch (IOException e) {
throw new RPCException("cannot unmarsharling", e);
}
}
@Override
public boolean isNotification() {
return null == this.response.id && null == this.response.error && null != this.response.result;
}
@Override
public RPCClientNotificationCodec notification() throws RPCException {
try {
String json = objectMapper.writeValueAsString(this.response.result);
return new JSONRPCClientNotificationCodec(objectMapper, json.getBytes());
} catch (IOException e) {
throw new RPCException("cannot marsharling", e);
}
}
@Override
public <T> T result(Class<T> resultType) throws RPCException {
String json = null;
try {
json = objectMapper.writeValueAsString(this.response.result);
} catch (IOException e) {
throw new RPCException("cannot marsharling", e);
}
try {
JavaType targetType = objectMapper.getTypeFactory().constructType(resultType);
if (!Primitives.isPrimitive(resultType) && !resultType.equals(String.class)) {
return objectMapper.readValue(json, targetType);
}
return objectMapper.convertValue(json, targetType);
} catch (IOException e) {
throw new RPCException("cannot unmarsharling", e);
}
}
@Override
public RPCError error() {
return this.response.error;
}
@Override
public Object id() {
return this.response.id;
}
}

View File

@ -0,0 +1,24 @@
package com.loafle.commons.rpc.protocol.json;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
/**
* JSONRPCCodec
*/
public abstract class JSONRPCCodec {
protected ObjectMapper objectMapper;
public JSONRPCCodec() {
this.objectMapper = new ObjectMapper();
this.objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
public JSONRPCCodec(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public void setObjectMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
}

View File

@ -6,26 +6,17 @@ import com.loafle.commons.rpc.RPCException;
import com.loafle.commons.rpc.protocol.RPCServerCodec; import com.loafle.commons.rpc.protocol.RPCServerCodec;
import com.loafle.commons.rpc.protocol.RPCServerRequestCodec; import com.loafle.commons.rpc.protocol.RPCServerRequestCodec;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.ObjectMapper;
/** /**
* JSONRPCServerCodec * JSONRPCServerCodec
*/ */
public class JSONRPCServerCodec implements RPCServerCodec { public class JSONRPCServerCodec extends JSONRPCCodec implements RPCServerCodec {
private ObjectMapper objectMapper;
public JSONRPCServerCodec() { public JSONRPCServerCodec() {
this.objectMapper = new ObjectMapper();
this.objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
} }
public JSONRPCServerCodec(ObjectMapper objectMapper) { public JSONRPCServerCodec(ObjectMapper objectMapper) {
this.objectMapper = objectMapper; super(objectMapper);
}
public void setObjectMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
} }
public RPCServerRequestCodec request(byte[] buff) throws RPCException { public RPCServerRequestCodec request(byte[] buff) throws RPCException {