0.87.0 release notes

13th June 2019

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