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 visible (Hide)

armeria -

Published by trustin over 7 years ago

New features

  • (Breaking) #553 Give up trying to be protocol-agnostic and go HTTP-only
    • It is now statically required to add a Service<? super HttpRequest, ? extends HttpResponse> when adding a Service to a ServerBuilder or a VirtualHostBuilder. We do not accept Service<?, ?> anymore.

    • Using a method reference to the one-arg constructor of a decorator service may not work anymore because of Java compiler's type inference failure. For example, you need to use LoggingService.newDecorator() instead of LoggingService::new.

    • The type of RequestContext.method() and RequestLog.method() were changed from String to HttpMethod.

    • RequestContext.path() and RequestLog.path() have been split into path() and query().

    • RequestContext.fragment() and RequestLog.fragment() are now nullable.

    • Revamped PathMapping to support path variables. You can now do the following:

      ServerBuilder sb = ...;
      sb.serviceAt("/hello/:name", new AbstractHttpService() {
          @Override
          protected void doGet(ServiceRequestContext ctx, HttpRequest req, HttpResponseWriter res) {
              final String name = ctx.pathParam("name");
              res.respond(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, "Hello, %s!", name);
          }
      });
      
      sb.service(PathMapping.ofRegex("^/files/(?<filePath>.*)$"), new AbstractHttpService() {
          @Override
          protected void doGet(ServiceRequestContext ctx, HttpRequest req, HttpResponseWriter res) {
              final String filePath = ctx.pathParam("filePath");
              // ... Serve the file ...
          }
      });
      

Improvements

  • #567 Inject AggregatedHttpMessage into a DynamicHttpFunction method automatically.

  • #567 Handle a DynamicHttpFunction method whose return type is AggregatdHttpMessage.

    public class MyAnnotatedHttpService {
        @Post
        @Path("/upload")
        public AggregatedHttpMessage hello(AggregatedHttpMessage uploadRequest) {
            ...
        }
    }
    

Bug fixes

  • #565 CatchAllPathMapping.prefix() should return '/'.
  • #571 #572 The CompletableFuture returned by HttpRequest/Response.aggregate() will not complete forever if the stream is aborted, mostly due to timeout.
  • #574 armeria-retrofit2 should respect the encoded annotation parameter.
armeria -

Published by trustin over 7 years ago

New features

  • #494 Spring Boot integration. The following new modules were added:
    • armeria-spring-boot
    • armeria-spring-boot-autoconfigure
    • armeria-spring-boot-starter
  • #518 #561 Revamp armeria-retrofit2 for cleaner API and @Url annotation support
  • #525 #557 Add Prometheus metric collecting decorators and PrometheusExporterHttpService
  • #544 #560 Add gRPC-JSON support
  • #549 Add DocService debug form support for unframed gRPC-JSON
  • #552 Inject ServiceRequest into a DynamicHttpService method automatically
  • #559 Add metric support for gRPC clients

Improvements

  • (Breaking) #525 Move Dropwizard metric collecting decorators from logging package to metric package for consistency
  • #539 #541 #545 Various gRPC improvements

Bug fixes

  • #556 DynamicHttpService does not allow binding a path without a path variable.
armeria -

Published by trustin over 7 years ago

New features

  • #527 Add ServerBuilder.maxNumConnections() which allows a user to limit the number of open connections of a Server.

Improvements

  • #536 Update Netty to 4.1.11

Bug fixes

  • #520 #527 Remove ServerBuilder.maxPendingRequests() which was never implemented
  • #535 Fix Netty buffer leaks in GRPC
  • #536 Fix NPE when resolving a hostname
armeria -

Published by trustin over 7 years ago

New features

  • #505 Add GRPC client support
  • #512 Add structured logging support for GRPC
  • #522 Add grpc-web draft support
  • #528 Add a variant of StreamMessage.subscribe(...) which yields reduced memory copies

Improvements

  • #514 #516 Allow negative jitter range in Backoff.withJitter()
  • #519 Update the dependencies - most notably:
    • Brave 4.0.6 -> 4.2.0
    • GRPC 1.2.0 -> 1.3.0
    • Netty 4.1.9 -> 4.1.10

Bug fixes

  • #513 #516 Off-by-one validation error in RandomBackoff
  • #526 #528 #533 Netty buffer leaks
  • #532 Client-side SNI does not work.
armeria -

Published by trustin over 7 years ago

New features

  • #499 Unframed GRPC support

  • #504 Allow adding a listener to any EndpointGroup implementations

    • Add Listeneable and AbstractListenable as a common utility
  • #507 More convenient deferred construction of RpcResponse and HttpResponse

    • Before:

      // RpcResponse
      DefaultRpcResponse res = new DefaultRpcResponse();
      CompletableFuture<Object> future = doAsync();
      future.whenComplete((value, cause) -> {
          if (cause != null) {
              res.completeExceptionally(cause);
          } else {
              res.complete(value);
          }
      });
      return res;
      
      // HttpResponse
      DeferredHttpResponse res = new DeferredHttpResponse();
      CompletableFuture<HttpResponse> future = doAsync();
      future.whenComplete((actualRes, cause) -> {
          if (cause != null) {
              res.close(cause);
          } else {
              res.delegate(actualRes);
          }
      });
      return res;
      
    • After:

      // RpcResponse
      return RpcResponse.from(doAsync());
      
      // HttpResponse
      return HttpResponse.from(doAsync());
      
  • #507 Add RpcResponse.join() and RpcResponse.getNow()

  • #507 Add Exceptions.throwUnsafely()

Improvements

  • #476 Reduce the number of memory copies in THttpService
  • #495 Update GRPC to 1.2.0
  • #509 Support Boolean type in DynamicHttpService

Bug fixes

  • #492 Health check metric is not always correct.
  • #496 NullPointerException when aggregating an HTTP message with a trailing header
  • #503 AssertionError in ThriftDocServicePlugin.toTypeSignature()
  • #504 OrElseEndpointGroup does not handle dynamic endpoint changes correctly

Known issues

  • This release depends on Netty 4.1.9, which has a bug related with domain name resolution. If you are in an IPv4 environment, specify the -Djava.net.preferIPv4Stack=true option to work around it. We will release a new version that depends on the Netty version with the fixes once it's available.
armeria -

Published by trustin over 7 years ago

New features

  • #421 #424 Add PathParamExtractor which extracts parameters from a URI path.

    PathParamExtractor e = new PathParamExtractor("/users/{userId}");
    assert e.extract("/users/lespinside").get("userId").equals("lespinside");
    
  • (Potentially breaking) #461 #483 Support Tomcat 8.5

    • armeria-tomcat will support the latest stable Tomcat release.
    • Use armeria-tomcat8.0 to use Tomcat 8.0.

Improvements

  • #475 Reimplement or copy the internal implementations from GRPC
  • (Potentially breaking) #486 Update the dependencies
    • Dropwizard Metrics 3.2.2
    • Kafka 0.10.2.0
    • Netty 4.1.9
    • Retrofit 2.2.0

Bug fixes

  • #472 Fix a missing return in armeria.js for DocService
  • #473 #474 Allow 'charset=utf-8' parameter in 'content-type' and 'accept' headers of Thrift requests
  • #487 Fix AssertionError due to broken RequestLogAvailabilitySet.of(int flags) implementation

Known issues

  • This release depends on Netty 4.1.9, which has a bug related with domain name resolution. If you are in an IPv4 environment, specify the -Djava.net.preferIPv4Stack=true option to work around it. We will release a new version that depends on the Netty version with the fixes once it's available.
armeria -

Published by trustin over 7 years ago

New features

  • #455 #465 Add RequestContext.onChild() which adds a callback that is invoked when a child context replaces the current context

    • This is useful especially when you want to inherit an attribute of the current context to its children:

      AttributeKey<UserInfo> CURRENT_USER = ...;
      RequestContext ctx = ...;
      ctx.onChild((curCtx, newCtx) -> {
          newCtx.attr(CURRENT_USER).set(curCtx.attr(CURRENT_USER).get());
      });
      
  • #460 Add DynamicEndpointGroup which notifies its listeners when its list of Endpoints changes

    • HealthCheckedEndpointGroup and ZooKeeperEndpointGroup extends DynamicEndpointGroup.
  • #471 Provide more simpler ways to write a decorating client/server

    • Add DecoratingClientFunction which is similar to DecoratingServiceFunction:

      ServerBuilder sb = new ServerBuilder();
      sb.serviceUnder("/my_service",
                      new MyService().decorate((delegate, ctx, req) -> {
                          // Intercept an incoming request here.
                          return delegate.serve(ctx, req);
                      });
      
      ClientBuilder cb = new ClientBuilder(...);
      cb.decorator(HttpRequest.class, HttpResponse.class,
                   (delegate, ctx, req) -> {
                       // Intercept an outgoing request here.
                       return delegate.execute(ctx, req);
                   });
      
    • Add SimpleDecoratingService and SimpleDecoratingClient, which is similar to DecoratingService and DecoratingClient but with fewer number of type parameters:

      public class MyDecoratingService extends SimpleDecoratingService<RpcRequest, RpcResponse> { ... }
      public class MyDecoratingClient extends SimpleDecoratingClient<RpcRequest, RpcResponse> { ... }
      

Improvements

  • (Potentially breaking) #457 Cancel context-aware callbacks automatically if the context has been timed out already

Bug fixes

  • #458 #464 Choose correct SerializationFormat when content-type is application/x-thrift without the protocol parameter
  • #462 #463 NullPointerException at ServiceRequestContext.toString()
  • #466 Handle FilteredHttpResponse completion callbacks correctly in the case of no encoding
armeria -

Published by trustin over 7 years ago

New features

  • #423 Add service documentation support for GRPC to DocService
    • See here to learn how to show the docstrings of your .proto file with DocService.
  • #423 Add an HTTP content decoding client decorator - HttpDecodingClient
  • #446 Add MediaTypeSet which provides the methods useful for HTTP content negotiation
    • SerializationFormat.mediaTypes() now returns MediaTypeSet instead of Set<MediaType>. It should be OK because MediaTypeSet implements Set<MediaType>.
  • #449 Add an option to enable or disable HTTP/1 pipelining - SessionOption.USE_HTTP1_PIPELINING
    • HTTP/1 pipelining is enabled by default. To turn it off:
      • Add the -Dcom.linecorp.armeria.defaultUseHttp1Pipelining=false option to JVM or
      • Set the SessionOption.USE_HTTP1_PIPELINING option to false when creating an AllInOneClientFactory.

Improvements

  • #448 Add more sanity checks for Thrift replies to THttpClient
    • All Thrift clients now reject the Thrift reply with mismatching sequence ID.

Bug fixes

  • #443 #446 THttpService does not handle HTTP accept header correctly.
  • #447 RequestLog.statusCode() is not set on server-side timeout.
  • #449 Fix various issues with client-side HTTP/1 connection management and protocol encoding
armeria -

Published by trustin over 7 years ago

New features

  • #357 Automatic service registration and discovery via ZooKeeper
  • #364 Add RetryingClient and RetryingRpcClient which are decorating clients that retry the requests with flexible retry policy such as exponential back-off with jitters.
  • (Breaking) #422 Revamp DocService for better extensibility
    • Use DocServiceBuilder instead of the DocService constructor to specify the example HTTP headers and requests.
  • (Breaking) #422 Bring back the example request support to DocService
    • Use DocServiceBuilder.exampleRequest(...). e.g. builder.exampleRequest(new HelloService.hello_args("foo"));
  • (Breaking) #441 Support both Thrift 0.10.0 and Thrift 0.9.3
    • armeria-thrift and armeria-thrift-shaded now depend on libthrift 0.10.0.
    • Use armeria-thrift0.9 or armeria-thrift0.9-shaded to use libthrift 0.9.3.

Improvements

  • #397 #415 Update GRPC to 1.1.2
  • #426 Relax the case-sensitivess constraints of HttpHeaders for better user experience
    • HttpHeaders now performs case-insensitive comparisons for header names.
    • HttpHeaders now accepts the header names with upper-case alphabets and silently lower-cases them.
  • #435 #438 Allow the lazy instantiation of Jetty SessionIdManager

Bug fixes

  • #104 #419 Do not ship the custom version of Apache Thrift IDL compiler
  • #425 RequestContextAwareEventLoop.next() must return itself, not its delegate.
  • #434 Fix intermittent UnsupportedOperationException when HttpMessage.aggregate() fails
armeria -

Published by trustin over 7 years ago

Breaking changes

  • #414 Change the type of the example HTTP headers map of DocService from Map<Class<?>, Iterable<HttpHeaders>> to Map<String, Iterable<HttpHeaders>> because not all RPC protocols use a class name as a service identifier

Improvements

  • #367 #411 Update the dependencies, most notably Brave 4.0.6, Jetty 9.4.1, Kafka 0.10.1.0, Logback 1.2.1 and Netty 4.1.8

Bug fixes

  • #410 #412 TomcatService throws a NullPointerException when a POST request contains an empty body.
  • #413 #417 DocService fails to handle typedef-ed types.
armeria -

Published by trustin over 7 years ago

Breaking changes

  • #395 #407 Hide Guava from the public API and provide the shaded and unshaded JARs

    • We do not expose the classes from Guava in our public API anymore. To list a few:
      • com.google.common.net.MediaType replaced with com.linecorp.armeria.common.MediaType
        • Run the 'replace in path...' command in your editor or IDE.
      • com.google.common.collect.Multimap replaced with java.util.Map<..., Collection<...>>
        • Convert a Multimap into a Map using Multimap.asMap().
    • The artifact ID of the shaded JARs all end with -shaded. For example:
      • armeria vs. armeria-shaded
      • armeria-thrift vs. armeria-thrift-shaded
    • We plan to shade more internal dependencies such as Netty in the near future. Please stay tuned.
  • #375 #408 Make HttpClient respect the path specified when creating it. For example:

    HttpClient hc = Clients.newClient("none+http://example.com/foo", HttpClient.class);
    HttpResponse res = hc.get("/bar"); // This will now send a request to /foo/bar, not /bar
    

    Note: If you were specifying a path when creating an HttpClient with an old Armeria, your code may stop to work because of this behavioral change. For example:

    HttpClient hc1 = Clients.newClient("none+https://api.github.com/zen", HttpClient.class);
    hc1.get("/zen"); // 404 - the request is sent to /zen/zen
    
    HttpClient hc2 = Clients.newClient("none+https://api.github.com/", HttpClient.class);
    hc2.get("/zen"); // 200 - the request is sent to /zen
    
armeria -

Published by trustin over 7 years ago

Breaking changes

  • #392 #398 #402 Move Thrift support from com.linecorp.armeria:armeria to com.linecorp.armeria:armeria-thrift
    • You need to add armeria-thrift to your dependencies if you are using Thrift.
    • The following types had tight coupling with Thrift, and thus had to be changed in a backward-incompatible way:
      • SessionProtocol and SerializationFormat are not enums anymore.
        • HTTP-related constants in SessionProtocol have been deprecated. Use HttpSessionProtocols.* instead.
        • Thrift-related constants in SerializationFormat have been deprecated. Use ThriftSerializationFormats.* instead.
      • The constructor signature of DocService has been changed.
        • You cannot specify the sample TBase requests anymore. We are going to add this feature back in less intrusive way in the future.
        • The type of sample HTTP headers is now Multimap<Class<?>, HttpHeaders>.
  • #388 Add protocol-agnostic request/response content to RequestLog
    • RequestLog.request/responseContent() returns RpcRequest and RpcResponse rather than ThriftCall and ThriftReply.
    • To get ThriftCall or ThriftReply, use RequestLog.rawRequest/ResponseLog().
    • RequestLogBuilder.request/responseContent(...) now requires 2 parameters - one for RpcRequest/Response and the other for ThriftCall/Reply.
  • #390 Make DynamicHttpService asynchronous
  • #393 Make authorization predicates asynchronous in HttpAuthService
  • (potentially breaking) #389 Update Guava to 0.21
    • You will have a problem if you depend on other 3rd party project that depends on Guava and it uses the Guava class or method that was removed in 0.21.
    • We will try to solve this issue in the next release.

Improvements

  • #355 Support application/vnd.apache.thrift.* media types in THttpService
  • #399 #401 Prefer Ascii.toLower/UpperCase/equalsIgnoreCase() to String.toLower/UpperCase/equalsIgnoreCase()

Bug fixes

  • #391 #406 Fix incorrect inter-module dependency scope in POM
  • #394 #405 Do not log Tomcat versions twice
armeria -

Published by trustin over 7 years ago

Improvements

  • #384 #385 Make RequestContext.makeContextAware(CompletableFuture) set the context even when alternative executor is specified

Bug fixes

  • #386 Fix NPE in ArmeriaCallFactory
armeria -

Published by trustin over 7 years ago

Improvements

  • #380 #382 #383 More strict EndpointGroup naming rule
    • An EndpointGroup name is now case-insensitive and must match /^[-_.0-9a-zA-Z]+$/

Bug fixes

  • #381 armeria-retrofit2 raises IllegalArgumentException when the URI scheme is h1, h1c, h2 or h2c.
armeria -

Published by trustin almost 8 years ago

Highlight: DynamicHttpService

It's much easier to build a non-RPC HTTP service now:

ServerBuilder builder = new ServerBuilder();

// Use annotations (like JAX-RS and Spring Web)
public class MyServiceA extends DynamicHttpService {
    @Get
    @Path("/int/{var}")
    public CompletionStage<Integer> returnInt(@PathParam("var") int var) {
        return CompletableFuture.supplyAsync(() -> var);
    }

    @Get
    @Path("/string/{var}")
    public String returnString(@PathParam("var") String var) {
        return var;
    }
}

builder.serviceUnder("/service/a", new MyServiceA());

// Use builder (like SparkJava)
builder.serviceUnder("/service/b", new DynamicHttpServiceBuilder()
        .addMapping(HttpMethod.GET, "/int/{var}",
                    (ctx, req, args) -> Integer.parseInt(args.get("var")))
        .addMapping(HttpMethod.GET, "/string/{var}",
                    (ctx, req, args) ->args.get("var"))
        .build());

For the complete example, please see HttpServiceTest.java.

Please note that this feature is experimental and thus it has some rough edges and its API may change (in a positive direction) in the future. If you have any feed back on the current API, please let us know!

New features

  • #321 Add DynamicHttpService which implements advanced request mapping
  • #365 #373 Add RequestContext.makeContextAware(CompletionStage) and makeContextAware(CompletableFuture)
  • #369 Add SampledLoggingService

Improvements

  • #368 #372 Update gRPC to 1.0.3

Bug fixes

  • #362 WeightedRoundRobinStrategy does not refresh min/max/sumWeight even if endpointGroup returns different endpoints.
  • #363 #371 Graceful shutdown does not respect quiet period correctly.
  • #376 #377 The raw okhttp3.Request object always has 0.0.0.0 authority when armeria-retrofit2 is used.
  • #378 Response is not completed when timeout is disabled dynamically.
armeria -

Published by trustin almost 8 years ago

Bug fix

  • #360 Fix NPE related with DeferredStreamMessage and DeferredHttpResponse
armeria -

Published by trustin almost 8 years ago

New features

  • #259 #328 HTTP authorization service
  • #348 #356 Make the number of boss I/O threads configurable.
    • See ServerBuilder.numBosses(int)
  • #358 Add ServerBuilder.serverListener(ServerListener)

Improvements

  • #354 Avoid making humongous object when armeria-retrofit2 handles a large response.
armeria -

Published by trustin almost 8 years ago

Features

  • #352 Easier instantiation of RpcRequest and RpcResponse
    • Add RpcRequest.of(), RpcResponse.of() andofFailure()` for easier instantiation

Bug fixes

  • #350 #352 Do not check null on RpcRequest parameters
  • #351 Deduplicate endpoint health metric by converting to MetricSet

Improvements

  • #349 Update gRPC to 1.0.2 and unignore the interoperability tests
armeria -

Published by trustin almost 8 years ago

Breaking changes

  • #343 Revamp RequestLog API
    • RequestLog and ResponseLog have been merged into RequestLog and rewritten.
    • RequestLogBuilder and ResponseLogBuilder have been merged into RequestLogBuilder and rewritten.
    • ThriftCall and ThriftReply have been replaced with DefaultRpcRequest and DefaultRpcResponse.
    • ApacheThriftCall and ApacheThriftReply have been renamed to ThriftCall and ThriftReply.

New features

  • #343 Revamp RequestLog API
    • A user has much finer control over when he or she is notified with a RequestLog.
    • See 'Structured logging` for more information.
  • #346 Add metrics for HttpHealthCheckedEndpointGroup
    • A user can check the health of each endpoint via Dropwizard MetricRegistry.
  • #347 Add ThriftCompletableFuture and ThriftListenableFuture
    • These classes will help you bridge AsyncMethodCallback and your favorite Future types.
armeria -

Published by trustin almost 8 years ago

Note: From this release on, the version string will not have the .Final suffix.

Breaking changes

  • #324 Rename UnitFormatter to TextFormatter
  • #342 Rename com.linecorp.armeria.client.routing to endpoint
  • #335 Replace MessageLog.start/endTimeNanos() with durationNanos()

New features

  • #320 #332 #337 Add ZooKeeper-based EndpointGroup implemenetation
  • #324 Add service log(structured request/response log) logging support with integration to Kafka
  • #333 Add HealthCheckedEndpointGroup to select the alive endpoint
  • #334 #336 Add EndpointGroup.orElse(EndpointGroup)
  • #335 Replace MessageLog.start/endTimeNanos() with durationNanos()

Bug fixes

  • #339 Fix to throw EndpointGroupException instead of ArithmeticException

Clean-up

  • #338 Upgrade to Gradle 3.2.1
  • #340 Remove SimpleHttpClient
  • #341 Shade the dependencies that are not exposed in public API
  • #342 Rename com.linecorp.armeria.client.routing to endpoint
Package Rankings
Top 5.13% on Repo1.maven.org
Related Projects