@SuppressWarnings("unchecked")
  @Test
  public void testRpcException() {
    Logger logger = EasyMock.createMock(Logger.class);
    RpcContext.getContext().setRemoteAddress("127.0.0.1", 1234);
    RpcException exception = new RpcException("TestRpcException");
    logger.error(
        EasyMock.eq(
            "Got unchecked and undeclared exception which called by 127.0.0.1. service: "
                + DemoService.class.getName()
                + ", method: sayHello, exception: "
                + RpcException.class.getName()
                + ": TestRpcException"),
        EasyMock.eq(exception));
    ExceptionFilter exceptionFilter = new ExceptionFilter(logger);
    RpcInvocation invocation =
        new RpcInvocation("sayHello", new Class<?>[] {String.class}, new Object[] {"world"});
    Invoker<DemoService> invoker = EasyMock.createMock(Invoker.class);
    EasyMock.expect(invoker.getInterface()).andReturn(DemoService.class);
    EasyMock.expect(invoker.invoke(EasyMock.eq(invocation))).andThrow(exception);

    EasyMock.replay(logger, invoker);

    try {
      exceptionFilter.invoke(invoker, invocation);
    } catch (RpcException e) {
      assertEquals("TestRpcException", e.getMessage());
    }
    EasyMock.verify(logger, invoker);
    RpcContext.removeContext();
  }
  /** Empty notify cause forbidden, non-empty notify cancels forbidden state */
  @Test
  public void testEmptyNotifyCauseForbidden() {
    RegistryDirectory registryDirectory = getRegistryDirectory();
    List invokers = null;

    List<URL> serviceUrls = new ArrayList<URL>();
    registryDirectory.notify(serviceUrls);

    RpcInvocation inv = new RpcInvocation();
    try {
      invokers = registryDirectory.list(inv);
    } catch (RpcException e) {
      Assert.assertEquals(RpcException.FORBIDDEN_EXCEPTION, e.getCode());
      Assert.assertEquals(false, registryDirectory.isAvailable());
    }

    serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
    serviceUrls.add(SERVICEURL2.addParameter("methods", "getXXX1,getXXX2"));
    serviceUrls.add(SERVICEURL3.addParameter("methods", "getXXX1,getXXX2,getXXX3"));

    registryDirectory.notify(serviceUrls);
    inv.setMethodName("getXXX2");
    invokers = registryDirectory.list(inv);
    Assert.assertEquals(true, registryDirectory.isAvailable());
    Assert.assertEquals(2, invokers.size());
  }
 public void doSubscribe(final URL url, final NotifyListener listener) {
   String service = RedisRegistryUtil.toServicePath(url, root);
   RedisRegistryNotifier notifier = notifiers.get(service);
   if (notifier == null) {
     RedisRegistryNotifier newNotifier = new RedisRegistryNotifier(service, this);
     notifiers.putIfAbsent(service, newNotifier);
     notifier = notifiers.get(service);
     if (notifier == newNotifier) {
       notifier.start();
     }
   }
   boolean success = false;
   RpcException exception = null;
   for (Map.Entry<String, JedisPool> entry : jedisPools.entrySet()) {
     JedisPool jedisPool = entry.getValue();
     try {
       Jedis jedis = jedisPool.getResource();
       try {
         if (service.endsWith(Constants.ANY_VALUE)) {
           admin = true;
           Set<String> keys = jedis.keys(service);
           if (keys != null && keys.size() > 0) {
             Map<String, Set<String>> serviceKeys = RedisRegistryUtil.getServiceKeys(keys, root);
             for (Set<String> sk : serviceKeys.values()) {
               doNotify(jedis, sk, url, Arrays.asList(listener));
             }
           }
         } else {
           doNotify(
               jedis,
               jedis.keys(service + Constants.PATH_SEPARATOR + Constants.ANY_VALUE),
               url,
               Arrays.asList(listener));
         }
         success = true;
         break; // 只需读一个服务器的数据
       } finally {
         jedisPool.returnResource(jedis);
       }
     } catch (Throwable t) { // 尝试下一个服务器
       exception =
           new RpcException(
               "Failed to subscribe service from redis registry. registry: "
                   + entry.getKey()
                   + ", service: "
                   + url
                   + ", cause: "
                   + t.getMessage(),
               t);
     }
   }
   if (exception != null) {
     if (success) {
       logger.warn(exception.getMessage(), exception);
     } else {
       throw exception;
     }
   }
 }
示例#4
0
 protected RpcException getRpcException(
     Class<?> type, URL url, Invocation invocation, Throwable e) {
   RpcException re =
       new RpcException(
           "Failed to invoke remote service: "
               + type
               + ", method: "
               + invocation.getMethodName()
               + ", cause: "
               + e.getMessage(),
           e);
   re.setCode(getErrorCode(e));
   return re;
 }
 public void doRegister(URL url) {
   String key = RedisRegistryUtil.toCategoryPath(url, root);
   String value = url.toFullString();
   String expire = String.valueOf(System.currentTimeMillis() + expirePeriod);
   boolean success = false;
   RpcException exception = null;
   for (Map.Entry<String, JedisPool> entry : jedisPools.entrySet()) {
     JedisPool jedisPool = entry.getValue();
     try {
       Jedis jedis = jedisPool.getResource();
       try {
         jedis.hset(key, value, expire);
         jedis.publish(key, Constants.REGISTER);
         success = true;
         if (!replicate) {
           break; //  如果服务器端已同步数据,只需写入单台机器
         }
       } finally {
         jedisPool.returnResource(jedis);
       }
     } catch (Throwable t) {
       exception =
           new RpcException(
               "Failed to register service to redis registry. registry: "
                   + entry.getKey()
                   + ", service: "
                   + url
                   + ", cause: "
                   + t.getMessage(),
               t);
     }
   }
   if (exception != null) {
     if (success) {
       logger.warn(exception.getMessage(), exception);
     } else {
       throw exception;
     }
   }
 }
 // forbid
 private void testforbid(RegistryDirectory registryDirectory) {
   invocation = new RpcInvocation();
   List<URL> serviceUrls = new ArrayList<URL>();
   serviceUrls.add(
       new URL(
           Constants.EMPTY_PROTOCOL,
           Constants.ANYHOST_VALUE,
           0,
           service,
           Constants.CATEGORY_KEY,
           Constants.PROVIDERS_CATEGORY));
   registryDirectory.notify(serviceUrls);
   Assert.assertEquals(
       "invokers size=0 ,then the registry directory is not available",
       false,
       registryDirectory.isAvailable());
   try {
     registryDirectory.list(invocation);
     fail("forbid must throw RpcException");
   } catch (RpcException e) {
     Assert.assertEquals(RpcException.FORBIDDEN_EXCEPTION, e.getCode());
   }
 }
 private Result wrapBreakerInvoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
   // 首先检查是否需要进入服务降级流程
   if (checkNeedCircuitBreak(invoker, invocation)) {
     logger.info(
         "[{}] activate the circuit break for url [{}],invoke method [{}]",
         localHost,
         invoker.getUrl(),
         invocation.getMethodName());
     // 进入服务降级
     return doCircuitBreak(invoker, invocation);
   }
   try {
     Result result = invoker.invoke(invocation);
     // 将该服务从服务降级中恢复出来
     toBeNormal(invoker, invocation);
     return result;
   } catch (RpcException e) {
     // 如果是请求超时或者网络异常,进行异常统计
     if (!e.isBiz()) {
       caughtException(invoker, invocation, e);
     }
     throw e;
   }
 }
  /**
   * When destroying, RegistryDirectory should: 1. be disconnected from Registry 2. destroy all
   * invokers
   */
  @Test
  public void testDestroy() {
    RegistryDirectory registryDirectory = getRegistryDirectory();

    List<URL> serviceUrls = new ArrayList<URL>();
    serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
    serviceUrls.add(SERVICEURL2.addParameter("methods", "getXXX1,getXXX2"));
    serviceUrls.add(SERVICEURL3.addParameter("methods", "getXXX1,getXXX2,getXXX3"));

    registryDirectory.notify(serviceUrls);
    List<Invoker> invokers = registryDirectory.list(invocation);
    Assert.assertEquals(true, registryDirectory.isAvailable());
    Assert.assertEquals(true, invokers.get(0).isAvailable());

    registryDirectory.destroy();
    Assert.assertEquals(false, registryDirectory.isAvailable());
    Assert.assertEquals(false, invokers.get(0).isAvailable());
    registryDirectory.destroy();

    Map<String, List<Invoker<RegistryDirectoryTest>>> methodInvokerMap =
        registryDirectory.getMethodInvokerMap();
    Map<String, Invoker<RegistryDirectoryTest>> urlInvokerMap =
        registryDirectory.getUrlInvokerMap();

    Assert.assertTrue(methodInvokerMap == null);
    Assert.assertEquals(0, urlInvokerMap.size());
    // List<U> urls = mockRegistry.getSubscribedUrls();

    RpcInvocation inv = new RpcInvocation();
    try {
      registryDirectory.list(inv);
      fail();
    } catch (RpcException e) {
      Assert.assertTrue(e.getMessage().contains("already destroyed"));
    }
  }