summaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/schema/document/Matching.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/component/BertEmbedder.java15
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/component/ColBertEmbedder.java31
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/component/HuggingFaceEmbedder.java31
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/component/HuggingFaceTokenizer.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/component/Model.java69
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/component/chain/ChainedComponent.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java70
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ModelIdResolver.java8
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFiles.java6
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/JvmHeapSizeValidatorTest.java7
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFilesTest.java9
12 files changed, 159 insertions, 96 deletions
diff --git a/config-model/src/main/java/com/yahoo/schema/document/Matching.java b/config-model/src/main/java/com/yahoo/schema/document/Matching.java
index 264fd0ff3b9..e3f49cb834d 100644
--- a/config-model/src/main/java/com/yahoo/schema/document/Matching.java
+++ b/config-model/src/main/java/com/yahoo/schema/document/Matching.java
@@ -133,7 +133,7 @@ public class Matching implements Cloneable, Serializable {
if ( this.exactMatchTerminator == null && other.exactMatchTerminator != null) return false;
if ( this.exactMatchTerminator != null && ( ! this.exactMatchTerminator.equals(other.exactMatchTerminator)) )
return false;
- if ( gramSize != other.gramSize) return false;
+ if ( ! gramSize.equals(other.gramSize)) return false;
return true;
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/component/BertEmbedder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/component/BertEmbedder.java
index 76bb1a9e02a..d02b7d0de5f 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/component/BertEmbedder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/component/BertEmbedder.java
@@ -6,10 +6,8 @@ import com.yahoo.config.ModelReference;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.embedding.BertBaseEmbedderConfig;
import com.yahoo.vespa.model.container.ApplicationContainerCluster;
-import com.yahoo.vespa.model.container.xml.ModelIdResolver;
import org.w3c.dom.Element;
-import static com.yahoo.text.XML.getChild;
import static com.yahoo.text.XML.getChildValue;
import static com.yahoo.vespa.model.container.ContainerModelEvaluation.INTEGRATION_BUNDLE_NAME;
@@ -18,8 +16,8 @@ import static com.yahoo.vespa.model.container.ContainerModelEvaluation.INTEGRATI
*/
public class BertEmbedder extends TypedComponent implements BertBaseEmbedderConfig.Producer {
- private final ModelReference model;
- private final ModelReference vocab;
+ private final ModelReference modelRef;
+ private final ModelReference vocabRef;
private final Integer maxTokens;
private final String transformerInputIds;
private final String transformerAttentionMask;
@@ -36,8 +34,9 @@ public class BertEmbedder extends TypedComponent implements BertBaseEmbedderConf
public BertEmbedder(ApplicationContainerCluster cluster, Element xml, DeployState state) {
super("ai.vespa.embedding.BertBaseEmbedder", INTEGRATION_BUNDLE_NAME, xml);
- model = ModelIdResolver.resolveToModelReference(getChild(xml, "transformer-model"), state);
- vocab = ModelIdResolver.resolveToModelReference(getChild(xml, "tokenizer-vocab"), state);
+ var model = Model.fromXml(state, xml, "transformer-model").orElseThrow();
+ modelRef = model.modelReference();
+ vocabRef = Model.fromXml(state, xml, "tokenizer-vocab").orElseThrow().modelReference();
maxTokens = getChildValue(xml, "max-tokens").map(Integer::parseInt).orElse(null);
transformerInputIds = getChildValue(xml, "transformer-input-ids").orElse(null);
transformerAttentionMask = getChildValue(xml, "transformer-attention-mask").orElse(null);
@@ -50,12 +49,12 @@ public class BertEmbedder extends TypedComponent implements BertBaseEmbedderConf
onnxInteropThreads = getChildValue(xml, "onnx-interop-threads").map(Integer::parseInt).orElse(null);
onnxIntraopThreads = getChildValue(xml, "onnx-intraop-threads").map(Integer::parseInt).orElse(null);
onnxGpuDevice = getChildValue(xml, "onnx-gpu-device").map(Integer::parseInt).orElse(null);
- cluster.onnxModelCost().registerModel(model);
+ model.registerOnnxModelCost(cluster);
}
@Override
public void getConfig(BertBaseEmbedderConfig.Builder b) {
- b.transformerModel(model).tokenizerVocab(vocab);
+ b.transformerModel(modelRef).tokenizerVocab(vocabRef);
if (maxTokens != null) b.transformerMaxTokens(maxTokens);
if (transformerInputIds != null) b.transformerInputIds(transformerInputIds);
if (transformerAttentionMask != null) b.transformerAttentionMask(transformerAttentionMask);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/component/ColBertEmbedder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/component/ColBertEmbedder.java
index 63096ebcbe2..66e3b1c9dfd 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/component/ColBertEmbedder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/component/ColBertEmbedder.java
@@ -6,12 +6,8 @@ import com.yahoo.config.ModelReference;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.embedding.ColBertEmbedderConfig;
import com.yahoo.vespa.model.container.ApplicationContainerCluster;
-import com.yahoo.vespa.model.container.xml.ModelIdResolver;
import org.w3c.dom.Element;
-import java.util.Optional;
-
-import static com.yahoo.config.model.builder.xml.XmlHelper.getOptionalChild;
import static com.yahoo.text.XML.getChildValue;
import static com.yahoo.vespa.model.container.ContainerModelEvaluation.INTEGRATION_BUNDLE_NAME;
@@ -20,8 +16,8 @@ import static com.yahoo.vespa.model.container.ContainerModelEvaluation.INTEGRATI
* @author bergum
*/
public class ColBertEmbedder extends TypedComponent implements ColBertEmbedderConfig.Producer {
- private final ModelReference model;
- private final ModelReference vocab;
+ private final ModelReference modelRef;
+ private final ModelReference vocabRef;
private final Integer maxQueryTokens;
@@ -42,11 +38,11 @@ public class ColBertEmbedder extends TypedComponent implements ColBertEmbedderCo
public ColBertEmbedder(ApplicationContainerCluster cluster, Element xml, DeployState state) {
super("ai.vespa.embedding.ColBertEmbedder", INTEGRATION_BUNDLE_NAME, xml);
- var transformerModelElem = getOptionalChild(xml, "transformer-model").orElseThrow();
- model = ModelIdResolver.resolveToModelReference(transformerModelElem, state);
- vocab = getOptionalChild(xml, "tokenizer-model")
- .map(elem -> ModelIdResolver.resolveToModelReference(elem, state))
- .orElseGet(() -> resolveDefaultVocab(transformerModelElem, state));
+ var model = Model.fromXml(state, xml, "transformer-model").orElseThrow();
+ modelRef = model.modelReference();
+ vocabRef = Model.fromXml(state, xml, "tokenizer-model")
+ .map(Model::modelReference)
+ .orElseGet(() -> resolveDefaultVocab(model, state));
maxTokens = getChildValue(xml, "max-tokens").map(Integer::parseInt).orElse(null);
maxQueryTokens = getChildValue(xml, "max-query-tokens").map(Integer::parseInt).orElse(null);
maxDocumentTokens = getChildValue(xml, "max-document-tokens").map(Integer::parseInt).orElse(null);
@@ -60,21 +56,20 @@ public class ColBertEmbedder extends TypedComponent implements ColBertEmbedderCo
onnxInteropThreads = getChildValue(xml, "onnx-interop-threads").map(Integer::parseInt).orElse(null);
onnxIntraopThreads = getChildValue(xml, "onnx-intraop-threads").map(Integer::parseInt).orElse(null);
onnxGpuDevice = getChildValue(xml, "onnx-gpu-device").map(Integer::parseInt).orElse(null);
- cluster.onnxModelCost().registerModel(model);
+ model.registerOnnxModelCost(cluster);
}
- private static ModelReference resolveDefaultVocab(Element model, DeployState state) {
- if (state.isHosted() && model.hasAttribute("model-id")) {
- var implicitVocabId = model.getAttribute("model-id") + "-vocab";
- return ModelIdResolver.resolveToModelReference(
- "tokenizer-model", Optional.of(implicitVocabId), Optional.empty(), Optional.empty(), state);
+ private static ModelReference resolveDefaultVocab(Model model, DeployState state) {
+ var modelId = model.modelId().orElse(null);
+ if (state.isHosted() && modelId != null) {
+ return Model.fromParams(state, model.name(), modelId + "-vocab", null, null).modelReference();
}
throw new IllegalArgumentException("'tokenizer-model' must be specified");
}
@Override
public void getConfig(ColBertEmbedderConfig.Builder b) {
- b.transformerModel(model).tokenizerPath(vocab);
+ b.transformerModel(modelRef).tokenizerPath(vocabRef);
if (maxTokens != null) b.transformerMaxTokens(maxTokens);
if (transformerInputIds != null) b.transformerInputIds(transformerInputIds);
if (transformerAttentionMask != null) b.transformerAttentionMask(transformerAttentionMask);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/component/HuggingFaceEmbedder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/component/HuggingFaceEmbedder.java
index 41b80bf1cb2..af47bee137a 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/component/HuggingFaceEmbedder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/component/HuggingFaceEmbedder.java
@@ -6,12 +6,8 @@ import com.yahoo.config.ModelReference;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.embedding.huggingface.HuggingFaceEmbedderConfig;
import com.yahoo.vespa.model.container.ApplicationContainerCluster;
-import com.yahoo.vespa.model.container.xml.ModelIdResolver;
import org.w3c.dom.Element;
-import java.util.Optional;
-
-import static com.yahoo.config.model.builder.xml.XmlHelper.getOptionalChild;
import static com.yahoo.text.XML.getChildValue;
import static com.yahoo.vespa.model.container.ContainerModelEvaluation.INTEGRATION_BUNDLE_NAME;
@@ -20,8 +16,8 @@ import static com.yahoo.vespa.model.container.ContainerModelEvaluation.INTEGRATI
* @author bjorncs
*/
public class HuggingFaceEmbedder extends TypedComponent implements HuggingFaceEmbedderConfig.Producer {
- private final ModelReference model;
- private final ModelReference vocab;
+ private final ModelReference modelRef;
+ private final ModelReference vocabRef;
private final Integer maxTokens;
private final String transformerInputIds;
private final String transformerAttentionMask;
@@ -36,11 +32,11 @@ public class HuggingFaceEmbedder extends TypedComponent implements HuggingFaceEm
public HuggingFaceEmbedder(ApplicationContainerCluster cluster, Element xml, DeployState state) {
super("ai.vespa.embedding.huggingface.HuggingFaceEmbedder", INTEGRATION_BUNDLE_NAME, xml);
- var transformerModelElem = getOptionalChild(xml, "transformer-model").orElseThrow();
- model = ModelIdResolver.resolveToModelReference(transformerModelElem, state);
- vocab = getOptionalChild(xml, "tokenizer-model")
- .map(elem -> ModelIdResolver.resolveToModelReference(elem, state))
- .orElseGet(() -> resolveDefaultVocab(transformerModelElem, state));
+ var model = Model.fromXml(state, xml, "transformer-model").orElseThrow();
+ modelRef = model.modelReference();
+ vocabRef = Model.fromXml(state, xml, "tokenizer-model")
+ .map(Model::modelReference)
+ .orElseGet(() -> resolveDefaultVocab(model, state));
maxTokens = getChildValue(xml, "max-tokens").map(Integer::parseInt).orElse(null);
transformerInputIds = getChildValue(xml, "transformer-input-ids").orElse(null);
transformerAttentionMask = getChildValue(xml, "transformer-attention-mask").orElse(null);
@@ -52,21 +48,20 @@ public class HuggingFaceEmbedder extends TypedComponent implements HuggingFaceEm
onnxIntraopThreads = getChildValue(xml, "onnx-intraop-threads").map(Integer::parseInt).orElse(null);
onnxGpuDevice = getChildValue(xml, "onnx-gpu-device").map(Integer::parseInt).orElse(null);
poolingStrategy = getChildValue(xml, "pooling-strategy").orElse(null);
- cluster.onnxModelCost().registerModel(model);
+ model.registerOnnxModelCost(cluster);
}
- private static ModelReference resolveDefaultVocab(Element model, DeployState state) {
- if (state.isHosted() && model.hasAttribute("model-id")) {
- var implicitVocabId = model.getAttribute("model-id") + "-vocab";
- return ModelIdResolver.resolveToModelReference(
- "tokenizer-model", Optional.of(implicitVocabId), Optional.empty(), Optional.empty(), state);
+ private static ModelReference resolveDefaultVocab(Model model, DeployState state) {
+ var modelId = model.modelId().orElse(null);
+ if (state.isHosted() && modelId != null) {
+ return Model.fromParams(state, model.name(), modelId + "-vocab", null, null).modelReference();
}
throw new IllegalArgumentException("'tokenizer-model' must be specified");
}
@Override
public void getConfig(HuggingFaceEmbedderConfig.Builder b) {
- b.transformerModel(model).tokenizerPath(vocab);
+ b.transformerModel(modelRef).tokenizerPath(vocabRef);
if (maxTokens != null) b.transformerMaxTokens(maxTokens);
if (transformerInputIds != null) b.transformerInputIds(transformerInputIds);
if (transformerAttentionMask != null) b.transformerAttentionMask(transformerAttentionMask);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/component/HuggingFaceTokenizer.java b/config-model/src/main/java/com/yahoo/vespa/model/container/component/HuggingFaceTokenizer.java
index 0bf5491e872..e9ac93caa68 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/component/HuggingFaceTokenizer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/component/HuggingFaceTokenizer.java
@@ -7,7 +7,6 @@ import com.yahoo.language.huggingface.config.HuggingFaceTokenizerConfig;
import com.yahoo.language.huggingface.config.HuggingFaceTokenizerConfig.Padding;
import com.yahoo.language.huggingface.config.HuggingFaceTokenizerConfig.Truncation;
import com.yahoo.text.XML;
-import com.yahoo.vespa.model.container.xml.ModelIdResolver;
import org.w3c.dom.Element;
import java.util.Map;
@@ -26,7 +25,7 @@ public class HuggingFaceTokenizer extends TypedComponent implements HuggingFaceT
super("com.yahoo.language.huggingface.HuggingFaceTokenizer", LINGUISTICS_BUNDLE_NAME, xml);
for (Element element : XML.getChildren(xml, "model")) {
var lang = element.hasAttribute("language") ? element.getAttribute("language") : "unknown";
- langToModel.put(lang, ModelIdResolver.resolveToModelReference(element, state));
+ langToModel.put(lang, Model.fromXml(state, element).modelReference());
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/component/Model.java b/config-model/src/main/java/com/yahoo/vespa/model/container/component/Model.java
new file mode 100644
index 00000000000..76d93c38aee
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/component/Model.java
@@ -0,0 +1,69 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+package com.yahoo.vespa.model.container.component;
+
+import com.yahoo.config.ModelReference;
+import com.yahoo.config.application.api.ApplicationFile;
+import com.yahoo.config.model.builder.xml.XmlHelper;
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.path.Path;
+import com.yahoo.vespa.model.container.ApplicationContainerCluster;
+import com.yahoo.vespa.model.container.xml.ModelIdResolver;
+import org.w3c.dom.Element;
+
+import java.net.URI;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Represents a model, e.g ONNX model for an embedder.
+ *
+ * @author bjorncs
+ */
+class Model {
+ private final String paramName;
+ private final String modelId;
+ private final URI url;
+ private final ApplicationFile file;
+ private final ModelReference ref;
+
+ private Model(DeployState ds, String paramName, String modelId, URI url, Path file) {
+ this.paramName = Objects.requireNonNull(paramName);
+ if (modelId == null && url == null && file == null)
+ throw new IllegalArgumentException("At least one of 'model-id', 'url' or 'path' must be specified");
+ this.modelId = modelId;
+ this.url = url;
+ this.file = file != null ? ds.getApplicationPackage().getFile(file) : null;
+ this.ref = ModelIdResolver.resolveToModelReference(
+ paramName, Optional.ofNullable(modelId), Optional.ofNullable(url).map(URI::toString),
+ Optional.ofNullable(file).map(Path::toString), ds);
+ }
+
+ static Model fromParams(DeployState ds, String paramName, String modelId, URI url, Path file) {
+ return new Model(ds, paramName, modelId, url, file);
+ }
+
+ static Optional<Model> fromXml(DeployState ds, Element parent, String name) {
+ return XmlHelper.getOptionalChild(parent, name).map(e -> fromXml(ds, e));
+ }
+
+ static Model fromXml(DeployState ds, Element model) {
+ var modelId = XmlHelper.getOptionalAttribute(model, "model-id").orElse(null);
+ var url = XmlHelper.getOptionalAttribute(model, "url").map(URI::create).orElse(null);
+ var path = XmlHelper.getOptionalAttribute(model, "path").map(Path::fromString).orElse(null);
+ return new Model(ds, model.getTagName(), modelId, url, path);
+ }
+
+ void registerOnnxModelCost(ApplicationContainerCluster c) {
+ var resolvedUrl = resolvedUrl().orElse(null);
+ if (file != null) c.onnxModelCost().registerModel(file);
+ else if (resolvedUrl != null) c.onnxModelCost().registerModel(resolvedUrl);
+ }
+
+ String name() { return paramName; }
+ Optional<String> modelId() { return Optional.ofNullable(modelId); }
+ Optional<URI> url() { return Optional.ofNullable(url); }
+ Optional<URI> resolvedUrl() { return ref.url().map(u -> URI.create(u.value())); }
+ Optional<ApplicationFile> file() { return Optional.ofNullable(file); }
+ ModelReference modelReference() { return ref; }
+}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/component/chain/ChainedComponent.java b/config-model/src/main/java/com/yahoo/vespa/model/container/component/chain/ChainedComponent.java
index c0431d01784..2354298779d 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/component/chain/ChainedComponent.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/component/chain/ChainedComponent.java
@@ -29,8 +29,6 @@ public class ChainedComponent<T extends ChainedComponentModel> extends Component
private ComponentId namespace() {
var owner = getParent().getParent();
- return (owner instanceof Chain) ?
- ((Chain) owner).getGlobalComponentId() :
- null;
+ return (owner instanceof Chain<?> chain) ? chain.getGlobalComponentId() : null;
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
index d9c4dea478c..474f3f5ce6d 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
@@ -39,6 +39,8 @@ import com.yahoo.container.jdisc.DataplaneProxyService;
import com.yahoo.container.logging.AccessLog;
import com.yahoo.container.logging.FileConnectionLog;
import com.yahoo.io.IOUtils;
+import com.yahoo.jdisc.http.filter.security.cloud.config.CloudTokenDataPlaneFilterConfig;
+import com.yahoo.jdisc.http.filter.security.cloud.config.CloudTokenDataPlaneFilterConfig.Builder;
import com.yahoo.jdisc.http.server.jetty.DataplaneProxyCredentials;
import com.yahoo.jdisc.http.server.jetty.VoidRequestLog;
import com.yahoo.osgi.provider.model.ComponentModel;
@@ -240,10 +242,9 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
private void addParameterStoreValidationHandler(ApplicationContainerCluster cluster, DeployState deployState) {
+ if ( ! deployState.isHosted()) return;
// Always add platform bundle. Cannot be controlled by a feature flag as platform bundle cannot change.
- if(deployState.isHosted()) {
- cluster.addPlatformBundle(PlatformBundles.absoluteBundlePath("jdisc-cloud-aws"));
- }
+ cluster.addPlatformBundle(PlatformBundles.absoluteBundlePath("jdisc-cloud-aws"));
if (deployState.zone().system().isPublic()) {
BindingPattern bindingPattern = SystemBindingPattern.fromHttpPath("/validate-secret-store");
Handler handler = new Handler(
@@ -459,7 +460,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
private static void addCloudDataPlaneFilter(DeployState deployState, ApplicationContainerCluster cluster) {
if (!deployState.isHosted() || !deployState.zone().system().isPublic()) return;
- var dataplanePort = getMtlsDataplanePort(deployState, cluster);
+ var dataplanePort = getMtlsDataplanePort(deployState);
// Setup secure filter chain
var secureChain = new HttpFilterChain("cloud-data-plane-secure", HttpFilterChain.Type.SYSTEM);
secureChain.addInnerComponent(new CloudDataPlaneFilter(cluster, deployState));
@@ -594,7 +595,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
String serverName = server.getComponentId().getName();
// If the deployment contains certificate/private key reference, setup TLS port
- var builder = HostedSslConnectorFactory.builder(serverName, getMtlsDataplanePort(state, cluster))
+ var builder = HostedSslConnectorFactory.builder(serverName, getMtlsDataplanePort(state))
.proxyProtocol(true, state.getProperties().featureFlags().enableProxyProtocolMixedMode())
.tlsCiphersOverride(state.getProperties().tlsCiphersOverride())
.endpointConnectionTtl(state.getProperties().endpointConnectionTtl());
@@ -627,19 +628,19 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
private void addCloudTokenSupport(DeployState state, ApplicationContainerCluster cluster) {
var server = cluster.getHttp().getHttpServer().get();
- if (!enableTokenSupport(state, cluster)) return;
+ if (!enableTokenSupport(state)) return;
Set<String> tokenEndpoints = tokenEndpoints(state).stream()
.map(ContainerEndpoint::names)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
var endpointCert = state.endpointCertificateSecrets().orElseThrow();
- int tokenPort = getTokenDataplanePort(state, cluster).orElseThrow();
+ int tokenPort = getTokenDataplanePort(state).orElseThrow();
// Set up component to generate proxy cert if token support is enabled
cluster.addSimpleComponent(DataplaneProxyCredentials.class);
cluster.addSimpleComponent(DataplaneProxyService.class);
var dataplaneProxy = new DataplaneProxy(
- getMtlsDataplanePort(state, cluster),
+ getMtlsDataplanePort(state),
tokenPort,
endpointCert.certificate(),
endpointCert.key(),
@@ -659,13 +660,24 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
// Setup token filter chain
var tokenChain = new HttpFilterChain("cloud-token-data-plane-secure", HttpFilterChain.Type.SYSTEM);
- tokenChain.addInnerComponent(new CloudTokenDataPlaneFilter(cluster, state));
+ var tokenFilter = new CloudTokenDataPlaneFilter(cluster, state);
+ tokenChain.addInnerComponent(tokenFilter);
cluster.getHttp().getFilterChains().add(tokenChain);
// Set as default filter for token port
cluster.getHttp().getHttpServer().orElseThrow().getConnectorFactories().stream()
.filter(c -> c.getListenPort() == tokenPort).findAny().orElseThrow()
.setDefaultRequestFilterChain(tokenChain.getComponentId());
+
+ // Set up handler that tells what fingerprints are known to the container
+ class CloudTokenDataPlaneHandler extends Handler implements CloudTokenDataPlaneFilterConfig.Producer {
+ CloudTokenDataPlaneHandler() {
+ super(new ComponentModel("com.yahoo.jdisc.http.filter.security.cloud.CloudTokenDataPlaneHandler", null, "jdisc-security-filters", null));
+ addServerBindings(SystemBindingPattern.fromHttpPortAndPath(Defaults.getDefaults().vespaWebServicePort(), "/data-plane-tokens/v1"));
+ }
+ @Override public void getConfig(Builder builder) { tokenFilter.getConfig(builder); }
+ }
+ cluster.addComponent(new CloudTokenDataPlaneHandler());
}
// Returns the client certificates of the clients defined for an application cluster
@@ -710,7 +722,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
}
private Http buildHttp(DeployState deployState, ApplicationContainerCluster cluster, Element httpElement, ConfigModelContext context) {
- Http http = new HttpBuilder(portBindingOverride(deployState, context, cluster)).build(deployState, cluster, httpElement);
+ Http http = new HttpBuilder(portBindingOverride(deployState, context)).build(deployState, cluster, httpElement);
if (networking == Networking.disable)
http.removeAllServers();
@@ -816,7 +828,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
cluster.addSearchAndDocprocBundles();
addIncludes(processingElement);
cluster.setProcessingChains(new DomProcessingBuilder(null).build(deployState, cluster, processingElement),
- serverBindings(deployState, context, processingElement, ProcessingChains.defaultBindings, cluster).toArray(BindingPattern[]::new));
+ serverBindings(deployState, context, processingElement, ProcessingChains.defaultBindings).toArray(BindingPattern[]::new));
validateAndAddConfiguredComponents(deployState, cluster, processingElement, "renderer", ContainerModelBuilder::validateRendererElement);
}
@@ -841,7 +853,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
private void addUserHandlers(DeployState deployState, ApplicationContainerCluster cluster, Element spec, ConfigModelContext context) {
for (Element component: XML.getChildren(spec, "handler")) {
cluster.addComponent(
- new DomHandlerBuilder(cluster, portBindingOverride(deployState, context, cluster)).build(deployState, cluster, component));
+ new DomHandlerBuilder(cluster, portBindingOverride(deployState, context)).build(deployState, cluster, component));
}
}
@@ -1129,10 +1141,10 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
private void addSearchHandler(DeployState deployState, ApplicationContainerCluster cluster, Element searchElement, ConfigModelContext context) {
var bindingPatterns = List.<BindingPattern>of(SearchHandler.DEFAULT_BINDING);
if (isHostedTenantApplication(context)) {
- bindingPatterns = SearchHandler.bindingPattern(getDataplanePorts(deployState, cluster));
+ bindingPatterns = SearchHandler.bindingPattern(getDataplanePorts(deployState));
}
SearchHandler searchHandler = new SearchHandler(cluster,
- serverBindings(deployState, context, searchElement, bindingPatterns, cluster),
+ serverBindings(deployState, context, searchElement, bindingPatterns),
ContainerThreadpool.UserOptions.fromXml(searchElement).orElse(null));
cluster.addComponent(searchHandler);
@@ -1140,17 +1152,17 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
searchHandler.addComponent(Component.fromClassAndBundle(SearchHandler.EXECUTION_FACTORY, PlatformBundles.SEARCH_AND_DOCPROC_BUNDLE));
}
- private List<BindingPattern> serverBindings(DeployState deployState, ConfigModelContext context, Element searchElement, Collection<BindingPattern> defaultBindings, ApplicationContainerCluster cluster) {
+ private List<BindingPattern> serverBindings(DeployState deployState, ConfigModelContext context, Element searchElement, Collection<BindingPattern> defaultBindings) {
List<Element> bindings = XML.getChildren(searchElement, "binding");
if (bindings.isEmpty())
return List.copyOf(defaultBindings);
- return toBindingList(deployState, context, bindings, cluster);
+ return toBindingList(deployState, context, bindings);
}
- private List<BindingPattern> toBindingList(DeployState deployState, ConfigModelContext context, List<Element> bindingElements, ApplicationContainerCluster cluster) {
+ private List<BindingPattern> toBindingList(DeployState deployState, ConfigModelContext context, List<Element> bindingElements) {
List<BindingPattern> result = new ArrayList<>();
- var portOverride = isHostedTenantApplication(context) ? getDataplanePorts(deployState, cluster) : Set.<Integer>of();
+ var portOverride = isHostedTenantApplication(context) ? getDataplanePorts(deployState) : Set.<Integer>of();
for (Element element: bindingElements) {
String text = element.getTextContent().trim();
if (!text.isEmpty())
@@ -1175,12 +1187,12 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
ContainerDocumentApi.HandlerOptions documentApiOptions = DocumentApiOptionsBuilder.build(documentApiElement);
Element ignoreUndefinedFields = XML.getChild(documentApiElement, "ignore-undefined-fields");
return new ContainerDocumentApi(cluster, documentApiOptions,
- "true".equals(XML.getValue(ignoreUndefinedFields)), portBindingOverride(deployState, context, cluster));
+ "true".equals(XML.getValue(ignoreUndefinedFields)), portBindingOverride(deployState, context));
}
- private Set<Integer> portBindingOverride(DeployState deployState, ConfigModelContext context, ApplicationContainerCluster cluster) {
+ private Set<Integer> portBindingOverride(DeployState deployState, ConfigModelContext context) {
return isHostedTenantApplication(context)
- ? getDataplanePorts(deployState, cluster)
+ ? getDataplanePorts(deployState)
: Set.<Integer>of();
}
@@ -1439,18 +1451,18 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
}
- private static Set<Integer> getDataplanePorts(DeployState ds, ApplicationContainerCluster cluster) {
- var tokenPort = getTokenDataplanePort(ds, cluster);
- var mtlsPort = getMtlsDataplanePort(ds, cluster);
+ private static Set<Integer> getDataplanePorts(DeployState ds) {
+ var tokenPort = getTokenDataplanePort(ds);
+ var mtlsPort = getMtlsDataplanePort(ds);
return tokenPort.isPresent() ? Set.of(mtlsPort, tokenPort.getAsInt()) : Set.of(mtlsPort);
}
- private static int getMtlsDataplanePort(DeployState ds, ApplicationContainerCluster cluster) {
- return enableTokenSupport(ds, cluster) ? 8443 : 4443;
+ private static int getMtlsDataplanePort(DeployState ds) {
+ return enableTokenSupport(ds) ? 8443 : 4443;
}
- private static OptionalInt getTokenDataplanePort(DeployState ds, ApplicationContainerCluster cluster) {
- return enableTokenSupport(ds, cluster) ? OptionalInt.of(8444) : OptionalInt.empty();
+ private static OptionalInt getTokenDataplanePort(DeployState ds) {
+ return enableTokenSupport(ds) ? OptionalInt.of(8444) : OptionalInt.empty();
}
private static Set<ContainerEndpoint> tokenEndpoints(DeployState deployState) {
@@ -1459,7 +1471,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
.collect(Collectors.toSet());
}
- private static boolean enableTokenSupport(DeployState state, ApplicationContainerCluster cluster) {
+ private static boolean enableTokenSupport(DeployState state) {
Set<ContainerEndpoint> tokenEndpoints = tokenEndpoints(state);
return state.isHosted() && state.zone().system().isPublic() && ! tokenEndpoints.isEmpty();
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ModelIdResolver.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ModelIdResolver.java
index be3ca0b8aa9..14216dd8855 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ModelIdResolver.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ModelIdResolver.java
@@ -3,7 +3,6 @@ package com.yahoo.vespa.model.container.xml;
import com.yahoo.config.ModelReference;
import com.yahoo.config.UrlReference;
-import com.yahoo.config.model.builder.xml.XmlHelper;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.text.XML;
import org.w3c.dom.Element;
@@ -88,13 +87,6 @@ public class ModelIdResolver {
}
}
-
- public static ModelReference resolveToModelReference(Element elem, DeployState state) {
- return resolveToModelReference(
- elem.getTagName(), XmlHelper.getOptionalAttribute(elem, "model-id"),
- XmlHelper.getOptionalAttribute(elem, "url"), XmlHelper.getOptionalAttribute(elem, "path"), state);
- }
-
public static ModelReference resolveToModelReference(
String paramName, Optional<String> id, Optional<String> url, Optional<String> path, DeployState state) {
if (id.isEmpty()) return createModelReference(Optional.empty(), url, path, state);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFiles.java b/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFiles.java
index 0095dec8079..8352a011b88 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFiles.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFiles.java
@@ -29,6 +29,7 @@ import static com.yahoo.vespa.model.container.ApplicationContainerCluster.UserCo
* Utility methods for registering file distribution of files/paths/urls/models defined by the user.
*
* @author gjoranv
+ * @author hmusum
*/
public class UserConfiguredFiles implements Serializable {
@@ -57,7 +58,7 @@ public class UserConfiguredFiles implements Serializable {
try {
register(builder, registeredFiles, key);
} catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("Unable to register file specified in services.xml for config '" + key + "': " +
+ throw new IllegalArgumentException("Invalid config in services.xml for '" + key + "': " +
Exceptions.toMessageString(e));
}
}
@@ -126,8 +127,7 @@ public class UserConfiguredFiles implements Serializable {
ConfigPayloadBuilder fileEntry = builder.getObject(name);
if (isEmptyOptionalPath(entry, fileEntry)) continue;
if (fileEntry.getValue() == null || fileEntry.getValue().equals("."))
- throw new IllegalArgumentException("Unable to register file for field '" + name +
- "': Invalid config value '" + fileEntry.getValue() + "'");
+ throw new IllegalArgumentException("Invalid config value '" + fileEntry.getValue() + "' for field '" + name);
registerFileEntry(fileEntry, registeredFiles, isModelType);
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/JvmHeapSizeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/JvmHeapSizeValidatorTest.java
index 447614b8396..9b3b659c252 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/JvmHeapSizeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/JvmHeapSizeValidatorTest.java
@@ -18,6 +18,7 @@ import org.junit.jupiter.api.Test;
import org.xml.sax.SAXException;
import java.io.IOException;
+import java.net.URI;
import java.util.concurrent.atomic.AtomicLong;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
@@ -117,9 +118,11 @@ class JvmHeapSizeValidatorTest {
@Override public long aggregatedModelCostInBytes() { return totalCost.get(); }
@Override public void registerModel(ApplicationFile path) {}
+ @SuppressWarnings("removal") @Override public void registerModel(ModelReference ref) {}
+
@Override
- public void registerModel(ModelReference ref) {
- assertEquals("https://my/url/model.onnx", ref.url().orElseThrow().value().toString());
+ public void registerModel(URI uri) {
+ assertEquals("https://my/url/model.onnx", uri.toString());
totalCost.addAndGet(modelCost);
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFilesTest.java b/config-model/src/test/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFilesTest.java
index 653bdbccf15..deea1a820d9 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFilesTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFilesTest.java
@@ -32,6 +32,7 @@ import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Ulf Lilleengen
+ * @author hmusum
*/
public class UserConfiguredFilesTest {
@@ -268,7 +269,8 @@ public class UserConfiguredFilesTest {
userConfiguredFiles().register(producer);
fail("Should have thrown exception");
} catch (IllegalArgumentException e) {
- assertEquals("Unable to register file specified in services.xml for config 'mynamespace.myname': No such file or directory 'foo.txt'", e.getMessage());
+ assertEquals("Invalid config in services.xml for 'mynamespace.myname': No such file or directory 'foo.txt'",
+ e.getMessage());
}
}
@@ -281,7 +283,7 @@ public class UserConfiguredFilesTest {
userConfiguredFiles().register(producer);
fail("Should have thrown exception");
} catch (IllegalArgumentException e) {
- assertEquals("Unable to register file specified in services.xml for config 'mynamespace.myname': Unable to register file for field 'fileVal': Invalid config value '.'",
+ assertEquals("Invalid config in services.xml for 'mynamespace.myname': Invalid config value '.' for field 'fileVal",
e.getMessage());
}
}
@@ -296,8 +298,7 @@ public class UserConfiguredFilesTest {
userConfiguredFiles().register(producer);
fail("Should have thrown exception");
} catch (IllegalArgumentException e) {
- assertEquals("Unable to register file specified in services.xml for config 'mynamespace.myname': Directory '" +
- relativeTempDir + "' is empty",
+ assertEquals("Invalid config in services.xml for 'mynamespace.myname': Directory '" + relativeTempDir + "' is empty",
e.getMessage());
}
}