armeria

Your go-to microservice framework for any situation, from the creator of Netty et al. You can build any type of microservice leveraging your favorite technologies, including gRPC, Thrift, Kotlin, Retrofit, Reactive Streams, Spring Boot and Dropwizard.

APACHE-2.0 License

Stars
4.7K
Committers
243

Bot releases are hidden (Show)

armeria -

Published by minwoox almost 5 years ago

🌟 What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation or other microservice frameworks.

🥳 New features

  • You can now bind multiple paths to an annotated service easily using @Path. #1822 #1870
    @Get
    @Post
    @Path("/a")
    @Path("/b")
    public String myAwesomeServcie(...) {...}
    
  • You can now make an annotated service run from blockingTaskExecutor by attaching @Blocking. #2078, #2187
    @Get("/myHeavyTask")
    @Blocking
    public HttpResponse reallyHeavyComputation(...) {...}
    
  • Armeria server now adds Server and Date headers to responses by default. #2137, #2188
    • If you do not want that behavior, you should call:
      Server.builder()
            .service(...)
            .disableServerHeader()
            .disableDateHeader()
            .build();
      
  • You can now configure a Caffeine cache spec for HttpFileService. #916, #2142
    HttpFileServiceBuilder.forClassPath("/")
                          .entryCacheSpec("maximumSize=512")
                          .build()
    
    Or, using JVM option:
    -Dcom.linecorp.armeria.fileServiceCache=maximumSize=1024,expireAfterAccess=600s
  • You can now see the Armeria version in the metric. #2179

💪 Improvements

  • Armeria server startup time is reduced to 80 percent when TLS is not used. #1645, #2184
  • The performance of getting HTTP timestamps is improved by caching the values every second. #2196
    • Use HttpTimestampSupplier.currentTime() to take advantage of it.
  • The performance of finding service is improved by not making an unused Map in RouteResult. #2153
  • The performance of gRPC call is improved by using the singleton HTTP headers when a service does not create a new HTTP headers. #2152
  • The performance of making metric Tags is improved by adding Tags in ascending order. #2150, #2163
  • We now have favicon in our DocService. #2186

👻 Bug fixes

  • ServerHttpRequest.getRemoteAddress() now returns proper address. #2208
  • You can now see descriptive error messages when sslContext is not configured properly. #1844, #2124
  • You can now build (Request|Response)Headers multiple times using builders. #2190, #2193
    • Previously, it raised ClassCastException if build() is called twice.
  • NoRequestContextException is not raised anymore if you configure the name of the non-request thread.
    RequestContextCurrentTraceContext.builder()
                                     .nonRequestThread("RMI TCP Connection")
                                     .build()
    
  • NullPointerException is not raised anymore in Http1ClientCodec when the server sends multiple responses for one request. #2210
  • You can now see the access logs when the method of a request is not allowed and there are no services that match the path. #2159

🚫 Breaking changes

  • All annotated services are run from EventLoop by default. #2187
    • Previously, if the return type is neither HttpResponse nor CompletableFuture, annotated services are run from blockingTaskExecutor.
  • ServerBuilder.tls() now throws a checked SSLException. #2124
  • ServerBuilder.sslContext() methods are completly removed. #2124

⛓ Dependencies

  • Brave 5.7.0 -> 5.8.0
  • Dropwizard 4.1.0 -> 4.1.1
  • gRPC 1.24.0 -> 1.24.1
  • Netty 4.1.42 -> 4.1.43
  • org.bouncycastle 1.63 -> 1.64
  • Prometheus 0.7.0 -> 0.8.0
  • RxJava2 2.2.12 -> 2.2.13
  • Spring Boot 2.1.8 -> 2.1.9
  • Tomcat
    • 9.0.26 -> 9.0.27
    • 8.5.43 -> 8.5.47
  • ZooKeeper 3.5.5 -> 3.5.6

🙇‍♂️ Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @adriancole
  • @anuraaga
  • @eunchan-kim
  • @heowc
  • @hirakida
  • @ikhoon
  • @imasahiro
  • @jyblue
  • @kojilin
  • @matsumana
  • @minwoox
  • @mumgmangmange
  • @rcsalome
  • @Ta2Rim
  • @trustin
armeria -

Published by trustin about 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation or other microservice frameworks.

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 and RpcRequest from RequestContext so you don’t need to downcast Request to HttpRequest or RpcRequest. #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 exmample 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 #2085
    • CircuitBreaker
    • 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

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 with RetryingHttpClient. #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 of pathPrefix(String prefix). #2040
  • RouteBuilder.prefix(String prefix, ...) has been deprecated in favor of pathPrefix(String prefix, ...). #2040
  • RouteBuilder.pathWithPrefix(String prefix, String pathPattern) has been deprecated in favor of path(String prefix, String pathPattern). #2040
  • new *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. #2120
  • RequestContext.request() returns HttpRequest instead of Request. #2120
    • RequestContext.updateRequest() always updates an HttpRequest. It returns void now because it never fails, unless null is specified.
    • RequestContext.newDerivedContext(Request) now requires both HttpRequest and RpcRequest.
  • 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.
  • AbstractStreamMessageDuplicator.close() does not abort all children StreamMessages. #2134
    • You should use AbstractStreamMessageDuplicator.abort() to abort all children StreamMessages anymore.

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

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @4whomtbts
  • @adriancole
  • @anuraaga
  • @heowc
  • @ikhoon
  • @kojilin
  • @minwoox
  • @moonchanyong
  • @sivaalli
  • @trustin
  • @young891221
armeria -

Published by trustin about 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation or other microservice frameworks.

New features

  • You can now create a Sampler from a specification string such as random=0.1 and rate-limited=10. #2108
    • This is going to be useful when you want to make the sampling policy of Brave{Client,Server} or Logging{Client,Server} configurable from external sources such as a configuration file or a system property.
    Sampler<Object> randomSampler = Sampler.of("random=0.1");
    Sampler<Object> rateLimitedSampler = Sampler.of("rate-limited=10");
    Sampler<Object> alwaysSampler = Sampler.of("always");
    Sampler<Object> neverSampler = Sampler.of("never");
    
  • You can now specify the Sampler specification string in the com.linecorp.armeria.verboseExceptions system property. #2105 #2111
    • From this release, the default value of this property is rate-limited=10 which means the stack trace of the exceptions will be recorded at the maximum rate of 10 exceptions/sec. Previously, the default value of this property was false, which eliminates all stack traces, which gave our users a hard time figuring out why.
  • You can now specify a common path prefix using @PathPrefix annotation in annotated services. #2031 #2099
    @PathPrefix("/users")
    public class MyUserService {
        @Get("/{id}") // Mapped to '/users/{id}'
        @ProducesJson
        public User getUser(@Param int id) { ... }
        ...
    }
    
    Server server = new ServerBuilder()
        .annotatedService(new MyUserService())
        .build();
    

Bug fixes

  • Fixed a memory leak in HealthCheckService. #2110
  • Prometheus and Dropwizard Metrics are now optional dependencies in armeria-spring-boot-*. #2106 #2107
  • armeria-spring-boot-actuator-autoconfigure does not refuse to start anymore when HealthStatusHttpMapper is missing. #2104

Breaking changes

  • Flags.verboseExceptions() has been replaced with verboseExceptionSampler() and verboseExceptionSamplerSpec(). #2111
  • Exceptions.isVerbose(), which was deprecated previously, has been removed. #2111
  • You may need to add io.micrometer:micrometer-registry-prometheus or io.dropwizard.metrics:metrics-json after upgrading if you were depending on them transitively. #2107

Dependencies

  • Netty 4.1.41 -> 4.1.42
  • Netty TCNative BoringSSL 2.0.25 -> 2.0.26
  • Project Reactor 3.2.12 -> 3.3.0
  • Prometheus 0.6.0 -> 0.7.0
  • Retrofit 2.6.1 -> 2.6.2

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @adriancole
  • @anuraaga
  • @heowc
  • @ikhoon
  • @jyblue
  • @minwoox
  • @sivaalli
  • @Ta2Rim
  • @trustin
armeria -

Published by minwoox about 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation or other microservice frameworks.

New features

  • You can now easily get the request URI using RequestHeaders.uri() and HttpRequest.uri(). #2092
    RequestHeaders headers = RequestHeaders.of(HttpMethod.GET, "/foo",
                                               HttpHeaderNames.SCHEME, "https",
                                               HttpHeaderNames.AUTHORITY, "example.com"));
    assert headers.uri().equals(URI.create("https://example.com/foo"));
    assert HttpRequest.of(header).uri() == headers.uri();
    
  • You can now decorate the Runnable of the Thread created using ThreadFactoryBuilder. #2047 #2067
    ThreadFactories.builder(...)
                   .eventLoop(true)
                   .daemon(true)
                   .priority(...)
                   .taskFunction(task -> {
                       // Specify your logic here so it's executed before the Runnable.
                       task.run();
                       // Specify your logic here so it's executed after the Runnable.
                   })
                   .build();
    
  • You can now configure Server using Consumer<ServerBuilder> as well as ArmeriaServerConfigurator when integrating with Spring Boot. #2070
    @Bean
    public Consumer<ServerBuilder> customizer() {
        return sb -> sb.port(...)
                       ...
                       .service(...);
    }
    
  • You can now set example requests using AnnotatedServiceRegistrationBean. #1855 #2026
    @Bean
    public AnnotatedServiceRegistrationBean okService() {
        return new AnnotatedServiceRegistrationBean()
                .setServiceName("myAnnotatedService")
                .setPathPrefix("/my_service")
                .setService(new MyAnnotatedService())
                .setExampleRequests(Lists.of(
                        AnnotatedExampleRequest.of("myMethod", "{\"foo\":\"bar\"}")));
    }
    
  • You can be aware of whether the response content is empty from an HTTP status code. #2058
    HttpStatus status = ...
    if (!status.isContentAlwaysEmpty()) {
        // We may have a body!
    }
    
  • You can use SettableHealthIndicator for health check responses when using Spring boot autoconfigure. #2088

Improvements

  • You will see the doc service automatically scrolls down to the debug form if the URL contains a request. #1682 #2045
  • The performance for parsing a struct context in Thrift is improved, thanks to the Stack-Walking API in Java 9. #1686 #2055
  • You will see the int values of Enum members if they have in doc service. #1966 #2015
  • RequestContext instead of RequestLog is used for trace parsing and sampling. #2038

Bug fixes

  • You can now get the gRPC web trailers in the client. #2030 #2076
  • The actuator now responds with the correct Spring boot content type. #2061
  • The blocking stub in gRPC now can read messages. #2065 #2066
  • The listeners for EndpointGroup are notified after the first health check even when all endpoints are unhealthy. #2074 #2075
  • The subscriber who subscribes to the Response from a WebClient gets notified when it's complete. #2080 #2087
  • IllegalStateException that indicates the log should have at least one child is no longer raised when retrying. #2082 #2083
  • DefaultEventLoopScheduler respects maxNumEventLoopsPerHttpHttp1Endpoint set from ClientFactoryBuilder. #2086

Deprecation

  • The EventLoopThreadFactory has been deprecated in favor of ThreadFactories. #2067
    ThreadFactory factory = ThreadFactories.builder("myThread")
                                           .eventLoop(true)
                                           .build();
    

Breaking changes

  • Specifying an :authority header in a request has no effect anymore. The current Endpoint always determines the authority. #2092
    // This does NOT work anymore.
    final HttpClient client = HttpClient.of("https://127.0.0.1:8080/");
    client.execute(RequestHeaders.of(HttpMethod.GET, "/",
                                     HttpHeaderNames.AUTHORITY, "foo.com"));
    // This works.
    final HttpClient client = 
            HttpClient.of(SessionProtocol.HTTPS,
                          Endpoint.of("foo.com", 8080).withIpAddr("127.0.0.1"));
    client.get("/");
    
    • Instead, you can now use ClientOption.HTTP_HEADERS or {Client,Service}RequestContext.additional{Request,Response}{Headers,Trailers}() to override the existing headers, including :authority. #2092
      // This works.
      final HttpHeaders customHeaders =
              HttpHeaders.of(HttpHeaderNames.AUTHORITY, "foo.com");
      final HttpClient client =
              HttpClient.of("http://127.0.0.1:8080/",
                            ClientOption.HTTP_HEADERS.newValue(customHeaders));
      client.get("/");
      
      // This also works.
      final HttpClient client = HttpClient.of("http://127.0.0.1:8080/");
      try (SafeCloseable ignored = Clients.withHttpHeader(
                   HttpHeaderNames.AUTHORITY, "foo.com")) {
          client.get("/");
      }
      
  • ExceptionHandlerFunction.handleExeption() accepts ServiceRequestContext instead of RequestContext. #2060
    • You don't have to downcast anymore. :)
  • GrpcServiceRegistrationBean.ExampleRequest has been removed. Use GrpcExampleRequest.

Dependencies

  • Micrometer 1.2.0 -> 1.2.1
  • Netty 4.1.39.Final -> 4.1.41.Final
  • Tomcat 9.0.24 -> 9.0.26
    • Tomcat8 8.5.43 -> 8.5.45

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @adriancole
  • @andrewoma
  • @anirudhr95
  • @anuraaga
  • @eugene70
  • @heowc
  • @hirakida
  • @ikhoon
  • @imasahiro
  • @jyblue
  • @kojilin
  • @minwoox
  • @moonchanyong
  • @SooJungDev
  • @Ta2Rim
  • @trustin
  • @Waynefn
armeria -

Published by minwoox about 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation or other microservice frameworks.

New features

  • You can specify the maximum number of event loops to handle connections. #1886
    ClientFactoryBuilder builder = ...;
    builder.maxNumEventLoopsPerEndpoint(5); // Assign 5 event loops for endpoints. 1 is used by default.
    builder.maxNumEventLoopsPerHttp1Endpoint(10); // Assign 10 event loops for HTTP/1.1 endpoints. 1 is used by default.
    // You can set a customized function.
    builder.maxNumEventLoopsFunction(endpoint -> {
        if (endpoint.equals(Endpoint.of("foo.com"))) {
            return 5;
        }
        if (endpoint.host().contains("bar.com")) {
            return Integer.MAX_VALUE; // The value will be clamped at the number of event loops.
        }
        return -1; // Should return 0 or a negative value to use the default value.
    });
    
  • You can now implement your own EventLoopScheduler which schedules EventLoops those handle connections. #1886
  • You can now see Armeria modules and their versions in DocService. #685 #1744
    version
  • You can now easily combine EndpointGroups and Endpoints. #1897 #1939
    Endpoint foo = ...;
    Endpoint bar = ...;
    DynamicEndpointGroup group1 = ...;
    DynamicEndpointGroup group2 = ...;
    EndpointGroup composite = EndpointGroup.of(foo, bar, group1, group2);
    
  • You can use the Fibonacci backoff. #1968 #1979
    Backoff backoff = Backoff.fibonacci(100 /* initial delay millis */,
                                        10000 /* max delay millis */);
    
  • You can now reuse the configuration of exising Armeria client when creating an Armeria Retrotit client and HealthCheckedEndpointGroup. #2019 #2020
    HttpClient myClient = ...;
    ArmeriaRetrofitBuilder builder = new ArmeriaRetrofitBuilder();
    // Use the same settings and decorators with `myClient` when sending requests.
    builder.clientOptions(myClient.options());
    
    HealthCheckedEndpointGroupBuilder builder2 = new HealthCheckedEndpointGroupBuilder();
    builder2.clientOptions(myClient.options());
    
  • You can unwrap a Client and bring the decorating client instance via Unwrappable.as() or ClientFactory.unwrap(). #1883 #2018 #2029
    HttpClient client = new HttpClientBuilder()
        .decorator(LoggingClient.newDecorator())
        .build();
    LoggingClient unwrapped = client.as(LoggingClient.class).get();
    LoggingClient unwrapped2 = clientFactory.unwrap(client, LoggingClient.class).get();
    
  • You can now easily retrieve the port number of the running server. #1956 #1967
    ServerBuilder sb = new ServerBuilder();
    Server server = sb.http(0) // Use an ephemeral port.
                      .build();
    ...
    int port = server.activeLocalPort();
    

Improvements

  • The delay calculation performance in ExponentialBackoff is improved. #1983
  • You can now run all Armeria examples using gradle run or gradle bootRun. #1988

Bug fixes

  • You no longer see a warning message when the connection is closed before the current session protocol is detected. #2043 #2048
  • ByteBufHttpData does not leak anymore when an exception is raised by a client-side decorator. #2034
  • You no longer see a NullPointerException when the remote server requires a protocol downgrade. #2010 #2021

Breaking changes

  • Only one HTTP/2 connection is made per endpoint by default. #1886
    • Previously, an Armeria client made as many connections as the number of event loops for each endpoint. Now, it creates only one connection per endpoint so one EventLoop handles all requests. Because of that, you may see performance degradation. If you want it to work as before, specify maxNumEventLoopsPerEndpoint with the number of event loops in ClientFactoryBuilder.

Dependencies

We now use Maven Boms(Bill of Materials) for Jackson, Brave and Netty

  • Brave 5.6.10 -> 5.7.0
  • Guava 28.0-jre -> 28.1-jre
  • Jackson 2.9.9 -> 2.9.9.20190807
  • net.shibboleth.utilities 7.3.0 -> 7.5.0
  • OpenSAML 3.3.0 -> 3.4.3
  • Reactivestreams 1.0.2 -> 1.0.3
  • Reactor 3.2.11.RELEASE -> 3.2.12.RELEASE
  • RxJava2 2.2.11 -> 2.2.12
  • Spring boot 2.1.7.RELEASE -> 2.1.8.RELEASE

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @adriancole
  • @anuraaga
  • @delegacy
  • @hexoul
  • @ho9science
  • @ikhoon
  • @imasahiro
  • @jyblue
  • @KangWooJin
  • @kojilin
  • @mauhiz
  • @minwoox
  • @thinkgruen
  • @trustin
  • @Untaek
  • @zacscoding
armeria -

Published by trustin about 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation or other microservice frameworks.

Bug fixes

  • HealthCheckedEndpointGroup does not report healthy endpoints as unhealthy anymore. #2004
  • UnaryGrpcClient now handles gRPC status in HTTP trailer correctly. #1998
  • byte[] or HttpData returned by an annotated service method is now handled correctly when @Produces annotation is used with certain media types. #1999 #2005

Dependencies

  • java-jwt 3.8.1 -> 3.8.2
  • Jetty 9.4.19 -> 9.4.20
  • Tomcat 9.0.22 -> 9.0.24

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @adriancole
  • @anuraaga
  • @elefeint
  • @ikhoon
  • @imasahiro
  • @mauhiz
  • @minwoox
  • @tobias-
  • @trustin
armeria -

Published by trustin about 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation or other microservice frameworks.

Security

This release updates Netty from 4.1.38 to 4.1.39 to address the HTTP/2 security issues found in its previous versions. Please upgrade as soon as possible if your application serves the traffic from untrusted environment such as the Internet. See Netty 4.1.39 release news and Netflix security bulletins for more information.

Dependencies

  • Brave 5.6.9 -> 5.6.10
  • gRPC 1.22.1 -> 1.22.2
  • Netty 4.1.38 -> 4.1.39
  • SLF4J 1.7.27 -> 1.7.28
armeria -

Published by trustin about 5 years ago

Bug fixes

  • RetryingClient now respects the Endpoint selection order, which was broken since 0.89.0. #1973 #1974
armeria -

Published by trustin about 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation or other microservice frameworks.

Bug fixes

  • Armeria does not fail to initialize SSLContext anymore when JRE does not support TLSv1.3 and OpenSSL support is missing. #1984 #1986
  • HealthCheckedEndpointGroup does not fail with ConcurrentModificationException anymore in a certain situation. #1989 #1990 #1992

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @anuraaga
  • @ikhoon
  • @minwoox
  • @rmohta
  • @trustin
armeria -

Published by trustin about 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation or other microservice frameworks.

New features

  • You can now send an HTTP request to an absolute URI, which means you don't need to create different HttpClients for different hosts. #1143 #1343 #1961
    HttpClient client = HttpClient.of(); // No base URI specified.
    client.get("http://foo.com").aggregate().join();
    client.execute(RequestHeaders.of(HttpMethod.GET, "http://bar.com")).aggregate().join();
    
    HttpClient client = HttpClient.of("http://baz.com"); // Base URI specified.
    client.get("/index.html").aggregate().join();
    client.get("http://qux.com").aggregate().join(); // Can override the base URI.
    
  • HealthCheckedEndpointGroup has been revamped and now supports long-polling when used with Armeria's HealthCheckService. #1948 #1977 #1982
    • Long-polling support enables HealthCheckedEndpointGroup to detect the server health changes immediately with much fewer number of health check requests.
    • Long-polling support is auto-detected based on a special HTTP header armeria-lphc, so it is fully backward-compatible with ordinary non-Armeria health check services.
    EndpointGroup group = 
        HealthCheckedEndpointGroup.of(
            new StaticEndpointGroup(Endpoint.of("foo.com", 8080),
                                    Endpoint.of("bar.com", 8080)),
            "/internal/l7check");
    EndpointGroupRegistry.register("myGroup", group,
                                   EndpointSelectionStrategy.WEIGHTED_ROUND_ROBIN);
    HttpClient client = HttpClient.of("http://group:myGroup");
    client.get("/").aggregate().join();
    
  • You can now send a delayed response easily using HttpResponse.delayed(), which may be useful when simulating a slow server. #1935
    Server server = new ServerBuilder()
        .service("/delayed", (ctx, req) -> HttpResponse.delayed(HttpResponse.of(200),
                                                                Duration.ofSeconds(3)))
        .build();
    
  • You can now write a mock HTTP server using MockWebServerExtension and JUnit 5. #1884 #1935
    class MyTest {
        @RegisterExtension
        static MockWebServerExtension server = new MockWebServerExtension();
    
        @Test
        void test() {
            server.enqueue(HttpResponse.of(200));
            HttpResponse actualRes = HttpClient.of(server.httpUri("/")).get("/");
            assertThat(actualRes.aggregate().join().status().code()).isEqualTo(200);
        }
    }
    
  • AsyncCloseable has been added to provide an asynchronous close operation. #1948
    public class IAmCloseable implements AutoCloseable, AsyncCloseable {
        @Override
        public CompletableFuture<?> closeAsync() {
            ...
        }
    
        @Override
        public void close() {
            closeAsync().join();
        }
    }
    
  • You can now specify an EventExecutor when using HttpResponse.from(). #1937
  • You can now suppress the false warnings from RequestContextCurrentTraceContext by using setCurrentThreadNotRequestThread() #1971 #1980
    • For example, you could prevent warnings from the administrative threads controlled by ThreadFactory like the following:
      ThreadFactory factory = (runnable) -> new Thread(new Runnable() {
          @Override
          public void run() {
              RequestContextCurrentTraceContext.setCurrentThreadNotRequestThread(true);
              runnable.run();
          }
      
          @Override
          public String toString() {
              return runnable.toString();
          }
      });
      

Bug fixes

  • RequestLog.responseCause() is now recorded correctly for client requests. #1977
  • RetryingClient now respects the Endpoint selection order, which was broken since 0.89.0. #1973 #1974
  • The health checked requests sent by HealthCheckedEndpointGroup are now sent at the correct interval, even if an endpoint is not responsive. #1948
  • ClosedPublisherException is not raised anymore when HttpResponse is aborted by the client who issued the request. #1962
  • Armeria gRPC client now sends the TE header, whose absence caused interoperability issues with some gRPC servers, such as Python gRPC server. #1963 #1965
  • Armeria HTTP client does not send more than two Host headers for HTTP/1 anymore. #1942
  • HealthCheckedEndpointGroup now waits until the initial Endpoints are available from its delegate group. #1940

Deprecations

  • HealthCheckedEndpointGroupBuilder.retryInterval() has been un-deprecated. #1948
  • HealthCheckedEndpointGroupBuilder.healthCheckPort() has been deprecated in favor of port(). #1948
  • CircuitBreakerBuilder.circuitBreakerMapping() has been deprecated in favor of mapping(). #1970

Breaking changes

  • HttpHealthCheckedEndpointGroup has been renamed to HealthCheckedEndpointGroup.
    • The old HealthCheckedEndpointGroup has been renamed to AbstractHealthCheckedEndpointGroup, and is now extensible enough for you to implement your own health-checking mechanism, such as sending a gRPC/Thrift call.

Dependencies

  • Caffeine 2.7.0 -> 2.8.0
  • fastutil 8.2.3 -> 8.3.0
  • Project Reactor 3.2.10 -> 3.2.11
  • Retrofit 2.6.0 -> 2.6.1
  • RxJava 2.2.10 -> 2.2.11
  • SLF4J 1.7.26 -> 1.7.27
  • Spring Boot 2.1.6 -> 2.1.7, 1.5.21 -> 1.5.22

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @adriancole
  • @anuraaga
  • @dawnbreaks
  • @ikhoon
  • @imasahiro
  • @minwoox
  • @mpaltun
  • @trustin
armeria -

Published by trustin about 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation.

New features

  • You can now specify decorators for all services in a Server in a functional way. #1882 #1900
    ServerBuilder sb = new ServerBuilder();
    sb.service(...);
    // After:
    sb.decorator((delegate, ctx, req) -> {
        ...
        return delegate.serve(ctx, req);
    });
    // Before:
    sb.decorator(delegate -> new SimpleServiceDecorator<HttpRequest, HttpResponse>(delegate) {
        @Override
        public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception {
            ...
            return delegate().serve(ctx, req);
        }
    });
    
  • You can now use HealthCheckService which has richer functionality than its predecessor HttpHealthCheckService. #1878
    ServerBuilder sb = new ServerBuilder();
    sb.service("/internal/l7check",
               HealthCheckService.builder()
                                 .checkers(...)
                                 .healthyResponse(...)
                                 .unhealthyResponse(...)
                                 .longPolling(Durations.ofMinutes(1))
                                 .updatable(true)
                                 .build());
    
    • Long-polling query support
      • You can wait until the server becomes healthy or unhealthy and get notified immediately.
    • Easy customization of healthy/unhealthy responses
    • Easy customization of update request handler
  • You now know exact host you are sending your request to when using Armeria client. #1917
    • It was previously not possible when you specified an EndpointGroup as the destination.
    • Therefore, ClientRequestContext.endpoint() may return null since this release when Armeria failed to determine the destination host.
    • ClientRequestContext.endpointSelector() has been added so that you still know which EndpointGroup you are connecting to.
  • BraveClient and BraveService now accept HttpTracing as well as Tracing. #1223 #1906
    Tracing tracing = ...;
    
    // Server-side
    ServerBuilder sb = new ServerBuilder();
    //// Before
    sb.service("/", myService.decorate(BraveService.newDecorator(tracing)));
    //// After
    HttpTracing httpTracing = HttpTracing.create(tracing);
    sb.service("/", myService.decorate(BraveService.newDecorator(httpTracing)));
    
    // Client-side
    HttpClientBuilder cb = new HttpClientBuilder(...);
    //// Before
    cb.decorator(BraveClient.newDecorator(tracing, "myBackend"));
    //// After
    cb.decorator(BraveClient.newDecorator(httpTracing.clientOf("myBackend")));
    
  • You can now create a decorating Service or Client in a less verbose way by extending new SimpleDecorating* classes. #1881 #1925
    • SimpleDecoratingHttpService extends SimpleDecoratingService<HttpRequest, HttpResponse>
    • SimpleDecoratingRpcService extends SimpleDecoratingService<RpcRequest, RpcResponse>
    • SimpleDecoratingHttpClient extends SimpleDecoratingClient<HttpRequest, HttpResponse>
    • SimpleDecoratingRpcClient extends SimpleDecoratingClient<RpcRequest, RpcResponse>
  • RpcService has been added for your convenience. #1881 #1925
    • RpcService extends Service<RpcRequest, RpcResponse>

Improvements

  • The output type of RequestLog sanitizer functions has been relaxed to ? so that a user can write much simpler and more efficient sanitizer function. #1810 #1879
    // Before
    Function<HttpHeaders, HttpHeaders> sanitizer = headers -> {
        return headers.toBuilder().removeAndThen("authorization").build();
    };
    // After
    Function<HttpHeaders, Object> sanitizer = headers -> {
        // No need to construct a new HttpHeaders object.
        return headers.toBuilder().removeAndThen("authorization").toString();
    };
    // Even more efficiently
    Function<HttpHeaders, Object> sanitizer = headers -> "sanitized!";
    
  • A glob path mapping is not translated into a regex path mapping when combined with path prefix anymore. #1929
  • ByteBufHttpData.toInputStream() does not perform extra memory copy anymore. #1918 #1919

Bug fixes

  • Armeria client now sends OPTIONS * HTTP/1.1 instead of HEAD / HTTP/1.1, so that the initial protocol upgrade does not trigger business logic when a server has business logic bound at /. #1895 #1896
  • Response content is not sanitized twice anymore. #1879
  • gRPC message compression is now enabled by default on the server side, so that the default behavior matches that of the upstream implementation. #1885 #1889
  • The max-age attribute in a set-cookie header is now handled correctly when using Spring WebFlux. #1904
  • Fixed a bug where the base URL of the received request is set incorrectly when using Spring WebFlux. #1904
  • HttpHealthCheckedEndpoint does not leak connections and requests after close() is called. #1899
  • BraveClient does not trigger RequestLogAvailabilityException anymore when the request being traced has failed without sending any data. #1911 #1912
  • @ConsumesJson annotation now accepts JSON documents with any charsets rather than only UTF-8. #1920
  • The IllegalStateException raised by pushIfAbsent() is now propagated properly to the CompletableFuture created by RequestContext.makeContextAware(). #1920

Deprecations

  • HttpHealthCheckService and SettableHttpHealthCheckService have been deprecated in favor of HealthCheckService and its builder. #1878

Breaking changes

  • ClientRequestContext.endpoint() may return null since this release. #1917
  • The Endpoint returned by ClientRequestContext.endpoint() now always refers to a single host, not an EndpointGroup. #1917
    • Use ClientRequestContext.endpointSelector().group() to retrieve the related EndpointGroup.

Dependencies

  • gRPC 1.21.0 -> 1.22.1
  • Netty 4.1.37 -> 4.1.38
  • Tomcat 9.0.21 -> 9.0.22, 8.5.42 -> 8.5.43

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @adriancole
  • @anuraaga
  • @babjo
  • @hirakida
  • @hyeonjames
  • @ikhoon
  • @imasahiro
  • @kojilin
  • @minwoox
  • @trustin
  • @whhan91
armeria -

Published by trustin over 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation.

New features

  • ClientRequestContext.current() and ServiceRequestContext.current() have been added so you don't need to downcast RequestContext to ClientRequestContext or ServiceRequestContext. It also makes sure the current context is client-side (or server-side), preventing a ClassCastException. #1869 #1872
    ClientRequestContext cctx = ClientRequestContext.current();
    ServiceReqiestContext sctx = ServiceRequestContext.current();
    
  • currentOrNull() static method has been added to (Client|Service)RequestContext, which is similar to current() but returning null when there's no current context. #1872
    // Before:
    RequestContext ctx = RequestContext.mapCurrent(Function.identity(), null);
    // After:
    ServiceRequestContext sctx = ServiceRequestContext.currentOrNull();
    
  • You can now specify different AccessLogWriters for different services. #1866
    Server server = new ServerBuilder()
            .route().path("/svc1")
                    .accessLogWriter(accessLogWriterForService1, true)
                    .build(service1)
            .route().path("/svc2") // Will use the fallbackAccessLogWriter.
                    .build(service2)
            .accessLogWriter(fallbackAccessLogWriter, true)
            .build();
    
  • The metrics of the Executor specified in ServerBuilder.blockingTaskExecutor() will be exposed under executor{name=armeriaBlockingTaskExecutor}. #1683 #1841
  • Armeria client will send a DNS query via TCP when a DNS response is truncated due to UDP packet size limitation. #1873
  • You can now specify health check request interval using a Backoff, which means you can have more flexible delay strategy such as adding jitter. #1846
    HttpHealthCheckedEndpointGroup group = new HttpHealthCheckedEndpointGroup(...)
            .retryBackoff(Backoff.fixed(10000).withJitter(0.3))
            .build();
    
    • By default, HealthCheckedEndpointGroup will now add 20% jitter to the health check request interval.
  • A new module armeria-brave has been added to replace the deprecated armeria-zipkin. #1840
    • The package name has been changed from com.linecorp.armeria.{common,client,server}.tracing to com.linecorp.armeria.{common,client,server}.brave.
    • HttpTracingClient and HttpTracingService have been renamed to BraveClient and BraveService.
  • You can now retrieve the retrofit2.Invocation object associated with the current Retrofit call via InvocationUtil.get(RequestLog), which can be useful when building a meter ID prefix. #1591 #1845
    public class MyRetrofitMeterIdPrefixFunction implements MeterIdPrefixFunction {
        @Override
        public MeterIdPrefix apply(MeterRegistry registry, RequestLog log) {
            final Invocation invocation = InvocationUtil.getInvocation(log);
            final String service;
            final String method;
            if (invocation != null) {
                service = invocation.method().getDeclaringClass().getSimpleName();
                method = invocation.method().getName();
            } else {
                service = "unknown";
                method = log.method().name();
            }
            return new MeterIdPrefix("call", "service", service, "method", method);
        }
    }
    
    • We also added RetrofitMeterIdPrefixFunction which provides the sensible default MeterIdPrefixFunction for Retrofit calls.

Improvements

  • The content negotiation logic has been relaxed so that the server falls back to the service with less constraint when content negotiation fails. Previously, it was rejecting the request. #1860
  • More exceptions are now wrapped by UnprocessedRequestException to indicate whether the request can be safely retried without worrying about sending the request more than once. #1653 #1848
    • Any exceptions that occurred during a connection attempt.
    • Any exceptions that occurred during acquiring an existing connection from a connection pool.
    • We also made UnprocessedRequestException.getCause() is non-null, so you do not need to worry about the case where there is no cause in UnprocessedRequestException.

Bug fixes

  • Server will now allow specifying a @Default annotation with null value. #1858 #1864
  • The DEBUG level log message which occurs when a client sent an ill-formed Accept header is now easier to understand. #1849
  • THttpService now handles HttpStatusException and HttpResponseException correctly, which means they will not be translated into a 200 OK response that contains a TApplicationException anymore. For example, your Thrift clients will see 503 Service Unavailable response when your service throws an HttpStatusException.of(503) rather than 200 OK. #1839 #1867
  • DocService debug form will validate the endpoint path properly now. #1856 #1857
  • RequestContextCurrentTraceContext now calls decorateScope() when necessary. #1840
  • Spring Web and WebFlux integration do not ignore the ssl.keyAlias property anymore. #1843 #1865
  • You will not see an ERROR log message when a client sends a HEAD request to your Spring WebFlux endpoint. #1847 #1859

Deprecations

  • HttpHealthCheckedEndpointGroupBuilder.retryInterval(Duration) has been deprecated. Use retryBackoff(Backoff). #1846
  • Everything in armeria-zipkin has been deprecated. Use armeria-brave. #1840

Breaking changes

  • N/A

Dependencies

  • Brave 5.6.3 -> 5.6.6
  • FastUtil 8.2.2 -> 8.2.3
  • Hibernate Validator 6.0.16 -> 6.0.17
  • javax.annotation-api -> jakarta.annotation-api 1.3.4
  • Jetty 9.4.18 -> 9.4.19
  • Micrometer 1.1.4 -> 1.2.0
  • Netty 4.1.34 -> 4.1.37
    • TCNative BoringSSL 2.0.23 -> 2.0.25
  • protobuf-jackson 0.4.0 -> 1.0.0
  • RxJava 2.2.9 -> 2.2.10
  • Spring Boot 2.1.5 -> 2.1.6

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @Adanz
  • @adriancole
  • @anuraaga
  • @cj848
  • @hyeonjames
  • @ikhoon
  • @imasahiro
  • @kojilin
  • @minwoox
  • @normanmaurer
  • @southernkasaist
  • @tobias-
  • @trustin
armeria -

Published by trustin over 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation.

New features

  • You can now jump to a service method quickly using a go-to form in a DocService debug page. #1815
  • From this release, TLSv1.3 is enabled by default. #1779
  • Route replaces PathMapping. #1789
    ServerBuilder sb = new ServerBuilder();
    sb.service(Route.builder()
                    .path("/greet/{name}")
                    .consumes(MediaType.JSON)
                    .produces(MediaType.JSON_UTF_8)
                    .build(),
               (ctx, req) -> HttpResponse.of(HttpStatus.OK,
                                             MediaType.JSON_UTF_8,
                                             ...));
    
  • AggregatedHttpMessage has been split into two subtypes: AggregatedHttpRequest and AggregatedHttpResponse. #1702 #1795
    • The factory methods and some getter methods in AggregatedHttpMessage have been pushed down to the two subtypes. For example, AggregatedHttpMessage.method() does not exist anymore and you will find it in AggregatedHttpRequest.
    • We have revised the API to use AggregatedHttpRequest or AggregatedHttpResponse rather than AggregatedHttpMessage wherever possible for clarity.
  • New static factory methods have been added to HttpData. #1797
    • HttpData.of() was not very clear about whether it will wrap the specified bytes or make a copy of them. HttpData.wrap() and HttpData.copyOf() removes such ambiguity.
      byte[] b = new byte[] { 1, 2, 3 }
      HttpData copied = HttpData.copyOf(b);
      HttpData wrapped = HttpData.wrap(b);
      
      b[0] = 0;
      assert copied.array()[0] == 1;
      assert wrapped.array()[0] == 0;
      
  • You can now specify SubscriptionOptions when subscribing to a StreamMessage to modify the contract between StreamMessage and Subscriber. #1700 #1808
    HttpRequest req = ...;
    // Subscriber.onError() will be invoked with a CancelledSubscriptionException
    // when the Subscription is cancelled.
    req.subscribe(mySubscriber, SubscriptionOption.NOTIFY_CANCELLATION);
    
  • The Endpoints loaded from a .properties file by PropertiesEndpointGroup are now automatically updated when the .properties file is modified. Note that the classpath resources are not auto-reloaded and you have to specify a real file as a java.nio.Path. #1787
    PropertiesEndpointGroup endpoints = PropertiesEndpointGroup.of(
            Paths.get("/etc/my/endpoints.properties"),
            "endpoints.");
    
  • You can now create a Client by specifying an Endpoint rather than a URI. #1743
    Endpoint endpoint = Endpoint.of("example.com");
    HttpClient client = new HttpClientBuilder(SessionProtocol.HTTPS, endpoint)
            ...
            .build();
    
  • You can now apply Armeria's default settings to an existing DropwizardMeterRegistry (or PrometheusMeterRegistry) using DropwizardMeterRegistries.configureRegistry() (or PrometheusMeterRegistries.configureRegistry()). Previously, Armeria's default settings were applied only to the MeterRegistrys created by DropwizardMeterRegistries.newRegistry() (or PrometheusMeterRegistries.newRegistry()). #1814 #1820
    import io.micrometer.jmx.JmxMeterRegistry;
    
    // JmxMeterRegistry is a subtype of DropwizardMeterRegistry.
    JmxMeterRegistry jmxRegistry = new JmxMeterRegistry(...);
    DropwizardMeterRegistries.configureRegistry(jmxRegistry);
    
  • A new exception type InvalidSamlRequestException has been added so that you can tell if a client sent an invalid SAML request from exception type. #1780 #1783

Improvements

  • Consolidated the logic related with TLS and improved TLS configuration validation. #1779
  • Stack trace is logged for better debuggability when RequestContextCurrentTraceContext cannot find the current RequestContext. #1800

Bug fixes

  • The percent-encoding of the characters such as # and / are now preserved correctly. #1805
  • gRPC Metadata is now supported. #1788 #1790
  • Fixed a bug where a bad gRPC client is created when a user specified a URL that does not end with a slash (/). #1785
  • The trailers added with ServiceRequestContext.addAdditionalResponseTrailer() are not ignored anymore. #1782
  • JUnit 5 extensions are now initialized and destroyed on BeforeAll and AfterAll rather than on Each. #1801
  • spring-boot-webflux-starter does not fail to start anymore even if more than one MeterRegistry exist. #1791

Deprecations

  • HttpData.offset() has been deprecated. It always returns 0. #1771 #1797
  • Some HttpData.of() methods have been deprecated in favor of HttpData.wrap() and/or HttpData.copyOf(). #1797
  • trailingHeaders() methods in AggregatedHttpMessage and HttpResult have been deprecated in favor of trailers(). #1795
  • StreamMessage methods which accept boolean withPooledObjects have been deprecated. Use the methods that accept SubscriptionOption and specify SubscriptionOption.WITH_POOLED_OBJECTS. #1700

Breaking changes

  • AggregatedHttpMessage has been split into two subtypes. See 'New features' for more information. #1702 #1795
  • PathMapping and its related classes have been replaced with Route and its related classes. See 'New features' for more information. #1789
    • ServiceWithPathMappings has been replaced with ServiceWithRoutes.
  • ClientCacheControl and ServerCacheControl have been moved to the com.linecorp.armeria.common package. #1813 #1816

Dependencies

  • Bouncy Castle 1.61 -> 1.62
  • gRPC 1.20.0 -> 1.21.0
  • Guava 27.1 -> 28.0
  • java-jwt 3.8.0 -> 3.8.1
  • Project Reactor 3.2.9 -> 3.2.10
  • protobuf-jackson 0.3.1 -> 0.4.0
  • Retrofit 2.5.0 -> 2.6.0
  • RxJava 2.2.8 -> 2.2.9
  • Tomcat 9.0.20 -> 9.0.21, 8.5.40 -> 8.5.42
  • ZooKeeper 3.4.14 -> 3.5.5

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @anuraaga
  • @dawnbreaks
  • @delegacy
  • @hyangtack
  • @ikhoon
  • @imasahiro
  • @jrhee17
  • @minwoox
  • @RyouZhang
  • @SeungukHan
  • @trustin
armeria -

Published by trustin over 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation.

Bug fixes

  • The percent-encoding of the characters such as # and / are now preserved correctly. #1805

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @hyangtack
  • @minwoox
  • @trustin
armeria -

Published by minwoox over 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation.

New features

  • The request body is injected automatically in annotated HTTP service when the parameter type is byte[], HttpData, String or CharSequence regardless of the content-type header. #1584, #1745
  • You can now create a curl command from the DocService using COPY AS A CURL COMMAND button. #196, #1747
  • You can now build your gRPC service without depending on gRPC stubs by extending AbstractUnsafeUnaryGrpcService. This is for advanced users only. #1766
  • You can now log available ciphers for TLS on startup by setting a system property: -Dcom.linecorp.armeria.dumpOpenSslInfo=true. #1777

Improvements

  • You can now use HttpTracingClient even when the client is used outside of Armeria server. #1767, #1768
  • You can now get pooled HTTP decode responses. #1770

Bug fixes

  • RequestLogAvailabilityException is no longer raised in HttpTracling(Client|Service) when a request timed out. #1769, #1775
  • Now, an exception is raised while building a server when TLS is configured but ALPN is not supported. #1772, #1774
  • :scheme and :authority headers are set for every received request in the server. #1773, #1776

Breaking change

  • newDecoder() in StreamDecoderFactory now takes a ByteBufAllocator. #1770

Dependencies

  • Jackson 2.9.8 -> 2.9.9
  • jsoup 1.11.3 -> 1.12.1
  • tomcat-embed-core 9.0.19 -> 9.0.20
  • Spring Boot
    • 2.1.4.RELEASE -> 2.1.5.RELEASE
    • 1.5.20.RELEASE -> 1.5.21.RELEASE

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @adriancole
  • @alex-lx
  • @anuraaga
  • @dawnbreaks
  • @gquintana
  • @hyangtack
  • @imasahiro
  • @jongmin92
  • @minwoox
  • @trustin
  • @wooyeong
armeria -

Published by trustin over 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation.

New features

  • You can now bind your Service to a certain HTTP method or enable HTTP content-type negotiation very easily with the new ServerBuilder.route() method. #1737

    ServerBuilder sb = new ServerBuilder();
    sb.route()
      .get("/users/{id}")
      .delete("/users/{id}")
      .post("/users")
      .consumes(MediaType.JSON)
      .produces(MediaType.JSON_UTF_8)
      .build(new MyUserService());
    
    // You can also configure using a lambda expression.
    sb.withRoute(b -> {
        b.path("/foo")
         .build(new MyFooService());
    });
    
  • It is now also possible to specify different settings for different services using the new route() method. It means you can specify a large timeout for a certain service only conveniently. #1737

    ServerBuilder sb = new ServerBuilder();
    sb.route()
      .path("/long_poll")
      .requestTimeoutMillis(0) // Disable timeout for /service.
      .build(new MyLongPollingService()); 
    sb.route()
      .path("/get_now") 
      .build(new MyOtherService()); // Use the default timeout.
    ```java
    
    
  • We revamped our HttpHeaders API to make it cleaner and safer. #1731

    • HttpHeaders has been split into three types:
      • RequestHeaders for request headers with :method and :path header
      • ResponseHeaders for response headers with :status header
      • HttpHeaders for trailers and other headers
      • RequestHeaders and ResponseHeaders extend HttpHeaders.
    • HttpHeaders and its subtypes are immutable and thus must be built using a factory method or a builder.
    • Quick examples:
      RequestHeaders reqHdrs = RequestHeaders.of(HttpMethod.GET, "/get",
                                                 HttpHeaderNames.ACCEPT, MediaType.JSON_UTF_8);
      RequestHeaders newReqHdrs = reqHdrs.toBuilder()
                                         .add("foo", "bar")
                                         .build();
      ResponseHeaders resHdrs = ResponseHeaders.of(200 /* OK */);
      
      HttpHeaders hdrs = HttpHeaders.builder()
                                    .add("alice", "bob");
                                    .build();
      HttpHeaders newHdrs = hdrs.withMutations(builder -> {
          builder.add("charlie", "debora");
      });
      
    • See HttpHeaders Javadoc for more examples.
  • You can now test your Armeria app with JUnit 5. A new module armeria-testing-junit5 has been added with the following extensions: #1736

    • com.linecorp.armeria.testing.junit.server.ServerExtension
    • com.linecorp.armeria.testing.junit.server.SelfSignedCertificateExtension
    • com.linecorp.armeria.testing.junit.common.EventLoopGroupExtension
    • com.linecorp.armeria.testing.junit.common.EventLoopExtension
  • You can now customize the behavior of gRPC JSON marshaller. #1696 #1753

    ServerBuilder sb = new ServerBuilder();
    sb.service(new GrpcServiceBuilder()
                   .addService(new MyServiceImpl())
                   .supportedSerializationFormats(GrpcSerializationFormats.values())
                   .jsonMarshallerCustomizer(marshaller -> {
                       marshaller.preservingProtoFieldNames(true);
                   })
                   .build());
    
  • You can now write a unary gRPC client without depending on grpc-java at all. #1703 #1748 #1751

    HelloRequest req = HelloRequest.newBuilder()
                                   .setName("Alice")
                                   .build();
    UnaryGrpcClient client = new UnaryGrpcClient(HttpClient.of("http://127.0.0.1:8080"));
    byte[] resBytes = client.execute("/com.example.HelloService/Greet",
                                     req.toByteArray()).join();
    HelloResponse res = HelloResponse.parseFrom(resBytes);
    
  • You can now use GrpcServiceRegistrationBean to register a gRPC service when using Spring Boot integration. #1749

    @Bean
    public GrpcServiceRegistrationBean helloService() {
        return new GrpcServiceRegistrationBean()
            .setServiceName("helloService")
            .setService(new GrpcServiceBuilder()
                            .addService(new HelloService())
                            .supportedSerializationFormats(GrpcSerializationFormats.values())
                            .enableUnframedRequests(true)
                            .build())
            .setDecorators(LoggingService.newDecorator())
            .setExampleRequests(List.of(ExampleRequest.of(HelloServiceGrpc.SERVICE_NAME,
                                                          "Hello",
                                                          HelloRequest.newBuilder()
                                                                      .setName("Armeria")
                                                                      .build())));
    }
    
  • You can now use wildcard pattern when specifying built-in properties in Logback RequestContextExportingAppender. #489 #1742

Bug fixes

  • Trailing slashes in a path pattern is now handled correctly. #1741
  • It is now disallowed to apply CorsDecorator more than once. #1740
  • HttpTracingClient and HttpTracingService now adds a valid addressable http.url tag. #1733 #1762
  • SessionProtocol and SerializationFormat are now added to http.protocol and http.serfmt tag instead.

Breaking changes

  • Artifact armeria-testing has been renamed to armeria-testing-junit4. Please update your project dependencies. #1736
  • Many places in the public API that use HttpHeaders as a parameter or a return value have been changed due to the revamped HttpHeaders API. #1731
  • The following ServerBuilder methods were removed:
    • virtualHost(VirtualHost)
    • defaultVirtualHost(VirtualHost)

Deprecations

  • The default prefix found in various configuration properties has been deprecated. Use the property setters without the default prefix. #1737

    ServerBuilder sb = new ServerBuilder();
    // Do NOT use this:
    sb.defaultRequestTimeout(...);
    // Use this:
    sb.requestTimeout(...);
    
  • HttpHeaders.EMPTY has been deprecated. Use HttpHeaders.of().

Dependencies

  • Dropwizard Metrics 4.0.5 -> 4.1.0
  • Jetty 9.4.17 -> 9.4.18
  • Project Reactor 3.2.8 -> 3.2.9

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @adriancole
  • @anuraaga
  • @delegacy
  • @ejona86
  • @hyangtack
  • @huydx
  • @karthikraman22
  • @masonshin
  • @matsumana
  • @minwoox
  • @trustin
armeria -

Published by trustin over 5 years ago

What is Armeria?

Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation.

New features

  • You can now access the detailed timing information for the connection attempts made by Armeria via RequestLog API, including DNS lookup and socket connect time. #1692
    HttpClient client = new HttpClientBuilder("https://example.com/")
        .decorator((delegate, ctx, req) -> {
            ctx.log().addListener(log -> {
                ClientConnectionTimings timings = ClientConnectionTimings.get(log);
                System.err.printf("Total time taken: %d ns%n",
                                  timings.connectionAcquisitionDurationNanos());
                System.err.printf("DNS lookup: %d ns%n",
                                  timings.dnsResolutionDurationNanos());
                System.err.printf("Socket connect:: %d ns%n",
                                  timings.socketConnectDurationNanos());
            }, RequestLogAvailability.REQUEST_START);
            return delegate.execute(ctx, req);
        })
        .build();
    client.get("/");
    
  • You can now customize server-side SslContext more conveniently. #1717
    ServerBuilder sb = new ServerBuilder();
    sb.tls(certChainFile, keyFile, tlsContextBuilder -> {
        // Use JDK SSLEngine instead of OpenSSL.
        tlsContextBuilder.sslProvider(SslProvider.JDK);
    });
    
  • Server.stop() is now able to stop its blockingTaskExecutor. You have to specify whether to stop the blockingTaskExecutor you specified or not when calling ServerBuilder.blockingTaskExecutor() from this release. #1685 #1707
    ServerBuilder sb = new ServerBuilder();
    // The thread pool will be terminated when the server stops.
    sb.blockingTaskExecutor(Executors.newFixedThreadPool(100), true);
    
  • The usability of RedirectService has been improved with some API changes. #1725 #1726
    • RedirectService preserves the query string by default. The query string of the old location was dropped previously.
    • Added preserveQueryString constructor parameter. Specifying false will let you go back to the previous behavior.
  • The usability of SettableHealthChecker has been improved with some API changes. #1714
    • SettableHealthChecker's initial healthiness is now true. It was false previously.
    • You can now specify the initial healthiness when instantiating SettableHealthChecker.
      SettableHealthChecker myHealthChecker = new SettableHealthChecker(false);
      ServerBuilder sb = new ServerBuilder();
      sb.service("/monitor/health", new HttpHealthCheckService(myHealthChecker));
      
    • SettableHealthChecker.setHealthy(boolean) is now chainable. #1714
      // Same with: new SettableHealthChecker(false)
      SettableHealthChecker myHealthChecker = new SettableHealthChecker().setHealthy(false);
      
  • You can now specify different path mappings for different CORS policies. #1698 #1699
    • Using a builder pattern:
      ServerBuilder sb = new ServerBuilder();
      // Add two services under /foo and /bar.
      sb.service("prefix:/foo", fooService);
      sb.service("prefix:/bar", barService);
      
      // Enable CORS for:
      // - GET and POST requests for all resources under http://example.com/foo/
      // - GET request for all resources under http://example.com/bar/
      sb.decorator(CorsServiceBuilder.forOrigins("http://example.com")
                                     .pathMapping("prefix:/foo")
                                     .allowCredentials()
                                     .allowRequestMethods(HttpMethod.GET, HttpMethod.POST)
                                     .andForOrigins("http://example.com")
                                     .pathMapping("prefix:/bar")
                                     .allowCredentials()
                                     .allowRequestMethods(HttpMethod.GET)
                                     .and()
                                     .newDecorator());
      
    • Using annotations:
      sb.annotatedService(
          @CorsDecorator(
              origins = "http://example.com",
              pathPatterns = "prefix:/foo",
              credentialsAllowed = true,
              allowedRequestMethods = { HttpMethod.GET, HttpMethod.POST })
          @CorsDecorator(
              origins = "http://example.com",
              pathPatterns = "prefix:/bar",
              credentialsAllowed = true,
              allowedRequestMethods = { HttpMethod.GET })
          new Object() {
              ...
          });
      
  • You can now build a gRPC service without depending on upstream gRPC API. #1720 #1727
    • Added armeria-grpc-protocol which provides a core functionality required for building a gRPC service, which does not depend on io.grpc:grpc-java but only on com.google.protobuf:protobuf-java.
    • Added AbstractUnaryGrpcService which allows you to implement a unary gRPC easily without depending on io.grpc:grpc-java.
      class MyUnaryGrpcService extends AbstractUnaryGrpcService {
          @Override
          protected CompletableFuture<byte[]> handleMessage(byte[] message) {
              final MyGrpcRequest req;
              try {
                  req = MyGrpcRequest.parseFrom(message);
              } catch (InvalidProtocolBufferException e) {
                  throw new UncheckedIOException(e);
              }
      
              MyGrpcResponse res = MyGrpcResponse.newBuilder()...build();
              return CompletableFuture.completedFuture(res.toByteArray());
          }
      }
      
  • Spring Boot integration now has content encoding options. #1716
    # Your application.yml:
    armeria:
      ports:
        - port: 8080
          protocol: HTTP
      compression:
        enabled: true
        mime-types: text/*, application/json
        excluded-user-agents: some-user-agent, another-user-agent
        minResponseSize: 1KB
    

Bug fixes

  • The default path pattern now handles a trailing slash properly. #1730 #1735
  • TwoElementFixedStreamMessage no longer throws an IllegalReferenceCountException. #1687 #1695
  • DnsEndpointGroup does not ignore the search directive in /etc/resolv.conf anymore. This fix should be useful for users in Kubernetes environment. #1694 #1697
  • DocService no longer raises a NullPointerException for a certain gRPC service metadata. #1705 #1715
  • An unframed gRPC service no longer becomes unresponsive when sending a response without content #1723
  • THttpService no longer fails to load the service metadata when .thrift file was compiled with the private-members option. #1728 #1729
  • THttpService no longer fails to load the service metadata when .thrift file defines a service that extends other service. #1734
  • HttpTracingClient and HttpTracingService do not fill service name automatically with host names or IP addresses anymore. #1706
  • Spring integration module now respects the com.linecorp.armeria.useOpenSsl flag properly. #1713

Deprecations

  • ServerBuilder.blockingTaskExecutor(Executor) has been deprecated. Use ServerBuilder.blockingTaskExecutor(Executor, boolean). #1685 #1707
  • TextFormatter.epoch() and appendEpoch() have been deprecated. Use TextFormatter.epochMillis() and appendEpochMillis(). #1692

Breaking changes

  • The initial healthiness of SettableHealthChecker is now true. #1714
  • RedirectService preserves the query string by default. The query string of the old location was dropped previously. #1725 #1726

Dependencies

  • gRPC 1.19.0 -> 1.20.0
    • Protobuf 3.6.1 -> 3.7.1
  • Jetty 9.4.15 -> 9.4.17
  • Micrometer 1.1.3 -> 1.1.4
  • Spring Boot 2.1.3 -> 2.1.4, 1.5.19 -> 1.5.20
  • Tomcat 9.0.17 -> 9.0.19, 8.5.39 -> 8.5.40
  • ZooKeeper 3.4.13 -> 3.4.14

Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

  • @adriancole
  • @anuraaga
  • @dawnbreaks
  • @edgao
  • @geminiKim
  • @gquintana
  • @huydx
  • @hyangtack
  • @minwoox
  • @syleeeee
  • @tacigar
  • @trustin
armeria -

Published by minwoox over 5 years ago

New features

  • You can now configure TLS for Armeria server when using armeria-spring-boot-autoconfigure. #1663
    # Your application.yml
    
    armeria:
       ports:
         - port: 8080
           protocol: HTTP
         - ip: 127.0.0.1
           port: 8081
           protocol:HTTP
         - port: 8443
           protocol: HTTPS
       ssl:
         key-alias: "host.name.com"
         key-store: "keystore.jks"
         key-store-password: "changeme"
         trust-store: "truststore.jks"
         trust-store-password: "changeme"
    
  • Now, you have enough information to determine the status of a Thrift endpoint with InvalidResponseHeadersException. #1668
  • EventLoopThread now implements NonBlocking tag interface using in Project Reactor. #1665
    • Schedulers.isInNonBlockingThread() returns true when you call in the Armeria EventLoops.

Improvement

  • Various documentation updates. #1666 #1671 #1677

Bug fixes

  • The request body form is now shown when the HTTP method is POST or PUT in DocService. #1667
  • You can now use the HttpHeaderNames.PREFER again. #1669
  • IllegalReferenceCountException is no longer raised when you enable content previews on the client-side. #1690
  • The request is no longer sent automatically but submitted only by clicking the submit button in DocService. #1689

Breaking Change

  • doStart() and doStop() methods in StartStopSupport now take a parameter which might be used as a startup and shutdown argument.
    • Listener notification methods take a parameter as well. #1673 #1675

Dependencies

  • Netty TCNative BoringSSL 2.0.22.Final -> 2.0.23.Final
  • Project Reactor 3.2.6 -> 3.2.8
  • RxJava 2.2.7 -> 2.2.8
  • Tomcat 9.0.16 -> 9.0.17, 8.5.38 -> 8.5.39
armeria -

Published by hyangtack over 5 years ago

New features

  • You can now include or exclude service methods using DocServiceFilter when building a DocService.
    See our documentation for more information. #1609
     ServerBuilder sb = new ServerBuilder();
     ...
     sb.serviceUnder("/docs", new DocServiceBuilder()
             // Include Thrift services and Annotated services.
             .include(DocServiceFilter.ofThrift().or(DocServiceFilter.ofAnnotated()))
             // Exclude the method whose name is "foo" in Thrift services.
             .exclude(DocServiceFilter.ofThrift().and(DocServiceFilter.ofMethodName("foo")))
             .build());
    
  • HttpHeaderNames now forks from Guava's HttpHeaders instead of Netty's HttpHeaderNames
    because it has more recent HTTP headers which may be useful to service authors.
  • You can use SystemInfo utility class in order to get the system information. #1656
     // Java version
     SystemInfo.javaVersion();
    
     // Hostname
     SystemInfo.hostname();
    
     // The current process ID
     SystemInfo.pid();
    
     // The current time in microseconds
     SystemInfo.currentTimeMicros();
    

Improvements

  • Set 0.5 to the default failure rate threshold of a circuit breaker. #1657
  • Various documentation updates. #1657 #1654 #1651

Bug fixes

  • Strip a leading slash in an HttpFile resource path. #1661 #1650
     // Will strip the leading slash
     HttpFile.ofResource(ClassLoader.getSystemClassLoader(), "/java/lang/Object.class");
    
  • ByteBufs are no longer leaked when you use Spring WebFlux integration. #1658
    It was possible to leak a ByteBuf if a client closes a connection before reading the body of an HTTP response.

Breaking Change

  • DocServicePlugin interface now has name() method and generateSpecification() method signature has changed. #1609
     // Before:
     ServiceSpecification generateSpecification(Set<ServiceConfig> serviceConfigs);
     // After:
     String name();
     ServiceSpecification generateSpecification(Set<ServiceConfig> serviceConfigs, DocServiceFilter filter);
    
  • Some header names in HttpHeaderNames were removed, although it is very unlikely to be used by users: #1660
  • Keep-Alive
  • Proxy-Connection
  • Content-Transfer-Encoding

Dependencies

  • java-jwt 3.7.0 -> 3.8.0
  • Guava 27.0.1 -> 27.1
  • Netty 4.1.33 -> 4.1.34
    • Netty TCNative BoringSSL 2.0.20 -> 2.0.22
  • Brave 5.6.1 -> 5.6.3
armeria -

Published by minwoox over 5 years ago

New features

  • A user now can generate cache-control header value programmatically. #1615
    HttpHeaders headers = HttpHeaders.of();
    HttpFileBuilder fileBuilder = HttpFileBuilder.of(...);
    HttpFileServiceBuilder fileServiceBuilder = HttpFileServiceBuilder.forFileSystem(...);
    
    // Before:
    headers.set(HttpHeaderNames.CACHE_CONTROL, "no-cache, no-store, must-revalidate"));
    fileBuilder.setHeader(HttpHeaderNames.CACHE_CONTROL,
                          "max-age=86400, no-cache, must-revalidate");
    fileServiceBuilder.setHeader(HttpHeaderNames.CACHE_CONTROL, "public, max-age=3600");
    
    // After:
    headers.setObject(HttpHeaderNames.CACHE_CONTROL, ServerCacheControl.DISABLED);
    fileBuilder.cacheControl(new ServerCacheControlBuilder()
                                     .maxAgeSeconds(86400)
                                     .noCache()
                                     .mustRevalidate()
                                     .build());
    fileServiceBuilder.cacheControl(new ServerCacheControlBuilder()
                                            .cachePublic()
                                            .maxAgeSeconds(3600)
                                            .build());
    
  • Armeria supports gRPC Server Reflection. #1623
    ServerBuilder sb = new ServerBuilder();
    sb.service(new GrpcServiceBuilder().addService(new MyHelloService())
                                       .addService(ProtoReflectionService.newInstance())
                                       .build());
    
  • Added StreamMessage.drailAll(...) to simply collect all the elements from the StreamMessage. #1620
    HttpResponse res = HttpResponse.of(HttpHeaders.of(HttpStatus.OK)
                                                  .contentType(PLAIN_TEXT_UTF_8),
                                       HttpData.ofUtf8("bob"),
                                       HttpHeaders.of(CONTENT_MD5, "hash"));
    // Simply collect all the elements.
    List<HttpObject> drained = res.drainAll().join();
    assertThat(drained).containsExactly(
            HttpHeaders.of(HttpStatus.OK)
                       .contentType(PLAIN_TEXT_UTF_8),
            HttpData.of(StandardCharsets.UTF_8, "bob"),
            HttpHeaders.of(CONTENT_MD5, "hash"));
    
  • A user is able to see the HTTP trailers in a RequestLog. #1614

Improvements

  • Added more logging to SamlService to inform the reasons of the failure. #1629
  • Various documentation updates. #1604, #1607, #1610, #1611, #1613, #1618, #1626, #1627, #1628

Bug fixes

  • Fixed a bug where HTTP trailers is added to message headers. #1620
  • Fixed a bug where the TLS handshake exception pollutes the log message. #1612
  • Fixed a bug where Server-Sent Events messages miss the end-of-line character. #1610
  • Fixed an API design flaw where a user cannot specify more than one decorator when adding a ServiceWithPathMappings. #1627
  • Fixed a bug where contentPreview is not working correctly. #1624
  • Fixed a bug where a StackOverFlowError is raised while finding annotations in AnnotationUtil. #1635
  • Fixed a bug where the Armeria actuator sends the response with the incorrect media type. #1641

Breaking Change

  • The HttpHeaders is added to get() in HttpVfs as a parameter. #1615
    • A user can easily add the HttpHeaders when building an HttpFile.

Dependencies

  • Caffeine 2.6.2 -> 2.7.0
  • Curator 4.1.0 -> 4.2.0
  • gRPC 1.18.0 -> 1.19.0
  • Hibernate Validator 6.0.14 -> 6.0.15
  • Jetty 9.4.14 -> 9.4.15
  • protobuf-java 3.5.1 -> 3.6.1
  • RxJava 2.2.6 -> 2.2.7
  • SLF4J 1.7.25 -> 1.7.26
  • Spring Boot 2.1.2 -> 2.1.3
Package Rankings
Top 5.13% on Repo1.maven.org
Related Projects