1.29.0 release notes
12th June 2024
🌟 New features
Armeria HTTP/JSON to GRPC transcoding service now supports Custom methods. #5613
rpc Watch(WatchRequest) returns (WatchResponse) { option (google.api.http) = { post: "/v1:watch" // 👈👈👈 body: "*" }; }
You can now specify when to remove multipart temporary files using
MultipartRemovalStrategy
. #5652 #5653Server .builder() .multipartRemovalStrategy( MultipartRemovalStrategy.ON_RESPONSE_COMPLETION) ...
- The default value is now
MultipartRemovalStrategy.ON_RESPONSE_COMPLETION
which removes the temporary files when the response is completed.
- The default value is now
A
ClientConnectionTimings
now includes the time spent on the TLS handshake. #3647 #5647ClientConnectionTimings timings = ... assert timings.tlsHandshakeDurationNanos() > 0;
You can now configure
TlsEngineType
usingClientFactoryBuilder
orServerBuilder
. #4962ClientFactory .builder() .tlsEngineType(TlsEngineType.OPENSSL) // 👈👈👈 .build();
You can now easily find both dynamic and static decorators that handle a request via
ServiceRequestContext.findService()
. #5670ServerBuilder sb = ... sb.decorator(CorsService.builderForAnyOrigin().newDecorator()); ... ServiceRequestContext ctx = ... CorsService corsService = ctx.findService(CorsService.class); assert corsService.config().isAnyOriginSupported();
You can now use the marshaller specified by gRPC
MethodDescriptor
by settingGrpcClientBuilder.useMethodMarshaller()
andGrpcServiceBuilder.useMethodMarshaller()
. #5103 #5630GrpcClientBuilder builder = ... builder.useMethodMarshaller(true); // 👈👈👈 GrpcServiceBuilder builder = ... builder.useMethodMarshaller(true); // 👈👈👈
You can now programmatically retrieve the server side metrics via
ServerMetrics
. #4992 #5627ServerMetrics metrics = serverConfig.serverMetrics(); metrics.activeConnections(); metrics.pendingRequests(); metrics.activeRequests();
You can now use a
CoroutineHttpService
that runs your service in a coroutine scope. #5442 #5603ServerBuilder sb = ... sb.service( "/hello", CoroutineHttpService { ctx, req -> HttpResponse.of("hello world") })
You can now specify options for an
HttpService
viaServiceOptions
. #5071 #5574static final ServiceOptions SERVICE_OPTIONS = ServiceOptions .builder() .requestTimeoutMillis(5000) .maxRequestLength(1024) .requestAutoAbortDelayMillis(1000) .build(); HttpService httpService = new HttpService() { ... @Override public ServiceOptions options() { return SERVICE_OPTIONS; } }; // Or use annotation for an annotated service. class MyService { @ServiceOption(requestTimeoutMillis = 5000, maxRequestLength = 1024) @Get("/hello") public HttpResponse hello() { return HttpResponse.of("Hello!"); } }
You can now inject a custom attribute from a
ServiceRequestContext
to an annotated service using@Attribute
annotation. #5514 #5547class MyAttributes { public static final AttributeKey<String> USERNAME = AttributeKey.valueOf(MyAttributes.class, "USERNAME"); } class MyAnnotatedService { @Get("/hello") public HttpResponse hello( @Attribute(prefix = MyAttributes.class, value = "USERNAME") // 👈👈👈 String username) { ... } }
You can now specify a graceful shutdown timeout for an HTTP/2 connection in
ClientFactory
. #5470 #5489ClientFactory .builder() .http2GracefulShutdownTimeoutMillis(1000) .build();
You can now specify an
EndpointGroup
when building aClientRequestContext
. #5292 #5298ClientRequestContext ctx = ClientRequestContext .builder(request) .endpointGroup(endpointGroup) .build();
You can now set a
GraphQL
instance directly to theGraphqlServiceBuilder
. #5269GraphQL graphQL = new GraphQL.Builder(graphqlSchema).build(); GraphqlServiceBuilder builder = ... builder.graphql(graphQL);
You can now specify a delay to close an HTTP/1.1 connection from the server side, allowing the client an opportunity for active closing. #4849 #5616
You can now configure the maximum length of a TLS client hello message that a server allows by using the
-Dcom.linecorp.armeria.defaultMaxClientHelloLength=<integer>
JVM option. #5747
📈 Improvements
XdsEndpointGroup
now supports Slow start mode. #5688 #5693- Priority and locality based load balancing is now available for an
XdsEndpointGroup
. #5610 - You can now view connection related information in the request logs. #5730
- CORS headers are added to responses even if an exception is raised while handling a request. #5632
AnnotatedService
is now available through a public API. #5382 #5628- The metrics for failed requests while retrying now include the cause of the failure. #5405 #5583
- The
RequestLog
from a retrying client now includes the current attempt number. #5716 #5719 - A colon is now allowed in the path for binding a service. #4577 #5676
- Timer histogram metrics now repects user-provided
serviceLevelObjectives
. #5661 ServiceErrorHandler.renderStatus()
can now access the currentServiceRequestContext
if available. #5634SamlSingleSignOnHandler.loginFailed()
can now access theMessageContext
for error handling if available. #5401 #5622- The copied cURL command from a doc service, is now quoted correctly. #5566
🛠️ Bug fixes
- Fixed a bug where
RetryingClient
gets to deadlock whenOAuth2Client
fails to obtain an access token. #5715 - Armeria client always uses HTTP/2 connection preface for
h2c
, regardless of the value ofClientFactoryOptions.useHttp2Preface()
. #5706 ArmeriaServerConfigurator
now properly overrides the properties set byArmeriaSettings
. #5009 #5692- Armeria server now returns a 408 status if a service didn't receive the request fully and the request times out. #5579 #5680
- A
NullPointerException
isn't raised anymore when running Armeria with a self-signed certificate. #5669 It happened when the following conditions are all met:- DEBUG-level logging of JDK security event is enabled.
- A user has no Bouncy Castle dependency.
@Description
annotations at the super class or interface are now used for the parameter description. #5195 #5562- The specfied
ObjectMapper
toWebClientRequestPreparation.asJson()
isn't ignored anymore. #5454 #5512 GrpcExceptionHandlerFunction
is now applied to convert a gRPC cancellations. #5329 #5398- In Spring integration, the default
ClientFactory
is now gracefully closed after the server shuts down. #5742 - A connection is not reused anymore after a
WriteTimeoutException
is raised. #5738 ServiceRequestContext
is now correctly propagated whenServerErrorHandler.onServiceException()
is invoked. #5746
🏚️ Deprecations
PrometheusMeterRegistries
andPrometheusExpositionService
are deprecated. #5698- Use the same classes in the
armeria-prometheus1
module.
- Use the same classes in the
HttpResult
is deprecated. UseResponseEntity
instead. #4910 #5586GraphqlConfigurator
and various setter methods for building aGraphQL
instance are deprecated.- Use
GraphqlServiceBuilder.graphql()
instead. #5269
- Use
☢️ Breaking changes
- We updated Micrometer to 1.13.0 that has breaking changes in its Prometheus support. #5698
- If you want to keep the old behavior that uses Prometheus Java client 0.x,
use the
io.micrometer:micrometer-registry-prometheus-simpleclient:1.13.0
module. - If you want to use Prometheus Java client 1.x, add
com.linecorp.armeria:armeria-prometheus1
module. - More details can be found in the Micrometer migration guide.
- If you want to keep the old behavior that uses Prometheus Java client 0.x,
use the
AbstractEndpointSelector.updateNewEndpoints()
now returns aCompletableFuture
. #5752- The following builder classes now have the
SELF
type parameter. #5733
⛓ Dependencies
- Blockhound 1.0.8.RELEASE → 1.0.9.RELEASE
- Control Plane 1.0.44 → 1.0.45
- GraphQL Kotlin 7.0.2 → 7.1.1
- gRPC Java 1.63.0 → 1.64.0
- Jackson 2.17.0 → 2.17.1
- Kotlin Coroutine 1.8.0 → 1.8.1
- Kubernetes client 6.11.0 → 6.12.1
- Mircometer 1.12.4 → 1.13.0
- Netty 4.1.108.Final → 4.1.110.Final
- Reactor 3.6.4 → 3.6.6
- Scala2.13 2.13.13 → 2.13.14
- Scala Collection compat 2.11.0 → 2.12.0
- Spring 6.1.5 → 6.1.8
- Spring Boot 3.2.4 → 3.3.0