From 722ecbf189a3bee0913f92a0bc79061b782bd6cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Novotn=C3=BD?= Date: Tue, 18 Jun 2024 21:37:44 +0200 Subject: [PATCH 1/2] fix(#607): Support for disabling keep-alive header in configuration Due to bug in Node.JS nodejs/node#47130 we need to provide ability to disable keep-alive header in evitaDB. --- documentation/user/en/operate/configure.md | 48 +++++++- .../externalApi/configuration/ApiOptions.java | 114 +++++++++++++++--- .../externalApi/http/ExternalApiServer.java | 15 ++- ...LArtificialFullDatabaseBenchmarkState.java | 8 +- ...cArtificialFullDatabaseBenchmarkState.java | 13 +- ...rArtificialFullDatabaseBenchmarkState.java | 13 +- ...tArtificialFullDatabaseBenchmarkState.java | 8 +- evita_server/run-server.sh | 2 +- .../main/resources/evita-configuration.yaml | 7 +- .../main/resources/evita-configuration.yaml | 7 +- 10 files changed, 177 insertions(+), 58 deletions(-) diff --git a/documentation/user/en/operate/configure.md b/documentation/user/en/operate/configure.md index acc8cb504..13df41722 100644 --- a/documentation/user/en/operate/configure.md +++ b/documentation/user/en/operate/configure.md @@ -53,7 +53,12 @@ cache: # [see Cache configuration](#c api: # [see API configuration](#api-configuration) exposedOn: null - ioThreads: 4 + ioThreads: null + idleTimeoutInMillis: 2K + requestTimeoutInMillis: 2K + parseTimeoutInMillis: 1K + keepAlive: true + maxEntitySizeInBytes: 2MB accessLog: false certificate: # [see TLS configuration](#tls-configuration) generateAndUseSelfSigned: true @@ -566,11 +571,6 @@ is resolved. This section of the configuration allows you to selectively enable, disable, and tweak specific APIs.
-
ioThreads
-
-

**Default:** `4`

-

Defines the number of IO threads that will be used by Undertow for accept and send HTTP payload.

-
exposedOn

When evitaDB is running in a Docker container and the ports are exposed on the host systems @@ -579,6 +579,42 @@ This section of the configuration allows you to selectively enable, disable, and the name (without port) of the host system host name that will be used by all API endpoints without specific `exposedHost` configuration property to use that host name and appropriate port.

+
ioThreads
+
+

**Default:** `number of CPUs * 2`

+

Defines the number of IO threads that will be used by Undertow for accept and send HTTP payload.

+
+
idleTimeoutInMillis
+
+

**Default:** `2K`

+

The amount of time a connection can be idle for before it is timed out. An idle connection is a connection + that has had no data transfer in the idle timeout period. Note that this is a fairly coarse grained approach, + and small values will cause problems for requests with a long processing time.

+
+
requestTimeoutInMillis
+
+

**Default:** `2K`

+

The amount of time a connection can sit idle without processing a request, before it is closed by the server.

+
+
parseTimeoutInMillis
+
+

**Default:** `1K`

+

How long a request can spend in the parsing phase before it is timed out. This timer is started when the first + bytes of a request are read, and finishes once all the headers have been parsed.

+
+
keepAlive
+
+

**Default:** `true`

+

If this is true then a Connection: keep-alive header will be added to responses, even when it is not strictly + required by the specification.

+
+
maxEntitySizeInBytes
+
+

**Default:** `2MB`

+

The default maximum size of a request entity. If entity body is larger than this limit then a IOException + will be thrown at some point when reading the request (on the first read for fixed length requests, when too + much data has been read for chunked requests).

+
accessLog

**Default:** `false`

diff --git a/evita_external_api/evita_external_api_core/src/main/java/io/evitadb/externalApi/configuration/ApiOptions.java b/evita_external_api/evita_external_api_core/src/main/java/io/evitadb/externalApi/configuration/ApiOptions.java index cf1ae2010..73aa6023e 100644 --- a/evita_external_api/evita_external_api_core/src/main/java/io/evitadb/externalApi/configuration/ApiOptions.java +++ b/evita_external_api/evita_external_api_core/src/main/java/io/evitadb/externalApi/configuration/ApiOptions.java @@ -42,20 +42,44 @@ /** * This DTO record encapsulates common settings shared among all the API endpoints. * - * @param exposedOn the name of the host the APIs will be exposed on when evitaDB is running inside a container - * @param ioThreads defines the number of IO thread will be used by Undertow for accept and send HTTP payload - * @param accessLog defines whether the access logs will be enabled or not - * @param endpoints contains specific configuration for all the API endpoints - * @param certificate defines the certificate settings that will be used to secure connections to the web servers providing APIs + * @param exposedOn the name of the host the APIs will be exposed on when evitaDB is running inside a container + * @param ioThreads defines the number of IO thread will be used by Undertow for accept and send HTTP payload + * @param idleTimeoutInMillis The amount of time a connection can be idle for before it is timed out. An idle connection is a + * connection that has had no data transfer in the idle timeout period. Note that this is a fairly coarse + * grained approach, and small values will cause problems for requests with a long processing time. + * @param parseTimeoutInMillis How long a request can spend in the parsing phase before it is timed out. This timer is started when + * the first bytes of a request are read, and finishes once all the headers have been parsed. + * @param requestTimeoutInMillis The amount of time a connection can sit idle without processing a request, before it is closed by + * the server. + * @param keepAlive If this is true then a Connection: keep-alive header will be added to responses, even when it is not strictly required by + * the specification. + * @param maxEntitySizeInBytes The default maximum size of a request entity. If entity body is larger than this limit then a + * java.io.IOException will be thrown at some point when reading the request (on the first read for fixed + * length requests, when too much data has been read for chunked requests). + * @param accessLog defines whether the access logs will be enabled or not + * @param endpoints contains specific configuration for all the API endpoints + * @param certificate defines the certificate settings that will be used to secure connections to the web servers providing APIs * @author Jan Novotný (novotny@fg.cz), FG Forrest a.s. (c) 2022 */ public record ApiOptions( @Nonnull String exposedOn, - @Nullable Integer ioThreads, + int ioThreads, + int idleTimeoutInMillis, + int requestTimeoutInMillis, + int parseTimeoutInMillis, + boolean keepAlive, + long maxEntitySizeInBytes, boolean accessLog, @Nonnull CertificateSettings certificate, @Nonnull Map endpoints ) { + // double the value of available processors (recommended by Undertow configuration) + public static final int DEFAULT_IO_THREADS = Runtime.getRuntime().availableProcessors() << 1; + public static final int DEFAULT_IDLE_TIMEOUT = 20 * 1000; + public static final int DEFAULT_PARSE_TIMEOUT = 1000; + public static final int DEFAULT_REQUEST_TIMEOUT = 1000; + public static final boolean DEFAULT_KEEP_ALIVE = true; + public static final long DEFAULT_MAX_ENTITY_SIZE = 2_097_152L; /** * Builder for the api options. Recommended to use to avoid binary compatibility problems in the future. @@ -64,8 +88,31 @@ public static ApiOptions.Builder builder() { return new ApiOptions.Builder(); } + public ApiOptions( + @Nonnull String exposedOn, + int ioThreads, int idleTimeoutInMillis, int requestTimeoutInMillis, int parseTimeoutInMillis, + boolean keepAlive, long maxEntitySizeInBytes, boolean accessLog, + @Nonnull CertificateSettings certificate, + @Nonnull Map endpoints + ) { + this.exposedOn = exposedOn; + this.ioThreads = ioThreads <= 0 ? DEFAULT_IO_THREADS : ioThreads; + this.idleTimeoutInMillis = idleTimeoutInMillis <= 0 ? DEFAULT_IDLE_TIMEOUT : idleTimeoutInMillis; + this.requestTimeoutInMillis = requestTimeoutInMillis <= 0 ? DEFAULT_REQUEST_TIMEOUT : requestTimeoutInMillis; + this.parseTimeoutInMillis = parseTimeoutInMillis <= 0 ? DEFAULT_PARSE_TIMEOUT : parseTimeoutInMillis; + this.keepAlive = keepAlive; + this.maxEntitySizeInBytes = maxEntitySizeInBytes <= 0 ? DEFAULT_MAX_ENTITY_SIZE : maxEntitySizeInBytes; + this.accessLog = accessLog; + this.certificate = certificate; + this.endpoints = endpoints; + } + public ApiOptions() { - this(null, null, false, new CertificateSettings(), new HashMap<>(8)); + this( + null, DEFAULT_IO_THREADS, DEFAULT_IDLE_TIMEOUT, DEFAULT_REQUEST_TIMEOUT, DEFAULT_PARSE_TIMEOUT, + DEFAULT_KEEP_ALIVE, DEFAULT_MAX_ENTITY_SIZE, false, + new CertificateSettings(), new HashMap<>(8) + ); } /** @@ -77,15 +124,6 @@ public T getEndpointConfiguration(@Nonnull return (T) endpoints.get(endpointCode); } - /** - * Returns set {@link #ioThreads} or returns a default value. - */ - public int ioThreadsAsInt() { - return ofNullable(ioThreads) - // double the value of available processors (recommended by Undertow configuration) - .orElseGet(() -> Runtime.getRuntime().availableProcessors() << 1); - } - /** * Standard builder pattern implementation. */ @@ -93,9 +131,14 @@ public int ioThreadsAsInt() { public static class Builder { private final Map> apiProviders; private final Map enabledProviders; + private int ioThreads = DEFAULT_IO_THREADS; + private int idleTimeoutInMillis = DEFAULT_IDLE_TIMEOUT; + private int requestTimeoutInMillis = DEFAULT_REQUEST_TIMEOUT; + private int parseTimeoutInMillis = DEFAULT_PARSE_TIMEOUT; + private boolean keepAlive = DEFAULT_KEEP_ALIVE; + private long maxEntitySizeInBytes = DEFAULT_MAX_ENTITY_SIZE; private CertificateSettings certificate; @Nullable private String exposedOn; - @Nullable private Integer ioThreads; private boolean accessLog; Builder() { @@ -119,8 +162,38 @@ public ApiOptions.Builder exposedOn(@Nonnull String exposedOn) { } @Nonnull - public ApiOptions.Builder ioThreads(int ioThreads) { - this.ioThreads = ioThreads; + public ApiOptions.Builder ioThreads(@Nullable Integer ioThreads) { + this.ioThreads = ofNullable(ioThreads).orElse(DEFAULT_IO_THREADS); + return this; + } + + @Nonnull + public ApiOptions.Builder idleTimeoutInMillis(int idleTimeoutInMillis) { + this.idleTimeoutInMillis = idleTimeoutInMillis; + return this; + } + + @Nonnull + public ApiOptions.Builder requestTimeoutInMillis(int requestTimeoutInMillis) { + this.requestTimeoutInMillis = requestTimeoutInMillis; + return this; + } + + @Nonnull + public ApiOptions.Builder parseTimeoutInMillis(int parseTimeoutInMillis) { + this.parseTimeoutInMillis = parseTimeoutInMillis; + return this; + } + + @Nonnull + public ApiOptions.Builder keepAlive(boolean keepAlive) { + this.keepAlive = keepAlive; + return this; + } + + @Nonnull + public ApiOptions.Builder maxEntitySizeInBytes(long maxEntitySizeInBytes) { + this.maxEntitySizeInBytes = maxEntitySizeInBytes; return this; } @@ -170,7 +243,8 @@ public ApiOptions.Builder enable(@Nonnull S @Nonnull public ApiOptions build() { return new ApiOptions( - exposedOn, ioThreads, accessLog, certificate, enabledProviders + exposedOn, ioThreads, idleTimeoutInMillis, requestTimeoutInMillis, parseTimeoutInMillis, + keepAlive, maxEntitySizeInBytes, accessLog, certificate, enabledProviders ); } } diff --git a/evita_external_api/evita_external_api_core/src/main/java/io/evitadb/externalApi/http/ExternalApiServer.java b/evita_external_api/evita_external_api_core/src/main/java/io/evitadb/externalApi/http/ExternalApiServer.java index 27c8c0605..984873e43 100644 --- a/evita_external_api/evita_external_api_core/src/main/java/io/evitadb/externalApi/http/ExternalApiServer.java +++ b/evita_external_api/evita_external_api_core/src/main/java/io/evitadb/externalApi/http/ExternalApiServer.java @@ -452,7 +452,7 @@ private void configureUndertow( /* IO threads represent separate thread pool, this is enforced by Undertow. */ - .setWorkerIoThreads(apiOptions.ioThreadsAsInt()) + .setWorkerIoThreads(apiOptions.ioThreads()) .setWorkerName("Undertow XNIO worker.") .build() ) @@ -470,19 +470,24 @@ private void configureUndertow( grained approach, and small values will cause problems for requests with a long processing time. (milliseconds) */ - .setServerOption(UndertowOptions.IDLE_TIMEOUT, 20 * 1000) + .setServerOption(UndertowOptions.IDLE_TIMEOUT, apiOptions.idleTimeoutInMillis()) /* How long a request can spend in the parsing phase before it is timed out. This timer is started when the first bytes of a request are read, and finishes once all the headers have been parsed. (milliseconds) */ - .setServerOption(UndertowOptions.REQUEST_PARSE_TIMEOUT, 1000) + .setServerOption(UndertowOptions.REQUEST_PARSE_TIMEOUT, apiOptions.parseTimeoutInMillis()) /* The amount of time a connection can sit idle without processing a request, before it is closed by the server. (milliseconds) */ - .setServerOption(UndertowOptions.NO_REQUEST_TIMEOUT, 1000) + .setServerOption(UndertowOptions.NO_REQUEST_TIMEOUT, apiOptions.requestTimeoutInMillis()) + /* + If this is true then a Connection: keep-alive header will be added to responses, even when it is not strictly required by + the specification. + */ + .setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, apiOptions.keepAlive()) /* The default maximum size of a request entity. If entity body is larger than this limit then a java.io.IOException will be thrown at some point when reading the request (on the first read for fixed @@ -490,7 +495,7 @@ java.io.IOException will be thrown at some point when reading the request (on th size, it is possible for a handler to override this for an individual request by calling io.undertow.server.HttpServerExchange.setMaxEntitySize(long size). Defaults to unlimited. */ - .setServerOption(UndertowOptions.MAX_ENTITY_SIZE, 2_097_152L); + .setServerOption(UndertowOptions.MAX_ENTITY_SIZE, apiOptions.maxEntitySizeInBytes()); final AccessLogReceiver accessLogReceiver = apiOptions.accessLog() ? new Slf4JAccessLogReceiver() : new NoopAccessLogReceiver(); diff --git a/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/graphql/artificial/GraphQLArtificialFullDatabaseBenchmarkState.java b/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/graphql/artificial/GraphQLArtificialFullDatabaseBenchmarkState.java index 0e348a860..88b74dbe1 100644 --- a/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/graphql/artificial/GraphQLArtificialFullDatabaseBenchmarkState.java +++ b/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/graphql/artificial/GraphQLArtificialFullDatabaseBenchmarkState.java @@ -6,7 +6,7 @@ * | __/\ V /| | || (_| | |_| | |_) | * \___| \_/ |_|\__\__,_|____/|____/ * - * Copyright (c) 2023 + * Copyright (c) 2023-2024 * * Licensed under the Business Source License, Version 1.1 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,6 @@ import io.evitadb.api.requestResponse.data.structure.EntityReference; import io.evitadb.api.requestResponse.schema.SealedEntitySchema; import io.evitadb.externalApi.configuration.ApiOptions; -import io.evitadb.externalApi.configuration.CertificateSettings; import io.evitadb.externalApi.graphql.GraphQLProvider; import io.evitadb.externalApi.graphql.GraphQLProviderRegistrar; import io.evitadb.externalApi.graphql.configuration.GraphQLConfig; @@ -39,7 +38,6 @@ import org.openjdk.jmh.annotations.TearDown; import java.util.Collections; -import java.util.Map; /** * Base state class for {@link GraphQLArtificialEntitiesBenchmark} benchmark. @@ -86,7 +84,9 @@ public void setUp() { // start graphql server server = new ExternalApiServer( this.evita, - new ApiOptions(null, null, false, new CertificateSettings.Builder().build(), Map.of(GraphQLProvider.CODE, new GraphQLConfig())), + ApiOptions.builder() + .enable(GraphQLProvider.CODE, new GraphQLConfig()) + .build(), Collections.singleton(new GraphQLProviderRegistrar()) ); server.start(); diff --git a/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/grpc/artificial/GrpcArtificialFullDatabaseBenchmarkState.java b/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/grpc/artificial/GrpcArtificialFullDatabaseBenchmarkState.java index 094b87e31..b05632857 100644 --- a/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/grpc/artificial/GrpcArtificialFullDatabaseBenchmarkState.java +++ b/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/grpc/artificial/GrpcArtificialFullDatabaseBenchmarkState.java @@ -6,7 +6,7 @@ * | __/\ V /| | || (_| | |_| | |_) | * \___| \_/ |_|\__\__,_|____/|____/ * - * Copyright (c) 2023 + * Copyright (c) 2023-2024 * * Licensed under the Business Source License, Version 1.1 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,6 @@ import io.evitadb.api.requestResponse.schema.SealedEntitySchema; import io.evitadb.externalApi.configuration.AbstractApiConfiguration; import io.evitadb.externalApi.configuration.ApiOptions; -import io.evitadb.externalApi.configuration.CertificateSettings; import io.evitadb.externalApi.grpc.GrpcProvider; import io.evitadb.externalApi.grpc.GrpcProviderRegistrar; import io.evitadb.externalApi.grpc.configuration.GrpcConfig; @@ -43,7 +42,6 @@ import org.openjdk.jmh.annotations.TearDown; import java.util.List; -import java.util.Map; /** * Base state class for {@link GrpcArtificialEntitiesBenchmark} benchmark. @@ -90,11 +88,10 @@ public void setUp() { // start grpc server server = new ExternalApiServer( this.evita, - new ApiOptions( - null, null, false, new CertificateSettings.Builder().build(), Map.of( - SystemProvider.CODE, new SystemConfig(AbstractApiConfiguration.LOCALHOST + ":" + SystemConfig.DEFAULT_SYSTEM_PORT), - GrpcProvider.CODE, new GrpcConfig()) - ), + ApiOptions.builder() + .enable(SystemProvider.CODE, new SystemConfig(AbstractApiConfiguration.LOCALHOST + ":" + SystemConfig.DEFAULT_SYSTEM_PORT)) + .enable(GrpcProvider.CODE, new GrpcConfig()) + .build(), List.of(new GrpcProviderRegistrar(), new SystemProviderRegistrar()) ); server.start(); diff --git a/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/javaDriver/artificial/JavaDriverArtificialFullDatabaseBenchmarkState.java b/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/javaDriver/artificial/JavaDriverArtificialFullDatabaseBenchmarkState.java index c4f5a582f..5223b199f 100644 --- a/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/javaDriver/artificial/JavaDriverArtificialFullDatabaseBenchmarkState.java +++ b/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/javaDriver/artificial/JavaDriverArtificialFullDatabaseBenchmarkState.java @@ -6,7 +6,7 @@ * | __/\ V /| | || (_| | |_| | |_) | * \___| \_/ |_|\__\__,_|____/|____/ * - * Copyright (c) 2023 + * Copyright (c) 2023-2024 * * Licensed under the Business Source License, Version 1.1 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,6 @@ import io.evitadb.driver.config.EvitaClientConfiguration; import io.evitadb.externalApi.configuration.AbstractApiConfiguration; import io.evitadb.externalApi.configuration.ApiOptions; -import io.evitadb.externalApi.configuration.CertificateSettings; import io.evitadb.externalApi.grpc.GrpcProvider; import io.evitadb.externalApi.grpc.GrpcProviderRegistrar; import io.evitadb.externalApi.grpc.configuration.GrpcConfig; @@ -47,7 +46,6 @@ import java.nio.file.Path; import java.util.List; -import java.util.Map; /** * Base state class for {@link JavaDriverArtificialEntitiesBenchmark} benchmark. @@ -93,11 +91,10 @@ public void setUp() { // start grpc server and system api server = new ExternalApiServer( this.evita, - new ApiOptions( - null, null, false, new CertificateSettings.Builder().build(), Map.of( - SystemProvider.CODE, new SystemConfig(AbstractApiConfiguration.LOCALHOST + ":" + SystemConfig.DEFAULT_SYSTEM_PORT), - GrpcProvider.CODE, new GrpcConfig()) - ), + ApiOptions.builder() + .enable(SystemProvider.CODE, new SystemConfig(AbstractApiConfiguration.LOCALHOST + ":" + SystemConfig.DEFAULT_SYSTEM_PORT)) + .enable(GrpcProvider.CODE, new GrpcConfig()) + .build(), List.of(new SystemProviderRegistrar(), new GrpcProviderRegistrar()) ); server.start(); diff --git a/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/rest/artificial/RestArtificialFullDatabaseBenchmarkState.java b/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/rest/artificial/RestArtificialFullDatabaseBenchmarkState.java index f377d4fd4..30b32461e 100644 --- a/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/rest/artificial/RestArtificialFullDatabaseBenchmarkState.java +++ b/evita_performance_tests/src/main/java/io/evitadb/performance/externalApi/rest/artificial/RestArtificialFullDatabaseBenchmarkState.java @@ -6,7 +6,7 @@ * | __/\ V /| | || (_| | |_| | |_) | * \___| \_/ |_|\__\__,_|____/|____/ * - * Copyright (c) 2023 + * Copyright (c) 2023-2024 * * Licensed under the Business Source License, Version 1.1 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,6 @@ import io.evitadb.api.requestResponse.data.structure.EntityReference; import io.evitadb.api.requestResponse.schema.SealedEntitySchema; import io.evitadb.externalApi.configuration.ApiOptions; -import io.evitadb.externalApi.configuration.CertificateSettings; import io.evitadb.externalApi.http.ExternalApiServer; import io.evitadb.externalApi.rest.RestProvider; import io.evitadb.externalApi.rest.RestProviderRegistrar; @@ -39,7 +38,6 @@ import org.openjdk.jmh.annotations.TearDown; import java.util.Collections; -import java.util.Map; /** * Base state class for {@link RestArtificialEntitiesBenchmark} benchmark. @@ -87,7 +85,9 @@ public void setUp() { // start rest server server = new ExternalApiServer( this.evita, - new ApiOptions(null, null, false, new CertificateSettings.Builder().build(), Map.of(RestProvider.CODE, new RestConfig())), + ApiOptions.builder() + .enable(RestProvider.CODE, new RestConfig()) + .build(), Collections.singleton(new RestProviderRegistrar()) ); server.start(); diff --git a/evita_server/run-server.sh b/evita_server/run-server.sh index 101e32e20..2ba9cafb8 100755 --- a/evita_server/run-server.sh +++ b/evita_server/run-server.sh @@ -23,7 +23,7 @@ # java \ - -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:8005 \ + -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8005 \ -javaagent:target/evita-server.jar \ -jar "target/evita-server.jar" \ "configDir=../config/" \ diff --git a/evita_server/src/main/resources/evita-configuration.yaml b/evita_server/src/main/resources/evita-configuration.yaml index 4ad29f2a6..f1ee9556f 100644 --- a/evita_server/src/main/resources/evita-configuration.yaml +++ b/evita_server/src/main/resources/evita-configuration.yaml @@ -41,7 +41,12 @@ cache: api: exposedOn: ${api.exposedOn:null} - ioThreads: ${api.ioThreads:4} + ioThreads: ${api.ioThreads:null} + idleTimeoutInMillis: ${api.idleTimeoutInMillis:2K} + requestTimeoutInMillis: ${api.requestTimeoutInMillis:2K} + parseTimeoutInMillis: ${api.parseTimeoutInMillis:1K} + keepAlive: ${api.keepAlive:true} + maxEntitySizeInBytes: ${api.maxEntitySizeInBytes:2MB} accessLog: ${api.accessLog:false} certificate: generateAndUseSelfSigned: ${api.certificate.generateAndUseSelfSigned:true} diff --git a/evita_test_support/src/main/resources/evita-configuration.yaml b/evita_test_support/src/main/resources/evita-configuration.yaml index f6f6b087a..4a50e7b39 100644 --- a/evita_test_support/src/main/resources/evita-configuration.yaml +++ b/evita_test_support/src/main/resources/evita-configuration.yaml @@ -41,7 +41,12 @@ cache: api: exposedOn: ${api.exposedOn:null} - ioThreads: ${api.ioThreads:4} + ioThreads: ${api.ioThreads:null} + idleTimeoutInMillis: ${api.idleTimeoutInMillis:2K} + requestTimeoutInMillis: ${api.requestTimeoutInMillis:2K} + parseTimeoutInMillis: ${api.parseTimeoutInMillis:1K} + keepAlive: ${api.keepAlive:true} + maxEntitySizeInBytes: ${api.maxEntitySizeInBytes:2MB} accessLog: ${api.accessLog:false} certificate: generateAndUseSelfSigned: ${api.certificate.generateAndUseSelfSigned:true} From c1c350462973c3d45d35d7c2ea76baa586a2a71e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Novotn=C3=BD?= Date: Tue, 18 Jun 2024 21:42:07 +0200 Subject: [PATCH 2/2] fix: TLS is automatically disabled for disabled API endpoints --- .../evitadb/externalApi/http/ExternalApiServer.java | 13 +++++++------ .../externalApi/system/SystemProviderRegistrar.java | 3 +-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/evita_external_api/evita_external_api_core/src/main/java/io/evitadb/externalApi/http/ExternalApiServer.java b/evita_external_api/evita_external_api_core/src/main/java/io/evitadb/externalApi/http/ExternalApiServer.java index 984873e43..e55bc6b91 100644 --- a/evita_external_api/evita_external_api_core/src/main/java/io/evitadb/externalApi/http/ExternalApiServer.java +++ b/evita_external_api/evita_external_api_core/src/main/java/io/evitadb/externalApi/http/ExternalApiServer.java @@ -146,11 +146,12 @@ public static CertificatePath initCertificate( final CertificateType[] certificateTypes = apiOptions.endpoints() .values() .stream() - .flatMap(it -> Stream.of( - it.isTlsEnabled() ? CertificateType.SERVER : null, - it.isMtlsEnabled() ? CertificateType.CLIENT : null - ) - .filter(Objects::nonNull)) + .flatMap( + it -> Stream.of( + it.isEnabled() && it.isTlsEnabled() ? CertificateType.SERVER : null, + it.isEnabled() && it.isMtlsEnabled() ? CertificateType.CLIENT : null + ).filter(Objects::nonNull) + ) .distinct() .toArray(CertificateType[]::new); @@ -362,7 +363,7 @@ public ExternalApiServer( initCertificate(apiOptions, serverCertificateManager) : ( certificateSettings.custom().certificate() != null && !certificateSettings.custom().certificate().isBlank() && - certificateSettings.custom().privateKey() != null && !certificateSettings.custom().privateKey().isBlank() ? + certificateSettings.custom().privateKey() != null && !certificateSettings.custom().privateKey().isBlank() ? new CertificatePath( certificateSettings.custom().certificate(), certificateSettings.custom().privateKey(), diff --git a/evita_external_api/evita_external_api_system/src/main/java/io/evitadb/externalApi/system/SystemProviderRegistrar.java b/evita_external_api/evita_external_api_system/src/main/java/io/evitadb/externalApi/system/SystemProviderRegistrar.java index 9c3d1c30b..74e08f5ed 100644 --- a/evita_external_api/evita_external_api_system/src/main/java/io/evitadb/externalApi/system/SystemProviderRegistrar.java +++ b/evita_external_api/evita_external_api_system/src/main/java/io/evitadb/externalApi/system/SystemProviderRegistrar.java @@ -30,7 +30,6 @@ import io.evitadb.externalApi.api.system.ProbesProvider.Readiness; import io.evitadb.externalApi.api.system.ProbesProvider.ReadinessState; import io.evitadb.externalApi.api.system.model.HealthProblem; -import io.evitadb.externalApi.configuration.AbstractApiConfiguration; import io.evitadb.externalApi.configuration.ApiOptions; import io.evitadb.externalApi.configuration.CertificatePath; import io.evitadb.externalApi.configuration.CertificateSettings; @@ -269,7 +268,7 @@ public ExternalApiProvider register( final boolean atLeastOnEndpointRequiresTls = apiOptions.endpoints() .values() .stream() - .anyMatch(AbstractApiConfiguration::isTlsEnabled); + .anyMatch(it -> it.isEnabled() && it.isTlsEnabled()); final boolean atLeastOnEndpointRequiresMtls = apiOptions.endpoints() .values() .stream()