1.19.0 release notes
13th September 2022
🌟 New features
You can now repeatedly aggregate an
HttpRequestandHttpResponsewhen usingHttpRequest.aggregate()andHttpResponse.aggregate(). If anHttpRequestor anHttpResponseis aggregated before, the cachedAggregatedHttpRequestorAggregatedHttpResponseis returned for subsequent calls. #3789 #4366HttpRequest request = ...; AggregatedHttpRequest aggregatedReq0 = request.aggregate().join(); AggregatedHttpRequest aggregatedReq1 = request.aggregate().join(); assert aggregatedReq0 == aggregatedReq1; HttpResponse response = ...; AggregatedHttpResponse aggregatedRes0 = response.aggregate().join(); AggregatedHttpResponse aggregatedRes1 = response.aggregate().join(); assert aggregatedRes0 == aggregatedRes1;You can now customize the behavior of auto-refresh for an
AddressResolverGroupwithDnsResolverGroupBuilder. #4400// Disable auto refresh ClientFactory .builder() .domainNameResolverCustomizer(customizer -> { customizer.enableAutoRefresh(false); // 👈👈👈 }) .build(); // Set a constant refresh timeout ClientFactory .builder() .domainNameResolverCustomizer(customizer -> { customizer.autoRefreshTimeout(Duration.ofDays(1)); // 👈👈👈 }) .build(); // Build a flexible refresh timeout depending on the hostname ClientFactory .builder() .domainNameResolverCustomizer(customizer -> { customizer.autoRefreshTimeout(hostname -> { // 👈👈👈 if (hostname.endsWith("busy.domain.com")) { // Automatically refresh the cached domain for 7 days. return Duration.ofDays(7).toMillis(); } if (hostname.endsWith("sporadic.domain.dom")) { // Don't need to refresh a sporadically used domain. return 0; } ... }); }) .build();You can now export
RequestOnlyLog.requestCause()andRequestLog.responseCause()to MDC by specifyingreq.causeandres.causeto an appender of a Logback configuration.<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="RCEA" class="com.linecorp.armeria.common.logback.RequestContextExportingAppender"> ... <export>req.cause</export> <!-- 👈👈👈 --> <export>res.cause</export> <!-- 👈👈👈 --> ... </appender> </configuration>You can now trace a
RequestContextleak by specifying-Dcom.linecorp.armeria.requestContextLeakDetectionSampler=<sampler-spec>or implementing a customFlagsProvider. #4100 #4232public final class LeakDetectingFlagsProvider implements FlagsProvider { @Override public Sampler<? super RequestContext> requestContextLeakDetectionSampler() { // Samples all request contexts. return Sampler.always(); } }DocServicenow automatically generates a specification of annotated services for well known types. #4309 #4322- Java POJO
- Kotlin data class
- Scala case class
- Protocol Buffers'
Message - ScalaPB's
GeneratedMessage
You can now upload files to your
GraphqlServiceusing GraphQL multipart requests. #3971 #4199You can now use
armeria-version-catalogmodule to easily import Armeria and Armeria's direct dependencies using Gradle's version catalog. #4377// in settings.gradle dependencyResolutionManagement { versionCatalogs { create("armeriaDeps") { from("com.linecorp.armeria:armeria-version-catalog:1.19.0") } } }
📈 Improvements
CompositeExceptionnow shows full stack traces of all nested exceptions when-Dcom.linecorp.armeria.verboseExceptions=trueis set. #4347 #4356
🛠️ Bug fixes
You can now use Armeria Spring actuator with WebFlux correctly. #4396 #4408
You no longer see
ClassCastExceptionwhen an invalid path request is received. #4405Annotated services now correctly return
204 No Contentstatus whenvoid,Publisher<Void>orCompletionStage<Void>and@ProducesJsonare used at the same time. #4390 #4398// 200 OK status and "null" string body is returned @Get("/null-content") @ProducesJson public Publisher<Void> nullBody() { return Mono.empty(); } // 204 No Content status and no body is returned @Get("/no-content") @StatusCode(204) @ProducesJson public Publisher<Void> noBody() { return Mono.empty(); }Armeria server no longer sends chunked encoding header with
304 Not Modifiedstatus. #4386HTTP/2 graceful shutdown timeout is correctly set using
ClientFactory.idleTimeoutMillis(). #4381Unframed
GrpcServicesnow supportapplication/x-protobufandapplication/x-google-protobufmedia types. #4355 #4364You can now use a custom
JsonFormat.PrinterforProtobufResponseConverterFunction. #4301 #4336
📃 Documentation
- You can now learn how to write a gRPC service and client with Armeria by walking through
the gRPC tutorial. #3987
- Special thanks to @freevie who volunteered for this.
🏚️ Deprecations
DnsResolverGroupBuilder.refreshBackoff()has been deprecated in favor ofDnsResolverGroupBuilder.autoRefreshBackoff(). #4400
☢️ Breaking changes
- The method signature of
ResponseConverterFunctionProvider.createResponseConverterFunction()has been changed.ResponseConverterFunctionProviderno longer takes aResponseConverterFunctionas the second parameter. UseDelegatingResponseConverterFunctionProviderto create a newResponseConverterFunctionbased on the delegatingResponseConverterFunction.
⛓ Dependencies
- Brave 5.13.10 → 5.13.11
- Brotli4J 1.7.1 → 1.8.0
- Dropwizard Metrics 4.2.10 → 4.2.12
- gRPC-Java 1.48.0 → 1.49.0
- Jackson 2.13.3 → 2.13.4
- Micrometer 1.9.2 → 1.9.3
- Reactor 3.4.21 → 3.4.22
- Sangria 3.0.1 → 3.2.0
- Scala 3.1.3 → 3.2.0
- Spring Boot 2.7.2 → 2.7.3