0.99.8 release notes

7th July 2020

🌟 New features

  • You can now use ClientRequestContext to build a complex RetryRule and CircuitBreakerRule. #2851
    RetryRuleWithContent.<RpcResponse>builder()
                        .onServerErrorStatus()
                         // Now it's the BiPredicate that takes ctx as well.
                        .onException((ctx, ex) -> {
                            RpcRequest request = ctx.rpcRequest();
                            if (request != null &&
                                !safeMethods.contains(request.method())) {
                                return isRetryableException(throwable);
                            } else {
                                return false;
                            }
                        })
                        .thenBackoff(backoff);
  • You can now run the gRPC server/client stubs generated by ScalaPB with Armeria. #2719
    • Please refer to the fully working example.
  • You can now parse a response trailers from a response body for gRPC-Web using GrpcWebUtil.parseTrailers(). #2848
    Clients.builder(...)
           .decorator(RetryingClient.newDecorator(
                   RetryRuleWithContent.onResponse(response -> {
                       return response.aggregate().thenApply(aggregated -> {
                          HttpHeaders trailers =
                                  GrpcWebUtil.parseTrailers(aggregated.content());
                          // Retry if the 'grpc-status' is not equal to 0.
                          return trailers != null &&
                                 trailers.getInt(GrpcHeaderNames.GRPC_STATUS) != 0;
                      });
                  })))
          .build(MyGrpcStub.class);
  • You can now access the metadata of HttpFile and FileService asynchronously. #1668 #2845
    HttpFile httpFile = HttpFile.of(...);
    CompletableFuture<HttpFileAttributes> attrs =
            httpFile.readAttributes(CommonPools.blockingTaskExecutor());
    CompletableFuture<ResponseHeaders> headers =
            httpFile.readHeaders(CommonPools.blockingTaskExecutor());
  • You can now easily customize MeterIdPrefixFunction using MeterIdPrefixFunction.andThen(). #2839
    MeterIdPrefixFunction
            .ofDefault("hoge")
            .andThen((registry, log, id) -> id.withTags(
                    "grpc-status", log.responseTrailers().get("grpc-status")));
  • Both synchronous and asynchronous APIs to select an Endpoint are added to EndpointSelector and thus EndpointGroup which is a sub-interface. #1910 #2837
    ClientRequestContext ctx = ...
    EndpointGroup group = ...
    // synchronous selection!
    Endpoint endpoint = group.selectNow(ctx);
    // asynchronous selection!
    CompletableFuture<Endpoint> future =
            group.select(ctx, ctx.eventLoop(), 1000 /* timeout */ );
  • You can now get the snapshot status of circuit breakers from monitoring system. #2841

📈 Improvements

🛠️ Bug fixes

🏚️ Deprecations

☢️ Breaking changes

  • The names of various artifacts are changed. #2676 #2677 #2829 #2843
    • armeria-dropwizard is now armeria-dropwizard2.
    • armeria-jetty is now armeria-jetty9.
    • armeria-rxjava is now armeria-rxjava3.
      • rxjava package is renamed to rxjava3.
    • armeria-spring-boot-actuator-autoconfigure is now armeria-spring-boot2-actuator-autoconfigure.
    • armeria-spring-boot-actuator-starter is now armeria-spring-boot2-actuator-starter.
    • armeria-spring-boot-autoconfigure is now armeria-spring-boot2-autoconfigure.
    • armeria-spring-boot-starter is now armeria-spring-boot2-starter.
    • armeria-spring-boot-webflux-autoconfigure is now armeria-spring-boot2-webflux-autoconfigure.
    • armeria-spring-boot-webflux-starter is now armeria-spring-boot2-webflux-starter.
    • armeria-testing-common has been removed.
    • armeria-testing-junit4 is now armeria-junit4.
    • armeria-testing-junit is now armeria-junit5.
      • junit package is renamed to junit5.
    • armeria-thrift is now armeria-thrift0.13.
    • armeria-tomcat is now armeria-tomcat9.
    • armeria-zookeeper is now armeria-zookeeper3.
  • RequestContext.eventLoop() now returns ContextAwareEventLoop which always set the RequestContext before executing any submitted tasks. #2629 #2834
  • The default logging level for successful requests and response has been changed. #2696 #2855
    • INFO to DEBUG for Logging{Client,Service}.newDecorator()
    • TRACE to DEBUG for Logging{Client,Service}Builder
  • The APIs of HttpFile and HttpVfs have been changed. #1668 #2845 #2861
  • AggregatedHttpFile does not extend HttpFile anymore. #2861
  • AbstractHttpFile.headers() is now AbstractHttpFile.additionalHeaders(). #2861
  • EndpointSelector API has been changed. #2837 #1910
  • UserClient API has been changed. #2837
    • Its constructor requires more parameters.
    • execute() requires less parameters.
  • StreamMessage.drainAll() and its variants have been removed. #2782 #2827
    • They are only used for unit tests and you can use reactor.test.StepVerifier instead.
  • UnprocessedRequestException(String, Throwable) constructor has been removed without replacement. #2836
  • Deprecated timeout APIs in {Service,Client}RequestContext have been removed. #2864
    • extend{Request,Response}TimeoutMillis(long) and extend{Request,Response}Timeout(Duration)
    • set{Request,Response}TimeoutAfterMillis(long) and set{Request,Response}TimeoutAfter(Duration)
    • set{Request,Response}TimeoutAtMillis(long) and set{Request,Response}TimeoutAt(Duration)

⛓ Dependencies

  • gRPC-Java 1.30.1 → 1.30.2
  • Jackson 2.11.0 → 2.11.1
  • Kafka 1.1.1 → 2.5.0
  • Micrometer 1.5.1 → 1.5.2
  • Reactor 3.3.6 → 3.3.7
  • Shaded dependencies
    • Caffeine 2.8.4 → 2.8.5
  • Examples:
    • Dagger 2.28 → 2.28.1
    • monix_reactive 3.2.2
    • ScalaPB 0.10.6
  • Build:
    • Checkstyle 8.33 → 8.34
    • Eureka 1.9.23 → 1.9.25
    • Finagle ServerSets 20.5.0 → 20.6.0
    • Gradle 6.5 → 6.5.1
    • gRPC-Kotlin 0.1.3 → 0.1.4

🙇 Thank you