1.26.0 release notes

23rd October 2023

🌟 New features

  • Context Path Support: You can now set services/decorators under a context path fluently. #3591 #4802 #5037 #5157 #5260

    Server.builder()
          .baseContextPath("/api")
          .contextPath("/v1", "/v2")
          .service(myService) // served under "/api/v1" and "/api/v2"
          .and()
          .virtualHost("foo.com")
          .contextPath("/v3")
          .service(myService) // served by virtual host "foo.com" under "/api/v3"
          .build();
    • You can also set the context path via Spring property.
    armeria:
      context-path: /api/v1
  • Easier Request Scoping for Kotlin: You can now easily propagate an Armeria RequestContext in Kotlin using ContextAwareExecutor.asCoroutineDispatcher(). #5171

    withContext(ctx.eventLoop().asCoroutineDispatcher()) {
      assert(RequestContext.current() == ctx)
      ...
    }
  • gRPC Exception Handler Annotation: You can now easily handle an exception that is raised from a gRPC service using @GrpcExceptionHandler annotation. #5046

    @GrpcExceptionHandler(MyGrpcExceptionHandlerFunction.class)
    @Override
    public void unaryCall(
      SimpleRequest request,
      StreamObserver<SimpleResponse> responseObserver) {
        ...
    }
    
    class MyGrpcExceptionHandlerFunction implements GrpcExceptionHandlerFunction {
      @Override
      public Status apply(RequestContext ctx, Throwable cause, Metadata metadata) {
        if (unauthenticatedException(cause)) {
          return Status.UNAUTHENTICATED;
        }
        ...
      }
    }
  • StreamMessage finalizer: You can now produce the last value for a StreamMessage when it completes exceptionally or successfully using StreamMessage.endWith(). #4816 #5198

    StreamMessage<Integer> message =
      original.endWith(th -> {
          if (th instanceof AbortedStreamException) {
              return 100;
          }
          return -1;
      });
  • Disable HTTP/2 for Requests: You can now disable HTTP/2 protocol when sending HTTP or HTTPS requests. #5168

    ClientFactory
      .builder()
      .preferHttp1(true)
      .build();
  • Client Certificate Metrics: You can now monitor client certificates with the following metrics. #5155

    • armeria.client.tls.certificates.validity: 1 if valid, 0 otherwise.
    • armeria.client.tls.certificates.validity.days: The number of days until the certificate expires.
  • You can now add a hook that is invoked when a RequestContext is pushed and popped. #4991 #5107

    Supplier<AutoCloseable> contextHook = () -> {
      System.out.println("Context is pushed.");
      return () -> {
        System.out.println("Context is popped.");
      };
    }
    
    // Client
    WebClient
      .builder()
      .contextHook(contextHook)
      ...
      .build();
    // Server
    Server
      .builder()
      .contextHook(contextHook)
      ...
      .build();
  • New Circuit Breaker and Retry Rule for Time-consuming Requests: You can now report a failure to a circuit breaking or retry when the total duration exceeds a certain threshold. #4782 #4827

    final CircuitBreakerRuleWithContent<HttpResponse> rule =
          CircuitBreakerRuleWithContent
                  .<HttpResponse>builder()
                  .onTotalDuration(
                      (ctx, duration) -> duration.toMillis() > 10000)
                  .thenFailure();
  • RST Flood Attack Prevention: You can now protect your server against DDoS caused by RST flood attack using ServerBuilder.http2MaxResetFramesPerWindow(). #5232

    • The default maximum number of allowed RST frames for an HTTP/2 connection is 400 per minute.
    Server
      .builder()
      .http2MaxResetFramesPerWindow(100, 10)
      .build();

📈 Improvements

  • Acquiring an EventLoop for sending a request is now improved when the number of EventLoops is small. #4439 #4682
  • Snappy is now supported for content compression. #5125 #5174
  • The CompletableFutures of a RequestLog are now completed with the RequestContext.eventLoop() thus their callbacks are also executed by the EventLoop. #5189
  • Adding services and decorators are now unified. #5038 #5040

🛠️ Bug fixes

🏚️ Deprecations

☢️ Breaking changes

  • N/A

⛓ Dependencies

  • Dropwizard2 2.1.6 → 2.1.8
  • Dropwizard metrics 4.2.19 → 4.2.21
  • Futures-extra 4.3.1 → 4.3.3
  • Graphql Kotlin 6.5.3 → 6.5.6
  • gRPC 1.57.2 → 1.58.0
  • gRPC Kotlin 1.3.0 → 1.4.0
  • Guava 32.1.2-jre → 32.1.3-jre
  • Jackson 2.15.2 → 2.15.3
  • Jetty
    • 10.0.15 → 10.0.17
    • 11.0.15 → 11.0.17
  • Kafka 3.5.1 → 3.6.0
  • Micrometer 1.11.3 → 1.11.5
  • Micrometer Tracing 1.1.4 → 1.1.6
  • Netty 4.1.96.Final → 4.1.100.Final
  • Netty io_uring 0.0.21.Final → 0.0.23.Final
  • Reactor 3.5.8 → 3.5.11
  • RxJava3 3.1.6 → 3.1.8
  • Sangria 4.0.1 → 4.0.2
  • Scala2.13 2.13.11 → 2.13.12
  • Spring Framework 6.0.11 → 6.0.13
  • Spring Boot
    • 2.7.14 → 2.7.16
    • 3.1.2 → 3.1.4
  • Tomcat
    • 8.5.85 → 8.5.94
    • 9.0.71 → 9.0.82
    • 10.1.12 → 10.1.15
  • ZooKeeper 3.8.2 → 3.9.1

🙇 Thank you