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
HttpRequest
andRpcRequest
fromRequestContext
so you don’t need to downcastRequest
toHttpRequest
orRpcRequest
. #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}ServiceRegisrationBean
for 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*Builder
constructors. #1719 #2085CircuitBreaker
CircuitBreakerHttpClient
CircuitBreakerRpcClient
DnsAddressEndpointGroup
DnsServiceEndpointGroup
DnsTextEndpointGroup
GrpcService
Server
RetryingHttpClient
RetryingRpcClient
// 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
RequestContextAwareFuture
for the recent changes of CompletableFuture API, thanks to the Multi-Release JAR Files. #1991 #2052 #2127
Bug fixes
ResponseTimeoutException
is not logged more than once anymore when the response has been timed out. #2000 #2138- You no longer see
AbortedStreamException
while 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-zipkin
has been removed for further clean-up. #2120RequestContext.request()
returnsHttpRequest
instead ofRequest
. #2120RequestContext.updateRequest()
always updates anHttpRequest
. It returnsvoid
now because it never fails, unlessnull
is specified.RequestContext.newDerivedContext(Request)
now requires bothHttpRequest
andRpcRequest
.
- 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_FOUND
status. - 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 childrenStreamMessage
s. #2134- You should use
AbstractStreamMessageDuplicator.abort()
to abort all childrenStreamMessage
s 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