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 almost 7 years ago

Improvements

  • #937 Add RequestContext.newDerivedContext(Request)
  • #939 Less surprising evaluation order of converter/exception handler evaluation in annotated services

Bug fixes

  • #930 #931 Incorrect cookie header handling
  • #933 #936 NoSuchElementException in ZooKeeperUpdatingListener
  • #934 An invalid JSON document does not result in a '400 Bad Request' response but in a '500 Internal Server Error' response.

Dependencies

  • Caffeine 2.6.0 -> 2.6.1

Known issues

  • Netty 4.1.19.Final has a data corruption issue when epoll transport is used. Specify the following JVM option to disable epoll transport and work around this problem until Netty 4.1.20.Final is released:

    -Dcom.linecorp.armeria.useEpoll=false
    
armeria -

Published by trustin almost 7 years ago

New features

  • #866 #913 #915 @RequestConverter and @RequestObject annotation which enable request conversion for an annotated service
  • #870 #894 RequestContext.newDerivedContext() method which creates a new context with the same properties (except the request log) from an existing context
  • #895 HTTP Access logging
  • #900 RequestLog can now contain one or more child RequestLogs, which is useful for recording the retry history of a request. From this release, RetryingRpcClient and RetryingHttpClient leverage this feature.
  • #904 HttpHeaders.contentType() which accesses the content-type header using MediaType

Improvements

  • #846 #889 The factory methods in HttpRequest and HttpResponse use highly-optimized dedicated Reactive Stream implementations for better performance and reduced memory footprint.
  • #890 A warning message is logged if a path variable of an annotated service does not have its corresponding @Param annotation.
  • #899 #903 #905 #917 #918 Various performance and robustness improvements
  • #929 Port the recent upstream changes of the forked code

Bug fixes

  • #869 #900 RetryingHttpClient does not create a new context for each retry attempt.
  • #893 #896 HttpVfs implementation exposed by DocService generated poor meter tag.
  • #910 Incorrect CompletionStage handling in annotated services
  • #924 Buffer leak when gRPC message parsing fails
  • #885 Various miscellaneous fixes related with Reactive Stream implementations

Deprecations

  • #909 The void doXXX() methods in AbstractHttpService have been deprecated in favor of the HttpResponse doXXX() methods: (Note the return type.)

    // Before
    public class MySerivce extends AbstractHttpService {
        @Override
        public void doGet(ServiceRequestContext ctx, HttpRequest req, HttpResponseWriter res) {
            res.respond(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF8, "Hello, World!");
        }
    }
    
    // After
    public class MySerivce extends AbstractHttpService {
        @Override
        public HttpResponse doGet(ServiceRequestContext ctx, HttpRequest req) {
            return HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF8, "Hello, World!");
        }
    }
    

    This change gives you the freedom of choosing better HttpResponse implementation depending on his or her needs. See #846 and #889 for more information.

  • #909 DefaultHttpRequest and DefaultHttpResponse have been deprecated in favor of HttpRequest.streaming() and HttpResponse.streaming(). See the pull request for the detailed migration instructions.

  • #909 The HttpResponseWriter.respond() methods were all deprecated. Create a new HttpResponse using the factory methods of HttpResponse instead.

Breaking changes

  • #893 #896 HttpVfs is not a functional interface anymore, due to its new method meterTag() which is used as a tag value of the cache metrics.
  • #902 HTTP/1 request pipelining has been disabled by default for better out-of-the-box compatibility with HTTP/1-only servers. You can re-enable it by specifying the -Dcom.linecorp.armeria.defaultUseHttp1Pipelining=true JVM option.
  • #907 @Converter annotation has been replaced by @ResponseConverter for consistency with other annotations such as @RequestConverter and @ExceptionHandler.
  • #920 ExceptionHandlerFunction interface has been revamped for more flexibility.
  • #923 HttpRequest.isKeepAlive() has been removed because it had no meaning and effect for most cases.

Dependencies

  • Brave 4.10.0 -> 4.13.1
  • Netty: 4.1.17.Final -> 4.1.19.Final
  • Reactive Streams 1.0.1 -> 1.0.2
  • Spring Boot 1.5.8.RELEASE -> 1.5.9.RELEASE
  • Tomcat 8.5.23 -> 8.5.24 and 8.0.47 -> 8.0.48

Known issues

  • Netty 4.1.19.Final has a data corruption issue when epoll transport is used. Specify the following JVM option to disable epoll transport and work around this problem until Netty 4.1.20.Final is released:

    -Dcom.linecorp.armeria.useEpoll=false
    
armeria -

Published by trustin almost 7 years ago

Improvements

  • #879 Reduced overhead for handling requests without content and trailing headers

Bug fixes

  • #872 Buffer leak in FilteredStreamMessage and FilteredHttpResponse
  • #873 #874 A Subscriber of PublisherBasedStreamMessage is sometimes not notified
  • #877 A successful HTTP request is sometimes marked as failed with AbortedStreamException

Dependencies

  • Brave 4.9.2 -> 4.10.0
  • gRPC 1.7.0 -> 1.8.0
  • Guava 23.4 -> 23.5
  • Micrometer 1.0.0-rc.4 -> 1.0.0-rc.5
armeria -

Published by trustin almost 7 years ago

Note: Use Armeria 0.55.1.

Breaking changes

  • #795 Updated Brave from 4.6.0 to 4.9.2
  • #823 Updated Micrometer from 0.10.0 to 1.0.0-rc.4
  • #797 The method signature of EndpointSelector.select() has been changed.
  • #849 StreamMessage.closeFuture() has been renamed to completionFuture().
  • #860 StreamMessage.subscribe(..., Executor, ...) has been replaced with subscribe(..., EventExecutor, ...).
    • You need to specify an EventLoop or an EventExecutor instead of a plain Executor.
  • #860 StreamMessage now always invokes its Subscriber from an EventExecutor (or an EventLoop), even if a user did not specify any EventExecutor with subscribe(). Previously, the Subscriber, which subscribed without an Executor, was invoked from the same thread with the publisher, but this is not always true anymore.
    • This change may affect your unit tests which performs stream publication from non-EventLoop threads due to the timing issues introduced by this change.

New features

  • #804 StickyEndpointSelectionStrategy

    ToLongFunction<ClientRequestContext> hasher = (ClientRequestContext ctx) -> {
        return ((HttpRequest) ctx.request()).headers().get(AsciiString.of("cookie")).hashCode();
    };
    EndpointGroupRegistry.register(
            "myGroup", new StaticEndpointGroup(Endpoint.of("foo.com", 80), Endpoint.of("bar.com", 80)),
            new StickyEndpointSelectionStrategy(hasher));
    
  • #807 Clients.withContextCustomizer() which allows a user change the properties of a ClientRequestContext without using a decorator:

    try (SafeCloseable ignored = Clients.withContextCustomizer(ctx -> {
        ctx.attr(USER_ID).set(userId);
        ctx.attr(USER_SECRET).set(secret);
    })) {
        client.executeSomething(..);
    }
    
  • #813 HttpHeaderNames.LINK has been added.

  • #824 @Decorator annotation which decorates an annotated service:

    public class MyAnnotatedService {
        @Get("/my_service")
        @Decorator(MyFirstDecorator.class)
        @Decorator(MySecondDecorator.class)
        public String myService(ServiceRequestContext ctx, HttpRequest req) { ... }
    }
    
  • #825 @Header annotation which injects an HTTP header value for an annotated service:

    public class MyAnnotatedService {
        @Get("/some_resource")
        public String aHeader(@Header("if-match") String ifMatch) { ... }
    }
    
  • #829 #837 Additional configuration properties for HTTP/1-related limits:

    final ClientFactory cf = new ClientFactoryBuilder()
            .maxHttp1InitialLineLength(8192)
            .maxHttp1HeaderSize(16384)
            .maxHttp1ChunkSize(16384)
            .build();
    final ServerBuilder sb = new ServerBuilder()
            .maxHttp1InitialLineLength(8192)
            .maxHttp1HeaderSize(16384)
            .maxHttp1ChunkSize(16384);
    
  • #835 Allow specifying remote service name for a Zipkin span when using HttpTracingClient.

  • #847 @ExceptionHandler annotation which allows a user handle an exception conveniently:

    @ExceptionHandler(MyExceptionHandlerFunction.class)
    public class MyAnnotatedService {
        @Get("/users/{id}")
        ...
    }
    
    public class MyExceptionHandlerFunction implements ExceptionHandlerFunction {
        @Override
        public HttpResponse handle(RequestContext ctx, HttpRequest req, Throwable cause) { ... }
    }
    
  • #855 EventLoopStreamMessage which is an alternative experimental StreamMessage implementation faster than DefaultStreamMessage in certain cases.

Improvements

  • #820 Performance improvements for content type matching in GrpcService
  • #836 #860 #863 Various performance improvements for DefaultStreamMessage
  • #861 It is now allowed to return null in an annotated service method.
  • #862 RequestLogBuilder.endResponse() will use RpcResponse.cause() as the response failure cause automatically if possible.

Bug fixes

  • #811 Zipkin spans are not opened or closed correctly due to a race condition.
  • #839 KeeperException.NoNodeException in ZooKeeperConnector due to a race condition
  • #841 #842 #843 #848 #853 #858 #859 Various bug fixes for StreamMessage implementations

Dependencies

  • Caffeine 2.5.6 -> 2.6.0
  • Guava 23.2 -> 23.4
  • Netty 4.1.16 -> 4.1.17
    • TCNative BoringSSL 2.0.6 -> 2.0.7
  • Brave 4.6.0 -> 4.9.2
  • Kafka 0.11.0.1 -> 1.0.0
  • ZooKeeper 3.4.10 -> 3.4.11
armeria -

Published by trustin almost 7 years ago

Bug fixes

  • #802 #803 'Too many open files' error when making a lot of connection attempts for short period
  • #810 ArrayIndexOutOfBoundsException from HdrHistogram
  • #812 Zipkin span is not closed correctly due to a race condition.
armeria -

Published by trustin almost 7 years ago

Bug fixes

  • #793 #796 IndexOutOfBoundsException while recording request metrics
    • Replaced Micrometer's CKMSQuantiles with RollingHdrQuantiles based on HrdHistogram
    • Added two meters:
      • armeria.hdrHistogram.count - the number of histogram objects in use by Armeria
      • armeria.hdrHistogram.estimatedFootprint - the total estimated memory footprint of all histogram objects in use by Armeria, in bytes.

Dependencies

  • HdrHistogram 2.1.10
armeria -

Published by trustin almost 7 years ago

Breaking changes

  • #738 #775 Replaced com.linecorp.armeria.server.annotation.Optional with com.linecorp.armeria.server.annotation.Default.

New features

  • #18 #726 Added ThrottlingHttpService and ThrottlingRpcService, which reject incoming requests based on ThrottlingStrategy

    ServerBuilder sb = new ServerBuilder();
    sb.service("/foo", myService.decorate(
            ThrottlingHttpService.newDecorator(
                    new RateLimitingThrottlingStrategy<>(10.0 /* requests per second */))));
    
  • #678 #772 Added LoggingClientBuilder for more customization of LoggingClient

    HttpClient client = new HttpClientBuilder("http://example.com/")
            .decorator(new LoggingClientBuilder()
                    .requestLogLevel(LogLevel.INFO)
                    .successfulResponseLogLevel(LogLevel.INFO)
                    .failureResponseLogLevel(LogLevel.WARN)
                    .newDecorator())
            .build();
    
  • #689 Replaced HttpVfs entry cache to Caffeine cache

    • Cache metrics are exported under armeria.server.file.vfsCache.
  • #738 #775 Support Optional<T> parameter type for annotated services.

    public class MyAnnotatedService {
        @Post("/style_1")
        public AggregatedHttpMessage postWithOptional(@Param("type") Optional<String> type,
                                                      @Param("value") String value) {
            final String actualType = type.orElse("plaintext");
            ...
        }
    
        @Post("/style_2")
        public AggregatedHttpMessage postWithDefault(@Param("type") @Default("plaintext") String type,
                                                     @Param("value") String value) {
            ...
        }
    }
    
  • #785 Added ConcurrentCompositeMeterRegistry which works around the known scalability issue with Micrometer CompositeMeterRegistry. We will remove this class once we upgrade to Micrometer 1.0.0-rc.3 or above.

Improvements

  • #746 Annotated services will respond with 400 Bad Request rather than 500 Internal Server Error when a handler method throws an IllegalArgumentException.

Bug fixes

  • #754 #788 Server raises an exception when received a request with unsupported method
  • #767 #770 Spring Boot configuration raises NoSuchElementException when no MeterRegistry bean is present.
  • #780 #781 Client-side Thrift callback is not notified correctly for a void method with RetryingRpcClient.
  • #782 #783 NullPointerException is raised when one-way Thrift method fails with an exception.
  • #784 The default MeterIdFunction does not add the hostnamePattern tag.

Dependencies

  • Caffeine 2.5.5 -> 2.5.6
  • Checkstyle 8.2 -> 8.3
  • completable-futures -> 0.3.1 -> 0.3.2
  • Dropwizard Metrics 3.2.4 -> 3.2.5
  • gRPC 1.6.1 -> 1.7.0
  • Guava 23.0 -> 23.2
  • Hibernate Validator 5.4.1 -> 6.0.3
  • Jackson 2.8.9 -> 2.9.2
  • java.validation 1.0.0 -> 2.0.0
  • Javassist 3.21.0 -> 3.22.0
  • Jetty 9.4.6 -> 9.4.7
  • Kafka clients 0.11.0.0 -> 0.11.0.1
  • Mockito 2.8.47 -> 2.11.0
  • Netty 4.1.15 -> 4.1.16
  • Prometheus 0.0.26 -> 0.1.0
  • Spring Boot 1.5.6 -> 1.5.8
  • Tomcat 8.5.20 -> 8.5.23, 8.0.46 -> 8.0.47
armeria -

Published by trustin about 7 years ago

Bug fixes

  • #768 Switch from WindowSketchQuantiles to CKMSQuantiles
armeria -

Published by trustin about 7 years ago

Bug fixes

  • #751 #752 Stack overflow at DnsServiceEndpointGroup.of(String)
  • #758 Exclude unnecessary transitive dependencies of micrometer-spring-legacy
  • #764 Work around IndexOutOfBoundsException in Micrometer WindowSketchQuantiles.get(double)
armeria -

Published by trustin about 7 years ago

This release contains the following commits backported from Armeria 0.53.0. Please note that it's strongly recommended to upgrade to 0.53.0, however.

  • 851ca5378ea3faed71f39505aaefcfb937340402 Add a function that removes inside caches when the last subscriber starts to subscribe to StreamMessageDuplicator
  • 058451b71b1023602b9f95cd0dbc08e692971c96 Propagate missing content-length header if Tomcat coyote response contains content-length header
  • 91c64e7e97dd163eaf0722ee2cd71ed2e2d8f129 Implement Server#toString()
  • a5b79478b9a42f06e1284a1ec0804e2e97626063 Modify RetryStrategy to return backoff according to the response
  • b8818baa692deed958adbddd0356bb383c1bca50 Add the response timeout corresponding to each request that are made in RetryingClient
  • 1164f242182d75309e7b8f5b22984fe03ca304b3 Fix DeferredStreamMessage may not call subscribeToDelegate method
  • 759feb0a5f1be1788e3747dbfbde89b97e61eb2c Fix large response handling issue with webapp container services
armeria -

Published by trustin about 7 years ago

Breaking changes

  • #696 Replace PathMappings with Router and change the API of PathMapping

    • Improve the service router by using Trie-based data structure
    • It is possible to implement more complicated service routing such as content negotiation.
  • #717 #727 #729 #733 #737 #747 Use Micrometer as the primary metric collection library.

    • Replace (Dropwizard|Prometheus)MetricCollecting(Client|Service) with
      MetricCollecting(Client|Service)

      ServerBuilder sb = new ServerBuilder();
      sb.service(...., myService.decorate(
              MetricCollectingService.newDecorator(MeterIdFunction.ofDefault())));
      
    • Replace DropwizardMetricsCircuitBreakerListener with
      MetricCollectingCircuitBreakerListener

    • Replace PathMapping.metricName() with PathMapping.meterTag()

    • Add Server.meterRegistry() and ClientFactory.meterRegistry()

      • The default registry is Metrics.globalRegistry.

      • A user can override the default registry using ServerBuilder.meterRegistry(..), ClientFactoryBuilder.meterRegistry(..) and ClientFactory.setMeterRegistry(..).

        ServerBuilder sb = new ServerBuilder();
        sb.meterRegistry(NoopMeterRegistry.get()); // Disable metrics
        
    • Add RequestContext.meterRegistry()

    • Add various utilities for Micrometer to common.metric

  • #720 RetryStrategy.shouldRetry() now returns CompletableFuture<Optional<BackOff>> to allow a user to choose a different Backoff for a different failure cause.

    // Use fixed delay on 500 and exponential delay on 503.
    Backoff backoffOn500 = Backoff.fixed(3000);
    Backoff backoffOn503 = Backoff.exponential(1000, 60000);
    RetryStrategy<HttpRequest, HttpResponse> strategy = RetryStrategy.onStatus(httpStatus -> {
        if (httpStatus == HttpStatus.SERVICE_UNAVAILABLE) {
            return Optional.of(backoffOn503);
        } else if (httpStatus == HttpStatus.INTERNAL_SERVER_ERROR) {
            return Optional.of(backoffOn500);
        } else {
            return Optional.empty();
        }
    });
    
  • #749 Rename PrometheusExporterHttpService to PrometheusExpositionService

New features

  • #690 #710 Easier Server integration test with ServerRule

    • A new module armeria-testing contains a JUnit rule ServerRule, which enables easier integration testing of a Server.

      public class MyTest {
          @ClassRule // or @Rule if you want to start a new Server for each test method.
          public static final ServerRule server = new ServerRule() {
              @Override
              protected void configure(ServerBuilder sb) throws Exception {
                  sb.service("/myService", ...);
              }
          });
      
          @Test
          public void myTest() throws Exception {
              // ServerRule provides various utility methods for getting URIs and port numbers.
              HttpClient client = HttpClient.of(server.uri("/"));
              AggregatedHttpMessage response = client.get("/myService").aggregate().get();
              assertThat(response.content().toStringUtf8()).isEqualTo("Hello, world!");
          }
      }
      
  • #694 DnsAddressEndpointGroup and DnsServiceEndpointGroup which uses DNS A/AAAA and SRV records respectively.

  • #696 Media type negotiation for annotated services using @ConsumerType and @ProducerType

    ServerBuilder sb = new ServerBuilder();
    sb.annotatedService(new Object() {
        @Get("/greet")
        @ProduceType("application/json;charset=UTF-8")
        public HttpResponse greetGet(@Param("name") String name) {
            return HttpResponse.of(HttpStatus.OK, MediaType.JSON_UTF_8, "{\"name\":\"%s\"}", name);
        }
    
        @Post("/greet")
        @ConsumeType("application/x-www-form-urlencoded")
        public HttpResponse greetPost(@Param("name") String name) {
            return HttpResponse.of(HttpStatus.OK);
        }
    });
    
  • #701 Add StreamMessageDuplicator.duplicateStream(boolean) for potentially reduced memory footprint and more convenience.

    HttpRequestDuplicator dup = new HttpRequestDuplicator(req);
    HttpRequest firstDuplicate = dup.duplicateStream();
    HttpRequest lastDuplicate = dup.duplicateStream(true);
    // No need to call dup.close(); underlying buffered content will be 
    // removed automatically as the duplicate streams are consumed.
    
  • #711 Provide a simpler way to add gRPC services.

    • GrpcService now implements a new interface ServiceWithPathMappings which allows a user not to specify path mapping:

      ServerBuilder sb = new ServerBuilder();
      sb.service(new GrpcServiceBuilder()
              .addService(new MyGrpcServiceOne())
              .supportedSerializationFormats(GrpcSerializationFormats.values())
              .build())
        .service(new GrpcServiceBuilder()
              .addService(new MyGrpcServiceTwo())
              .addService(new MyGrpcServiceThree())
              .supportedSerializationFormats(GrpcSerializationFormats.values())
              .build(), authDecorator);
      
  • This doesn't work only for GrpcService but any ServiceWithPathMappings implementations.

  • #728 Add session-level options for client-side initial HTTP/2 settings

    ClientFactory cf = new ClientFactoryBuilder()
            .initialHttp2ConnectionWindowSize(1048576)
            .initialHttp2StreamWindowSize(131072)
            .http2MaxFrameSize(32768)
            .build();
    
  • #735 Allow specifying alternative timeout for retry attempts. e.g. Set the timeout of each attempt to 1 second while RetryingClient will give up 10 seconds after the initial attempt.

    // Retry when could not receive a resonse before timeout.
    RetryStrategy<HttpRequest, HttpResponse> strategy = new RetryStrategy<HttpRequest, HttpResponse>() {
        final Backoff backoff = Backoff.fixed(1000);
        @Override
        public CompletableFuture<Optional<Backoff>> shouldRetry(HttpRequest request,
                                                                HttpResponse response) {
            return response.aggregate().handle((result, cause) -> {
                if (cause instanceof ResponseTimeoutException) {
                    return Optional.of(backoff);
                }
                return Optional.empty();
            });
        }
    };
    
    HttpClient client = new HttpClientBuilder("http://example.com/")
            .decorator(RetryingHttpClient.newDecorator(
                    strategy, /* defaultMatAttempts */ 10, /* responseTimeoutForEachAttempt */ 1000))
            .build();
    

Improvements

  • #696 Service router now uses Caffeine as its caching layer, and its stats are exported to Micrometer.
  • #721 Implement Server.toString()
  • #750 Log stacktrace for error responses in LoggingService

Bug fixes

  • #579 #696 Inability to bind two annotated methods at the same path with different HTTP methods. e.g. one at /greet for GET and the other at /greet for POST
  • #714 #715 A request whose path contains an asterisk (*) is not handled correctly.
  • #722 #748 HttpResponse produced by TomcatService does not contain content-length header.
  • #731 Add missing service(ServiceWithPathMappings,...) to AbstractVirtualHostBuilder
  • #744 A race condition in DeferredStreamMessage causes a subscription leak.
  • #748 JettyService fails with IllegalStateException when ResourceHandler tries to serve the resource greated than 8192 bytes.

Dependencies

  • Brave 4.5.1 -> 4.6.0
  • Caffeine 2.5.3 -> 2.5.5
  • Dropwizard Metrics 3.2.3 -> 3.2.4
  • gRPC 1.4.0 -> 1.6.1
  • Guava 22.0 -> 23.0
  • Kafka 0.10.2.1 -> 0.11.0.0
  • Netty 4.1.13 -> 4.1.15
  • Reactive Streams 1.0.1-RC1 -> 1.0.1
  • Spring Boot 1.5.4 -> 1.5.6
  • Tomcat 8.5.16 -> 8.5.20 / 8.0.45 -> 8.0.46
armeria -

Published by minwoox about 7 years ago

Breaking changes

  • #686 Remove CommonPools.bossGroup
    • Server doesn't share the daemon thread from bossGroup() and creates a single-thread boss EventLoopGroup using newly added method that is EventLoopGroups.newEventLoopGroup(numThreads, threadFactory)
    • Server terminates the boss groups lastly so that the JVM does not terminate itself until the graceful shutdown is complete.

New features

  • #691 A user can throw a new HttpResponseException(HttpStatus) to send an error response

Bug fixes

  • #686 A Server creates a dedicated single-thread boss EventLoopGroup for each ServerPort in order to prevent premature shutdown as well
  • #697 Fix a bug where Armeria server starts even if AnnotatedServiceRegistrationBeans is not present
  • #698 Make RequestContext accessible during converting a response by ResponseConverter
armeria -

Published by trustin over 7 years ago

Breaking changes

  • #644 Replace SessionOptions with ClientFactoryBuilder

    // Before
    ClientFactory factory = new AllInOneClientFactory(SessionOptions.of(
            SessionOption.USE_HTTP2_PREFACE.newValue(true),
            SessionOption.USE_HTTP1_PIPELINING.newValue(true), ...);
    // After
    ClientFactory factory = new ClientFactoryBuilder()
            .useHttp2Preface(true)
            .useHttp1Pipelining(true)
            ...
            .build();
    
  • #619 #648 Change the parameters of JitterAddingBackoff from absolute values to rates

    // Before
    Backoff backoff = Backoff.exponential(1000, 60000).withJitter(1000); // 1-second jitter
    // After
    Backoff backoff = Backoff.exponential(1000, 60000).withJitter(0.3); // 30% jitter
    
  • #652 Add common EventLoopGroups and blocking task executor

    • Previously, unless specified explicitly, a ClientFactory and a Server had their own EventLoopGroups. From this release, we provide common EventLoopGroups via com.linecorp.armeria.common.CommonPools so that Armeria does not create unnecessarily large number of event loop threads.

      // Before: nCpuCore * 2 * 3 threads (s1, s2 and cf do not share the event loops)
      Server s1 = new ServerBuilder()...build();
      Server s2 = new ServerBuilder()...build();
      ClientFactory cf = new AllInOneClientFactory();
      // After: nCpuCore * 2 threads (s1, s2 and cf share the event loops)
      Server s1 = new ServerBuilder()...build();
      Server s2 = new ServerBuilder()...build();
      ClientFactory cf = new ClientFactoryBuilder()...build();
      
    • We also added ServerBuilder.worker/bossGroup() and ClientFactoryBuilder.workerGroup() so that you can specify an alternative EventLoopGroup easily. You'll find com.linecorp.armeria.common.util.EventLoopGroups.newEventLoopGroup() useful as well.

      Server s = new ServerBuilder()
              // 4 dedicated event loop threads.
              // 'true' means 'shut down the event loops when server stops.'
              .workerGroup(EventLoopGroups.newEventLoopGroup(4), true)
              ...
              .build();
      ClientFactory cf = new ClientFactoryBuilder()
              // 2 dedicated event loop threads.
              // 'true' means 'shut down the event loops when factory closes.'
              .workerGroup(EventLoopGroups.newEventLoopGroup(2), true)
              ...
              .build();
      
    • Similarly, we provide common blocking task executor via CommonPools, which was created per-Server until this release.

  • #667 Make StreamMessage implementations pass Reactive Streams TCK and clarify the behavior of StreamMessage.abort()

    • StreamMessage.subscribe() does not raise an exception immediately anymore. The subscriber is notified via onError() about subscription failure.
    • When a stream is aborted, AbortedStreamException is signaled to the subscriber's onError().
  • #645 #672 Allow more customization of LoggingService.

    • Separated log levels for request, response and failure.

    • Added customizable log sanitization

    • We changed the log level of failed responses from INFO to WARN.

      ServerBuilder sb = new ServerBuilder();
      sb.service(..., myService.decorate(new LoggingServiceBuilder()
              .requestLogLevel(LogLevel.INFO)
              .successfulResponseLogLevel(LogLevel.INFO)
              .failureResponseLogLevel(LogLevel.WARN)
              .newDecorator()));
      
  • #681 #677 Update dependencies

    • Brave 4.2.0 -> 4.5.1
    • completable-futures 0.3.0 -> 0.3.1
    • Dropwizard Metrics 3.2.2 -> 3.2.3
    • fastutil 7.2.1 -> 8.1.0
    • Netty 4.1.12 -> 4.1.13
    • Prometheus simpleclient 0.0.23 -> 0.0.24
    • Tomcat 8.5.15 -> 8.5.16 and 8.0.44 -> 8.0.45

New features

  • #680 Add HttpClientBuilder and HttpClient.of() which allows easier construction of HttpClient

    // Before:
    HttpClient c1 = Clients.newClient("none+http://example.com/");
    HttpClient c2 = new ClientBuilder("none+http://example.com/")
            .decorator(HttpRequest.class, HttpResponse.class, LoggingClient.newDecorator())
            .build(HttpClient.class);
    // After:
    // - No need to prepend 'none+'
    // - No need to specify HttpRequest.class` and HttpResponse.classs
    // - No need to specify HttpClient.class
    HttpClient c1 = HttpClient.of("http://example.com/");
    HttpClient c2 = new HttpClientBuilder("http://example.com/")
            .decorator(LoggingClient.newDecorator()) 
            .build();
    
  • #628 #660 Provide a way to specify a Backoff using a string expression

    // Useful when you want to make backoff strategy configurable:
    Backoff backoff = Backoff.of("exponential=1000:60000,jitter=0.3,maxAttempts=10");
    
  • #521 #662 Allow setting a custom request timeout handler

    @Get("/hello/:name")
    public HttpResponse hello(ServiceRequestContext ctx, @Param("name") name) {
        DefaultHttpResponse res = new DefaultHttpResponse();
        ctx.setRequestTimeoutHandler(() -> {
            res.respond(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, 
                        "A very late hello, %s.", name);
        });
        ...
    }
    
  • #657 Add content-security-policy and x-frame-options to HttpHeaderNames

Improvements

  • #675 Increase the chance of reusing idle client connections
  • #676 Clean up the closed channels more aggressively from DefaultKeyedChannelPool

Bug fixes

  • #651 #659 Fix PathMapping implementations to produce their loggerName and metricName correctly
  • #663 Only log an unexpected exception during authorization
  • #665 Fix EventLoop.terminationFuture() listener leak
  • #627 #656 Enable response timeout is enforced across the retries by RetryingClient
armeria -

Published by trustin over 7 years ago

Improvements

  • #669 Reduce the number of client-side connections by increasing the chance of reusing connections.
  • #670 Clean up the closed channels from connection pools more aggressively.
armeria -

Published by trustin over 7 years ago

Bug fixes

  • #664 Fix EventLoop.terminationFuture() listener leak
armeria -

Published by trustin over 7 years ago

Breaking changes

  • #616 Renamed RetryRequestStrategy to RetryStrategy.

  • #616 Renamed Backoff.nextIntervalMillis() to nextDelayMillis().

  • #631 Removed .http. from the package names. Use the following command for migration:

    find -name '*.java' -exec perl -pi -e \
        's/(com\.linecorp\.armeria\.(?:client|common|server|internal)\.)http\./$1/g' {} ';'
    
  • #631 HttpSessionProtocols, which was deprecated in 0.49.0, has been removed.

New features

  • #616 Added RetryingHttpClient

    HttpClient client = new ClientBuilder("none+http://example.com/")
            .decorator(HttpRequest.class, HttpResponse.class,
                       new RetryingHttpClientBuilder(...)...build())
            .build(HttpClient.class);
    

Bug fixes

  • #633 Fixed a memory leak which can occur when an HTTP client gets a ResponseTimeoutException.
  • #638 #641 Fixed a bug where an HTTP client does not send an HTTP/2 GOAWAY frame when closing an idle connection
  • #640 Removed noisy debug-level error messages from Reflections
  • #643 Fixed incorrect Spring annotation in MonitoringConfiguration
armeria -

Published by trustin over 7 years ago

Bug fixes

  • #632 Fix memory leak which occurs when a client-side response stream is closed unexpectedly
armeria -

Published by minwoox over 7 years ago

New features

  • (Breaking) #618 More HTTP-friendliness and simplicity
    • Simplify the type parameter signatures of services and clients.
      • Replace ? super I, ? extends O with RpcRequest, RpcResponse or HttpRequest, HttpResponse.
    • Remove SessionProtocolProvider.
    • Deprecate HttpSessionProtocols.
    • Make SessionProtocol an enum and undeprecate its values.
    • Make RequestLog and RequestLogBuilder more HTTP-friendly.
      • Replace requestEnvelope() with requestHeaders().
      • Replace responseEnvelope() with responseHeaders().
      • Replace RequestLogAvailability.REQUEST_ENVELOPE with REQUEST_HEADERS.
      • Replace RequestLogAvailability.RESPONSE_ENVELOPE with RESPONSE_HEADERS.
      • Add status() which is HttpStatus.
      • Remove RequestLogAvailability.STATUS_CODE because HttpStatus.
        becomes available when responseEnvelope becomes available.
  • (Spring integration) #621 Add the registration bean for an annotated service object
    • You can, now add an annotated service object to a Server without using the configurator. For example:
      public AnnotatedServiceRegistrationBean okService() {
          return new AnnotatedServiceRegistrationBean()
              .setServiceName("myAnnotatedService")
              .setPathPrefix("/my_service")
              .setService(new MyAnnotatedService())
              .setDecorator(LoggingService.newDecorator());
      
  • #617 Allow arbitrary customization of client SslContext
    • SessionOption.TRUST_MANAGER_FACTORY is deprecated. Use SessionOption.SSL_CONTEXT_CUSTOMIZER instead. You can set a TrustManagerFactory with SslContextBuilder as follows:
      private static final ClientFactory clientFactory =
            new AllInOneClientFactory(SessionOptions.of(
                    SessionOption.SSL_CONTEXT_CUSTOMIZER.newValue(
                            b -> b.trustManager(InsecureTrustManagerFactory.INSTANCE)),
                            ...
      

Bug fixes

  • #620 The default blockingTaskExecutor is not single-threaded anymore.
  • #626 Fix a race condition in DeferredStreamMessage.subscribeToDelegate().
armeria -

Published by minwoox over 7 years ago

New features

  • (Breaking) #581 #589 DynamicHttpService is merged into the core. Also, HTTP parameters are automatically injected as arguments when calling an annotated service method. Your code will fail to compile if you wrote your service using DynamicHttpService.
    • DynamicHttpServiceBuilder class is removed. You can use ServerBuilder.annotatedService(...) to add an annotated service object to the builder as follows:
      ServerBuilder sb = ...;
      // Using a query parameter (e.g. /greet5?name=alice) on an annotated service object:
      sb.annotatedService(new Object() {
          @Get("/greet5")
          public HttpResponse greet(@Param("name") String name,
                                    @Param("title") @Optional("Mr.") String title) {
              // "Mr." is used by default if there is no title parameter in the request.
              return HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8,
                                     "Hello, %s %s!", title, name);
          }
      });
      
    • @PathParam annotation has been replaced with @param, which is much shorter and handles query parameters as well.
    • The package name of HTTP method anntations, such as @Get, is changed to com.linecorp.armeria.server.http.annotation from com.linecorp.armeria.server.http.dynamic.
  • #584 #585 Provide more ways to specify a path pattern. The following patterns would be accepted as a path pattern.
    • /login (no path parameters)
    • /users/{userId} (curly-brace style)
    • /list/:productType/by/:ordering (colon style)
    • exact:/foo/bar (exact match)
    • prefix:/files (prefix match)
    • glob:/~*/downloads/** (glob pattern)
    • regex:^/files/(?.*)$ (regular expression)
  • #593 Restore prefix mapping stripping to allow it to work together with arbitrarily mapped PathMappingResult. ServiceRequestContext.mappedPath() would return the value from PathMappingResult.path().
  • #611 Move the JVM system property flags to Flags
    • You can now find out what JVM system property options to specify that can change the behavior of Armeria.
  • #599 Simplify type parameters of clients and services by assuming the type parameters are only one of the following
    • HttpReqeust and HttpResponse
    • RpcRequest and RpcResponse
  • #596 Add StreamMessageDuplicator. StreamMessage can be subscribed by multiple subscribers now.
  • #577 Add AggregatedHttpMessage.toHttpRequest/Response()
  • #576 Enable example headers in ThriftServiceRegistrationBean
  • #515 Implement ManagedHttpHealthCheckService, so you can override the healthiness via a PUT request.

Improvements

  • #606 Update dependencies
  • #602 Provide a default value that limits the number of request try attempt
  • #600 Cleanup native transport usages

Bug fixes

  • #595 Fix a leak in DefaultStreamMessage / Improve the life cycle contract of reference-counted objects in StreamMessage.
  • #597 Ensure DefaultStreamMessage cleans up the objects even when demand is 0.
  • #588 Do not cache PathMappingResult when query string exists.
  • #608 Ensure an HTTP object is requested after reading headers in a gRPC stream.
  • #590 Remove exception throwing when a context is timed out.
  • #587 Support path parameter names that start with a digit.
  • #578 Rename HttpResponse.ofFailed() to ofFailure().
  • #609 Add missing source files to armeria-tomcat8.0 and armeria-thrift0.9.
  • #592 Allow duplicate docstring keys in grpc docstring extractor.
  • #594 Exclude thrift module dependency from spring-boot-autoconfigure POM to allow a user to choose Thrift version.
armeria -

Published by trustin over 7 years ago

Bug fixes

  • #590 Remove exception throwing when a context is timed out
  • #572 Notify HTTP message aggregation future even on abortion
  • #595 Fix a leak in DefaultStreamMessage and improve the life cycle contract of reference-counted objects in StreamMessage
  • #597 Ensure DefaultStreamMessage cleans up the objects even when demand is 0
Package Rankings
Top 5.13% on Repo1.maven.org
Related Projects