0.94.0 release notes
4th October 2019
New features
You can now decorate multiple services by path mapping. See the documentation for more information. #582 #2040 #2057
ServerBuilder sb = new ServerBuilder(); // Register vipService and memberService under '/users' path sb.annotatedService("/users/vip", vipService) .annotatedService("/users/members", memberService); // Decorate all services under '/users' path sb.decoratorUnder("/users", (delegate, ctx, req) -> { if (!authenticate(req)) { return HttpResponse.of(HttpStatus.UNAUTHORIZED); } return delegate.serve(ctx, req); });You can also use fluent route builder with
routeDecorator()to decorate more than one service by path mapping.// Decorate services under '/users' path with fluent route builder sb.routeDecorator() .pathPrefix("/users") .build((delegate, ctx, req) -> { if (!authenticate(req)) { return HttpResponse.of(HttpStatus.UNAUTHORIZED); } return delegate.serve(ctx, req); });You can now get the current
HttpRequestandRpcRequestfromRequestContextso you don’t need to downcastRequesttoHttpRequestorRpcRequest. #2089 #2120// Before: Request req = ctx.request(); if (req instanceof HttpRequest) { RequestHeaders headers = (HttpRequest) req).headers(); } // After: RequestHeaders headers = ctx.request().headers(); // Before: if (req instanceof RpcRequest) { String rpcMethod = (RpcRequest) requestContent).method(); } // After: // `rpcRequest()` method will return `null` when the request being handled is not // an RPC request or not decoded into an RPC request yet. String rpcMethod = ctx.rpcRequest().method();You can now set example headers when using
{Annotated,Grpc,Thrift}ServiceRegisrationBeanfor Spring Boot integration. #2100@Bean public AnnotatedServiceRegistrationBean annotatedService() { return new AnnotatedServiceRegistrationBean() .setServiceName("annotatedService") .setService(new AnnotatedService()) // Add example headers for annotated service .addExampleHeaders("x-additional-header", "headerVal") .addExampleHeaders("get", "x-additional-header", "headerVal"); }You can now create the following classes using the
builder()method instead of their*Builderconstructors. #1719 #2085CircuitBreakerCircuitBreakerHttpClientCircuitBreakerRpcClientDnsAddressEndpointGroupDnsServiceEndpointGroupDnsTextEndpointGroupGrpcServiceServerRetryingHttpClientRetryingRpcClient// Before: Server server = new ServerBuilder() .service("/hello", (ctx, req) -> HttpResponse.of(OK)) .build(); // After: Server server = Server.builder() .service("/hello", (ctx, req) -> HttpResponse.of(OK)) .build();
Improvement
- You can use Java 9 version specific
RequestContextAwareFuturefor the recent changes of CompletableFuture API, thanks to the Multi-Release JAR Files. #1991 #2052 #2127
Bug fixes
ResponseTimeoutExceptionis not logged more than once anymore when the response has been timed out. #2000 #2138- You no longer see
AbortedStreamExceptionwhile sending long-lived requests withRetryingHttpClient. #2134 - You can now see a warning message when JSON request conversion fails in an annotated service. #2041 #2131
Deprecations
AbstractBindingBuilder.pathUnder(String prefix)has been deprecated in favor ofpathPrefix(String prefix). #2040RouteBuilder.prefix(String prefix, ...)has been deprecated in favor ofpathPrefix(String prefix, ...). #2040RouteBuilder.pathWithPrefix(String prefix, String pathPattern)has been deprecated in favor ofpath(String prefix, String pathPattern). #2040new *Builder()constructors which are mentioned in 'New Features' have been deprecated in favor of*.builder(). #1719 #2085
Breaking changes
armeria-zipkinhas been removed for further clean-up. #2120RequestContext.request()returnsHttpRequestinstead ofRequest. #2120RequestContext.updateRequest()always updates anHttpRequest. It returnsvoidnow because it never fails, unlessnullis specified.RequestContext.newDerivedContext(Request)now requires bothHttpRequestandRpcRequest.
- A default virtual host service can serve any virtual host requests. #2057 #2040
- Before: If a custom virtual host fails to match the given request to a service, it returns
NOT_FOUNDstatus. - After: If a custom virtual host fails to match the given request to a service, looking up a default virtual host services to match the request.
- Before: If a custom virtual host fails to match the given request to a service, it returns
AbstractStreamMessageDuplicator.close()does not abort all childrenStreamMessages. #2134- You should use
AbstractStreamMessageDuplicator.abort()to abort all childrenStreamMessages anymore.
- You should use
Dependencies
- gRPC 1.23.0 -> 1.24.0
- Dropwizard Metrics 4.0.0 -> 4.1.0
- Jetty 9.4.20.v20190813 -> 9.4.21.v20190926
- Jackson 2.9.9.20190807 -> 2.10.0
- Java JWT 3.8.2 -> 3.8.3
- Micrometer 1.2.1 -> 1.3.0