0.90.0 release notes

12th August 2019

New features

  • You can now send an HTTP request to an absolute URI, which means you don't need to create different HttpClients for different hosts. #1143 #1343 #1961

    HttpClient client = HttpClient.of(); // No base URI specified.
    client.get("http://foo.com").aggregate().join();
    client.execute(RequestHeaders.of(HttpMethod.GET, "http://bar.com")).aggregate().join();
    
    HttpClient client = HttpClient.of("http://baz.com"); // Base URI specified.
    client.get("/index.html").aggregate().join();
    client.get("http://qux.com").aggregate().join(); // Can override the base URI.
  • HealthCheckedEndpointGroup has been revamped and now supports long-polling when used with Armeria's HealthCheckService. #1948 #1977 #1982

    • Long-polling support enables HealthCheckedEndpointGroup to detect the server health changes immediately with much fewer number of health check requests.
    • Long-polling support is auto-detected based on a special HTTP header armeria-lphc, so it is fully backward-compatible with ordinary non-Armeria health check services.
    EndpointGroup group =
        HealthCheckedEndpointGroup.of(
            new StaticEndpointGroup(Endpoint.of("foo.com", 8080),
                                    Endpoint.of("bar.com", 8080)),
            "/internal/l7check");
    EndpointGroupRegistry.register("myGroup", group,
                                   EndpointSelectionStrategy.WEIGHTED_ROUND_ROBIN);
    HttpClient client = HttpClient.of("http://group:myGroup");
    client.get("/").aggregate().join();
  • You can now send a delayed response easily using HttpResponse.delayed(), which may be useful when simulating a slow server. #1935

    Server server = new ServerBuilder()
        .service("/delayed", (ctx, req) -> HttpResponse.delayed(HttpResponse.of(200),
                                                                Duration.ofSeconds(3)))
        .build();
  • You can now write a mock HTTP server using MockWebServerExtension and JUnit 5. #1884 #1935

    class MyTest {
        @RegisterExtension
        static MockWebServerExtension server = new MockWebServerExtension();
    
        @Test
        void test() {
            server.enqueue(HttpResponse.of(200));
            HttpResponse actualRes = HttpClient.of(server.httpUri("/")).get("/");
            assertThat(actualRes.aggregate().join().status().code()).isEqualTo(200);
        }
    }
  • AsyncCloseable has been added to provide an asynchronous close operation. #1948

    public class IAmCloseable implements AutoCloseable, AsyncCloseable {
        @Override
        public CompletableFuture<?> closeAsync() {
            ...
        }
    
        @Override
        public void close() {
            closeAsync().join();
        }
    }
  • You can now specify an EventExecutor when using HttpResponse.from(). #1937

  • You can now suppress the false warnings from RequestContextCurrentTraceContext by using setCurrentThreadNotRequestThread() #1971 #1980

    • For example, you could prevent warnings from the administrative threads controlled by ThreadFactory like the following:

      ThreadFactory factory = (runnable) -> new Thread(new Runnable() {
          @Override
          public void run() {
              RequestContextCurrentTraceContext.setCurrentThreadNotRequestThread(true);
              runnable.run();
          }
      
          @Override
          public String toString() {
              return runnable.toString();
          }
      });

Bug fixes

  • RequestLog.responseCause() is now recorded correctly for client requests. #1977
  • RetryingClient now respects the Endpoint selection order, which was broken since 0.89.0. #1973 #1974
  • The health checked requests sent by HealthCheckedEndpointGroup are now sent at the correct interval, even if an endpoint is not responsive. #1948
  • ClosedPublisherException is not raised anymore when HttpResponse is aborted by the client who issued the request. #1962
  • Armeria gRPC client now sends the TE header, whose absence caused interoperability issues with some gRPC servers, such as Python gRPC server. #1963 #1965
  • Armeria HTTP client does not send more than two Host headers for HTTP/1 anymore. #1942
  • HealthCheckedEndpointGroup now waits until the initial Endpoints are available from its delegate group. #1940

Deprecations

  • HealthCheckedEndpointGroupBuilder.retryInterval() has been un-deprecated. #1948
  • HealthCheckedEndpointGroupBuilder.healthCheckPort() has been deprecated in favor of port(). #1948
  • CircuitBreakerBuilder.circuitBreakerMapping() has been deprecated in favor of mapping(). #1970

Breaking changes

  • HttpHealthCheckedEndpointGroup has been renamed to HealthCheckedEndpointGroup.
    • The old HealthCheckedEndpointGroup has been renamed to AbstractHealthCheckedEndpointGroup, and is now extensible enough for you to implement your own health-checking mechanism, such as sending a gRPC/Thrift call.

Dependencies

  • Caffeine 2.7.0 -> 2.8.0
  • fastutil 8.2.3 -> 8.3.0
  • Project Reactor 3.2.10 -> 3.2.11
  • Retrofit 2.6.0 -> 2.6.1
  • RxJava 2.2.10 -> 2.2.11
  • SLF4J 1.7.26 -> 1.7.27
  • Spring Boot 2.1.6 -> 2.1.7, 1.5.21 -> 1.5.22

Thank you