aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@vespa.ai>2024-06-06 11:08:45 +0200
committerBjørn Christian Seime <bjorncs@vespa.ai>2024-06-06 11:40:41 +0200
commitcf00a65940560c8fbfe32a015f4ef50942e997d8 (patch)
tree277661ff338df1834daaa955b0f225eb5f3d7417
parentd6818209d90b407dc1a9bde5cae4269c071eea2d (diff)
Move parsing of configuration string to config model
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java38
-rw-r--r--container-core/abi-spec.json45
-rw-r--r--container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLoggingRequestHandler.java15
-rw-r--r--container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def4
-rw-r--r--container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java13
5 files changed, 87 insertions, 28 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java
index f8b739c638b..9c9e20062f8 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java
@@ -1,6 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.container.http.ssl;
+import ai.vespa.utils.BytesQuantity;
import com.yahoo.config.model.api.EndpointCertificateSecrets;
import com.yahoo.jdisc.http.ConnectorConfig;
import com.yahoo.security.tls.TlsContext;
@@ -21,6 +22,8 @@ import java.util.TreeSet;
*/
public class HostedSslConnectorFactory extends ConnectorFactory {
+ private record EntityLoggingEntry(String prefix, double sampleRate, BytesQuantity maxEntitySize) {}
+
private final SslClientAuth clientAuth;
private final List<String> tlsCiphersOverride;
private final boolean proxyProtocolEnabled;
@@ -28,7 +31,7 @@ public class HostedSslConnectorFactory extends ConnectorFactory {
private final List<String> remoteAddressHeaders;
private final List<String> remotePortHeaders;
private final Set<String> knownServerNames;
- private final Set<String> requestPrefixForLoggingContent;
+ private final List<EntityLoggingEntry> entityLoggingEntries;
public static Builder builder(String name, int listenPort) { return new Builder(name, listenPort); }
@@ -41,12 +44,22 @@ public class HostedSslConnectorFactory extends ConnectorFactory {
this.remoteAddressHeaders = List.copyOf(builder.remoteAddressHeaders);
this.remotePortHeaders = List.copyOf(builder.remotePortHeaders);
this.knownServerNames = Collections.unmodifiableSet(new TreeSet<>(builder.knownServerNames));
- builder.requestPrefixForLoggingContent.forEach(prefix -> {
- var regex = "^.*:[01](\\.\\d+)?:\\d+[a-zA-Z]+$";
- if (!prefix.matches(regex))
- throw new IllegalArgumentException("Invalid prefix '%s, must match regex '%s'".formatted(prefix, regex));
- });
- this.requestPrefixForLoggingContent = Collections.unmodifiableSet(new TreeSet<>(builder.requestPrefixForLoggingContent));
+ this.entityLoggingEntries = builder.requestPrefixForLoggingContent.stream()
+ .map(prefix -> {
+ var parts = prefix.split(":");
+ if (parts.length != 3) {
+ throw new IllegalArgumentException("Expected string of format 'prefix:sample-rate:max-entity-size', got '%s'".formatted(prefix));
+ }
+ var pathPrefix = parts[0];
+ if (pathPrefix.isBlank())
+ throw new IllegalArgumentException("Path prefix must not be blank");
+ var sampleRate = Double.parseDouble(parts[1]);
+ if (sampleRate < 0 || sampleRate > 1)
+ throw new IllegalArgumentException("Sample rate must be in range [0, 1], got '%s'".formatted(sampleRate));
+ var maxEntitySize = BytesQuantity.fromString(parts[2]);
+ return new EntityLoggingEntry(pathPrefix, sampleRate, maxEntitySize);
+ })
+ .toList();
}
private static SslProvider createSslProvider(Builder builder) {
@@ -79,9 +92,14 @@ public class HostedSslConnectorFactory extends ConnectorFactory {
.idleTimeout(Duration.ofSeconds(30).toSeconds())
.maxConnectionLife(endpointConnectionTtl != null ? endpointConnectionTtl.toSeconds() : 0)
.accessLog(new ConnectorConfig.AccessLog.Builder()
- .remoteAddressHeaders(remoteAddressHeaders)
- .remotePortHeaders(remotePortHeaders)
- .contentPathPrefixes(requestPrefixForLoggingContent))
+ .remoteAddressHeaders(remoteAddressHeaders)
+ .remotePortHeaders(remotePortHeaders)
+ .content(entityLoggingEntries.stream()
+ .map(e -> new ConnectorConfig.AccessLog.Content.Builder()
+ .pathPrefix(e.prefix)
+ .sampleRate(e.sampleRate)
+ .maxSize(e.maxEntitySize.toBytes()))
+ .toList()))
.serverName.known(knownServerNames);
}
diff --git a/container-core/abi-spec.json b/container-core/abi-spec.json
index bf9a177c28e..ef00a1e3087 100644
--- a/container-core/abi-spec.json
+++ b/container-core/abi-spec.json
@@ -1047,16 +1047,51 @@
"public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Builder remoteAddressHeaders(java.util.Collection)",
"public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Builder remotePortHeaders(java.lang.String)",
"public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Builder remotePortHeaders(java.util.Collection)",
- "public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Builder contentPathPrefixes(java.lang.String)",
- "public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Builder contentPathPrefixes(java.util.Collection)",
+ "public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Builder content(com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Content$Builder)",
+ "public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Builder content(java.util.function.Consumer)",
+ "public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Builder content(java.util.List)",
"public com.yahoo.jdisc.http.ConnectorConfig$AccessLog build()"
],
"fields" : [
"public java.util.List remoteAddressHeaders",
"public java.util.List remotePortHeaders",
- "public java.util.List contentPathPrefixes"
+ "public java.util.List content"
]
},
+ "com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Content$Builder" : {
+ "superClass" : "java.lang.Object",
+ "interfaces" : [
+ "com.yahoo.config.ConfigBuilder"
+ ],
+ "attributes" : [
+ "public",
+ "final"
+ ],
+ "methods" : [
+ "public void <init>()",
+ "public void <init>(com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Content)",
+ "public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Content$Builder pathPrefix(java.lang.String)",
+ "public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Content$Builder maxSize(long)",
+ "public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Content$Builder sampleRate(double)",
+ "public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Content build()"
+ ],
+ "fields" : [ ]
+ },
+ "com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Content" : {
+ "superClass" : "com.yahoo.config.InnerNode",
+ "interfaces" : [ ],
+ "attributes" : [
+ "public",
+ "final"
+ ],
+ "methods" : [
+ "public void <init>(com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Content$Builder)",
+ "public java.lang.String pathPrefix()",
+ "public long maxSize()",
+ "public double sampleRate()"
+ ],
+ "fields" : [ ]
+ },
"com.yahoo.jdisc.http.ConnectorConfig$AccessLog" : {
"superClass" : "com.yahoo.config.InnerNode",
"interfaces" : [ ],
@@ -1070,8 +1105,8 @@
"public java.lang.String remoteAddressHeaders(int)",
"public java.util.List remotePortHeaders()",
"public java.lang.String remotePortHeaders(int)",
- "public java.util.List contentPathPrefixes()",
- "public java.lang.String contentPathPrefixes(int)"
+ "public java.util.List content()",
+ "public com.yahoo.jdisc.http.ConnectorConfig$AccessLog$Content content(int)"
],
"fields" : [ ]
},
diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLoggingRequestHandler.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLoggingRequestHandler.java
index 670fb3f41ee..31fd55bb987 100644
--- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLoggingRequestHandler.java
+++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLoggingRequestHandler.java
@@ -10,6 +10,7 @@ import com.yahoo.jdisc.handler.ContentChannel;
import com.yahoo.jdisc.handler.DelegatedRequestHandler;
import com.yahoo.jdisc.handler.RequestHandler;
import com.yahoo.jdisc.handler.ResponseHandler;
+import com.yahoo.jdisc.http.ConnectorConfig;
import com.yahoo.jdisc.http.HttpHeaders;
import com.yahoo.jdisc.http.HttpRequest;
@@ -71,16 +72,10 @@ public class AccessLoggingRequestHandler extends AbstractRequestHandler implemen
this.jettyRequest = jettyRequest;
this.delegateRequestHandler = delegateRequestHandler;
this.accessLogEntry = accessLogEntry;
- var contentPathPrefixes = getConnector(jettyRequest).connectorConfig().accessLog().contentPathPrefixes();
- this.pathPrefixes = contentPathPrefixes.stream()
- .map(s -> s.split(":")[0])
- .toList();
- this.samplingRate = contentPathPrefixes.stream()
- .map(s -> Double.parseDouble(s.split(":")[1]))
- .toList();
- this.maxSize = contentPathPrefixes.stream()
- .map(s -> BytesQuantity.fromString(s.split(":")[2]).toBytes())
- .toList();
+ var cfg = getConnector(jettyRequest).connectorConfig().accessLog().content();
+ this.pathPrefixes = cfg.stream().map(e -> e.pathPrefix()).toList();
+ this.samplingRate = cfg.stream().map(e -> e.sampleRate()).toList();
+ this.maxSize = cfg.stream().map(e -> e.maxSize()).toList();
}
@Override
diff --git a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def b/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def
index b11081cad92..44750b15324 100644
--- a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def
+++ b/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def
@@ -156,4 +156,6 @@ accessLog.remoteAddressHeaders[] string
accessLog.remotePortHeaders[] string
# Path prefixes for which content should be logged
-accessLog.contentPathPrefixes[] string
+accessLog.content[].pathPrefix string
+accessLog.content[].maxSize long
+accessLog.content[].sampleRate double
diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java
index 5905061212f..792d3a6e436 100644
--- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java
+++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java
@@ -1,6 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.jdisc.http.server.jetty;
+import ai.vespa.utils.BytesQuantity;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.yahoo.container.logging.ConnectionLog;
@@ -745,8 +746,16 @@ public class HttpServerTest {
new ServerConfig.Builder(),
new ConnectorConfig.Builder().accessLog(
new ConnectorConfig.AccessLog.Builder()
- .contentPathPrefixes("/search:1:1k")
- .contentPathPrefixes("/document/v1:0.001:1M")),
+ .content(List.of(
+ new ConnectorConfig.AccessLog.Content.Builder()
+ .pathPrefix("/search")
+ .maxSize(BytesQuantity.ofKB(1).toBytes())
+ .sampleRate(1),
+ new ConnectorConfig.AccessLog.Content.Builder()
+ .pathPrefix("/document/v1")
+ .maxSize(BytesQuantity.ofMB(1).toBytes())
+ .sampleRate(0.001)
+ ))),
binder -> binder.bind(RequestLog.class).toInstance(requestLogMock));
driver.client().newPost("/search/").setContent("abcdef").execute().expectStatusCode(is(OK));
RequestLogEntry entry = requestLogMock.poll(Duration.ofSeconds(5));