You're seeing the release note of an old version. Check out the latest release note.
v1.16.0
April 19, 2022
🌟 New features
-
Armeria
Servernow exposes the metrics about TLS handshake results. #4191armeria_server_tls_handshakes_total{cipher_suite=<the negotiated TLS cipher suite>,common_name=<the common name in TLS certificate>,protocol=<h1 or h2>,result=<success or failure>,tls_protocol=<TLS protocol name, e.g. TLSv1.3>} -
You can use the
@Delimiterannotation in an annotated service to specify the delimiter of a query parameter or header. #4060public class MyAnnotatedService {// Given the request:// GET /api/v1/users?ids=1,2,3// Armeria will inject:// List.of(1, 2, 3)// into:// List<Integer> ids@Get("/api/v1/users")public List<User> getUsers(@Param @Delimiter(",") List<Integer> ids) {...}}- You can also specify a delimiter programmatically with
AnnotatedServiceBindingBuilder.queryDelimiter()
- You can also specify a delimiter programmatically with
-
You can now use the no-op
subscribe()to drain elements from aStreamMessage#4145 #4185// The following statement prints 1, 2 and 3.StreamMessage.of(1, 2, 3).peek(value -> System.out.println(value)).subscribe().join(); // 👈👈👈 -
You can now use the
response_bodyoption in gRPC-JSON transcoding. #4052 #4132 #4174-
This option is useful when you need to make a certain response field as a response body. For example, the following Protobuf definition allows you to send a JSON array body whose values are sourced from
GetNumbersResponse.myNumberArray:service MyService {rpc GetNumbers(GetNumbersRequest) returns (GetNumbersResponse) {option (google.api.http) = {get: "/api/v1/numbers"response_body: "my_number_array" // 👈👈👈};}}message GetNumbersRequest {}message GetNumbersResponse {repeated string my_number_array = 1; // 👈👈👈}
-
-
You can now use the
@Decoratorannotation to apply decorators to your gRPC stubs. #3967 #4041@LoggingDecorator // 👈👈👈public class GreeterImpl extends GreeterGrpc.GreeterImplBase {@Override@RateLimitingDecorator(/* requestsPerSec */ 10.0) // 👈👈👈public void sayHello(HelloRequest req,StreamObserver<HelloReply> responseObserver) {responseObserver.onNext(HelloReply.newBuilder().setMessage(req.getName()).build());responseObserver.onCompleted();}} -
AbstractUnaryGrpcServiceand unframedGrpcServicenow include the stack trace for failed requests whenverboseResponsesoption is enabled for easier debuggability. #4114 #4171 -
You can now specify query parameters additively by calling
WebClientRequestPreparation.queryParam()#4173// Send GET /api/v1/greet?foo=1&bar=2WebClient.of().prepare().get("/api/v1/greet").queryParam("foo", "1").queryParams(Map.of("bar", "2")) // 👈👈👈.execute() -
You can now override the global
Flagsby implementing your ownFlagsProviderand loading it via Java SPI. #4093 #4151package com.example.providers;// Add the following text file to your classpath or JAR file://// $ cat META-INF/services/com.linecorp.armeria.common.FlagsProvider// com.example.providers.MyFlagsProvider//public class MyFlagsProvider implements FlagsProvider {@Overridepublic int priority() {// The provider with higher value will be evaluated first.return 100;}@Overridepublic int numCommonBlockingTaskThreads() {return 100;}} -
When using
armeria-graphql, you can now retrieve the currentServiceRequestContextwithGraphqlServiceContexts.get()#4201new DataFetcher<>() {@Overridepublic String get(DataFetchingEnvironment env) throws Exception {ServiceRequestContext ctx = GraphqlServiceContexts.get(env);...}} -
You can now disable the warning message about masked routes when building a
Serverby specifying the-Dcom.linecorp.armeria.reportMaskedRoutes=falseJVM option. #4086
📈 Improvements
armeria-graphqldoesn't use deprecatedgraphql-javaAPI anymore. #4201- Less verbose and clearer TLS handshake logging #4181
🛠️ Bug fixes
- JSON-gRPC transcoding now works even if you bind a
GrpcServicewith path prefix. #4086 #4215Server.builder().route().pathPrefix("/api") // 👈👈👈.build(GrpcService.builder().enableHttpJsonTranscoding(true).addService(...).build()).build() - You now get the
HeaderListSizeExceptionas expected when the length of request headers is too long. #4180 EurekaEndpointGroupnow continues refreshing itself even if it failed to refresh once. #4206HealthCheckedEndpointGroupnow leaves a detailed error message if all endpoints are unhealthy on the first check. #4200- Fixed a rare infinite loop in
EndpointSelectionStrategy.rampingUp()#4219 - The search domain DNS resolver no longer incorrectly resolves a search domain that starts with a dot. #4195 #4196
- Fixed a bug where Armeria server doesn't log the remote address when TLS handshake fails. #4181
- Reduced the cardinality of TLS certificate expiry metrics by using a hostname pattern instead of a hostname as a label. #4191
TomcatServicenow records the request start time ofCoyoteRequestcorrectly. #4182 #4183- You don't get an exception anymore when parsing a multipart request with an empty body. #4175 #4179
- You don't get the noisy warning message about double-completion of future, which occurs when a user
misconfigured a
ClientFactory#4191
📃 Documentation
🏚️ Deprecations
Flags.verboseExceptionSamplerSpec()has been deprecated in favor ofFlags.verboseExceptionSampler()#4093 #4151
☢️ Breaking changes
- The TLS certificate expiry metrics were renamed from
armeria.server.certificate.*toarmeria.server.tls.certificate.*for consistency. #4191- Also, the
hostnamelabel has been replaced withhostname_patternto reduce the cardinality.
- Also, the
- The return type of
Flags.requestContextStorageProvider()was changed fromStringtoRequestContextStorageProvider, so that a user knows which provider will be used exactly. #4093 #4151
⛓ Dependencies
- Brave 5.13.7 → 5.13.8
- Brotli4j 1.6.0 → 1.7.1
- Bucket4j 7.3.0 → 7.4.0
- Dropwizard 2.0.28 → 2.0.29
- gRPC 1.45.0 → 1.45.1
- Jackson 2.13.2 → 2.13.2.1
- java-jwt 3.19.0 → 3.19.1
- Jetty 9.4.45 → 9.4.46
- Kotlin 1.6.10 → 1.6.20
- Coroutines 1.6.0 → 1.6.1
- Micrometer 1.8.4 → 1.8.5
- Netty 4.1.75 → 4.1.76
- Reactor 3.4.16 → 3.4.17
- Scala 3.1.1 → 3.1.2
- Spring Boot 2.6.5 → 2.6.6
- Tomcat 9.0.56 → 9.0.62, 8.5.77 → 8.5.78
🙇 Thank you
This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:
























