use of org.apache.dubbo.remoting.exchange.Request in project dubbo by alibaba.
the class HeaderExchangeHandlerTest method test_received_request_event_readonly.
@Test
public void test_received_request_event_readonly() throws RemotingException {
final Request request = new Request();
request.setTwoWay(true);
request.setEvent(READONLY_EVENT);
final Channel mchannel = new MockedChannel();
HeaderExchangeHandler hexhandler = new HeaderExchangeHandler(new MockedExchangeHandler());
hexhandler.received(mchannel, request);
Assertions.assertTrue(mchannel.hasAttribute(Constants.CHANNEL_ATTRIBUTE_READONLY_KEY));
}
use of org.apache.dubbo.remoting.exchange.Request in project dubbo by alibaba.
the class HeaderExchangeHandlerTest method test_received_request_twoway.
@Test
public void test_received_request_twoway() throws RemotingException {
final Person requestdata = new Person("charles");
final Request request = new Request();
request.setTwoWay(true);
request.setData(requestdata);
final AtomicInteger count = new AtomicInteger(0);
final Channel mchannel = new MockedChannel() {
@Override
public void send(Object message) throws RemotingException {
Response res = (Response) message;
Assertions.assertEquals(request.getId(), res.getId());
Assertions.assertEquals(request.getVersion(), res.getVersion());
Assertions.assertEquals(Response.OK, res.getStatus());
Assertions.assertEquals(requestdata, res.getResult());
Assertions.assertNull(res.getErrorMessage());
count.incrementAndGet();
}
};
ExchangeHandler exhandler = new MockedExchangeHandler() {
@Override
public CompletableFuture<Object> reply(ExchangeChannel channel, Object request) throws RemotingException {
return CompletableFuture.completedFuture(request);
}
@Override
public void received(Channel channel, Object message) throws RemotingException {
Assertions.fail();
}
};
HeaderExchangeHandler hexhandler = new HeaderExchangeHandler(exhandler);
hexhandler.received(mchannel, request);
Assertions.assertEquals(1, count.get());
}
use of org.apache.dubbo.remoting.exchange.Request in project dubbo by alibaba.
the class DubboCodec method decodeBody.
@Override
protected Object decodeBody(Channel channel, InputStream is, byte[] header) throws IOException {
byte flag = header[2], proto = (byte) (flag & SERIALIZATION_MASK);
// get request id.
long id = Bytes.bytes2long(header, 4);
if ((flag & FLAG_REQUEST) == 0) {
// decode response.
Response res = new Response(id);
if ((flag & FLAG_EVENT) != 0) {
res.setEvent(true);
}
// get status.
byte status = header[3];
res.setStatus(status);
try {
if (status == Response.OK) {
Object data;
if (res.isEvent()) {
byte[] eventPayload = CodecSupport.getPayload(is);
if (CodecSupport.isHeartBeat(eventPayload, proto)) {
// heart beat response data is always null;
data = null;
} else {
ObjectInput in = CodecSupport.deserialize(channel.getUrl(), new ByteArrayInputStream(eventPayload), proto);
data = decodeEventData(channel, in, eventPayload);
}
} else {
DecodeableRpcResult result;
if (channel.getUrl().getParameter(DECODE_IN_IO_THREAD_KEY, DEFAULT_DECODE_IN_IO_THREAD)) {
result = new DecodeableRpcResult(channel, res, is, (Invocation) getRequestData(id), proto);
result.decode();
} else {
result = new DecodeableRpcResult(channel, res, new UnsafeByteArrayInputStream(readMessageData(is)), (Invocation) getRequestData(id), proto);
}
data = result;
}
res.setResult(data);
} else {
ObjectInput in = CodecSupport.deserialize(channel.getUrl(), is, proto);
res.setErrorMessage(in.readUTF());
}
} catch (Throwable t) {
if (log.isWarnEnabled()) {
log.warn("Decode response failed: " + t.getMessage(), t);
}
res.setStatus(Response.CLIENT_ERROR);
res.setErrorMessage(StringUtils.toString(t));
}
return res;
} else {
// decode request.
Request req = new Request(id);
req.setVersion(Version.getProtocolVersion());
req.setTwoWay((flag & FLAG_TWOWAY) != 0);
if ((flag & FLAG_EVENT) != 0) {
req.setEvent(true);
}
try {
Object data;
if (req.isEvent()) {
byte[] eventPayload = CodecSupport.getPayload(is);
if (CodecSupport.isHeartBeat(eventPayload, proto)) {
// heart beat response data is always null;
data = null;
} else {
ObjectInput in = CodecSupport.deserialize(channel.getUrl(), new ByteArrayInputStream(eventPayload), proto);
data = decodeEventData(channel, in, eventPayload);
}
} else {
DecodeableRpcInvocation inv;
if (channel.getUrl().getParameter(DECODE_IN_IO_THREAD_KEY, DEFAULT_DECODE_IN_IO_THREAD)) {
inv = new DecodeableRpcInvocation(channel, req, is, proto);
inv.decode();
} else {
inv = new DecodeableRpcInvocation(channel, req, new UnsafeByteArrayInputStream(readMessageData(is)), proto);
}
data = inv;
}
req.setData(data);
} catch (Throwable t) {
if (log.isWarnEnabled()) {
log.warn("Decode request failed: " + t.getMessage(), t);
}
// bad request
req.setBroken(true);
req.setData(t);
}
return req;
}
}
use of org.apache.dubbo.remoting.exchange.Request in project dubbo by alibaba.
the class ThriftCodec method decode.
private Object decode(TProtocol protocol) throws IOException {
// version
String serviceName;
String path;
long id;
TMessage message;
try {
protocol.readI16();
protocol.readByte();
serviceName = protocol.readString();
path = protocol.readString();
id = protocol.readI64();
message = protocol.readMessageBegin();
} catch (TException e) {
throw new IOException(e.getMessage(), e);
}
if (message.type == TMessageType.CALL) {
RpcInvocation result = new RpcInvocation();
result.setAttachment(INTERFACE_KEY, serviceName);
result.setAttachment(PATH_KEY, path);
result.setMethodName(message.name);
String argsClassName = ExtensionLoader.getExtensionLoader(ClassNameGenerator.class).getExtension(ThriftClassNameGenerator.NAME).generateArgsClassName(serviceName, message.name);
if (StringUtils.isEmpty(argsClassName)) {
throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, "The specified interface name incorrect.");
}
Class clazz = CACHED_CLASS.get(argsClassName);
if (clazz == null) {
try {
clazz = ClassUtils.forNameWithThreadContextClassLoader(argsClassName);
CACHED_CLASS.putIfAbsent(argsClassName, clazz);
} catch (ClassNotFoundException e) {
throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
}
}
TBase args;
try {
args = (TBase) clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
}
try {
args.read(protocol);
protocol.readMessageEnd();
} catch (TException e) {
throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
}
List<Object> parameters = new ArrayList<>();
List<Class<?>> parameterTypes = new ArrayList<>();
int index = 1;
while (true) {
TFieldIdEnum fieldIdEnum = args.fieldForId(index++);
if (fieldIdEnum == null) {
break;
}
String fieldName = fieldIdEnum.getFieldName();
String getMethodName = ThriftUtils.generateGetMethodName(fieldName);
Method getMethod;
try {
getMethod = clazz.getMethod(getMethodName);
} catch (NoSuchMethodException e) {
throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
}
parameterTypes.add(getMethod.getReturnType());
try {
parameters.add(getMethod.invoke(args));
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
}
}
result.setArguments(parameters.toArray());
result.setParameterTypes(parameterTypes.toArray(new Class[0]));
Request request = new Request(id);
request.setData(result);
CACHED_REQUEST.putIfAbsent(id, RequestData.create(message.seqid, serviceName, message.name));
return request;
} else if (message.type == TMessageType.EXCEPTION) {
TApplicationException exception;
try {
exception = TApplicationException.readFrom(protocol);
protocol.readMessageEnd();
} catch (TException e) {
throw new IOException(e.getMessage(), e);
}
AppResponse result = new AppResponse();
result.setException(new RpcException(exception.getMessage()));
Response response = new Response();
response.setResult(result);
response.setId(id);
return response;
} else if (message.type == TMessageType.REPLY) {
String resultClassName = ExtensionLoader.getExtensionLoader(ClassNameGenerator.class).getExtension(ThriftClassNameGenerator.NAME).generateResultClassName(serviceName, message.name);
if (StringUtils.isEmpty(resultClassName)) {
throw new IllegalArgumentException("Could not infer service result class name from service name " + serviceName + ", the service name you specified may not generated by thrift idl compiler");
}
Class<?> clazz = CACHED_CLASS.get(resultClassName);
if (clazz == null) {
try {
clazz = ClassUtils.forNameWithThreadContextClassLoader(resultClassName);
CACHED_CLASS.putIfAbsent(resultClassName, clazz);
} catch (ClassNotFoundException e) {
throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
}
}
TBase<?, ? extends TFieldIdEnum> result;
try {
result = (TBase<?, ?>) clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
}
try {
result.read(protocol);
protocol.readMessageEnd();
} catch (TException e) {
throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
}
Object realResult = null;
int index = 0;
while (true) {
TFieldIdEnum fieldIdEnum = result.fieldForId(index++);
if (fieldIdEnum == null) {
break;
}
Field field;
try {
field = clazz.getDeclaredField(fieldIdEnum.getFieldName());
ReflectUtils.makeAccessible(field);
} catch (NoSuchFieldException e) {
throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
}
try {
realResult = field.get(result);
} catch (IllegalAccessException e) {
throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
}
if (realResult != null) {
break;
}
}
Response response = new Response();
response.setId(id);
AppResponse appResponse = new AppResponse();
if (realResult instanceof Throwable) {
appResponse.setException((Throwable) realResult);
} else {
appResponse.setValue(realResult);
}
response.setResult(appResponse);
return response;
} else {
// Impossible
throw new IOException();
}
}
use of org.apache.dubbo.remoting.exchange.Request in project dubbo by alibaba.
the class PayloadDropper method getRequestWithoutData.
/**
* only log body in debugger mode for size & security consideration.
*
* @param message
* @return
*/
public static Object getRequestWithoutData(Object message) {
if (logger.isDebugEnabled()) {
return message;
}
if (message instanceof Request) {
Request request = (Request) message;
request.setData(null);
return request;
} else if (message instanceof Response) {
Response response = (Response) message;
response.setResult(null);
return response;
}
return message;
}
Aggregations