Search in sources :

Example 11 with RpcResult

use of com.alibaba.dubbo.rpc.RpcResult in project dubbo by alibaba.

the class FutureFilterTest method testSyncCallbackHasException.

@Test(expected = RuntimeException.class)
public void testSyncCallbackHasException() throws RpcException, Throwable {
    @SuppressWarnings("unchecked") Invoker<DemoService> invoker = EasyMock.createMock(Invoker.class);
    EasyMock.expect(invoker.isAvailable()).andReturn(true).anyTimes();
    EasyMock.expect(invoker.getInterface()).andReturn(DemoService.class).anyTimes();
    RpcResult result = new RpcResult();
    result.setException(new RuntimeException());
    EasyMock.expect(invoker.invoke(invocation)).andReturn(result).anyTimes();
    URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1&" + Constants.ON_THROW_METHOD_KEY + "=echo");
    EasyMock.expect(invoker.getUrl()).andReturn(url).anyTimes();
    EasyMock.replay(invoker);
    eventFilter.invoke(invoker, invocation).recreate();
}
Also used : RpcResult(com.alibaba.dubbo.rpc.RpcResult) DemoService(com.alibaba.dubbo.rpc.protocol.dubbo.support.DemoService) URL(com.alibaba.dubbo.common.URL) Test(org.junit.Test)

Example 12 with RpcResult

use of com.alibaba.dubbo.rpc.RpcResult in project dubbo by alibaba.

the class ThriftCodecTest method testEncodeReplyResponse.

@Test
public void testEncodeReplyResponse() throws Exception {
    URL url = URL.valueOf(ThriftProtocol.NAME + "://127.0.0.1:40880/" + Demo.Iface.class.getName());
    Channel channel = new MockedChannel(url);
    Request request = createRequest();
    RpcResult rpcResult = new RpcResult();
    rpcResult.setResult("Hello, World!");
    Response response = new Response();
    response.setResult(rpcResult);
    response.setId(request.getId());
    ChannelBuffer bos = ChannelBuffers.dynamicBuffer(1024);
    ThriftCodec.RequestData rd = ThriftCodec.RequestData.create(ThriftCodec.getSeqId(), Demo.Iface.class.getName(), "echoString");
    ThriftCodec.cachedRequest.putIfAbsent(request.getId(), rd);
    codec.encode(channel, bos, response);
    byte[] buf = new byte[bos.writerIndex() - 4];
    System.arraycopy(bos.array(), 4, buf, 0, bos.writerIndex() - 4);
    ByteArrayInputStream bis = new ByteArrayInputStream(buf);
    if (bis.markSupported()) {
        bis.mark(0);
    }
    TIOStreamTransport transport = new TIOStreamTransport(bis);
    TBinaryProtocol protocol = new TBinaryProtocol(transport);
    Assert.assertEquals(ThriftCodec.MAGIC, protocol.readI16());
    Assert.assertEquals(protocol.readI32() + 4, bos.writerIndex());
    int headerLength = protocol.readI16();
    Assert.assertEquals(ThriftCodec.VERSION, protocol.readByte());
    Assert.assertEquals(Demo.Iface.class.getName(), protocol.readString());
    Assert.assertEquals(request.getId(), protocol.readI64());
    if (bis.markSupported()) {
        bis.reset();
        bis.skip(headerLength);
    }
    TMessage message = protocol.readMessageBegin();
    Assert.assertEquals("echoString", message.name);
    Assert.assertEquals(TMessageType.REPLY, message.type);
    Assert.assertEquals(ThriftCodec.getSeqId(), message.seqid);
    Demo.echoString_result result = new Demo.echoString_result();
    result.read(protocol);
    protocol.readMessageEnd();
    Assert.assertEquals(rpcResult.getValue(), result.getSuccess());
}
Also used : Demo(com.alibaba.dubbo.rpc.gen.thrift.Demo) Channel(com.alibaba.dubbo.remoting.Channel) Request(com.alibaba.dubbo.remoting.exchange.Request) RpcResult(com.alibaba.dubbo.rpc.RpcResult) TIOStreamTransport(org.apache.thrift.transport.TIOStreamTransport) URL(com.alibaba.dubbo.common.URL) ChannelBuffer(com.alibaba.dubbo.remoting.buffer.ChannelBuffer) Response(com.alibaba.dubbo.remoting.exchange.Response) TBinaryProtocol(org.apache.thrift.protocol.TBinaryProtocol) ByteArrayInputStream(java.io.ByteArrayInputStream) TMessage(org.apache.thrift.protocol.TMessage) Test(org.junit.Test)

Example 13 with RpcResult

use of com.alibaba.dubbo.rpc.RpcResult in project dubbo by alibaba.

the class ThriftCodecTest method testEncodeExceptionResponse.

@Test
public void testEncodeExceptionResponse() throws Exception {
    URL url = URL.valueOf(ThriftProtocol.NAME + "://127.0.0.1:40880/" + Demo.Iface.class.getName());
    Channel channel = new MockedChannel(url);
    Request request = createRequest();
    RpcResult rpcResult = new RpcResult();
    String exceptionMessage = "failed";
    rpcResult.setException(new RuntimeException(exceptionMessage));
    Response response = new Response();
    response.setResult(rpcResult);
    response.setId(request.getId());
    ChannelBuffer bos = ChannelBuffers.dynamicBuffer(1024);
    ThriftCodec.RequestData rd = ThriftCodec.RequestData.create(ThriftCodec.getSeqId(), Demo.Iface.class.getName(), "echoString");
    ThriftCodec.cachedRequest.put(request.getId(), rd);
    codec.encode(channel, bos, response);
    byte[] buf = new byte[bos.writerIndex() - 4];
    System.arraycopy(bos.array(), 4, buf, 0, bos.writerIndex() - 4);
    ByteArrayInputStream bis = new ByteArrayInputStream(buf);
    if (bis.markSupported()) {
        bis.mark(0);
    }
    TIOStreamTransport transport = new TIOStreamTransport(bis);
    TBinaryProtocol protocol = new TBinaryProtocol(transport);
    Assert.assertEquals(ThriftCodec.MAGIC, protocol.readI16());
    Assert.assertEquals(protocol.readI32() + 4, bos.writerIndex());
    int headerLength = protocol.readI16();
    Assert.assertEquals(ThriftCodec.VERSION, protocol.readByte());
    Assert.assertEquals(Demo.Iface.class.getName(), protocol.readString());
    Assert.assertEquals(request.getId(), protocol.readI64());
    if (bis.markSupported()) {
        bis.reset();
        bis.skip(headerLength);
    }
    TMessage message = protocol.readMessageBegin();
    Assert.assertEquals("echoString", message.name);
    Assert.assertEquals(TMessageType.EXCEPTION, message.type);
    Assert.assertEquals(ThriftCodec.getSeqId(), message.seqid);
    TApplicationException exception = TApplicationException.read(protocol);
    protocol.readMessageEnd();
    Assert.assertEquals(exceptionMessage, exception.getMessage());
}
Also used : Demo(com.alibaba.dubbo.rpc.gen.thrift.Demo) Channel(com.alibaba.dubbo.remoting.Channel) Request(com.alibaba.dubbo.remoting.exchange.Request) RpcResult(com.alibaba.dubbo.rpc.RpcResult) TIOStreamTransport(org.apache.thrift.transport.TIOStreamTransport) URL(com.alibaba.dubbo.common.URL) ChannelBuffer(com.alibaba.dubbo.remoting.buffer.ChannelBuffer) TApplicationException(org.apache.thrift.TApplicationException) Response(com.alibaba.dubbo.remoting.exchange.Response) TBinaryProtocol(org.apache.thrift.protocol.TBinaryProtocol) ByteArrayInputStream(java.io.ByteArrayInputStream) TMessage(org.apache.thrift.protocol.TMessage) Test(org.junit.Test)

Example 14 with RpcResult

use of com.alibaba.dubbo.rpc.RpcResult in project dubbo by alibaba.

the class RedisProtocol method refer.

public <T> Invoker<T> refer(final Class<T> type, final URL url) throws RpcException {
    try {
        GenericObjectPool.Config config = new GenericObjectPool.Config();
        config.testOnBorrow = url.getParameter("test.on.borrow", true);
        config.testOnReturn = url.getParameter("test.on.return", false);
        config.testWhileIdle = url.getParameter("test.while.idle", false);
        if (url.getParameter("max.idle", 0) > 0)
            config.maxIdle = url.getParameter("max.idle", 0);
        if (url.getParameter("min.idle", 0) > 0)
            config.minIdle = url.getParameter("min.idle", 0);
        if (url.getParameter("max.active", 0) > 0)
            config.maxActive = url.getParameter("max.active", 0);
        if (url.getParameter("max.wait", 0) > 0)
            config.maxWait = url.getParameter("max.wait", 0);
        if (url.getParameter("num.tests.per.eviction.run", 0) > 0)
            config.numTestsPerEvictionRun = url.getParameter("num.tests.per.eviction.run", 0);
        if (url.getParameter("time.between.eviction.runs.millis", 0) > 0)
            config.timeBetweenEvictionRunsMillis = url.getParameter("time.between.eviction.runs.millis", 0);
        if (url.getParameter("min.evictable.idle.time.millis", 0) > 0)
            config.minEvictableIdleTimeMillis = url.getParameter("min.evictable.idle.time.millis", 0);
        final JedisPool jedisPool = new JedisPool(config, url.getHost(), url.getPort(DEFAULT_PORT), url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT));
        final int expiry = url.getParameter("expiry", 0);
        final String get = url.getParameter("get", "get");
        final String set = url.getParameter("set", Map.class.equals(type) ? "put" : "set");
        final String delete = url.getParameter("delete", Map.class.equals(type) ? "remove" : "delete");
        return new AbstractInvoker<T>(type, url) {

            protected Result doInvoke(Invocation invocation) throws Throwable {
                Jedis resource = null;
                try {
                    resource = jedisPool.getResource();
                    if (get.equals(invocation.getMethodName())) {
                        if (invocation.getArguments().length != 1) {
                            throw new IllegalArgumentException("The redis get method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
                        }
                        byte[] value = resource.get(String.valueOf(invocation.getArguments()[0]).getBytes());
                        if (value == null) {
                            return new RpcResult();
                        }
                        ObjectInput oin = getSerialization(url).deserialize(url, new ByteArrayInputStream(value));
                        return new RpcResult(oin.readObject());
                    } else if (set.equals(invocation.getMethodName())) {
                        if (invocation.getArguments().length != 2) {
                            throw new IllegalArgumentException("The redis set method arguments mismatch, must be two arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
                        }
                        byte[] key = String.valueOf(invocation.getArguments()[0]).getBytes();
                        ByteArrayOutputStream output = new ByteArrayOutputStream();
                        ObjectOutput value = getSerialization(url).serialize(url, output);
                        value.writeObject(invocation.getArguments()[1]);
                        resource.set(key, output.toByteArray());
                        if (expiry > 1000) {
                            resource.expire(key, expiry / 1000);
                        }
                        return new RpcResult();
                    } else if (delete.equals(invocation.getMethodName())) {
                        if (invocation.getArguments().length != 1) {
                            throw new IllegalArgumentException("The redis delete method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
                        }
                        resource.del(String.valueOf(invocation.getArguments()[0]).getBytes());
                        return new RpcResult();
                    } else {
                        throw new UnsupportedOperationException("Unsupported method " + invocation.getMethodName() + " in redis service.");
                    }
                } catch (Throwable t) {
                    RpcException re = new RpcException("Failed to invoke redis service method. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url + ", cause: " + t.getMessage(), t);
                    if (t instanceof TimeoutException || t instanceof SocketTimeoutException) {
                        re.setCode(RpcException.TIMEOUT_EXCEPTION);
                    } else if (t instanceof JedisConnectionException || t instanceof IOException) {
                        re.setCode(RpcException.NETWORK_EXCEPTION);
                    } else if (t instanceof JedisDataException) {
                        re.setCode(RpcException.SERIALIZATION_EXCEPTION);
                    }
                    throw re;
                } finally {
                    if (resource != null) {
                        try {
                            jedisPool.returnResource(resource);
                        } catch (Throwable t) {
                            logger.warn("returnResource error: " + t.getMessage(), t);
                        }
                    }
                }
            }

            public void destroy() {
                super.destroy();
                try {
                    jedisPool.destroy();
                } catch (Throwable e) {
                    logger.warn(e.getMessage(), e);
                }
            }
        };
    } catch (Throwable t) {
        throw new RpcException("Failed to refer redis service. interface: " + type.getName() + ", url: " + url + ", cause: " + t.getMessage(), t);
    }
}
Also used : Invocation(com.alibaba.dubbo.rpc.Invocation) ObjectOutput(com.alibaba.dubbo.common.serialize.ObjectOutput) RpcResult(com.alibaba.dubbo.rpc.RpcResult) AbstractInvoker(com.alibaba.dubbo.rpc.protocol.AbstractInvoker) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) GenericObjectPool(org.apache.commons.pool.impl.GenericObjectPool) JedisDataException(redis.clients.jedis.exceptions.JedisDataException) Jedis(redis.clients.jedis.Jedis) SocketTimeoutException(java.net.SocketTimeoutException) ByteArrayInputStream(java.io.ByteArrayInputStream) RpcException(com.alibaba.dubbo.rpc.RpcException) JedisPool(redis.clients.jedis.JedisPool) ObjectInput(com.alibaba.dubbo.common.serialize.ObjectInput) JedisConnectionException(redis.clients.jedis.exceptions.JedisConnectionException) TimeoutException(java.util.concurrent.TimeoutException) SocketTimeoutException(java.net.SocketTimeoutException)

Example 15 with RpcResult

use of com.alibaba.dubbo.rpc.RpcResult in project dubbo by alibaba.

the class MergeableClusterInvoker method invoke.

@SuppressWarnings("rawtypes")
public Result invoke(final Invocation invocation) throws RpcException {
    List<Invoker<T>> invokers = directory.list(invocation);
    String merger = getUrl().getMethodParameter(invocation.getMethodName(), Constants.MERGER_KEY);
    if (ConfigUtils.isEmpty(merger)) {
        // 如果方法不需要Merge,退化为只调一个Group
        for (final Invoker<T> invoker : invokers) {
            if (invoker.isAvailable()) {
                return invoker.invoke(invocation);
            }
        }
        return invokers.iterator().next().invoke(invocation);
    }
    Class<?> returnType;
    try {
        returnType = getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes()).getReturnType();
    } catch (NoSuchMethodException e) {
        returnType = null;
    }
    Map<String, Future<Result>> results = new HashMap<String, Future<Result>>();
    for (final Invoker<T> invoker : invokers) {
        Future<Result> future = executor.submit(new Callable<Result>() {

            public Result call() throws Exception {
                return invoker.invoke(new RpcInvocation(invocation, invoker));
            }
        });
        results.put(invoker.getUrl().getServiceKey(), future);
    }
    Object result = null;
    List<Result> resultList = new ArrayList<Result>(results.size());
    int timeout = getUrl().getMethodParameter(invocation.getMethodName(), Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
    for (Map.Entry<String, Future<Result>> entry : results.entrySet()) {
        Future<Result> future = entry.getValue();
        try {
            Result r = future.get(timeout, TimeUnit.MILLISECONDS);
            if (r.hasException()) {
                log.error(new StringBuilder(32).append("Invoke ").append(getGroupDescFromServiceKey(entry.getKey())).append(" failed: ").append(r.getException().getMessage()).toString(), r.getException());
            } else {
                resultList.add(r);
            }
        } catch (Exception e) {
            throw new RpcException(new StringBuilder(32).append("Failed to invoke service ").append(entry.getKey()).append(": ").append(e.getMessage()).toString(), e);
        }
    }
    if (resultList.size() == 0) {
        return new RpcResult((Object) null);
    } else if (resultList.size() == 1) {
        return resultList.iterator().next();
    }
    if (returnType == void.class) {
        return new RpcResult((Object) null);
    }
    if (merger.startsWith(".")) {
        merger = merger.substring(1);
        Method method;
        try {
            method = returnType.getMethod(merger, returnType);
        } catch (NoSuchMethodException e) {
            throw new RpcException(new StringBuilder(32).append("Can not merge result because missing method [ ").append(merger).append(" ] in class [ ").append(returnType.getClass().getName()).append(" ]").toString());
        }
        if (method != null) {
            if (!Modifier.isPublic(method.getModifiers())) {
                method.setAccessible(true);
            }
            result = resultList.remove(0).getValue();
            try {
                if (method.getReturnType() != void.class && method.getReturnType().isAssignableFrom(result.getClass())) {
                    for (Result r : resultList) {
                        result = method.invoke(result, r.getValue());
                    }
                } else {
                    for (Result r : resultList) {
                        method.invoke(result, r.getValue());
                    }
                }
            } catch (Exception e) {
                throw new RpcException(new StringBuilder(32).append("Can not merge result: ").append(e.getMessage()).toString(), e);
            }
        } else {
            throw new RpcException(new StringBuilder(32).append("Can not merge result because missing method [ ").append(merger).append(" ] in class [ ").append(returnType.getClass().getName()).append(" ]").toString());
        }
    } else {
        Merger resultMerger;
        if (ConfigUtils.isDefault(merger)) {
            resultMerger = MergerFactory.getMerger(returnType);
        } else {
            resultMerger = ExtensionLoader.getExtensionLoader(Merger.class).getExtension(merger);
        }
        if (resultMerger != null) {
            List<Object> rets = new ArrayList<Object>(resultList.size());
            for (Result r : resultList) {
                rets.add(r.getValue());
            }
            result = resultMerger.merge(rets.toArray((Object[]) Array.newInstance(returnType, 0)));
        } else {
            throw new RpcException("There is no merger to merge result.");
        }
    }
    return new RpcResult(result);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Result(com.alibaba.dubbo.rpc.Result) RpcResult(com.alibaba.dubbo.rpc.RpcResult) Invoker(com.alibaba.dubbo.rpc.Invoker) RpcException(com.alibaba.dubbo.rpc.RpcException) RpcInvocation(com.alibaba.dubbo.rpc.RpcInvocation) RpcResult(com.alibaba.dubbo.rpc.RpcResult) Method(java.lang.reflect.Method) RpcException(com.alibaba.dubbo.rpc.RpcException) Merger(com.alibaba.dubbo.rpc.cluster.Merger) Future(java.util.concurrent.Future) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

RpcResult (com.alibaba.dubbo.rpc.RpcResult)34 Result (com.alibaba.dubbo.rpc.Result)19 Test (org.junit.Test)17 URL (com.alibaba.dubbo.common.URL)15 RpcException (com.alibaba.dubbo.rpc.RpcException)14 Invocation (com.alibaba.dubbo.rpc.Invocation)11 Invoker (com.alibaba.dubbo.rpc.Invoker)9 DemoService (com.alibaba.dubbo.rpc.support.DemoService)9 RpcInvocation (com.alibaba.dubbo.rpc.RpcInvocation)8 Method (java.lang.reflect.Method)8 TMessage (org.apache.thrift.protocol.TMessage)6 Request (com.alibaba.dubbo.remoting.exchange.Request)5 Response (com.alibaba.dubbo.remoting.exchange.Response)5 TBinaryProtocol (org.apache.thrift.protocol.TBinaryProtocol)5 TIOStreamTransport (org.apache.thrift.transport.TIOStreamTransport)5 Channel (com.alibaba.dubbo.remoting.Channel)4 ChannelBuffer (com.alibaba.dubbo.remoting.buffer.ChannelBuffer)4 Demo (com.alibaba.dubbo.rpc.gen.thrift.Demo)4 IOException (java.io.IOException)4 ArrayList (java.util.ArrayList)4