All Versions
19
Latest Version
Avg Release Cycle
12 days
Latest Release
150 days ago

Changelog History
Page 1

  • v0.98.7

    March 17, 2020

    🍱 💮 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

    • 🛠 Fixed a bug where an exception is not wrapped by UnprocessedRequestException in a certain case. #2594

    🍱 🙇 Thank you

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

  • v0.98.6

    March 16, 2020

    🍱 💮 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

    • ➕ Added TextFormatter.socketAddress() and inetAddress() that convert a SocketAddress or an InetAddress into a String without repeating an IP address twice. #2591

    📈 Improvements

    • RequestContext.toString() now returns a String that includes its RequestId. #2591

    🛠️ Bug fixes

    • 🛠 Fixed a bug where a client-side response is not closed quickly enough for a certain case. #2590
    • 🛠 Fixed a bug where Sampler.random(0.01) never samples. #2592
    • 🌲 The Logger returned by RequestContext.makeContextAware(Logger) now pushes the context whenever logging a message, so that RequestContextExporter can retrieve the current context. #2587

    🍱 🙇 Thank you

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

  • v0.98.5

    March 14, 2020

    🍱 💮 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 use UUID as a parameter in your annotated service. #2573 #2577

      public class MyAnnotatedService { @Get("/user/by-uuid/{uuid}") public User findUserByUuid(@Param UUID uuid) { ... } }

    • 🌲 LogLevel.OFF and LogLevel.log(Logger, String, Object...) have been added. #2532

    📈 Improvements

    • ClosedSessionException and ClosedStreamException now have a specific cause or message to help you understand why a connection or a stream has been closed. #2580
    • ⚠ A once-per-thread warning message will now be logged, as well as throwing an exception, when a user pushes a context incorrectly. #2583
    • 0️⃣ Some common socket exceptions raised by annotated services are not logged anymore by default to reduce the amount of less useful log messages. #2572

    🛠️ Bug fixes

    • ConcurrencyLimitingClient does not fail with an 'illegal context' error under load anymore. #2579
    • RetryingClient and RetryingRpcClient handles negative System.nanoTime() values correctly now. #2584
    • 🛠 Fixed a bug where RetryingClient and RetryingRpcClient do not complete a request when RetryStrategy or RetryStrategyWithContent throws an exception. #2581
    • EventLoopCheckingFuture and its subtypes do not warn about blocking operation anymore when they are done already. #2564

    🍱 ⛓ Dependencies

    • ⬇️ Dropwizard Metrics 4.1.4 → 4.1.5
    • gRPC 1.27.2 → 1.28.0
    • Netty 4.1.46 → 4.1.47
    • RxJava 2.2.18 → 2.2.19

    🍱 🙇 Thank you

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

  • v0.98.4

    March 06, 2020

    🍱 💮 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

    • HealthCheckService does not leak the event loop tasks it scheduled anymore. #2557
    • ServiceRequestContext.setRequestTimeout() and ClientRequestContext.setResponseTimeout() now schedules a timeout correctly even if no timeout was scheduled before. #2537
    • Made sure Subscriber.onError() is invoked rather than onComplete() when a StreamMessage has been aborted. #2539
    • 🛠 Fixed specification violations in our Reactive Streams Subscriber implementations. #2533

    🍱 ⛓ Dependencies

    • ⬇️ Dropwizard 1.3.19 → 1.3.20
    • ⬇️ Dropwizard Metrics 4.1.3 → 4.1.4
    • gRPC 1.27.1 → 1.27.2
    • Jackson 2.10.2.20200130 → 2.10.3
    • Netty 4.1.45 → 4.1.46
      • netty-tcnative-boringssl-static 2.0.28 → 2.0.29
    • Jetty 9.4.26 → 9.4.27
    • Project Reactor 3.3.2 → 3.3.3
    • Retrofit 2.7.1 → 2.7.2

    🍱 🙇 Thank you

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

  • v0.98.3

    February 25, 2020

    🍱 💮 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

    • RequestContextExporter and RequestContextExportingAppender for Logback can now export the current request ID into MDC. #2511

      <?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} %X{req.id} %msg%n</pattern> </encoder> </appender> <appender name="RCEA" class="com.linecorp.armeria.common.logback.RequestContextExportingAppender"> <appender-ref ref="CONSOLE" /> <export>req.id</export> </appender> </configuration>

    • Client-side options API (ClientOption and ClientFactoryOption) has been revamped. #2523

      • ClientOptions.get() and ClientFactoryOptions.get() never throws an exception. A default value is returned for an unspecified option. Therefore, other getter methods such as getOrElse() have been removed.

    📈 Improvements

    • You'll now get a ClosedStreamException instead of Http2Exception when your HTTP/2 connection was closed due to an RST_STREAM frame. #2508

    🛠️ Bug fixes

    • *ClientBuilder.options(ClientOptions) now overrides only the specified options. #2516

      ClientFactory factory = ClientFactory.insecure();ClientOptions options = ClientOptions.builder() .responseTimeMillis(5000) .build();WebClient client = WebClient.builder("http://foo.com") .factory(factory) .options(options) .build();// This assertion does not fail anymore.assert client.options().factory() == ClientFactory.insecure();

    • 🛠 Fixed a bug where DocService throws the java.lang.IllegalStateException: zip file closed exception while starting up. #2518 #2519

    • MetricCollectingClient does not count the request that failed initially due to a connection refused error and then succeeded after a retry as failure anymore. #2517

    • 🛠 Fixed a bug where LoggingClient and LoggingSerivce does not push the current context when logging. #2528

    • RequestContextExporter and RequestContextExportingAppender can now export a single custom attribute into multiple MDC properties. #2521

    • RequestContextExporter and RequestContextExportingAppender does not export outdated custom attributes anymore. #2520

    • 📇 Renamed incorrect meter ID armeria.server.pendingResponses into armeria.server.pending.responses. #2506

    • The Date header is now encoded properly even when System.nanoTime() returns a negative value. #2530

    • GrpcStatus.fromThrowable() now treats ContentTooLargeException as RESOURCE_EXHAUSTED rather than INTERNAL_ERROR. #2523

    🍱 ☢️ Breaking changes

    • 🚚 ClientOptions.getOrElse() and getOrNull() have been removed. get() always returns a non-null value now. #2523
    • ClientOptions.asMap() and ClientFactoryOptions.asMap() now return only the options overridden by a user. You can get the Set of available options using ClientOptions.allOptions() or ClientFactoryOptions.allOptions(): #2516 #2523

      ClientOptions myOptions = ...;Map<ClientOption<?>, Object> map = new IdentityHashMap<>();for (ClientOption o : ClientOptions.allOptions()) { map.put(myOptions.get(o)); }

    • ClientOptions.valueOf() and ClientFactoryOptions.valueOf() have been split into two methods: define() and of() #2523.

      • Use of() if you're getting an existing option.
      • Use define() if you're defining a new option.
    • 🚀 You might need to adjust your monitoring system if you were watching armeria.server.pendingResponses, which has been renamed to armeria.server.pending.responses in this release. #2506

    🍱 ⛓ Dependencies

    • ⬇️ Dropwizard 1.3.18 → 1.3.19
    • ⬇️ Dropwizard Metrics 4.1.2 → 4.1.3
    • java-jwt 3.9.0 → 3.10.0
    • RxJava 2.2.17 → 2.2.18
    • Shaded dependencies
      • Reflections 0.9.12 → 0.9.11 (Downgrade)

    🍱 🙇 Thank you

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

  • v0.98.2

    February 18, 2020

    🍱 💮 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 specify any client options when building with ArmeriaRetrofitBuilder, because it extends AbstractClientOptionsBuilder. #2483

      Retrofit retrofit = ArmeriaRetrofit.builder("http://example.com") .factory(...) .decorator(...) .responseTimeout(...) .build();

    📈 Improvements

    • FallthroughException is not a part of the internal API anymore, so you can refer to it when testing your annotation service extensions. #2495

    🛠️ Bug fixes

    • Armeria clients will not violate the MAX_CONCURRENT_STREAMS setting enforced by an HTTP/2 server anymore. #2256 #2374
    • 🛠 Fixed a regression where Server fails to read PKCS#5 a private key since 0.98.0 #2485
    • RequestContextExporter does not export an entry whose value is null anymore. #2492
    • 📄 DocService does not fail with a ReflectionsException on startup anymore. #2491 #2494
    • 🛠 Fixed some potential buffer leaks. #2497 #2498 #2499 #2500

    🍱 ⛓ Dependencies

    • Brave 5.9.4 → 5.9.5
    • gRPC 1.27.0 → 1.27.1
      • Protobuf 3.11.3 → 3.11.4
    • Micrometer 1.3.3 → 1.3.5
    • Tomcat 9.0.30 → 9.0.31, 8.5.50 → 8.5.51
    • ZooKeeper 3.5.6 → 3.5.7
    • Shaded dependencies:
      • fastutil 8.3.0 → 8.3.1

    🍱 🙇 Thank you

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

  • v0.98.1

    February 10, 2020
  • v0.98.0

    February 08, 2020
  • v0.97.0

    December 06, 2019
  • v0.96.0

    November 23, 2019

    🍱 💮 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

    • 👀 The type signature of clients and services has been greatly simplified. Note that this involves various breaking changes unfortunately. See the 'Breaking changes' section for the details. #2239 #2254

      // Before:public class FooHttpService implements Service<HttpRequest, HttpResponse> { ... }public class FooRpcService implements Service<RpcRequest, RpcResponse> { ... }public class FooHttpClient implements Client<HttpRequest, HttpResponse> { ... }public class FooRpcClient implements Client<RpcRequest, RpcResponse> { ... }Service<HttpRequest, HttpResponse> foo(Service<HttpRequest, HttpResponse> bar) { ... }Function<Service<HttpRequest, HttpResponse>, ? extends Service<HttpRequest, HttpResponse>> httpServiceDecorator;Function<Service<RpcRequest, RpcResponse>, ? extends Service<RpcRequest, RpcResponse>> rpcServiceDecorator;Function<Client<HttpRequest, HttpResponse>, ? extends Client<HttpRequest, HttpResponse>> httpClientDecorator;Function<Client<RpcRequest, RpcResponse>, ? extends Client<RpcRequest, RpcResponse>> rpcClientDecorator;// After:public class FooHttpService implements HttpService { ... }public class FooRpcService implements RpcService { ... }public class FooHttpClient implements HttpClient { ... }public class FooRpcClient implements RpcClient { ... }HttpService foo(HttpService bar) { ... }Function<? super HttpService, ? extends HttpService> httpServiceDecorator;Function<? super RpcService, ? extends RpcService> rpcServiceDecorator;Function<? super HttpClient, ? extends HttpClient> httpClientDecorator;Function<? super RpcClient, ? extends RpcClient> rpcClientDecorator;

    • You can now specify service-level settings for annotated services, just like other service types. #2180 #2222

      Server server =Server.builder() .annotatedService().pathPrefix("/api") .requestTimeoutMillis(5000) .exceptionHandler((ctx, req, cause) -> ...) .build(new Object() { ... })) .build();

    • 0️⃣ RequestContext now has its own RequestId, which is a 64-bit random integer by default. #2001 #2174 #2203 #2224

      Server server =Server.builder() .service("/", (ctx, req) -> { return HttpResponse.of("Request ID: %s", ctx.id().text()); }) .build();

    • You can now add a cause to an HttpStatusException. #2253

      HttpService service = (ctx, req) -> { try (FileInputStream in = new FileInputStream(...)) { ... } catch (FileNotFoundException e) { throw HttpStatusException.of(HttpStatus.NOT_FOUND, e); } };

    • Armeria server now always has a fallback service which is matched when no routes match a request. #1625 #2255

      • As a result, a route decorator bound at prefix:/ can intercept any requests, even the requests not handled by any services:

      // CorsService will intercept any requests,// even the ones not handled by any services.Server server =Server.builder() .service("/foo", fooService) .service("/bar", barService) .routeDecorator().pathPrefix("/") .build(CorsService.newDecorator(...)) .build();

    • 🌲 You can now determine the log level of LoggingClient and LoggingService dynamically. #2250 #2258

      LoggingClient.builder() .requestLogLevel(log -> ...) .responseLogLevel(log -> { if (log.responseCause() == null || log.responseCause() instanceof HarmlessException) { return LogLevel.INFO; } else { return LogLevel.WARN; } });

    • ClientFactoryOptions has been added to allow programmatic access to the ClientFactory settings. #2230

      ClientFactory factory = ...;boolean pipelining = factory.options().useHttp1Pipelining();

    • 0️⃣ You can now disable Armeria's Netty-based asynchronous DNS resolver by specifying -Dcom.linecorp.armeria.useJdkDnsResolver=true JVM option. Use it only when the default resolver does not work. #2261

    🍱 💪 Improvements

    • Armeria client does not block a request anymore when DNS resolution takes long time. #2017 #2217 #2231
    • You do not have to prepend none+ prefix to non-RPC URIs anymore. #2219 #2241

      // Before:Clients.of("none+https://...", ...);// After:Clients.of("https://...", ...);

      • The behavior of Scheme.parse() and tryParse() has been improved in the same manner:

      // Scheme.parse() now uses SerializationFormat.NONE automatically:assert Scheme.parse("http") == Scheme.parse("none+http");

    🛠️ Bug fixes

    • 🔧 Armeria Spring auto-configuration now works correctly even when only GrpcServiceRegistrationBeans are given. #2234
    • RequestContext is not pushed more often than necessary anymore when notifying RequestLogListeners. #2227
    • DynamicEndpointGroup now handles the case where an endpoint address does not change but only a weight. #2240
    • 👀 HttpStatusException now respects Flags.verboseExceptionSampler(). #2253
    • AccessLogWriter does not fail with a ClassCastException anymore. #2259
    • 🛠 Fixed a bug where a service receives an OPTIONS request even if the service did not opt-in for OPTIONS method. #2263

    🍱 🏚️ Deprecations

    • 🗄 ClientFactory.DEFAULT has been deprecated in favor of ClientFactory.ofDefault().
    • 🗄 The getters for host-level settings in ServerConfig have been deprecated. #2244 #2246

      // Before:HttpService service = (ctx, req) -> { return HttpResponse.of("maxRequestLength: %d", ctx.server().maxRequestLength()); };// After:HttpService service = (ctx, req) -> { return HttpResponse.of("maxRequestLength: %d", ctx.virtualHost().maxRequestLength()); };

    • 🏗 Continuing the migration to static builder() factory methods, the following classes have switched from constructors to static builder() methods: #2221

      • ClientCacheControl
      • ClientConnectionTimings
      • ClientDecoration
      • ClientFactory
      • ClientOptions
      • ClientRequestContext
      • EndpointInfo
      • FieldInfo
      • HttpClient
      • LoggingClient
      • LoggingService
      • RequestContextCurrentTraceContext
      • RetrofitMeterIdPrefixFunction
      • ServerCacheControl
      • ServiceRequestContext

    🍱 ☢️ Breaking changes

    • The signatures of RequestContext.newDerivedContext() have been changed so they always require RequestId, HttpRequest and RpcRequest for less ambiguity. #2209 #2224
    • 📜 Scheme.parse() and tryParse() do not fail anymore even if the scheme does not start with none+: #2219 #2241

      // Scheme.parse() now uses SerializationFormat.NONE automatically:assert Scheme.parse("http") == Scheme.parse("none+http");

    • ClientBuilderParams.uri() does not return a URI with none+ prefix anymore. #2219 #2241

    • HttpClient interface has been renamed to WebClient. HttpClient is now a different interface that extends Client<HttpRequest, HttpResponse>. #2254

      // Doesn't work:HttpClient client = HttpClient.of("https://www.google.com/");// Good:WebClient client = WebClient.of("https://www.google.com/");

    • Services must implement HttpService or RpcService and clients must implement HttpClient or RpcClient: #2239 #2254

      // Before:public class FooHttpService implements Service<HttpRequest, HttpResponse> { ... }public class FooRpcService implements Service<RpcRequest, RpcResponse> { ... }public class FooHttpClient implements Client<HttpRequest, HttpResponse> { ... }public class FooRpcClient implements Client<RpcRequest, RpcResponse> { ... }// After:public class FooHttpService implements HttpService { ... }public class FooRpcService implements RpcService { ... }public class FooHttpClient implements HttpClient { ... }public class FooRpcClient implements RpcClient { ... }

      • You'll have to change any Service<...> and Client<...> usages in your code into HttpService, RpcService, HttpClient or RpcClient, unless you intended to express both HTTP- and RPC- level types.

      // Before:Service<HttpRequest, HttpResponse> foo(Service<HttpRequest, HttpResponse> bar) { ... }// After:HttpService foo(HttpService bar) { ... }

      • Similarly, you must use SimpleDecoratingHttpClient or SimpleDecoratingRpcClient instead of SimpleDecoratingClient, and SimpleDecoratingHttpService or SimpleDecoratingRpcService instead of SimpleDecoratingService.

      // Does not work:class MyDecoratorService extends SimpleDecoratingService<HttpRequest, HttpResponse> { MyDecoratorService(Service<HttpRequest, HttpResponse> delegate) { super(delegate); } ...}// Good:class MyDecoratorService extends SimpleDecoratingHttpService { // Note the constructor parameter change.MyDecoratorService(HttpService delegate) { super(delegate); } ...}

      • If you implemented your decorator without extending the SimpleDecorating{Http,Rpc}Service or SimpleDecorating{Http,Rpc}Client, then you must make sure that it implements HttpService, RpcRequest, HttpClient or RpcClient.

      // Does not work:class MyDecoratorService implements Service<HttpRequest, HttpResponse> { final Service<HttpRequest, HttpResponse> delegate; MyDecoratorService(Service<HttpRequest, HttpResponse> delegate) { this.delegate = delegate; } ...}// Good:class MyDecoratorService implements HttpService { // Note the type change.final HttpService delegate; // Note the constructor parameter change.MyDecoratorService(HttpService delegate) { this.delegate = delegate; } ...}

    • Service.decorate() has been pushed down to HttpService and RpcService: #2239 #2254

      // Does not work:Service<HttpRequest, HttpResponse> service = (ctx, req) -> ...; service.decorate(myDecorator); // No such method// Good:HttpService service (ctx, req) -> ...; service.decorate(myDecorator); // OK!

    • The type parameters of decorator Functions have been changed. #2239 #2254

      // Before:Function<Service<HttpRequest, HttpResponse>, ? extends Service<HttpRequest, HttpResponse>> httpServiceDecorator;Function<Service<RpcRequest, RpcResponse>, ? extends Service<RpcRequest, RpcResponse>> rpcServiceDecorator;Function<Client<HttpRequest, HttpResponse>, ? extends Client<HttpRequest, HttpResponse>> httpClientDecorator;Function<Client<RpcRequest, RpcResponse>, ? extends Client<RpcRequest, RpcResponse>> rpcClientDecorator;// After:Function<? super HttpService, ? extends HttpService> httpServiceDecorator;Function<? super RpcService, ? extends RpcService> rpcServiceDecorator;Function<? super HttpClient, ? extends HttpClient> httpClientDecorator;Function<? super RpcClient, ? extends RpcClient> rpcClientDecorator;

    • Some types, which could be used at both HTTP- and RPC- level, have been split into two different types. For example:

      • DecoratingClientFunction has been split into DecoratingHttpClientFunction and DecoratingRpcClientFunction.
      • DecoratingServiceFunction has been split into DecoratingHttpServiceFunction and DecoratingRpcServiceFunction.
      • LoggingClient has been split into LoggingClient and LoggingRpcClient.
      • ServiceWithRoutes has been split into HttpServiceWithRoutes and RpcServiceWithRoutes.
      • TransientService has been split into TransientHttpService and TransientRpcService.
    • The following services are now provided only at HTTP-level. Please let us know if you need an RPC-level version of them.

      • LoggingService
      • MetricCollectingService
      • StructuredLoggingService
      • KafkaStructuredLoggingService

    🍱 ⛓ Dependencies

    • Brave 5.8.0 -> 5.9.0
    • gRPC 1.24.1 -> 1.25.0
    • Jackson 2.10.0 -> 2.10.1
    • Micrometer 1.3.0 -> 1.3.1
    • Netty TCNative BoringSSL 2.0.26 -> 2.0.27
    • Protobuf 3.9.1 -> 3.10.0
    • RxJava 2.2.13 -> 2.2.14
    • SLF4J 1.7.28 -> 1.7.29
    • Spring Boot 2.1.9 -> 2.1.10

    🍱 🙇 Thank you

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