Search in sources :

Example 46 with RpcException

use of org.apache.dubbo.rpc.RpcException in project dubbo by alibaba.

the class FailoverClusterInvokerTest method testInvokerDestroyAndReList.

/**
 * When invokers in directory changes after a failed request but just before a retry effort,
 * then we should reselect from the latest invokers before retry.
 */
@Test
public void testInvokerDestroyAndReList() {
    final URL url = URL.valueOf("test://localhost/" + Demo.class.getName() + "?loadbalance=roundrobin&retries=" + retries);
    RpcException exception = new RpcException(RpcException.TIMEOUT_EXCEPTION);
    MockInvoker<Demo> invoker1 = new MockInvoker<Demo>(Demo.class, url);
    invoker1.setException(exception);
    MockInvoker<Demo> invoker2 = new MockInvoker<Demo>(Demo.class, url);
    invoker2.setException(exception);
    final List<Invoker<Demo>> invokers = new ArrayList<Invoker<Demo>>();
    invokers.add(invoker1);
    invokers.add(invoker2);
    Callable<Object> callable = () -> {
        // Simulation: all invokers are destroyed
        for (Invoker<Demo> invoker : invokers) {
            invoker.destroy();
        }
        invokers.clear();
        MockInvoker<Demo> invoker3 = new MockInvoker<Demo>(Demo.class, url);
        invoker3.setResult(AsyncRpcResult.newDefaultAsyncResult(null));
        invokers.add(invoker3);
        return null;
    };
    invoker1.setCallable(callable);
    invoker2.setCallable(callable);
    RpcInvocation inv = new RpcInvocation();
    inv.setMethodName("test");
    Directory<Demo> dic = new MockDirectory<Demo>(url, invokers);
    FailoverClusterInvoker<Demo> clusterinvoker = new FailoverClusterInvoker<Demo>(dic);
    clusterinvoker.invoke(inv);
}
Also used : RpcInvocation(org.apache.dubbo.rpc.RpcInvocation) ArrayList(java.util.ArrayList) URL(org.apache.dubbo.common.URL) AbstractInvoker(org.apache.dubbo.rpc.protocol.AbstractInvoker) Invoker(org.apache.dubbo.rpc.Invoker) RpcException(org.apache.dubbo.rpc.RpcException) Test(org.junit.jupiter.api.Test)

Example 47 with RpcException

use of org.apache.dubbo.rpc.RpcException in project dubbo by alibaba.

the class MergeableClusterInvoker method doInvoke.

@Override
protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
    checkInvokers(invokers, invocation);
    String merger = getUrl().getMethodParameter(invocation.getMethodName(), MERGER_KEY);
    if (ConfigUtils.isEmpty(merger)) {
        // If a method doesn't have a merger, only invoke one Group
        for (final Invoker<T> invoker : invokers) {
            if (invoker.isAvailable()) {
                try {
                    return invoker.invoke(invocation);
                } catch (RpcException e) {
                    if (e.isNoInvokerAvailableAfterFilter()) {
                        log.debug("No available provider for service" + getUrl().getServiceKey() + " on group " + invoker.getUrl().getParameter(GROUP_KEY) + ", will continue to try another group.");
                    } else {
                        throw e;
                    }
                }
            }
        }
        return invokers.iterator().next().invoke(invocation);
    }
    Class<?> returnType;
    try {
        returnType = getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes()).getReturnType();
    } catch (NoSuchMethodException e) {
        returnType = null;
    }
    Map<String, Result> results = new HashMap<>();
    for (final Invoker<T> invoker : invokers) {
        RpcInvocation subInvocation = new RpcInvocation(invocation, invoker);
        subInvocation.setAttachment(ASYNC_KEY, "true");
        results.put(invoker.getUrl().getServiceKey(), invoker.invoke(subInvocation));
    }
    Object result = null;
    List<Result> resultList = new ArrayList<Result>(results.size());
    for (Map.Entry<String, Result> entry : results.entrySet()) {
        Result asyncResult = entry.getValue();
        try {
            Result r = asyncResult.get();
            if (r.hasException()) {
                log.error("Invoke " + getGroupDescFromServiceKey(entry.getKey()) + " failed: " + r.getException().getMessage(), r.getException());
            } else {
                resultList.add(r);
            }
        } catch (Exception e) {
            throw new RpcException("Failed to invoke service " + entry.getKey() + ": " + e.getMessage(), e);
        }
    }
    if (resultList.isEmpty()) {
        return AsyncRpcResult.newDefaultAsyncResult(invocation);
    } else if (resultList.size() == 1) {
        return AsyncRpcResult.newDefaultAsyncResult(resultList.get(0).getValue(), invocation);
    }
    if (returnType == void.class) {
        return AsyncRpcResult.newDefaultAsyncResult(invocation);
    }
    if (merger.startsWith(".")) {
        merger = merger.substring(1);
        Method method;
        try {
            method = returnType.getMethod(merger, returnType);
        } catch (NoSuchMethodException e) {
            throw new RpcException("Can not merge result because missing method [ " + merger + " ] in class [ " + returnType.getName() + " ]");
        }
        ReflectUtils.makeAccessible(method);
        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("Can not merge result: " + e.getMessage(), e);
        }
    } 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 AsyncRpcResult.newDefaultAsyncResult(result, invocation);
}
Also used : RpcInvocation(org.apache.dubbo.rpc.RpcInvocation) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) RpcException(org.apache.dubbo.rpc.RpcException) AsyncRpcResult(org.apache.dubbo.rpc.AsyncRpcResult) Result(org.apache.dubbo.rpc.Result) Merger(org.apache.dubbo.rpc.cluster.Merger) RpcException(org.apache.dubbo.rpc.RpcException) HashMap(java.util.HashMap) Map(java.util.Map)

Example 48 with RpcException

use of org.apache.dubbo.rpc.RpcException in project dubbo by alibaba.

the class FilterTest method testInvokeException.

@Test
public void testInvokeException() {
    try {
        Invoker<FilterTest> invoker = new LegacyInvoker<FilterTest>(null);
        Invocation invocation = new LegacyInvocation("aa");
        myFilter.invoke(invoker, invocation);
        fail();
    } catch (RpcException e) {
        Assertions.assertTrue(e.getMessage().contains("arg0 illegal"));
    }
}
Also used : Invocation(com.alibaba.dubbo.rpc.Invocation) RpcException(org.apache.dubbo.rpc.RpcException) Test(org.junit.jupiter.api.Test)

Example 49 with RpcException

use of org.apache.dubbo.rpc.RpcException in project dubbo by alibaba.

the class ConsumerContextFilter method invoke.

@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
    RpcContext context = RpcContext.getContext();
    context.setInvoker(invoker).setInvocation(invocation).setLocalAddress(NetUtils.getLocalHost(), 0).setRemoteAddress(invoker.getUrl().getHost(), invoker.getUrl().getPort()).setRemoteApplicationName(invoker.getUrl().getParameter(REMOTE_APPLICATION_KEY)).setAttachment(REMOTE_APPLICATION_KEY, invoker.getUrl().getParameter(APPLICATION_KEY));
    if (invocation instanceof RpcInvocation) {
        ((RpcInvocation) invocation).setInvoker(invoker);
    }
    // pass default timeout set by end user (ReferenceConfig)
    Object countDown = context.get(TIME_COUNTDOWN_KEY);
    if (countDown != null) {
        TimeoutCountDown timeoutCountDown = (TimeoutCountDown) countDown;
        if (timeoutCountDown.isExpired()) {
            return AsyncRpcResult.newDefaultAsyncResult(new RpcException(RpcException.TIMEOUT_TERMINATE, "No time left for making the following call: " + invocation.getServiceName() + "." + invocation.getMethodName() + ", terminate directly."), invocation);
        }
    }
    return invoker.invoke(invocation);
}
Also used : RpcContext(org.apache.dubbo.rpc.RpcContext) RpcInvocation(org.apache.dubbo.rpc.RpcInvocation) RpcException(org.apache.dubbo.rpc.RpcException) TimeoutCountDown(org.apache.dubbo.rpc.TimeoutCountDown)

Example 50 with RpcException

use of org.apache.dubbo.rpc.RpcException in project dubbo by alibaba.

the class GenericFilter method invoke.

@Override
public Result invoke(Invoker<?> invoker, Invocation inv) throws RpcException {
    if ((inv.getMethodName().equals($INVOKE) || inv.getMethodName().equals($INVOKE_ASYNC)) && inv.getArguments() != null && inv.getArguments().length == 3 && !GenericService.class.isAssignableFrom(invoker.getInterface())) {
        String name = ((String) inv.getArguments()[0]).trim();
        String[] types = (String[]) inv.getArguments()[1];
        Object[] args = (Object[]) inv.getArguments()[2];
        try {
            Method method = ReflectUtils.findMethodByMethodSignature(invoker.getInterface(), name, types);
            Class<?>[] params = method.getParameterTypes();
            if (args == null) {
                args = new Object[params.length];
            }
            if (types == null) {
                types = new String[params.length];
            }
            if (args.length != types.length) {
                throw new RpcException("GenericFilter#invoke args.length != types.length, please check your " + "params");
            }
            String generic = inv.getAttachment(GENERIC_KEY);
            if (StringUtils.isBlank(generic)) {
                generic = RpcContext.getContext().getAttachment(GENERIC_KEY);
            }
            if (StringUtils.isEmpty(generic) || ProtocolUtils.isDefaultGenericSerialization(generic) || ProtocolUtils.isGenericReturnRawResult(generic)) {
                try {
                    args = PojoUtils.realize(args, params, method.getGenericParameterTypes());
                } catch (IllegalArgumentException e) {
                    throw new RpcException(e);
                }
            } else if (ProtocolUtils.isGsonGenericSerialization(generic)) {
                args = getGsonGenericArgs(args, method.getGenericParameterTypes());
            } else if (ProtocolUtils.isJavaGenericSerialization(generic)) {
                Configuration configuration = ApplicationModel.getEnvironment().getConfiguration();
                if (!configuration.getBoolean(CommonConstants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE, false)) {
                    String notice = "Trigger the safety barrier! " + "Native Java Serializer is not allowed by default." + "This means currently maybe being attacking by others. " + "If you are sure this is a mistake, " + "please set `" + CommonConstants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE + "` enable in configuration! " + "Before doing so, please make sure you have configure JEP290 to prevent serialization attack.";
                    logger.error(notice);
                    throw new RpcException(new IllegalStateException(notice));
                }
                for (int i = 0; i < args.length; i++) {
                    if (byte[].class == args[i].getClass()) {
                        try (UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream((byte[]) args[i])) {
                            args[i] = ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(GENERIC_SERIALIZATION_NATIVE_JAVA).deserialize(null, is).readObject();
                        } catch (Exception e) {
                            throw new RpcException("Deserialize argument [" + (i + 1) + "] failed.", e);
                        }
                    } else {
                        throw new RpcException("Generic serialization [" + GENERIC_SERIALIZATION_NATIVE_JAVA + "] only support message type " + byte[].class + " and your message type is " + args[i].getClass());
                    }
                }
            } else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
                for (int i = 0; i < args.length; i++) {
                    if (args[i] instanceof JavaBeanDescriptor) {
                        args[i] = JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) args[i]);
                    } else {
                        throw new RpcException("Generic serialization [" + GENERIC_SERIALIZATION_BEAN + "] only support message type " + JavaBeanDescriptor.class.getName() + " and your message type is " + args[i].getClass().getName());
                    }
                }
            } else if (ProtocolUtils.isProtobufGenericSerialization(generic)) {
                // as proto3 only accept one protobuf parameter
                if (args.length == 1 && args[0] instanceof String) {
                    try (UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream(((String) args[0]).getBytes())) {
                        args[0] = ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(GENERIC_SERIALIZATION_PROTOBUF).deserialize(null, is).readObject(method.getParameterTypes()[0]);
                    } catch (Exception e) {
                        throw new RpcException("Deserialize argument failed.", e);
                    }
                } else {
                    throw new RpcException("Generic serialization [" + GENERIC_SERIALIZATION_PROTOBUF + "] only support one " + String.class.getName() + " argument and your message size is " + args.length + " and type is" + args[0].getClass().getName());
                }
            }
            RpcInvocation rpcInvocation = new RpcInvocation(method, invoker.getInterface().getName(), invoker.getUrl().getProtocolServiceKey(), args, inv.getObjectAttachments(), inv.getAttributes());
            rpcInvocation.setInvoker(inv.getInvoker());
            rpcInvocation.setTargetServiceUniqueName(inv.getTargetServiceUniqueName());
            return invoker.invoke(rpcInvocation);
        } catch (NoSuchMethodException | ClassNotFoundException e) {
            throw new RpcException(e.getMessage(), e);
        }
    }
    return invoker.invoke(inv);
}
Also used : RpcInvocation(org.apache.dubbo.rpc.RpcInvocation) Configuration(org.apache.dubbo.common.config.Configuration) UnsafeByteArrayInputStream(org.apache.dubbo.common.io.UnsafeByteArrayInputStream) Method(java.lang.reflect.Method) GenericException(org.apache.dubbo.rpc.service.GenericException) JsonSyntaxException(com.google.gson.JsonSyntaxException) IOException(java.io.IOException) RpcException(org.apache.dubbo.rpc.RpcException) JavaBeanDescriptor(org.apache.dubbo.common.beanutil.JavaBeanDescriptor) RpcException(org.apache.dubbo.rpc.RpcException)

Aggregations

RpcException (org.apache.dubbo.rpc.RpcException)102 URL (org.apache.dubbo.common.URL)37 Test (org.junit.jupiter.api.Test)29 RpcInvocation (org.apache.dubbo.rpc.RpcInvocation)28 Result (org.apache.dubbo.rpc.Result)21 Invocation (org.apache.dubbo.rpc.Invocation)17 ArrayList (java.util.ArrayList)15 AppResponse (org.apache.dubbo.rpc.AppResponse)13 AsyncRpcResult (org.apache.dubbo.rpc.AsyncRpcResult)13 Invoker (org.apache.dubbo.rpc.Invoker)13 IOException (java.io.IOException)9 List (java.util.List)9 Method (java.lang.reflect.Method)8 Gson (com.google.gson.Gson)6 InvocationTargetException (java.lang.reflect.InvocationTargetException)6 HashMap (java.util.HashMap)5 RemotingException (org.apache.dubbo.remoting.RemotingException)5 TException (org.apache.thrift.TException)5 SocketTimeoutException (java.net.SocketTimeoutException)4 CountDownLatch (java.util.concurrent.CountDownLatch)4