1.24.0 release notes

15th June 2023

🌟 New features

  • Unix Domain Socket Support: You can now use Unix domain socket to serve and send requests which is useful for configuring a service mesh to communicate with a sidecar. #1837 #4846

    import com.linecorp.armeria.common.util.DomainSocketAddress;
    
    DomainSocketAddress domainSocketAddress =
      DomainSocketAddress.of(Paths.get("/tmp/armeria.sock"));
    
    Server
      .builder()
      .http(domainSocketAddress)
      ...
      .build();
    
    WebClient
      .builder("http://" + domainSocketAddress.authority())
      ...
      .build();
  • WebSocket Support: You can now send and receive data over WebSocket using WebSocketService. #1076 #3904

    Server
      .builder()
      .service("/chat", WebSocketService.of((ctx, messages) -> {
          WebSocketWriter webSocketWriter = WebSocket.streaming();
          // Write frames using back pressure.
          return webSocketWriter;
       }));
  • Customizable Logging: You can now use LogFormatter and LogWriter to customize the log format and consumer. #3918 #4267 #4943

    // Convert RequestLog to JSON.
    LogFormatter logFormatter = LogFormatter.ofJson();
    LogWriter logWriter =
      LogWriter
        .builder() // Use SLF4J logger for logging.
        .logFormatter(logFormatter)
        .logger(logger)
        .build();
    
    LoggingClient
      .builder()
      .logWriter(logWriter)
      .newDecorator();
  • BlockHound Integrations: Armeria now provides BlockHound integrations, offering enhanced support for detecting with blocking calls in event loops. #4493

  • Delayed Request Abortion: You can now delay aborting the HttpRequest when the HttpResponse completes. This may be useful when you want to send additional data even after the response is complete. #4913

    Server
      .builder()
      .requestAutoAbortDelayMillis(2000) // Delay aborting the request for 2 second.
      ...
      .build();
    
    WebClient
      .builder()
      .requestAutoAbortDelayMillis(1000) // Delay aborting the request for 1 second.
      ...
      .build();
  • Circuit Breaker and Retry Rule for timeout: You can now use RetryRule.onTimeoutException() and CircuitBreakerRule.onTimeoutException() to open the circuit or retry the request when the response is timed out. #4876 #4882

  • Customizable ExecutionId for GraphQL-Java: You can now customize ExecutionId of GraphQL-Java using GraphqlServiceBuilder.executionIdGenerator(). #4867 #4877

    GraphqlService
      .builder()
      .executionIdGenerator((requestCtx, query, operation, graphqlCtx) -> {
         return ExecutionId.from(requestContext.headers.get("traceparent"));
      })
      ...
      .build();
  • Custom CoroutineContext for gRPC-Kotlin: You can now inject a custom CoroutineContext for gRPC-Kotlin with CoroutineContextProvider. #4842 #4866

    class CustomCoroutineContextProvider : CoroutineContextProvider {
      override fun provide(ctx: ServiceRequestContext): CoroutineContext {
        return ... // A custom CoroutineContext
      }
    }
  • Retrieving CallOptions with GrpcCallOptions: With GrpcCallOptions in Armeria, you can now easily retrieve CallOptions from a given RequestContext. #4776 #4822

    GrpcClients
      .builder(grpcServerUri)
      .decorator((delegate, ctx, req) -> {
        CallOptions options = GrpcCallOptions.get(ctx);
        MyOption myOption = options.getOption(myOptionKey);
        // act on myOption if needed
        ...
    
        return delegate.execute(ctx, req);
      })
      .build(MyGrpcStub.class);
  • Fallback Strategy for CircuitBreakerClient: You can now easily set a fallback strategy to CircuitBreakerClient when a CircuitBreaker is open. #4800 #4818

    CircuitBreakerClient
      .builder(...)
      .recover((ctx, req) -> {
        // A fallback response when the circuit is open.
        return HttpResponse.of(...);
      });
  • Netty ChannelPipeline Customizer: You can now customize the Netty ChannelPipeline for the server side #4710 #4813

    Server
      .builder()
      .childChannelPipelineCustomizer(pipeline -> {
        // Add a custom handler to the pipeline.
      })
      .build();
  • HTTP/2 over TLS without ALPN: Armeria now supports using HTTP/2 over TLS without the need for ALPN. #4702 #4704

    ClientFactory
      .builder()
      .useHttp2WithoutAlpn(true)
      ...
      .build();
  • Armeria with Jetty: Armeria is now compatible with Jetty 10 and Jetty 11. #4845

  • Armeria with Thrift: Armeria is now compatible with Thrift 0.18.1. #4812

📈 Improvements

  • RequestContext.makeContextAware() now returns instances of ContextAwareRunnable, ContextAwareCallable, ContextAwareFunction, ContextAwareBiFunction, ContextAwareConsumer and ContextAwareBiConsumer. #4878 #4890
  • Annotated services now perform as fast as functional-style services under the following conditions: #4888
    • The annotated method returns an HttpResponse.
    • The annotated method is run on the event loop (i.e. not annotated with @Blocking).
  • You can now use the following features with Spring Boot Actuator integration. #4874 #4880
    • management.endpoints.web.exposure.*
    • management.endpoints.web.path-mapping.*
    • management.endpoints.web.discovery.*
    • management.endpoint.health.status.http-mapping.*
    • application/vnd.spring-boot.actuator.v3+json, application/vnd.spring-boot.actuator.v2+json and application/json
  • Armeria client now exports metrics for RetryingClient with the following metric name: #3350 #4707
    • armeria.client.actual.requests.attempts
  • You can now set the default log name for VirtualHost via VirtualHostBuilder.defaultLogName() #4817
  • Synchronized blocks in core/common have been migrated to ReentrantLock for improved compatibility with virtual threads. #4578
  • We did groundwork for supporting PKCS#12 and JKS keystore formats when configuring TLS in a future release. #4801

🛠️ Bug fixes

📃 Documentation

🏚️ Deprecations

☢️ Breaking changes

⛓ Dependencies

  • Brave 5.15.0 → 5.16.0
  • Brotli4J 1.11.0 → 1.12.0
  • Curator 5.4.0 → 5.5.0
  • Dropwizard 2.1.5 → 2.1.6
  • Dropwizard Metrics 4.2.18 → 4.2.19
  • GraphQL Java 20.0 → 20.4
  • GraphQL Kotlin 6.4.0 → 6.5.2
  • gRPC-Java 1.49.1 → 1.56.0
  • Jackson 2.14.2 → 2.15.2
  • java-jwt 4.3.0 → 4.4.0
  • Jetty 9.4.50.v20221201 -> 9.4.51.v20230217, 10.0.15, 11.0.0
  • Kafka client 3.4.0 → 3.4.1
  • Kotlin 1.8.10 → 1.8.22
  • Kotlin Coroutine 1.6.4 → 1.7.1
  • Micrometer 1.10.5 → 1.11.1
  • Netty 4.1.91 → 4.1.93
    • io_uring 0.0.19 → 0.0.21
  • Protobuf 3.21.1 -> 3.22.3
  • protobuf-jackson 2.0.0 → 2.2.0
  • Reactive gRPC 1.2.3 → 1.2.4
  • Reactor 3.5.1 → 3.5.7
  • Sangria 3.5.3 → 4.0.0
  • Sangria slowlog 2.0.5 → 3.0.0
  • Scala 2.12.17 → 2.12.18, 2.13.10 → 2.13.11, 3.2.2 → 3.3.0
  • scala-collection-compat 2.9.0 → 2.10.0
  • Spring 6.0.6 → 6.0.9
  • Spring Boot 2.7.10 → 2.7.12, 3.0.5 → 3.1.0
  • Tomcat 10.1.4 → 10.1.10
  • Thrift 0.18.1

🙇 Thank you