Skip to content

Commit

Permalink
Add the release note for 1.29.0 (#5723)
Browse files Browse the repository at this point in the history
  • Loading branch information
minwoox authored Jun 12, 2024
1 parent f430ad6 commit 9495a06
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.google.common.math.IntMath;

import com.linecorp.armeria.common.annotation.Nullable;
import com.linecorp.armeria.common.annotation.UnstableApi;

import io.netty.util.AsciiString;

Expand Down Expand Up @@ -237,6 +238,7 @@ public final class HttpHeaderNames {
* The HTTP {@code "Git-Protocol"} header field name, as described in
* <a href="https://git-scm.com/docs/protocol-v2#_http_transport">HTTP Transport</a>.
*/
@UnstableApi
public static final AsciiString GIT_PROTOCOL = create("Git-Protocol");
/**
* The HTTP {@code "Host"} header field name.
Expand Down
3 changes: 3 additions & 0 deletions core/src/main/java/com/linecorp/armeria/common/MediaType.java
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ private static MediaType addKnownType(MediaType mediaType) {
* This constant is used for advertising the capabilities of a Git server,
* as described in <a href="https://git-scm.com/docs/http-protocol/2.34.0#_smart_clients">Smart Clients</a>.
*/
@UnstableApi
public static final MediaType GIT_UPLOAD_PACK_ADVERTISEMENT =
createConstant(APPLICATION_TYPE, "x-git-upload-pack-advertisement");

Expand All @@ -504,6 +505,7 @@ private static MediaType addKnownType(MediaType mediaType) {
* <a href="https://git-scm.com/docs/http-protocol/2.34.0#_smart_service_git_upload_pack">
* Smart Service git-upload-pack</a>.
*/
@UnstableApi
public static final MediaType GIT_UPLOAD_PACK_REQUEST =
createConstant(APPLICATION_TYPE, "x-git-upload-pack-request");

Expand All @@ -512,6 +514,7 @@ private static MediaType addKnownType(MediaType mediaType) {
* <a href="https://git-scm.com/docs/http-protocol/2.34.0#_smart_service_git_upload_pack">
* Smart Service git-upload-pack</a>.
*/
@UnstableApi
public static final MediaType GIT_UPLOAD_PACK_RESULT =
createConstant(APPLICATION_TYPE, "x-git-upload-pack-result");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.linecorp.armeria.common;

import com.linecorp.armeria.common.annotation.UnstableApi;

/**
* String constants defined in {@link MediaType} class.
*/
Expand Down Expand Up @@ -348,14 +350,17 @@ public final class MediaTypeNames {
/**
* {@value #GIT_UPLOAD_PACK_ADVERTISEMENT}.
*/
@UnstableApi
public static final String GIT_UPLOAD_PACK_ADVERTISEMENT = "application/x-git-upload-pack-advertisement";
/**
* {@value #GIT_UPLOAD_PACK_REQUEST}.
*/
@UnstableApi
public static final String GIT_UPLOAD_PACK_REQUEST = "application/x-git-upload-pack-request";
/**
* {@value #GIT_UPLOAD_PACK_RESULT}.
*/
@UnstableApi
public static final String GIT_UPLOAD_PACK_RESULT = "application/x-git-upload-pack-result";
/**
* {@value #GZIP}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@
* 4. ServerBuilder
*/
class ServiceOptionsTest {
private final ServiceOptions serviceOptions =
ServiceOptions.builder().requestTimeoutMillis(100001).maxRequestLength(10002)
.requestAutoAbortDelayMillis(10003).build();

private static final ServiceOptions SERVICE_OPTIONS =
ServiceOptions.builder().requestTimeoutMillis(5000)
.maxRequestLength(1024)
.requestAutoAbortDelayMillis(1000)
.build();

@Test
void serviceOptionsShouldNotOverrideServiceBindingBuilder() {
Expand All @@ -45,7 +48,7 @@ public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) {

@Override
public ServiceOptions options() {
return serviceOptions;
return SERVICE_OPTIONS;
}
};

Expand Down Expand Up @@ -73,7 +76,7 @@ public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) {

@Override
public ServiceOptions options() {
return serviceOptions;
return SERVICE_OPTIONS;
}
};
try (Server server = Server.builder()
Expand All @@ -89,10 +92,10 @@ public ServiceOptions options() {
.filter(s -> s.route().paths().contains("/test"))
.findFirst().get();

assertThat(sc.requestTimeoutMillis()).isEqualTo(serviceOptions.requestTimeoutMillis());
assertThat(sc.maxRequestLength()).isEqualTo(serviceOptions.maxRequestLength());
assertThat(sc.requestTimeoutMillis()).isEqualTo(SERVICE_OPTIONS.requestTimeoutMillis());
assertThat(sc.maxRequestLength()).isEqualTo(SERVICE_OPTIONS.maxRequestLength());
assertThat(sc.requestAutoAbortDelayMillis()).isEqualTo(
serviceOptions.requestAutoAbortDelayMillis());
SERVICE_OPTIONS.requestAutoAbortDelayMillis());
}
}

Expand All @@ -106,7 +109,7 @@ public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) {

@Override
public ServiceOptions options() {
return serviceOptions;
return SERVICE_OPTIONS;
}
};

Expand All @@ -124,10 +127,10 @@ public ServiceOptions options() {
.stream()
.filter(s -> s.route().paths().contains("/test"))
.findFirst().get();
assertThat(sc1.requestTimeoutMillis()).isEqualTo(serviceOptions.requestTimeoutMillis());
assertThat(sc1.maxRequestLength()).isEqualTo(serviceOptions.maxRequestLength());
assertThat(sc1.requestTimeoutMillis()).isEqualTo(SERVICE_OPTIONS.requestTimeoutMillis());
assertThat(sc1.maxRequestLength()).isEqualTo(SERVICE_OPTIONS.maxRequestLength());
assertThat(sc1.requestAutoAbortDelayMillis()).isEqualTo(
serviceOptions.requestAutoAbortDelayMillis());
SERVICE_OPTIONS.requestAutoAbortDelayMillis());
}
}
}
260 changes: 260 additions & 0 deletions site/src/pages/release-notes/1.29.0.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
---
date: 2024-06-12
---

## 🌟 New features

- Armeria [HTTP/JSON to GRPC transcoding](https://cloud.google.com/endpoints/docs/grpc/transcoding) service now
supports [Custom methods](https://cloud.google.com/apis/design/custom_methods). #5613
```protobuf
rpc Watch(WatchRequest) returns (WatchResponse) {
option (google.api.http) = {
post: "/v1:watch" // 👈👈👈
body: "*"
};
}
```
- You can now specify when to remove multipart temporary files using <type://MultipartRemovalStrategy>. #5652 #5653
```java
Server
.builder()
.multipartRemovalStrategy(
MultipartRemovalStrategy.ON_RESPONSE_COMPLETION)
...
```
- The default value is now <type://ON_RESPONSE_COMPLETION`> which removes the temporary files
when the response is completed.
- A <type://ClientConnectionTimings> now includes the time spent on the TLS handshake. #3647 #5647
```java
ClientConnectionTimings timings = ...
assert timings.tlsHandshakeDurationNanos() > 0;
```
- You can now configure <type://TlsEngineType> using <type://ClientFactoryBuilder> or <type://ServerBuilder>. #4962
```java
ClientFactory
.builder()
.tlsEngineType(TlsEngineType.OPENSSL) // 👈👈👈
.build();
```
- You can now easily find both dynamic and static decorators that handle a request
via <type://ServiceRequestContext.findService(Class)>. #5670
```java
ServerBuilder sb = ...
sb.decorator(CorsService.builderForAnyOrigin().newDecorator());
...
ServiceRequestContext ctx = ...
CorsService corsService = ctx.findService(CorsService.class);
assert corsService.config().isAnyOriginSupported();
```
- You can now use the marshaller specified by gRPC `MethodDescriptor` by setting
<type://GrpcClientBuilder#useMethodMarshaller(boolean)> and
<type://GrpcServiceBuilder#useMethodMarshaller(boolean)>. #5103 #5630
```java
GrpcClientBuilder builder = ...
builder.useMethodMarshaller(true); // 👈👈👈

GrpcServiceBuilder builder = ...
builder.useMethodMarshaller(true); // 👈👈👈
```
- You can now programmatically retrieve the server side metrics via <type://ServerMetrics>. #4992 #5627
```java
ServerMetrics metrics = serverConfig.serverMetrics();
metrics.activeConnections();
metrics.pendingRequests();
metrics.activeRequests();
```
- You can now use a <type://CoroutineHttpService> that runs your service in a coroutine scope. #5442 #5603
```kotlin
ServerBuilder sb = ...
sb.service(
"/hello",
CoroutineHttpService { ctx, req ->
HttpResponse.of("hello world")
})
```
- You can now specify options for an <type://HttpService> via <type://ServiceOptions>. #5071 #5574
```java
static final ServiceOptions SERVICE_OPTIONS =
ServiceOptions
.builder()
.requestTimeoutMillis(5000)
.maxRequestLength(1024)
.requestAutoAbortDelayMillis(1000)
.build();

HttpService httpService = new HttpService() {
...
@Override
public ServiceOptions options() {
return SERVICE_OPTIONS;
}
};

// Or use annotation for an annotated service.
class MyService {
@ServiceOption(requestTimeoutMillis = 5000, maxRequestLength = 1024)
@Get("/hello")
public HttpResponse hello() {
return HttpResponse.of("Hello!");
}
}
```
- You can now inject a custom attribute from a <type://ServiceRequestContext> to an annotated service
using <type://@Attribute> annotation. #5514 #5547
```java
class MyAttributes {
public static final AttributeKey<String> USERNAME =
AttributeKey.valueOf(MyAttributes.class, "USERNAME");
}

class MyAnnotatedService {

@Get("/hello")
public HttpResponse hello(
@Attribute(prefix = MyAttributes.class, value = "USERNAME") // 👈👈👈
String username) { ... }
}
```
- You can now specify a graceful shutdown timeout for an HTTP/2 connection in <type://ClientFactory>. #5470 #5489
```java
ClientFactory
.builder()
.http2GracefulShutdownTimeoutMillis(1000)
.build();
```
- You can now specify an <type://EndpointGroup> when building a <type://ClientRequestContext>. #5292 #5298
```java
ClientRequestContext ctx =
ClientRequestContext
.builder(request)
.endpointGroup(endpointGroup)
.build();
```
- You can now set a `GraphQL` instance directly to the <type://GraphqlServiceBuilder>. #5269
```java
GraphQL graphQL = new GraphQL.Builder(graphqlSchema).build();
GraphqlServiceBuilder builder = ...
builder.graphql(graphQL);
- You can now specify a delay to close an HTTP/1.1 connection from the server side, allowing the client an
opportunity for active closing. #4849 #5616
- You can now configure the maximum length of a TLS client hello message that a server allows by using the
`-Dcom.linecorp.armeria.defaultMaxClientHelloLength=<integer>` JVM option. #5747

## 📈 Improvements

- <type://XdsEndpointGroup> now supports [Slow start mode](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/slow_start). #5688 #5693
- Priority and locality based load balancing is now available for an <type://XdsEndpointGroup>. #5610
- You can now view connection related information in the request logs. #5730
- CORS headers are added to responses even if an exception is raised while handling a request. #5632
- <type://AnnotatedService> is now available through a public API. #5382 #5628
- The metrics for failed requests while retrying now include the cause of the failure. #5405 #5583
- The <type://RequestLog> from a retrying client now includes the current attempt number. #5716 #5719
- A colon is now allowed in the path for binding a service. #4577 #5676
- Timer histogram metrics now repects user-provided `serviceLevelObjectives`. #5661
- <type://ServiceErrorHandler#renderStatus(ServiceRequestContext,RequestHeaders,HttpStatus,String,Throwable)>
can now access the current <type://ServiceRequestContext> if available. #5634
- <type://SamlSingleSignOnHandler#loginFailed(ServiceRequestContext,AggregatedHttpRequest,MessageContext,Throwable)>
can now access the <type://MessageContext> for error handling if available. #5401 #5622
- The copied cURL command from a doc service, is now quoted correctly. #5566

## 🛠️ Bug fixes

- Fixed a bug where <type://RetryingClient> gets to deadlock when <type://OAuth2Client> fails to obtain
an access token. #5715
- Armeria client always uses HTTP/2 connection preface for `h2c`, regardless of
the value of <type://ClientFactoryOptions#useHttp2Preface()>. #5706
- <type://ArmeriaServerConfigurator> now properly overrides the properties set by <type://ArmeriaSettings>. #5009 #5692
- Armeria server now returns a 408 status if a service didn't receive the request fully and
the request times out. #5579 #5680
- A `NullPointerException` isn't raised anymore when running Armeria with a self-signed certificate. #5669
It happened when the following conditions are all met:
- DEBUG-level logging of JDK security event is enabled.
- A user has no Bouncy Castle dependency.
- <type://@Description> annotations at the super class or interface are now used for the parameter description. #5195 #5562
- The specfied `ObjectMapper` to <type://WebClientRequestPreparation#asJson(Class,ObjectMapper)> isn't
ignored anymore. #5454 #5512
- <type://GrpcExceptionHandlerFunction> is now applied to convert a gRPC cancellations. #5329 #5398
- In Spring integration, the default <type://ClientFactory> is now gracefully closed after the server shuts down. #5742
- A connection is not reused anymore after a <type://WriteTimeoutException> is raised. #5738
- <type://ServiceRequestContext> is now correctly propagated when
<type://ServerErrorHandler#onServiceException(ServiceRequestContext,Throwable)> is invoked. #5746

## 🏚️ Deprecations

- <type://PrometheusMeterRegistries> and <type://PrometheusExpositionService> are deprecated. #5698
- Use the same classes in the `armeria-prometheus1` module.
- <type://HttpResult> is deprecated. Use <type://ResponseEntity> instead. #4910 #5586
- <type://GraphqlConfigurator> and various setter methods for building a `GraphQL` instance are deprecated.
- Use <type://GraphqlServiceBuilder#graphql(GraphQL)> instead. #5269

## ☢️ Breaking changes

- We updated Micrometer to 1.13.0 that has breaking changes in its Prometheus support. #5698
- If you want to keep the old behavior that uses Prometheus Java client 0.x,
use the `io.micrometer:micrometer-registry-prometheus-simpleclient:1.13.0` module.
- If you want to use Prometheus Java client 1.x, add `com.linecorp.armeria:armeria-prometheus1` module.
- More details can be found in the [Micrometer migration guide](https://github.com/micrometer-metrics/micrometer/wiki/1.13-Migration-Guide).
- <type://AbstractEndpointSelector#updateNewEndpoints(List)> now returns a `CompletableFuture`. #5752
- The following builder classes now have the `SELF` type parameter. #5733
- <type://AbstractDnsResolverBuilder>
- <type://AbstractRuleBuilder>
- <type://AbstractRuleWithContentBuilder>
- <type://AbstractCircuitBreakerMappingBuilder>
- <type://AbstractDynamicEndpointGroupBuilder>
- <type://DynamicEndpointGroupSetters>
- <type://AbstractCuratorFrameworkBuilder>

## ⛓ Dependencies

- Blockhound 1.0.8.RELEASE1.0.9.RELEASE
- Control Plane 1.0.441.0.45
- GraphQL Kotlin 7.0.27.1.1
- gRPC Java 1.63.01.64.0
- Jackson 2.17.02.17.1
- Kotlin Coroutine 1.8.01.8.1
- Kubernetes client 6.11.06.12.1
- Mircometer 1.12.41.13.0
- Netty 4.1.108.Final4.1.110.Final
- Reactor 3.6.43.6.6
- Scala2.13 2.13.132.13.14
- Scala Collection compat 2.11.02.12.0
- Spring 6.1.56.1.8
- Spring Boot 3.2.43.3.0

## 🙇 Thank you

<ThankYou usernames={[
'ahnyujin',
'Be-poz',
'Dogacel',
'ChangguHan',
'chickenchickenlove',
'cj848',
'dachshu',
'efaurie',
'HappyHacker123',
'ikhoon',
'imasahiro',
'injae-kim',
'jaeseung-bae',
'jrhee17',
'KarboniteKream',
'ks-yim',
'Leewongi0731',
'minwoox',
'moromin',
'my4-dev',
'pinest94',
'ribafish',
'runningcode',
'sato9818',
'seonWKim',
'seongbeenkim',
'SeungWook-Han',
'sh-cho',
'sjy982',
'taisey',
'trustin',
'YangSiJun528',
'yeojin-dev'
]} />

0 comments on commit 9495a06

Please sign in to comment.