@Test(expected = HystrixBadRequestException.class)
 public void testGetUserByNameIgnoreBadRequestException() {
   restClient.getUserByNameIgnoreExc(" ");
   assertEquals(1, HystrixRequestLog.getCurrentRequest().getExecutedCommands().size());
   HystrixCommand getUserByNameIgnoreExc = getHystrixCommandByKey("getUserByNameIgnoreExc");
   assertTrue(getUserByNameIgnoreExc.getExecutionEvents().contains(HystrixEventType.FAILURE));
 }
 @Test
 public void testFindAllAsynchronouslyWithFallback()
     throws ExecutionException, InterruptedException {
   int commandCount = 1;
   int fallbackCount = 2;
   List<User> users = restClient.findAllAsync(3, 10).get();
   assertEquals(1, users.size());
   assertEquals(DEF_USER, users.get(0));
   assertEquals(
       commandCount + fallbackCount,
       HystrixRequestLog.getCurrentRequest().getExecutedCommands().size());
   HystrixCommand findAllAsyncCommand = getHystrixCommandByKey("findAllAsync");
   HystrixCommand findAllFallbackCommand = getHystrixCommandByKey("findAllFallback");
   HystrixCommand findAllFallback2Command = getHystrixCommandByKey("findAllFallback2");
   assertTrue(findAllAsyncCommand.isFailedExecution());
   assertTrue(findAllFallbackCommand.isFailedExecution());
   assertTrue(findAllFallback2Command.isExecutionComplete());
   assertExecutedCommands("findAllAsync", "findAllFallback", "findAllFallback2");
   // confirm that initial command has failed
   assertTrue(findAllAsyncCommand.getExecutionEvents().contains(HystrixEventType.FAILURE));
   // confirm that fallback has failed
   assertTrue(findAllFallbackCommand.getExecutionEvents().contains(HystrixEventType.FAILURE));
   // and that last fallback was successful
   assertTrue(
       findAllFallbackCommand.getExecutionEvents().contains(HystrixEventType.FALLBACK_SUCCESS));
 }
  public static void main(String... args) {
    // initialize
    DiscoveryAndLoadBalancer.getFactory();
    // hystrix stream => http://localhost:9999
    startHystrixMetricsStream();

    System.out.println("Server => Starting at http://localhost:8080/");
    System.out.println("   Sample URLs: ");
    System.out.println("      - http://localhost:8080/device/home?userId=123");
    System.out.println("----------------------------------------------------------------");

    // start web services => http://localhost:8080
    RxNetty.createHttpServer(
            8080,
            (request, response) -> {
              if (request.getPath().contains("favicon.ico")) {
                return Observable.empty();
              }
              // System.out.println("Server => Request: " + request.getPath());
              return Observable.defer(
                      () -> {
                        HystrixRequestContext.initializeContext();
                        try {
                          return handleRoutes(request, response);
                        } catch (Throwable e) {
                          System.err.println("Server => Error [" + request.getPath() + "] => " + e);
                          response.setStatus(HttpResponseStatus.BAD_REQUEST);
                          return response.writeStringAndFlush(
                              "Error 500: Bad Request\n" + e.getMessage() + "\n");
                        }
                      })
                  .onErrorResumeNext(
                      error -> {
                        System.err.println("Server => Error: " + error.getMessage());
                        error.printStackTrace();
                        return writeError(request, response, "Failed: " + error.getMessage());
                      })
                  .doOnTerminate(
                      () -> {
                        if (HystrixRequestContext.isCurrentThreadInitialized()) {
                          System.out.println(
                              "Server => Request ["
                                  + request.getPath()
                                  + "] => "
                                  + HystrixRequestLog.getCurrentRequest()
                                      .getExecutedCommandsAsString());
                          HystrixRequestContext.getContextForCurrentThread().shutdown();
                        } else {
                          System.err.println(
                              "HystrixRequestContext not initialized for thread: "
                                  + Thread.currentThread());
                        }
                        response.close();
                      });
            })
        .startAndWait();
  }
  /**
   * Test that an open circuit is closed after 1 success. This also ensures that the rolling window
   * (containing failures) is cleared after the sleep window Otherwise, the next bucket roll would
   * produce another signal to fail unless it is explicitly cleared (via {@link
   * HystrixCommandMetrics#resetStream()}.
   */
  @Test
  public void testCircuitClosedAfterSuccess() {
    String key = "cmd-G";
    try {
      int sleepWindow = 20;
      HystrixCommand<Boolean> cmd1 = new FailureCommand(key, 1, sleepWindow);
      HystrixCircuitBreaker cb = cmd1.circuitBreaker;

      // this should start as allowing requests
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());

      cmd1.execute();
      HystrixCommand<Boolean> cmd2 = new FailureCommand(key, 1, sleepWindow);
      cmd2.execute();
      HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1, sleepWindow);
      cmd3.execute();
      HystrixCommand<Boolean> cmd4 = new TimeoutCommand(key, sleepWindow);
      cmd4.execute();

      // everything has failed in the test window so we should return false now
      Thread.sleep(100);
      System.out.println(
          "ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
      System.out.println("CircuitBreaker state 1 : " + cmd1.getMetrics().getHealthCounts());
      assertFalse(cb.allowRequest());
      assertTrue(cb.isOpen());

      // wait for sleepWindow to pass
      Thread.sleep(sleepWindow + 50);

      // but the circuit should still be open
      assertTrue(cb.isOpen());

      // we should now allow 1 request, and upon success, should cause the circuit to be closed
      HystrixCommand<Boolean> cmd5 = new SuccessCommand(key, 60, sleepWindow);
      Observable<Boolean> asyncResult = cmd5.observe();

      // and further requests are still blocked while the singleTest command is in flight
      assertFalse(cb.allowRequest());

      asyncResult.toBlocking().single();

      // all requests should be open again
      System.out.println("CircuitBreaker state 2 : " + cmd1.getMetrics().getHealthCounts());
      assertTrue(cb.allowRequest());
      assertTrue(cb.allowRequest());
      assertTrue(cb.allowRequest());
      // and the circuit should be closed again
      assertFalse(cb.isOpen());

    } catch (Exception e) {
      e.printStackTrace();
      fail("Error occurred: " + e.getMessage());
    }
  }
  @Test
  public void testCollapser() throws ExecutionException, InterruptedException {

    User u1 = userService.getUser("1");
    User u2 = userService.getUser("2");
    User u3 = userService.getUser("3");
    User u4 = userService.getUser("4");

    assertEquals("name: 1", u1.getName());
    assertEquals("name: 2", u2.getName());
    assertEquals("name: 3", u3.getName());
    assertEquals("name: 4", u4.getName());
    assertEquals(4, HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().size());
    HystrixInvokableInfo<?> command =
        HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().iterator().next();
    assertEquals("getUsers", command.getCommandKey().name());
    // confirm that it was a COLLAPSED command execution
    assertTrue(command.getExecutionEvents().contains(HystrixEventType.COLLAPSED));
    // and that it was successful
    assertTrue(command.getExecutionEvents().contains(HystrixEventType.SUCCESS));
  }
 @Test
 public void testGetUserByIdSuccess() {
   User user = restClient.getUserById("1");
   User exUser = new User("1", "Alex");
   assertExecutedCommands("GetUserByIdCommand");
   assertEquals(1, HystrixRequestLog.getCurrentRequest().getExecutedCommands().size());
   HystrixCommand getUserByIdCommand = getHystrixCommandByKey("GetUserByIdCommand");
   assertEquals("SimpleRestClient", getUserByIdCommand.getCommandGroup().name());
   assertEquals("GetUserByIdCommand", getUserByIdCommand.getCommandKey().name());
   assertEquals(exUser, user);
   // confirm that command has success
   assertTrue(getUserByIdCommand.getExecutionEvents().contains(HystrixEventType.SUCCESS));
 }
  @Test
  public void testGetUserByName() {
    User user = restClient.getUserByName("timeout");
    assertExecutedCommands("GetUserByNameCommand");
    assertEquals(DEF_USER, user);
    assertEquals(1, HystrixRequestLog.getCurrentRequest().getExecutedCommands().size());
    HystrixCommand<?> hystrixCommand =
        HystrixRequestLog.getCurrentRequest()
            .getExecutedCommands()
            .toArray(new HystrixCommand<?>[1])[0];
    assertEquals("GetUserByNameCommand", hystrixCommand.getCommandKey().name());
    assertEquals("SimpleRestClientTest", hystrixCommand.getThreadPoolKey().name());
    assertFalse(hystrixCommand.isExecutedInThread());

    assertEquals(
        Integer.valueOf(500),
        hystrixCommand.getProperties().executionIsolationThreadTimeoutInMilliseconds().get());
    // confirm that command has failed
    assertTrue(hystrixCommand.getExecutionEvents().contains(HystrixEventType.FAILURE));
    // and that fallback was successful
    assertTrue(hystrixCommand.getExecutionEvents().contains(HystrixEventType.FALLBACK_SUCCESS));
  }
  /** Test that if the % of failures is higher than the threshold that the circuit trips. */
  @Test
  public void testCircuitDoesNotTripOnFailuresBelowThreshold() {
    String key = "cmd-C";
    try {
      HystrixCommand<Boolean> cmd1 = new SuccessCommand(key, 60);
      HystrixCircuitBreaker cb = cmd1.circuitBreaker;

      // this should start as allowing requests
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());

      // success with high latency
      cmd1.execute();
      HystrixCommand<Boolean> cmd2 = new SuccessCommand(key, 1);
      cmd2.execute();
      HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1);
      cmd3.execute();
      HystrixCommand<Boolean> cmd4 = new SuccessCommand(key, 1);
      cmd4.execute();
      HystrixCommand<Boolean> cmd5 = new SuccessCommand(key, 1);
      cmd5.execute();
      HystrixCommand<Boolean> cmd6 = new FailureCommand(key, 1);
      cmd6.execute();
      HystrixCommand<Boolean> cmd7 = new SuccessCommand(key, 1);
      cmd7.execute();
      HystrixCommand<Boolean> cmd8 = new FailureCommand(key, 1);
      cmd8.execute();

      // this should remain closed as the failure threshold is below the percentage limit
      Thread.sleep(100);
      System.out.println(
          "ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
      System.out.println("Current CircuitBreaker Status : " + cmd1.getMetrics().getHealthCounts());
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());
    } catch (Exception e) {
      e.printStackTrace();
      fail("Error occurred: " + e.getMessage());
    }
  }
  protected void assertSaneHystrixRequestLog(final int numCommands) {
    HystrixRequestLog currentRequestLog = HystrixRequestLog.getCurrentRequest();

    try {
      assertEquals(numCommands, currentRequestLog.getAllExecutedCommands().size());
      assertFalse(currentRequestLog.getExecutedCommandsAsString().contains("Executed"));
      assertTrue(
          currentRequestLog.getAllExecutedCommands().iterator().next().getExecutionEvents().size()
              >= 1);
      // Most commands should have 1 execution event, but fallbacks / responses from cache can cause
      // more than 1.  They should never have 0
    } catch (Throwable ex) {
      System.out.println(
          "Problematic Request log : "
              + currentRequestLog.getExecutedCommandsAsString()
              + " , expected : "
              + numCommands);
      throw new RuntimeException(ex);
    }
  }
Exemple #10
0
 public void shutdown(HystrixRequestLog value) {
   // write this value to the Request stream
   HystrixRequestEventsStream.getInstance().write(value.getAllExecutedCommands());
 }