summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom <58065733+tomglk@users.noreply.github.com>2024-01-03 20:26:46 +0100
committerGitHub <noreply@github.com>2024-01-03 20:26:46 +0100
commitd9198f2bbaa3790cbd614fc6bbd7b60bd365d602 (patch)
treedd1f3f25f363dae66c49a5b21db384a127d0dcdb
parent5614a846b5c4d6980a9880577ffa9253a2112ce0 (diff)
parent776ace0650b26fd6ba0e1452c81c139d7554834d (diff)
Merge branch 'vespa-engine:master' into multifield-collapsing
-rw-r--r--Gemfile.lock8
-rw-r--r--client/go/go.mod2
-rw-r--r--client/go/go.sum3
-rw-r--r--client/go/internal/admin/envvars/env_vars.go1
-rw-r--r--client/js/app/yarn.lock156
-rw-r--r--config-model-api/abi-spec.json12
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/ValidationOverrides.java9
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java2
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/OnnxModelCost.java16
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java2
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java7
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java210
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java2
-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/application/validation/change/CertificateRemovalChangeValidatorTest.java8
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidatorTest.java25
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidatorTest.java8
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RestartOnDeployForOnnxModelChangesValidatorTest.java9
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/TenantHandler.java3
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/SecretStoreExternalIdRetriever.java15
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/MockSecretStore.java3
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/TenantHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/tenant/SecretStoreExternalIdRetrieverTest.java39
-rw-r--r--container-core/src/main/java/com/yahoo/processing/request/ErrorMessage.java6
-rw-r--r--container-search/abi-spec.json1
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java7
-rw-r--r--container-search/src/main/java/com/yahoo/search/result/ErrorMessage.java8
-rw-r--r--dependency-versions/pom.xml16
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flags.java62
-rw-r--r--integration/intellij/build.gradle.kts2
-rw-r--r--jdisc_core/src/test/resources/exportPackages.properties2
-rw-r--r--maven-plugins/allowed-maven-dependencies.txt4
-rw-r--r--metrics/src/main/java/ai/vespa/metrics/set/InfrastructureMetricSet.java1
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/DelegatingOsUpgrader.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsUpgrader.java33
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java53
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/RebuildingOsUpgrader.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/RetiringOsUpgrader.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java13
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java47
-rw-r--r--parent/pom.xml21
-rw-r--r--searchlib/src/tests/attribute/direct_posting_store/CMakeLists.txt1
-rw-r--r--searchlib/src/tests/attribute/direct_posting_store/direct_posting_store_test.cpp123
-rw-r--r--searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp2
-rw-r--r--searchlib/src/tests/query/streaming_query_test.cpp139
-rw-r--r--searchlib/src/vespa/searchlib/query/query_term_simple.cpp216
-rw-r--r--searchlib/src/vespa/searchlib/query/query_term_simple.h59
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/query.cpp10
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/query.h31
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/querynode.cpp38
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/querynode.h2
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/querynoderesultbase.h5
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/queryterm.cpp9
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/queryterm.h2
-rw-r--r--storage/src/vespa/storage/visiting/countvisitor.cpp35
-rw-r--r--storage/src/vespa/storageapi/mbusprot/protocolserialization7.cpp8
-rw-r--r--storage/src/vespa/storageapi/message/datagram.cpp18
-rw-r--r--storage/src/vespa/storageapi/message/visitor.h6
-rw-r--r--streamingvisitors/src/tests/rank_processor/rank_processor_test.cpp2
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/querytermdata.h15
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp114
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/searchvisitor.h13
-rw-r--r--streamingvisitors/src/vespa/vsm/searcher/floatfieldsearcher.cpp2
-rw-r--r--streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp99
-rw-r--r--streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.h17
-rw-r--r--vdslib/src/vespa/vdslib/container/parameters.cpp37
-rw-r--r--vdslib/src/vespa/vdslib/container/parameters.h36
-rw-r--r--vdslib/src/vespa/vdslib/container/parameters.hpp8
-rw-r--r--vespa-dependencies-enforcer/allowed-maven-dependencies.txt6
-rw-r--r--vespalib/src/vespa/vespalib/locale/locale.h2
-rw-r--r--zookeeper-server/zookeeper-server/pom.xml8
75 files changed, 1101 insertions, 803 deletions
diff --git a/Gemfile.lock b/Gemfile.lock
index 1962b421269..0134d845e34 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -2,7 +2,7 @@ GEM
remote: https://rubygems.org/
specs:
Ascii85 (1.1.0)
- addressable (2.8.5)
+ addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
afm (0.2.2)
async (2.6.4)
@@ -25,7 +25,7 @@ GEM
fiber-annotation (0.2.0)
fiber-local (1.0.0)
forwardable-extended (2.6.0)
- google-protobuf (3.24.3-x86_64-linux)
+ google-protobuf (3.24.4)
hashery (2.1.2)
html-proofer (5.0.8)
addressable (~> 2.3)
@@ -40,7 +40,7 @@ GEM
i18n (1.14.1)
concurrent-ruby (~> 1.0)
io-event (1.3.2)
- jekyll (4.3.2)
+ jekyll (4.3.3)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
@@ -87,7 +87,7 @@ GEM
hashery (~> 2.0)
ruby-rc4
ttfunk
- public_suffix (5.0.3)
+ public_suffix (5.0.4)
racc (1.7.1)
rainbow (3.1.1)
rake (13.1.0)
diff --git a/client/go/go.mod b/client/go/go.mod
index 8d46118dea6..b69a64f87f7 100644
--- a/client/go/go.mod
+++ b/client/go/go.mod
@@ -11,7 +11,7 @@ require (
github.com/klauspost/compress v1.17.4
github.com/mattn/go-colorable v0.1.13
github.com/mattn/go-isatty v0.0.20
- github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
+ github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
diff --git a/client/go/go.sum b/client/go/go.sum
index c4dd9837194..6af9dbf84c9 100644
--- a/client/go/go.sum
+++ b/client/go/go.sum
@@ -32,6 +32,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
+github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
+github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
@@ -53,6 +55,7 @@ golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
diff --git a/client/go/internal/admin/envvars/env_vars.go b/client/go/internal/admin/envvars/env_vars.go
index 1586292a13d..5e8b5d29b53 100644
--- a/client/go/internal/admin/envvars/env_vars.go
+++ b/client/go/internal/admin/envvars/env_vars.go
@@ -22,6 +22,7 @@ const (
MALLOC_ARENA_MAX = "MALLOC_ARENA_MAX"
NO_VESPAMALLOC_LIST = "NO_VESPAMALLOC_LIST"
NUM_PROCESSES_LIMIT = "num_processes_limit"
+ OPENBLAS_CORETYPE = "OPENBLAS_CORETYPE"
PATH = "PATH"
PRELOAD = "PRELOAD"
ROOT = "ROOT"
diff --git a/client/js/app/yarn.lock b/client/js/app/yarn.lock
index c06265edaa1..b4493e1df56 100644
--- a/client/js/app/yarn.lock
+++ b/client/js/app/yarn.lock
@@ -15,15 +15,7 @@
"@jridgewell/gen-mapping" "^0.3.0"
"@jridgewell/trace-mapping" "^0.3.9"
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.5":
- version "7.22.13"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e"
- integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==
- dependencies:
- "@babel/highlight" "^7.22.13"
- chalk "^2.4.2"
-
-"@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5":
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5":
version "7.23.5"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244"
integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==
@@ -31,6 +23,14 @@
"@babel/highlight" "^7.23.4"
chalk "^2.4.2"
+"@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.5":
+ version "7.22.13"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e"
+ integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==
+ dependencies:
+ "@babel/highlight" "^7.22.13"
+ chalk "^2.4.2"
+
"@babel/compat-data@^7.22.9":
version "7.23.5"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98"
@@ -181,14 +181,7 @@
dependencies:
"@babel/types" "^7.22.5"
-"@babel/helper-module-imports@^7.16.7":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c"
- integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==
- dependencies:
- "@babel/types" "^7.22.5"
-
-"@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.22.5":
+"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.22.5":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0"
integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==
@@ -452,11 +445,11 @@
regenerator-runtime "^0.14.0"
"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3":
- version "7.22.6"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438"
- integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==
+ version "7.23.6"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.6.tgz#c05e610dc228855dc92ef1b53d07389ed8ab521d"
+ integrity sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==
dependencies:
- regenerator-runtime "^0.13.11"
+ regenerator-runtime "^0.14.0"
"@babel/template@^7.22.15", "@babel/template@^7.22.5", "@babel/template@^7.3.3":
version "7.22.15"
@@ -499,7 +492,7 @@
debug "^4.1.0"
globals "^11.1.0"
-"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.5":
+"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.23.0", "@babel/types@^7.23.5":
version "7.23.5"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.5.tgz#48d730a00c95109fa4393352705954d74fb5b602"
integrity sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==
@@ -526,6 +519,15 @@
"@babel/helper-validator-identifier" "^7.22.19"
to-fast-properties "^2.0.0"
+"@babel/types@^7.22.5":
+ version "7.23.6"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd"
+ integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==
+ dependencies:
+ "@babel/helper-string-parser" "^7.23.4"
+ "@babel/helper-validator-identifier" "^7.22.20"
+ to-fast-properties "^2.0.0"
+
"@babel/types@^7.23.3":
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.3.tgz#d5ea892c07f2ec371ac704420f4dcdb07b5f9598"
@@ -587,23 +589,23 @@
integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==
"@emotion/react@^11":
- version "11.11.1"
- resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.1.tgz#b2c36afac95b184f73b08da8c214fdf861fa4157"
- integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==
+ version "11.11.3"
+ resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.3.tgz#96b855dc40a2a55f52a72f518a41db4f69c31a25"
+ integrity sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA==
dependencies:
"@babel/runtime" "^7.18.3"
"@emotion/babel-plugin" "^11.11.0"
"@emotion/cache" "^11.11.0"
- "@emotion/serialize" "^1.1.2"
+ "@emotion/serialize" "^1.1.3"
"@emotion/use-insertion-effect-with-fallbacks" "^1.0.1"
"@emotion/utils" "^1.2.1"
"@emotion/weak-memoize" "^0.3.1"
hoist-non-react-statics "^3.3.1"
-"@emotion/serialize@^1.1.2":
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.2.tgz#017a6e4c9b8a803bd576ff3d52a0ea6fa5a62b51"
- integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==
+"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3":
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.3.tgz#84b77bfcfe3b7bb47d326602f640ccfcacd5ffb0"
+ integrity sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==
dependencies:
"@emotion/hash" "^0.9.1"
"@emotion/memoize" "^0.8.1"
@@ -1306,10 +1308,10 @@
dependencies:
"@babel/runtime" "^7.13.10"
-"@remix-run/router@1.14.0":
- version "1.14.0"
- resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.14.0.tgz#9bc39a5a3a71b81bdb310eba6def5bc3966695b7"
- integrity sha512-WOHih+ClN7N8oHk9N4JUiMxQJmRVaOxcg8w7F/oHUXzJt920ekASLI/7cYX8XkntDWRhLZtsk6LbGrkgOAvi5A==
+"@remix-run/router@1.14.1":
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.14.1.tgz#6d2dd03d52e604279c38911afc1079d58c50a755"
+ integrity sha512-Qg4DMQsfPNAs88rb2xkdk03N3bjK4jgX5fR24eHCTR9q6PrhZQZ4UJBPzCHJkIpTRN1UKxx2DzjZmnC+7Lj0Ow==
"@rollup/rollup-android-arm-eabi@4.9.0":
version "4.9.0"
@@ -1488,9 +1490,9 @@
integrity sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==
"@types/parse-json@^4.0.0":
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
- integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239"
+ integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==
"@types/stack-utils@^2.0.0":
version "2.0.1"
@@ -2208,9 +2210,9 @@ csstype@3.0.9:
integrity sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==
csstype@^3.0.2:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
- integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
+ integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
debug@^2.2.0, debug@^2.3.3:
version "2.6.9"
@@ -2564,12 +2566,12 @@ eslint-plugin-import@^2:
tsconfig-paths "^3.15.0"
eslint-plugin-prettier@^5:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.0.tgz#f14bb2b18756ad54f1ad3dc4c989cb73dfa326a3"
- integrity sha512-hQc+2zbnMeXcIkg+pKZtVa+3Yqx4WY7SMkn1PLZ4VbBEU7jJIpVn9347P8BBhTbz6ne85aXvQf30kvexcqBeWw==
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.2.tgz#584c94d4bf31329b2d4cbeb10fd600d17d6de742"
+ integrity sha512-dhlpWc9vOwohcWmClFcA+HjlvUpuyynYs0Rf+L/P6/0iQE6vlHW9l5bkfzN62/Stm9fbq8ku46qzde76T1xlSg==
dependencies:
prettier-linter-helpers "^1.0.0"
- synckit "^0.8.5"
+ synckit "^0.8.6"
eslint-plugin-react-hooks@^4:
version "4.6.0"
@@ -3351,13 +3353,6 @@ is-ci@^2.0.0:
dependencies:
ci-info "^2.0.0"
-is-core-module@^2.11.0, is-core-module@^2.9.0:
- version "2.13.0"
- resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db"
- integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==
- dependencies:
- has "^1.0.3"
-
is-core-module@^2.13.0, is-core-module@^2.13.1:
version "2.13.1"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384"
@@ -3365,6 +3360,13 @@ is-core-module@^2.13.0, is-core-module@^2.13.1:
dependencies:
hasown "^2.0.0"
+is-core-module@^2.9.0:
+ version "2.13.0"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db"
+ integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==
+ dependencies:
+ has "^1.0.3"
+
is-data-descriptor@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
@@ -4466,9 +4468,9 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1:
path-key "^3.0.0"
npm-run-path@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00"
- integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.2.0.tgz#224cdd22c755560253dd71b83a1ef2f758b2e955"
+ integrity sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==
dependencies:
path-key "^4.0.0"
@@ -4850,19 +4852,19 @@ react-refresh@^0.14.0:
integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==
react-router-dom@^6:
- version "6.21.0"
- resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.21.0.tgz#aa4c6bc046a8e8723095bc09b3c0ab2254532712"
- integrity sha512-1dUdVj3cwc1npzJaf23gulB562ESNvxf7E4x8upNJycqyUm5BRRZ6dd3LrlzhtLaMrwOCO8R0zoiYxdaJx4LlQ==
+ version "6.21.1"
+ resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.21.1.tgz#58b459d2fe1841388c95bb068f85128c45e27349"
+ integrity sha512-QCNrtjtDPwHDO+AO21MJd7yIcr41UetYt5jzaB9Y1UYaPTCnVuJq6S748g1dE11OQlCFIQg+RtAA1SEZIyiBeA==
dependencies:
- "@remix-run/router" "1.14.0"
- react-router "6.21.0"
+ "@remix-run/router" "1.14.1"
+ react-router "6.21.1"
-react-router@6.21.0:
- version "6.21.0"
- resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.21.0.tgz#6fe3e59877aca3dccceec1801d26991ddf42d12b"
- integrity sha512-hGZ0HXbwz3zw52pLZV3j3+ec+m/PQ9cTpBvqjFQmy2XVUWGn5MD+31oXHb6dVTxYzmAeaiUBYjkoNz66n3RGCg==
+react-router@6.21.1:
+ version "6.21.1"
+ resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.21.1.tgz#8db7ee8d7cfc36513c9a66b44e0897208c33be34"
+ integrity sha512-W0l13YlMTm1YrpVIOpjCADJqEUpz1vm+CMo47RuFX4Ftegwm6KOYsL5G3eiE52jnJpKvzm6uB/vTKTPKM8dmkA==
dependencies:
- "@remix-run/router" "1.14.0"
+ "@remix-run/router" "1.14.1"
react-textarea-autosize@8.3.4:
version "8.3.4"
@@ -4902,11 +4904,6 @@ reflect.getprototypeof@^1.0.3:
globalthis "^1.0.3"
which-builtin-type "^1.1.3"
-regenerator-runtime@^0.13.11:
- version "0.13.11"
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
- integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
-
regenerator-runtime@^0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
@@ -4985,12 +4982,12 @@ resolve.exports@^2.0.0:
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800"
integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==
-resolve@^1.19.0:
- version "1.22.2"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f"
- integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==
+resolve@^1.19.0, resolve@^1.22.4:
+ version "1.22.8"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
+ integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
dependencies:
- is-core-module "^2.11.0"
+ is-core-module "^2.13.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
@@ -5003,15 +5000,6 @@ resolve@^1.20.0:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
-resolve@^1.22.4:
- version "1.22.8"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
- integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
- dependencies:
- is-core-module "^2.13.0"
- path-parse "^1.0.7"
- supports-preserve-symlinks-flag "^1.0.0"
-
resolve@^2.0.0-next.4:
version "2.0.0-next.4"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660"
@@ -5441,7 +5429,7 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
-synckit@^0.8.5:
+synckit@^0.8.6:
version "0.8.6"
resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.6.tgz#b69b7fbce3917c2673cbdc0d87fb324db4a5b409"
integrity sha512-laHF2savN6sMeHCjLRkheIU4wo3Zg9Ln5YOjOo7sZ5dVQW8yF5pPE5SIw1dsPhq3TRp1jisKRCdPhfs/1WMqDA==
diff --git a/config-model-api/abi-spec.json b/config-model-api/abi-spec.json
index c3e20e534ff..b4bf45d655a 100644
--- a/config-model-api/abi-spec.json
+++ b/config-model-api/abi-spec.json
@@ -771,7 +771,9 @@
"attributes" : [
"public"
],
- "methods" : [ ],
+ "methods" : [
+ "public java.util.Map messagesById()"
+ ],
"fields" : [ ]
},
"com.yahoo.config.application.api.ValidationOverrides" : {
@@ -1278,9 +1280,7 @@
"public java.util.List ignoredHttpUserAgents()",
"public boolean enableProxyProtocolMixedMode()",
"public java.lang.String logFileCompressionAlgorithm(java.lang.String)",
- "public boolean enableGlobalPhase()",
"public java.lang.String summaryDecodePolicy()",
- "public boolean enableNestedMultivalueGrouping()",
"public int contentLayerMetadataFeatureLevel()",
"public boolean dynamicHeapSize()",
"public java.lang.String unknownConfigDefinition()",
@@ -1457,9 +1457,7 @@
],
"methods" : [
"public abstract long aggregatedModelCostInBytes()",
- "public abstract void registerModel(com.yahoo.config.application.api.ApplicationFile)",
"public abstract void registerModel(com.yahoo.config.application.api.ApplicationFile, com.yahoo.config.model.api.OnnxModelOptions)",
- "public abstract void registerModel(java.net.URI)",
"public abstract void registerModel(java.net.URI, com.yahoo.config.model.api.OnnxModelOptions)",
"public abstract java.util.Map models()",
"public abstract void setRestartOnDeploy()",
@@ -1481,9 +1479,7 @@
"public void <init>()",
"public com.yahoo.config.model.api.OnnxModelCost$Calculator newCalculator(com.yahoo.config.application.api.ApplicationPackage, com.yahoo.config.provision.ApplicationId)",
"public long aggregatedModelCostInBytes()",
- "public void registerModel(com.yahoo.config.application.api.ApplicationFile)",
"public void registerModel(com.yahoo.config.application.api.ApplicationFile, com.yahoo.config.model.api.OnnxModelOptions)",
- "public void registerModel(java.net.URI)",
"public void registerModel(java.net.URI, com.yahoo.config.model.api.OnnxModelOptions)",
"public java.util.Map models()",
"public void setRestartOnDeploy()",
@@ -1501,7 +1497,9 @@
"record"
],
"methods" : [
+ "public void <init>(java.lang.String, long, long, com.yahoo.config.model.api.OnnxModelOptions)",
"public void <init>(java.lang.String, long, long, java.util.Optional)",
+ "public com.yahoo.config.model.api.OnnxModelOptions options()",
"public final java.lang.String toString()",
"public final int hashCode()",
"public final boolean equals(java.lang.Object)",
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationOverrides.java b/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationOverrides.java
index 1edddb63e52..7b52d825473 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationOverrides.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationOverrides.java
@@ -15,6 +15,7 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -36,7 +37,7 @@ public class ValidationOverrides {
private final String xmlForm;
- /** Creates a validation overrides which does not have an xml form */
+ /** Creates a validation overrides which does not have an XML form */
public ValidationOverrides(List<Allow> overrides) {
this(overrides, null);
}
@@ -163,10 +164,13 @@ public class ValidationOverrides {
*/
public static class ValidationException extends IllegalArgumentException {
+ private final Map<ValidationId, Collection<String>> messagesById = new LinkedHashMap<>();
+
static final long serialVersionUID = 789984668;
private ValidationException(ValidationId validationId, String message) {
super(validationId + ": " + message + ". " + toAllowMessage(validationId));
+ messagesById.put(validationId, List.of(message));
}
private ValidationException(Map<ValidationId, Collection<String>> messagesById) {
@@ -175,8 +179,11 @@ public class ValidationOverrides {
String.join("\n\t", messages.getValue()) + "\n" +
toAllowMessage(messages.getKey()))
.collect(Collectors.joining("\n")));
+ messagesById.forEach((id, messages) -> this.messagesById.put(id, List.copyOf(messages)));
}
+ public Map<ValidationId, Collection<String>> messagesById() { return Map.copyOf(messagesById); }
+
}
}
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
index 4ee7b00b79f..31ef1e75acd 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
@@ -106,9 +106,7 @@ public interface ModelContext {
@ModelFeatureFlag(owners = {"arnej", "andreer"}) default List<String> ignoredHttpUserAgents() { return List.of(); }
@ModelFeatureFlag(owners = {"tokle"}) default boolean enableProxyProtocolMixedMode() { return true; }
@ModelFeatureFlag(owners = {"arnej"}) default String logFileCompressionAlgorithm(String defVal) { return defVal; }
- @ModelFeatureFlag(owners = {"arnej, bjorncs"}, removeAfter = "8.262") default boolean enableGlobalPhase() { return true; }
@ModelFeatureFlag(owners = {"baldersheim"}, comment = "Select summary decode type") default String summaryDecodePolicy() { return "eager"; }
- @ModelFeatureFlag(owners = {"baldersheim"}, removeAfter = "8.261") default boolean enableNestedMultivalueGrouping() { return true; }
@ModelFeatureFlag(owners = {"vekterli"}) default int contentLayerMetadataFeatureLevel() { return 0; }
@ModelFeatureFlag(owners = {"bjorncs"}) default boolean dynamicHeapSize() { return false; }
@ModelFeatureFlag(owners = {"hmusum"}) default String unknownConfigDefinition() { return "warn"; }
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/OnnxModelCost.java b/config-model-api/src/main/java/com/yahoo/config/model/api/OnnxModelCost.java
index d70b751eba0..17a0d64aac9 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/OnnxModelCost.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/OnnxModelCost.java
@@ -18,9 +18,7 @@ public interface OnnxModelCost {
interface Calculator {
long aggregatedModelCostInBytes();
- void registerModel(ApplicationFile path);
void registerModel(ApplicationFile path, OnnxModelOptions onnxModelOptions);
- void registerModel(URI uri);
void registerModel(URI uri, OnnxModelOptions onnxModelOptions);
Map<String, ModelInfo> models();
void setRestartOnDeploy();
@@ -28,16 +26,24 @@ public interface OnnxModelCost {
void store();
}
- record ModelInfo(String modelId, long estimatedCost, long hash, Optional<OnnxModelOptions> onnxModelOptions) {}
+ record ModelInfo(String modelId, long estimatedCost, long hash, Optional<OnnxModelOptions> onnxModelOptions) {
+
+ public ModelInfo(String modelId, long estimatedCost, long hash, OnnxModelOptions onnxModelOptions) {
+ this(modelId, estimatedCost, hash, Optional.of(onnxModelOptions));
+ }
+
+ public OnnxModelOptions options() {
+ return onnxModelOptions.orElseThrow(() -> new IllegalStateException("No onnxModelOptions exist"));
+ }
+
+ }
static OnnxModelCost disabled() { return new DisabledOnnxModelCost(); }
class DisabledOnnxModelCost implements OnnxModelCost, Calculator {
@Override public Calculator newCalculator(ApplicationPackage appPkg, ApplicationId applicationId) { return this; }
@Override public long aggregatedModelCostInBytes() {return 0;}
- @Override public void registerModel(ApplicationFile path) {}
@Override public void registerModel(ApplicationFile path, OnnxModelOptions onnxModelOptions) {}
- @Override public void registerModel(URI uri) {}
@Override public void registerModel(URI uri, OnnxModelOptions onnxModelOptions) {}
@Override public Map<String, ModelInfo> models() { return Map.of(); }
@Override public void setRestartOnDeploy() {}
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
index 33dfee58d1a..f19341098f4 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
@@ -172,7 +172,7 @@ public class DeployState implements ConfigDefinitionStore {
/** Get the global rank profile registry for this application. */
public final RankProfileRegistry rankProfileRegistry() { return rankProfileRegistry; }
- /** Returns the validation overrides of this. This is never null */
+ /** Returns the validation overrides of this. This is never null. */
public ValidationOverrides validationOverrides() { return validationOverrides; }
@Override
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
index 2e1c661e09a..6f0254145d6 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
@@ -141,7 +141,6 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
@Override public String summaryDecodePolicy() { return summaryDecodePolicy; }
@Override public Optional<CloudAccount> cloudAccount() { return cloudAccount; }
@Override public boolean allowUserFilters() { return allowUserFilters; }
- @Override public boolean enableGlobalPhase() { return true; } // Enable global-phase by default for unit tests only
@Override public List<DataplaneToken> dataplaneTokens() { return dataplaneTokens; }
@Override public int contentLayerMetadataFeatureLevel() { return contentLayerMetadataFeatureLevel; }
@Override public boolean dynamicHeapSize() { return dynamicHeapSize; }
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java b/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
index 903f1c06024..65572d07cc2 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
@@ -217,13 +217,6 @@ public class VespaModelFactory implements ModelFactory {
private List<ConfigChangeAction> validateModel(VespaModel model, DeployState deployState, ValidationParameters validationParameters) {
try {
return new Validation(additionalValidators).validate(model, validationParameters, deployState);
- } catch (ValidationOverrides.ValidationException e) {
- if (deployState.isHosted() && zone.environment().isManuallyDeployed())
- deployState.getDeployLogger().logApplicationPackage(Level.WARNING,
- "Auto-overriding validation which would be disallowed in production: " +
- Exceptions.toMessageString(e));
- else
- rethrowUnlessIgnoreErrors(e, validationParameters.ignoreValidationErrors());
} catch (IllegalArgumentException | TransientException | QuotaExceededException e) {
rethrowUnlessIgnoreErrors(e, validationParameters.ignoreValidationErrors());
} catch (Exception e) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
index 56277345515..0f7a415c33a 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
@@ -3,8 +3,8 @@ package com.yahoo.vespa.model.application.validation;
import com.yahoo.config.application.api.ValidationId;
import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.config.application.api.ValidationOverrides.ValidationException;
import com.yahoo.config.model.api.ConfigChangeAction;
-import com.yahoo.config.model.api.Model;
import com.yahoo.config.model.api.ValidationParameters;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.provision.ClusterSpec;
@@ -25,21 +25,17 @@ import com.yahoo.vespa.model.application.validation.change.RestartOnDeployForOnn
import com.yahoo.vespa.model.application.validation.change.StartupCommandChangeValidator;
import com.yahoo.vespa.model.application.validation.change.StreamingSearchClusterChangeValidator;
import com.yahoo.vespa.model.application.validation.first.RedundancyValidator;
+import com.yahoo.yolean.Exceptions;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
+import java.util.logging.Level;
import java.util.stream.Collectors;
-import static java.util.stream.Collectors.groupingBy;
-import static java.util.stream.Collectors.mapping;
-import static java.util.stream.Collectors.toCollection;
-
/**
* Executor of validators. This defines the right order of validator execution.
*
@@ -51,7 +47,7 @@ public class Validation {
public Validation() { this(List.of()); }
- /** Create instance taking additional validators (e.g for cloud applications) */
+ /** Create instance taking additional validators (e.g., for cloud applications) */
public Validation(List<Validator> additionalValidators) { this.additionalValidators = additionalValidators; }
/**
@@ -62,85 +58,80 @@ public class Validation {
* @throws ValidationOverrides.ValidationException if the change fails validation
*/
public List<ConfigChangeAction> validate(VespaModel model, ValidationParameters validationParameters, DeployState deployState) {
+ Execution execution = new Execution(model, deployState);
if (validationParameters.checkRouting()) {
- new RoutingValidator().validate(model, deployState);
- new RoutingSelectorValidator().validate(model, deployState);
+ validateRouting(execution);
}
- new SchemasDirValidator().validate(model, deployState);
- new BundleValidator().validate(model, deployState);
- new PublicApiBundleValidator().validate(model, deployState);
- new SearchDataTypeValidator().validate(model, deployState);
- new ComplexFieldsWithStructFieldAttributesValidator().validate(model, deployState);
- new ComplexFieldsWithStructFieldIndexesValidator().validate(model, deployState);
- new StreamingValidator().validate(model, deployState);
- new RankSetupValidator(validationParameters.ignoreValidationErrors()).validate(model, deployState);
- new NoPrefixForIndexes().validate(model, deployState);
- new ContainerInCloudValidator().validate(model, deployState);
- new DeploymentSpecValidator().validate(model, deployState);
- new ValidationOverridesValidator().validate(model, deployState);
- new ConstantValidator().validate(model, deployState);
- new SecretStoreValidator().validate(model, deployState);
- new EndpointCertificateSecretsValidator().validate(model, deployState);
- new AccessControlFilterValidator().validate(model, deployState);
- new QuotaValidator().validate(model, deployState);
- new UriBindingsValidator().validate(model, deployState);
- new CloudDataPlaneFilterValidator().validate(model, deployState);
- new AccessControlFilterExcludeValidator().validate(model, deployState);
- new CloudUserFilterValidator().validate(model, deployState);
- new CloudHttpConnectorValidator().validate(model, deployState);
- new UrlConfigValidator().validate(model, deployState);
- new JvmHeapSizeValidator().validate(model, deployState);
-
- additionalValidators.forEach(v -> v.validate(model, deployState));
-
- List<ConfigChangeAction> result = Collections.emptyList();
+
+ validateModel(validationParameters, execution);
+
+ additionalValidators.forEach(execution::run);
+
if (deployState.getProperties().isFirstTimeDeployment()) {
- validateFirstTimeDeployment(model, deployState);
- } else {
- Optional<Model> currentActiveModel = deployState.getPreviousModel();
- if (currentActiveModel.isPresent() && (currentActiveModel.get() instanceof VespaModel)) {
- result = validateChanges((VespaModel) currentActiveModel.get(), model, deployState);
- deferConfigChangesForClustersToBeRestarted(result, model);
- }
+ validateFirstTimeDeployment(execution);
+ }
+ else if (deployState.getPreviousModel().isPresent() && (deployState.getPreviousModel().get() instanceof VespaModel vespaModel)) {
+ validateChanges(vespaModel, execution);
+ // TODO: Why is this done here? It won't be done on more than one config server?
+ deferConfigChangesForClustersToBeRestarted(execution.actions, model);
}
- return result;
+
+ execution.throwIfFailed();
+ return execution.actions;
}
- private static List<ConfigChangeAction> validateChanges(VespaModel currentModel, VespaModel nextModel,
- DeployState deployState) {
- ChangeValidator[] validators = new ChangeValidator[] {
- new IndexingModeChangeValidator(),
- new GlobalDocumentChangeValidator(),
- new IndexedSearchClusterChangeValidator(),
- new StreamingSearchClusterChangeValidator(),
- new ConfigValueChangeValidator(),
- new StartupCommandChangeValidator(),
- new ContentTypeRemovalValidator(),
- new ContentClusterRemovalValidator(),
- new ResourcesReductionValidator(),
- new ResourcesReductionValidator(),
- new ContainerRestartValidator(),
- new NodeResourceChangeValidator(),
- new RedundancyIncreaseValidator(),
- new CertificateRemovalChangeValidator(),
- new RedundancyValidator(),
- new RestartOnDeployForOnnxModelChangesValidator(),
- };
- List<ConfigChangeAction> actions = Arrays.stream(validators)
- .flatMap(v -> v.validate(currentModel, nextModel, deployState).stream())
- .toList();
-
- Map<ValidationId, Collection<String>> disallowableActions = actions.stream()
- .filter(action -> action.validationId().isPresent())
- .collect(groupingBy(action -> action.validationId().orElseThrow(),
- mapping(ConfigChangeAction::getMessage,
- toCollection(LinkedHashSet::new))));
- deployState.validationOverrides().invalid(disallowableActions, deployState.now());
- return actions;
+ private static void validateRouting(Execution execution) {
+ execution.run(new RoutingValidator());
+ execution.run(new RoutingSelectorValidator());
}
- private static void validateFirstTimeDeployment(VespaModel model, DeployState deployState) {
- new RedundancyValidator().validate(model, deployState);
+ private static void validateModel(ValidationParameters validationParameters, Execution execution) {
+ execution.run(new SchemasDirValidator());
+ execution.run(new BundleValidator());
+ execution.run(new PublicApiBundleValidator());
+ execution.run(new SearchDataTypeValidator());
+ execution.run(new ComplexFieldsWithStructFieldAttributesValidator());
+ execution.run(new ComplexFieldsWithStructFieldIndexesValidator());
+ execution.run(new StreamingValidator());
+ execution.run(new RankSetupValidator(validationParameters.ignoreValidationErrors()));
+ execution.run(new NoPrefixForIndexes());
+ execution.run(new ContainerInCloudValidator());
+ execution.run(new DeploymentSpecValidator());
+ execution.run(new ValidationOverridesValidator());
+ execution.run(new ConstantValidator());
+ execution.run(new SecretStoreValidator());
+ execution.run(new EndpointCertificateSecretsValidator());
+ execution.run(new AccessControlFilterValidator());
+ execution.run(new QuotaValidator());
+ execution.run(new UriBindingsValidator());
+ execution.run(new CloudDataPlaneFilterValidator());
+ execution.run(new AccessControlFilterExcludeValidator());
+ execution.run(new CloudUserFilterValidator());
+ execution.run(new CloudHttpConnectorValidator());
+ execution.run(new UrlConfigValidator());
+ execution.run(new JvmHeapSizeValidator());
+ }
+
+ private static void validateFirstTimeDeployment(Execution execution) {
+ execution.run(new RedundancyValidator());
+ }
+
+ private static void validateChanges(VespaModel currentModel, Execution execution) {
+ execution.run(new IndexingModeChangeValidator(), currentModel);
+ execution.run(new GlobalDocumentChangeValidator(), currentModel);
+ execution.run(new IndexedSearchClusterChangeValidator(), currentModel);
+ execution.run(new StreamingSearchClusterChangeValidator(), currentModel);
+ execution.run(new ConfigValueChangeValidator(), currentModel);
+ execution.run(new StartupCommandChangeValidator(), currentModel);
+ execution.run(new ContentTypeRemovalValidator(), currentModel);
+ execution.run(new ContentClusterRemovalValidator(), currentModel);
+ execution.run(new ResourcesReductionValidator(), currentModel);
+ execution.run(new ContainerRestartValidator(), currentModel);
+ execution.run(new NodeResourceChangeValidator(), currentModel);
+ execution.run(new RedundancyIncreaseValidator(), currentModel);
+ execution.run(new CertificateRemovalChangeValidator(), currentModel);
+ execution.run(new RedundancyValidator(), currentModel);
+ execution.run(new RestartOnDeployForOnnxModelChangesValidator(), currentModel);
}
private static void deferConfigChangesForClustersToBeRestarted(List<ConfigChangeAction> actions, VespaModel model) {
@@ -159,4 +150,61 @@ public class Validation {
}
}
+
+ private static class Execution {
+
+ private final Map<ValidationId, List<String>> failures = new LinkedHashMap<>();
+ private final VespaModel model;
+ private final DeployState deployState;
+ private final List<ConfigChangeAction> actions = new ArrayList<>();
+
+ private Execution(VespaModel model, DeployState deployState) {
+ this.model = model;
+ this.deployState = deployState;
+ }
+
+ private void run(Validator validator) {
+ try {
+ validator.validate(model, deployState);
+ }
+ catch (ValidationException e) {
+ e.messagesById().forEach((id, messages) -> failures.computeIfAbsent(id, __ -> new ArrayList<>()).addAll(messages));
+ }
+ }
+
+ private void run(ChangeValidator validator, VespaModel previousModel) {
+ try {
+ // Some change validators throw, while some return a list of changes that may again be disallowed.
+ for (ConfigChangeAction action : validator.validate(previousModel, model, deployState)) {
+ actions.add(action);
+ if (action.validationId().isPresent()) run(new Validator() { // Changes without a validation ID are always allowed.
+ @Override public void validate(VespaModel model, DeployState deployState) {
+ deployState.validationOverrides().invalid(action.validationId().get(), action.getMessage(), deployState.now());
+ }
+ });
+ }
+ }
+ catch (ValidationException e) {
+ e.messagesById().forEach((id, messages) -> failures.computeIfAbsent(id, __ -> new ArrayList<>()).addAll(messages));
+ }
+ }
+
+ private void throwIfFailed() {
+ try {
+ if (failures.size() == 1 && failures.values().iterator().next().size() == 1) // Retain single-form exception message when possible.
+ deployState.validationOverrides().invalid(failures.keySet().iterator().next(), failures.values().iterator().next().get(0), deployState.now());
+ else
+ deployState.validationOverrides().invalid(failures, deployState.now());
+ }
+ catch (ValidationException e) {
+ if (deployState.isHosted() && deployState.zone().environment().isManuallyDeployed())
+ deployState.getDeployLogger().logApplicationPackage(Level.WARNING,
+ "Auto-overriding validation which would be disallowed in production: " +
+ Exceptions.toMessageString(e));
+ else throw e;
+ }
+ }
+
+ }
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java
index fb07f65b5f4..e2dd3aca0b9 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java
@@ -40,7 +40,7 @@ public class IndexingScriptChangeValidator {
String fieldName = nextField.getName();
ImmutableSDField currentField = currentSchema.getConcreteField(fieldName);
if (currentField != null) {
- validateScripts(currentField, nextField).ifPresent(r -> result.add(r));
+ validateScripts(currentField, nextField).ifPresent(result::add);
}
else if (nextField.isExtraField()) {
result.add(VespaReindexAction.of(id,
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 0b32194e257..31e4c661151 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
@@ -126,16 +126,9 @@ class JvmHeapSizeValidatorTest {
@Override public boolean restartOnDeploy() { return false;}
@Override public void store() {}
@Override public long aggregatedModelCostInBytes() { return totalCost.get(); }
- @Override public void registerModel(ApplicationFile path) {}
@Override public void registerModel(ApplicationFile path, OnnxModelOptions onnxModelOptions) {}
@Override
- public void registerModel(URI uri) {
- assertEquals("https://my/url/model.onnx", uri.toString());
- totalCost.addAndGet(modelCost);
- }
-
- @Override
public void registerModel(URI uri, OnnxModelOptions onnxModelOptions) {
assertEquals("https://my/url/model.onnx", uri.toString());
totalCost.addAndGet(modelCost);
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java
index 6b7df8871aa..bc36b800bfb 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java
@@ -23,9 +23,11 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
public class CertificateRemovalChangeValidatorTest {
private static final String validationOverrides =
- "<validation-overrides>\n" +
- " <allow until='2000-01-14' comment='test override'>certificate-removal</allow>\n" +
- "</validation-overrides>\n";
+ """
+ <validation-overrides>
+ <allow until='2000-01-14' comment='test override'>certificate-removal</allow>
+ </validation-overrides>
+ """;
@Test
void validate() {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidatorTest.java
index 3fd3180b37e..9e0eab9aba7 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidatorTest.java
@@ -22,19 +22,28 @@ import static org.junit.jupiter.api.Assertions.fail;
public class IndexingModeChangeValidatorTest {
@Test
+ void testChangingIndexModeFromIndexedToStreamingWhenDisallowedButInDev() {
+ ValidationTester tester = new ValidationTester();
+
+ VespaModel oldModel =
+ tester.deploy(null, getServices("index"), Environment.dev, "<validation-overrides />").getFirst();
+ List<ConfigChangeAction> actions = tester.deploy(oldModel, getServices("streaming"), Environment.dev, "<calidation-overrides />").getSecond();
+ assertReindexingChange("Document type 'music' in cluster 'default-content' changed indexing mode from 'indexed' to 'streaming'", actions);
+ }
+
+ @Test
void testChangingIndexModeFromIndexedToStreamingWhenDisallowed() {
ValidationTester tester = new ValidationTester();
VespaModel oldModel =
tester.deploy(null, getServices("index"), Environment.prod, "<validation-overrides />").getFirst();
try {
- List<ConfigChangeAction> changeActions =
- tester.deploy(oldModel, getServices("streaming"), Environment.prod, "<calidation-overrides />").getSecond();
+ tester.deploy(oldModel, getServices("streaming"), Environment.prod, "<calidation-overrides />").getSecond();
fail("Should throw on disallowed config change action");
}
catch (ValidationException e) {
- assertEquals("indexing-mode-change:\n" +
- "\tDocument type 'music' in cluster 'default-content' changed indexing mode from 'indexed' to 'streaming'\n" +
+ assertEquals("indexing-mode-change: " +
+ "Document type 'music' in cluster 'default-content' changed indexing mode from 'indexed' to 'streaming'. " +
"To allow this add <allow until='yyyy-mm-dd'>indexing-mode-change</allow> to validation-overrides.xml, see https://docs.vespa.ai/en/reference/validation-overrides.html",
e.getMessage());
}
@@ -94,8 +103,10 @@ public class IndexingModeChangeValidatorTest {
}
private static final String validationOverrides =
- "<validation-overrides>\n" +
- " <allow until='2000-01-14' comment='test override'>indexing-mode-change</allow>\n" +
- "</validation-overrides>\n";
+ """
+ <validation-overrides>
+ <allow until='2000-01-14' comment='test override'>indexing-mode-change</allow>
+ </validation-overrides>
+ """;
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidatorTest.java
index f9c0d00ac2c..b7e612127c1 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidatorTest.java
@@ -29,6 +29,14 @@ public class ResourcesReductionValidatorTest {
private final ValidationTester tester = new ValidationTester(provisioner);
@Test
+ void ok_when_reduction_by_over_50_percent_in_hosted_dev() {
+ var fromResources = new NodeResources(8, 64, 800, 1);
+ var toResources = new NodeResources(8, 16, 800, 1);
+ VespaModel previous = tester.deploy(null, contentServices(6, fromResources), Environment.dev, null, CONTAINER_CLUSTER).getFirst();
+ tester.deploy(previous, contentServices(6, toResources), Environment.dev, null, CONTAINER_CLUSTER);
+ }
+
+ @Test
void fail_when_reduction_by_over_50_percent() {
var fromResources = new NodeResources(8, 64, 800, 1);
var toResources = new NodeResources(8, 16, 800, 1);
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RestartOnDeployForOnnxModelChangesValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RestartOnDeployForOnnxModelChangesValidatorTest.java
index adcf58785fa..13389689de5 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RestartOnDeployForOnnxModelChangesValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RestartOnDeployForOnnxModelChangesValidatorTest.java
@@ -15,7 +15,6 @@ import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -89,17 +88,11 @@ public class RestartOnDeployForOnnxModelChangesValidatorTest {
public long aggregatedModelCostInBytes() { return estimatedCost; }
@Override
- public void registerModel(ApplicationFile path) {}
-
- @Override
public void registerModel(ApplicationFile path, OnnxModelOptions onnxModelOptions) {}
@Override
- public void registerModel(URI uri) {}
-
- @Override
public void registerModel(URI uri, OnnxModelOptions onnxModelOptions) {
- models.put(uri.toString(), new OnnxModelCost.ModelInfo(uri.toString(), estimatedCost, hash, Optional.ofNullable(onnxModelOptions)));
+ models.put(uri.toString(), new OnnxModelCost.ModelInfo(uri.toString(), estimatedCost, hash, onnxModelOptions));
}
@Override
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/TenantHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/TenantHandler.java
index 79a55466021..e9b1c8c83f8 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/TenantHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/TenantHandler.java
@@ -6,6 +6,7 @@ import com.yahoo.component.annotation.Inject;
import com.yahoo.config.provision.TenantName;
import com.yahoo.container.jdisc.HttpResponse;
import com.yahoo.restapi.ErrorResponse;
+import com.yahoo.restapi.MessageResponse;
import com.yahoo.restapi.RestApi;
import com.yahoo.restapi.RestApiException;
import com.yahoo.restapi.RestApiRequestHandler;
@@ -63,7 +64,7 @@ public class TenantHandler extends RestApiRequestHandler<TenantHandler> {
private HttpResponse putTenant(RestApi.RequestContext context) {
TenantName name = TenantName.from(context.pathParameters().getStringOrThrow("tenant"));
if (tenantRepository.checkThatTenantExists(name))
- throw new RestApiException.BadRequest("There already exists a tenant '" + name + "'");
+ return new MessageResponse("Tenant '" + name + "' already exists");
if ( ! name.value().matches(TENANT_NAME_REGEXP))
throw new RestApiException.BadRequest("Illegal tenant name: " + name);
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/SecretStoreExternalIdRetriever.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/SecretStoreExternalIdRetriever.java
index 5afb2188fac..c6f9a0268c1 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/SecretStoreExternalIdRetriever.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/SecretStoreExternalIdRetriever.java
@@ -4,7 +4,10 @@ package com.yahoo.vespa.config.server.tenant;
import com.yahoo.config.model.api.TenantSecretStore;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.TenantName;
+import com.yahoo.container.jdisc.secretstore.SecretNotFoundException;
import com.yahoo.container.jdisc.secretstore.SecretStore;
+import com.yahoo.vespa.config.server.http.InvalidApplicationException;
+
import java.util.List;
import java.util.stream.Collectors;
@@ -19,10 +22,14 @@ public class SecretStoreExternalIdRetriever {
return tenantSecretStores.stream()
.map(tenantSecretStore -> {
var secretName = secretName(tenant, system, tenantSecretStore.getName());
- String secret = secretStore.getSecret(secretName);
- if (secret == null)
- throw new RuntimeException("No secret found in secret store for " + secretName);
- return tenantSecretStore.withExternalId(secret);
+ try {
+ String secret = secretStore.getSecret(secretName);
+ if (secret == null)
+ throw new InvalidApplicationException("No secret found in secret store for " + secretName);
+ return tenantSecretStore.withExternalId(secret);
+ } catch (SecretNotFoundException e) {
+ throw new InvalidApplicationException("Could not find externalId for secret store: %s".formatted(tenantSecretStore.getName()));
+ }
})
.toList();
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/MockSecretStore.java b/configserver/src/test/java/com/yahoo/vespa/config/server/MockSecretStore.java
index bd469cb8f0b..ac97fe0ba05 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/MockSecretStore.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/MockSecretStore.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.config.server;
+import com.yahoo.container.jdisc.secretstore.SecretNotFoundException;
import com.yahoo.container.jdisc.secretstore.SecretStore;
import java.util.HashMap;
@@ -13,7 +14,7 @@ public class MockSecretStore implements SecretStore {
public String getSecret(String key) {
if(secrets.containsKey(key))
return secrets.get(key).get(0);
- throw new RuntimeException("Key not found: " + key);
+ throw new SecretNotFoundException("Key not found: " + key);
}
@Override
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/TenantHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/TenantHandlerTest.java
index 49e6ebbfcff..fbebd463569 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/TenantHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/TenantHandlerTest.java
@@ -108,7 +108,7 @@ public class TenantHandlerTest {
"{\"message\":\"Tenant a created.\"}");
assertEquals(tenantRepository.getTenant(a).getName(), a);
assertResponse(PUT, "/application/v2/tenant/a",
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"There already exists a tenant 'a'\"}");
+ "{\"message\":\"Tenant 'a' already exists\"}");
}
@Test
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/SecretStoreExternalIdRetrieverTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/SecretStoreExternalIdRetrieverTest.java
new file mode 100644
index 00000000000..96c7d9e6957
--- /dev/null
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/SecretStoreExternalIdRetrieverTest.java
@@ -0,0 +1,39 @@
+// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+package com.yahoo.vespa.config.server.tenant;
+
+import com.yahoo.config.model.api.TenantSecretStore;
+import com.yahoo.config.provision.SystemName;
+import com.yahoo.config.provision.TenantName;
+import com.yahoo.vespa.config.server.MockSecretStore;
+import com.yahoo.vespa.config.server.http.InvalidApplicationException;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+/**
+ * @author mortent
+ */
+public class SecretStoreExternalIdRetrieverTest {
+ private final MockSecretStore secretStore = new MockSecretStore();
+ private final TenantName tenantName = TenantName.from("myTenant");
+ private final TenantSecretStore tenantSecretStore = new TenantSecretStore("name", "123456789012", "role");
+
+ @Test
+ public void fills_external_ids() {
+ secretStore.put(SecretStoreExternalIdRetriever.secretName(tenantName, SystemName.PublicCd, "name"), "externalId");
+
+ List<TenantSecretStore> tenantSecretStores = SecretStoreExternalIdRetriever.populateExternalId(secretStore, tenantName, SystemName.PublicCd, List.of(tenantSecretStore));
+ assertEquals(1, tenantSecretStores.size());
+ assertEquals("externalId", tenantSecretStores.get(0).getExternalId().get());
+ }
+
+ @Test
+ public void reports_application_package_error_when_external_id_not_found() {
+ InvalidApplicationException exception = assertThrows(InvalidApplicationException.class, () -> SecretStoreExternalIdRetriever.populateExternalId(secretStore, tenantName, SystemName.PublicCd, List.of(tenantSecretStore)));
+ assertEquals("Could not find externalId for secret store: name", exception.getMessage());
+ }
+}
diff --git a/container-core/src/main/java/com/yahoo/processing/request/ErrorMessage.java b/container-core/src/main/java/com/yahoo/processing/request/ErrorMessage.java
index ca2a00ffe46..9fca0bb0ddb 100644
--- a/container-core/src/main/java/com/yahoo/processing/request/ErrorMessage.java
+++ b/container-core/src/main/java/com/yahoo/processing/request/ErrorMessage.java
@@ -160,7 +160,7 @@ public class ErrorMessage implements Cloneable {
message = getMessage(t);
if (message == null) continue;
if (lastMessage != null && lastMessage.equals(message)) continue;
- if (b.length() > 0)
+ if (!b.isEmpty())
b.append(": ");
b.append(message);
}
@@ -191,9 +191,7 @@ public class ErrorMessage implements Cloneable {
*/
@Override
public boolean equals(Object o) {
- if (!(o instanceof ErrorMessage)) return false;
-
- ErrorMessage other = (ErrorMessage) o;
+ if (!(o instanceof ErrorMessage other)) return false;
if (this.code != other.code) return false;
diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json
index 80833e3e27c..aedccbee46b 100644
--- a/container-search/abi-spec.json
+++ b/container-search/abi-spec.json
@@ -7802,6 +7802,7 @@
"public static com.yahoo.search.result.ErrorMessage createNotFound(java.lang.String)",
"public static com.yahoo.search.result.ErrorMessage createBadRequest(java.lang.String)",
"public static com.yahoo.search.result.ErrorMessage createInternalServerError(java.lang.String)",
+ "public static com.yahoo.search.result.ErrorMessage createInternalServerError(java.lang.String, java.lang.Throwable)",
"public static com.yahoo.search.result.ErrorMessage createSearchReplyError(java.lang.String)",
"public static com.yahoo.search.result.ErrorMessage createDocsumReplyError(java.lang.String)",
"public void setSource(java.lang.String)",
diff --git a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
index e20c4271fe0..441c4326355 100644
--- a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
@@ -270,7 +270,12 @@ public class ClusterSearcher extends Searcher {
Result result = task.get();
mergedResult.mergeWith(result);
mergedResult.hits().addAll(result.hits().asUnorderedHits());
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
+ mergedResult.hits().addError(ErrorMessage.createInternalServerError("Failed querying '" +
+ query.getModel().getRestrict() + "': " +
+ Exceptions.toMessageString(e),
+ e));
+ } catch (InterruptedException e) {
mergedResult.hits().addError(ErrorMessage.createInternalServerError("Failed querying '" +
query.getModel().getRestrict() + "': " +
Exceptions.toMessageString(e)));
diff --git a/container-search/src/main/java/com/yahoo/search/result/ErrorMessage.java b/container-search/src/main/java/com/yahoo/search/result/ErrorMessage.java
index a6f57aa866a..503bbd725c3 100644
--- a/container-search/src/main/java/com/yahoo/search/result/ErrorMessage.java
+++ b/container-search/src/main/java/com/yahoo/search/result/ErrorMessage.java
@@ -163,6 +163,14 @@ public class ErrorMessage extends com.yahoo.processing.request.ErrorMessage {
return new ErrorMessage(INTERNAL_SERVER_ERROR.code, "Internal server error.", detailedMessage);
}
+ /**
+ * Creates an error analog to HTTP internal server error. If this error is present, a
+ * HTTP layer will return 500.
+ */
+ public static ErrorMessage createInternalServerError(String detailedMessage, Throwable cause) {
+ return new ErrorMessage(INTERNAL_SERVER_ERROR.code, "Internal server error.", detailedMessage, cause);
+ }
+
/** Wraps an error message received in a SearchReply packet */
public static ErrorMessage createSearchReplyError(String detailedMessage) {
return new ErrorMessage(RESULT_HAS_ERRORS.code, "Error in search reply.", detailedMessage);
diff --git a/dependency-versions/pom.xml b/dependency-versions/pom.xml
index 56ecabd5a32..7768fdcc52d 100644
--- a/dependency-versions/pom.xml
+++ b/dependency-versions/pom.xml
@@ -33,10 +33,10 @@
<!-- DO NOT UPGRADE THESE TO A NEW MAJOR VERSION WITHOUT CHECKING FOR BINARY COMPATIBILITY -->
<aopalliance.vespa.version>1.0</aopalliance.vespa.version>
- <error-prone-annotations.vespa.version>2.23.0</error-prone-annotations.vespa.version>
- <guava.vespa.version>32.1.3-jre</guava.vespa.version>
+ <error-prone-annotations.vespa.version>2.24.0</error-prone-annotations.vespa.version>
+ <guava.vespa.version>33.0.0-jre</guava.vespa.version>
<guice.vespa.version>6.0.0</guice.vespa.version>
- <jackson2.vespa.version>2.16.0</jackson2.vespa.version>
+ <jackson2.vespa.version>2.16.1</jackson2.vespa.version>
<jackson-databind.vespa.version>${jackson2.vespa.version}</jackson-databind.vespa.version>
<jakarta.inject.vespa.version>2.0.1</jakarta.inject.vespa.version>
<javax.inject.vespa.version>1</javax.inject.vespa.version>
@@ -62,11 +62,11 @@
<apache.httpcore5.vespa.version>5.2.4</apache.httpcore5.vespa.version>
<apiguardian.vespa.version>1.1.2</apiguardian.vespa.version>
<asm.vespa.version>9.6</asm.vespa.version>
- <assertj.vespa.version>3.24.2</assertj.vespa.version>
+ <assertj.vespa.version>3.25.1</assertj.vespa.version>
<!-- Athenz dependencies. Make sure these dependencies match those in Vespa's internal repositories -->
- <athenz.vespa.version>1.11.48</athenz.vespa.version>
- <aws-sdk.vespa.version>1.12.623</aws-sdk.vespa.version>
+ <athenz.vespa.version>1.11.49</athenz.vespa.version>
+ <aws-sdk.vespa.version>1.12.629</aws-sdk.vespa.version>
<!-- Athenz END -->
<!-- WARNING: If you change curator version, you also need to update
@@ -94,6 +94,7 @@
<dropwizard.metrics.vespa.version>4.2.23</dropwizard.metrics.vespa.version> <!-- ZK 3.9.1 requires this -->
<eclipse-collections.vespa.version>11.1.0</eclipse-collections.vespa.version>
<eclipse-sisu.vespa.version>0.9.0.M2</eclipse-sisu.vespa.version>
+ <failureaccess.vespa.version>1.0.2</failureaccess.vespa.version>
<felix.vespa.version>7.0.5</felix.vespa.version>
<felix.log.vespa.version>1.3.0</felix.log.vespa.version>
<findbugs.vespa.version>3.0.2</findbugs.vespa.version> <!-- Should be kept in sync with guava -->
@@ -128,6 +129,7 @@
<org.json.vespa.version>20231013</org.json.vespa.version>
<org.lz4.vespa.version>1.8.0</org.lz4.vespa.version>
<prometheus.client.vespa.version>0.16.0</prometheus.client.vespa.version>
+ <plexus-interpolation.vespa.version>1.27</plexus-interpolation.vespa.version>
<protobuf.vespa.version>3.25.1</protobuf.vespa.version>
<questdb.vespa.version>7.3.7</questdb.vespa.version>
<spifly.vespa.version>1.3.7</spifly.vespa.version>
@@ -153,7 +155,7 @@
<maven-antrun-plugin.vespa.version>3.1.0</maven-antrun-plugin.vespa.version>
<maven-assembly-plugin.vespa.version>3.6.0</maven-assembly-plugin.vespa.version>
<maven-bundle-plugin.vespa.version>5.1.9</maven-bundle-plugin.vespa.version>
- <maven-compiler-plugin.vespa.version>3.12.0</maven-compiler-plugin.vespa.version>
+ <maven-compiler-plugin.vespa.version>3.12.1</maven-compiler-plugin.vespa.version>
<maven-core.vespa.version>3.9.6</maven-core.vespa.version>
<maven-dependency-plugin.vespa.version>3.6.1</maven-dependency-plugin.vespa.version>
<maven-deploy-plugin.vespa.version>3.1.1</maven-deploy-plugin.vespa.version>
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
index 79b3fb00d71..72792b23e2c 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
@@ -51,14 +51,14 @@ public class Flags {
public static final UnboundDoubleFlag DEFAULT_TERM_WISE_LIMIT = defineDoubleFlag(
"default-term-wise-limit", 1.0,
- List.of("baldersheim"), "2020-12-02", "2023-12-31",
+ List.of("baldersheim"), "2020-12-02", "2024-12-31",
"Default limit for when to apply termwise query evaluation",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundStringFlag QUERY_DISPATCH_POLICY = defineStringFlag(
"query-dispatch-policy", "adaptive",
- List.of("baldersheim"), "2022-08-20", "2023-12-31",
+ List.of("baldersheim"), "2022-08-20", "2024-12-31",
"Select query dispatch policy, valid values are adaptive, round-robin, best-of-random-2," +
" latency-amortized-over-requests, latency-amortized-over-time",
"Takes effect at redeployment (requires restart)",
@@ -66,21 +66,21 @@ public class Flags {
public static final UnboundStringFlag SUMMARY_DECODE_POLICY = defineStringFlag(
"summary-decode-policy", "eager",
- List.of("baldersheim"), "2023-03-30", "2023-12-31",
+ List.of("baldersheim"), "2023-03-30", "2024-12-31",
"Select summary decoding policy, valid values are eager and on-demand/ondemand.",
"Takes effect at redeployment (requires restart)",
INSTANCE_ID);
public static final UnboundStringFlag FEED_SEQUENCER_TYPE = defineStringFlag(
"feed-sequencer-type", "THROUGHPUT",
- List.of("baldersheim"), "2020-12-02", "2023-12-31",
+ List.of("baldersheim"), "2020-12-02", "2024-12-31",
"Selects type of sequenced executor used for feeding in proton, valid values are LATENCY, ADAPTIVE, THROUGHPUT",
"Takes effect at redeployment (requires restart)",
INSTANCE_ID);
public static final UnboundStringFlag NESSUS_AGENT_GROUP = defineStringFlag(
"nessus-agent-group", ":legacy",
- List.of("hakonhall"), "2023-11-29", "2023-12-29",
+ List.of("hakonhall"), "2023-11-29", "2024-02-29",
"Link nessusagent to the given group, or run legacy task (\":legacy\"), or disable task (\"\").",
"Takes effect after host admin restart",
(String value) -> value.equals(":legacy") || // Run legacy task. Is a no-op outside YAHOO cloud.
@@ -92,42 +92,42 @@ public class Flags {
public static final UnboundIntFlag MAX_UNCOMMITTED_MEMORY = defineIntFlag(
"max-uncommitted-memory", 130000,
- List.of("geirst, baldersheim"), "2021-10-21", "2023-12-31",
+ List.of("geirst, baldersheim"), "2021-10-21", "2024-12-31",
"Max amount of memory holding updates to an attribute before we do a commit.",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundStringFlag RESPONSE_SEQUENCER_TYPE = defineStringFlag(
"response-sequencer-type", "ADAPTIVE",
- List.of("baldersheim"), "2020-12-02", "2023-12-31",
+ List.of("baldersheim"), "2020-12-02", "2024-12-31",
"Selects type of sequenced executor used for mbus responses, valid values are LATENCY, ADAPTIVE, THROUGHPUT",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundIntFlag RESPONSE_NUM_THREADS = defineIntFlag(
"response-num-threads", 2,
- List.of("baldersheim"), "2020-12-02", "2023-12-31",
+ List.of("baldersheim"), "2020-12-02", "2024-12-31",
"Number of threads used for mbus responses, default is 2, negative number = numcores/4",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundBooleanFlag USE_ASYNC_MESSAGE_HANDLING_ON_SCHEDULE = defineFeatureFlag(
"async-message-handling-on-schedule", false,
- List.of("baldersheim"), "2020-12-02", "2023-12-31",
+ List.of("baldersheim"), "2020-12-02", "2024-12-31",
"Optionally deliver async messages in own thread",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundDoubleFlag FEED_CONCURRENCY = defineDoubleFlag(
"feed-concurrency", 0.5,
- List.of("baldersheim"), "2020-12-02", "2023-12-31",
+ List.of("baldersheim"), "2020-12-02", "2024-12-31",
"How much concurrency should be allowed for feed",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundDoubleFlag FEED_NICENESS = defineDoubleFlag(
"feed-niceness", 0.0,
- List.of("baldersheim"), "2022-06-24", "2023-12-31",
+ List.of("baldersheim"), "2022-06-24", "2024-12-31",
"How nice feeding shall be",
"Takes effect at redeployment",
INSTANCE_ID);
@@ -135,71 +135,71 @@ public class Flags {
public static final UnboundIntFlag MBUS_JAVA_NUM_TARGETS = defineIntFlag(
"mbus-java-num-targets", 2,
- List.of("baldersheim"), "2022-07-05", "2023-12-31",
+ List.of("baldersheim"), "2022-07-05", "2024-12-31",
"Number of rpc targets per service",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundIntFlag MBUS_CPP_NUM_TARGETS = defineIntFlag(
"mbus-cpp-num-targets", 2,
- List.of("baldersheim"), "2022-07-05", "2023-12-31",
+ List.of("baldersheim"), "2022-07-05", "2024-12-31",
"Number of rpc targets per service",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundIntFlag RPC_NUM_TARGETS = defineIntFlag(
"rpc-num-targets", 2,
- List.of("baldersheim"), "2022-07-05", "2023-12-31",
+ List.of("baldersheim"), "2022-07-05", "2024-12-31",
"Number of rpc targets per content node",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundIntFlag MBUS_JAVA_EVENTS_BEFORE_WAKEUP = defineIntFlag(
"mbus-java-events-before-wakeup", 1,
- List.of("baldersheim"), "2022-07-05", "2023-12-31",
+ List.of("baldersheim"), "2022-07-05", "2024-12-31",
"Number write events before waking up transport thread",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundIntFlag MBUS_CPP_EVENTS_BEFORE_WAKEUP = defineIntFlag(
"mbus-cpp-events-before-wakeup", 1,
- List.of("baldersheim"), "2022-07-05", "2023-12-31",
+ List.of("baldersheim"), "2022-07-05", "2024-12-31",
"Number write events before waking up transport thread",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundIntFlag RPC_EVENTS_BEFORE_WAKEUP = defineIntFlag(
"rpc-events-before-wakeup", 1,
- List.of("baldersheim"), "2022-07-05", "2023-12-31",
+ List.of("baldersheim"), "2022-07-05", "2024-12-31",
"Number write events before waking up transport thread",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundIntFlag MBUS_NUM_NETWORK_THREADS = defineIntFlag(
"mbus-num-network-threads", 1,
- List.of("baldersheim"), "2022-07-01", "2023-12-31",
+ List.of("baldersheim"), "2022-07-01", "2024-12-31",
"Number of threads used for mbus network",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundBooleanFlag SHARED_STRING_REPO_NO_RECLAIM = defineFeatureFlag(
"shared-string-repo-no-reclaim", false,
- List.of("baldersheim"), "2022-06-14", "2023-12-31",
+ List.of("baldersheim"), "2022-06-14", "2024-12-31",
"Controls whether we do track usage and reclaim unused enum values in shared string repo",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundBooleanFlag CONTAINER_DUMP_HEAP_ON_SHUTDOWN_TIMEOUT = defineFeatureFlag(
"container-dump-heap-on-shutdown-timeout", false,
- List.of("baldersheim"), "2021-09-25", "2023-12-31",
+ List.of("baldersheim"), "2021-09-25", "2024-12-31",
"Will trigger a heap dump during if container shutdown times out",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundBooleanFlag LOAD_CODE_AS_HUGEPAGES = defineFeatureFlag(
"load-code-as-hugepages", false,
- List.of("baldersheim"), "2022-05-13", "2023-12-31",
+ List.of("baldersheim"), "2022-05-13", "2024-12-31",
"Will try to map the code segment with huge (2M) pages",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundDoubleFlag CONTAINER_SHUTDOWN_TIMEOUT = defineDoubleFlag(
"container-shutdown-timeout", 50.0,
- List.of("baldersheim"), "2021-09-25", "2023-12-31",
+ List.of("baldersheim"), "2021-09-25", "2024-12-31",
"Timeout for shutdown of a jdisc container",
"Takes effect at redeployment",
INSTANCE_ID);
@@ -228,7 +228,7 @@ public class Flags {
public static final UnboundStringFlag SYSTEM_MEMORY_HIGH = defineStringFlag(
"system-memory-high", "",
- List.of("baldersheim"), "2023-02-14", "2023-12-31",
+ List.of("baldersheim"), "2023-02-14", "2024-12-31",
"The value to write to /sys/fs/cgroup/system.slice/memory.high, if non-empty. " +
"You may want lower memory.high before lowering memory.max, " +
"and raise memory.high after raising memory.max.",
@@ -237,7 +237,7 @@ public class Flags {
public static final UnboundStringFlag SYSTEM_MEMORY_MAX = defineStringFlag(
"system-memory-max", "",
- List.of("baldersheim"), "2023-02-14", "2023-12-31",
+ List.of("baldersheim"), "2023-02-14", "2024-12-31",
"The value to write to /sys/fs/cgroup/system.slice/memory.max, if non-empty. " +
"You may want lower memory.high before lowering memory.max, " +
"and raise memory.high after raising memory.max.",
@@ -246,7 +246,7 @@ public class Flags {
public static final UnboundBooleanFlag ENABLED_HORIZON_DASHBOARD = defineFeatureFlag(
"enabled-horizon-dashboard", false,
- List.of("olaa"), "2021-09-13", "2024-01-01",
+ List.of("olaa"), "2021-09-13", "2024-03-01",
"Enable Horizon dashboard",
"Takes effect immediately",
TENANT_ID, CONSOLE_USER_EMAIL
@@ -261,7 +261,7 @@ public class Flags {
public static final UnboundIntFlag MAX_COMPACT_BUFFERS = defineIntFlag(
"max-compact-buffers", 1,
- List.of("baldersheim", "geirst", "toregge"), "2021-12-15", "2023-12-31",
+ List.of("baldersheim", "geirst", "toregge"), "2021-12-15", "2024-12-31",
"Upper limit of buffers to compact in a data store at the same time for each reason (memory usage, address space usage)",
"Takes effect at redeployment",
INSTANCE_ID);
@@ -282,14 +282,14 @@ public class Flags {
public static final UnboundBooleanFlag SEPARATE_METRIC_CHECK_CONFIG = defineFeatureFlag(
"separate-metric-check-config", false,
- List.of("olaa"), "2022-07-04", "2024-01-01",
+ List.of("olaa"), "2022-07-04", "2024-03-01",
"Determines whether one metrics config check should be written per Vespa node",
"Takes effect on next tick",
HOSTNAME);
public static final UnboundStringFlag TLS_CAPABILITIES_ENFORCEMENT_MODE = defineStringFlag(
"tls-capabilities-enforcement-mode", "disable",
- List.of("bjorncs", "vekterli"), "2022-07-21", "2024-01-01",
+ List.of("bjorncs", "vekterli"), "2022-07-21", "2025-01-01",
"Configure Vespa TLS capability enforcement mode",
"Takes effect on restart of Docker container",
INSTANCE_ID,HOSTNAME,NODE_TYPE,TENANT_ID,VESPA_VERSION
@@ -297,7 +297,7 @@ public class Flags {
public static final UnboundBooleanFlag ENABLE_OTELCOL = defineFeatureFlag(
"enable-otel-collector", false,
- List.of("olaa"), "2022-09-23", "2024-01-01",
+ List.of("olaa"), "2022-09-23", "2024-03-01",
"Whether an OpenTelemetry collector should be enabled",
"Takes effect at next tick",
INSTANCE_ID);
@@ -396,7 +396,7 @@ public class Flags {
public static final UnboundIntFlag SEARCH_HANDLER_THREADPOOL = defineIntFlag(
"search-handler-threadpool", 2,
- List.of("bjorncs", "baldersheim"), "2023-10-01", "2024-01-01",
+ List.of("bjorncs", "baldersheim"), "2023-10-01", "2025-01-01",
"Adjust search handler threadpool size",
"Takes effect at redeployment",
APPLICATION);
@@ -441,7 +441,7 @@ public class Flags {
TENANT_ID, CONSOLE_USER_EMAIL);
public static final UnboundBooleanFlag CENTRALIZED_AUTHZ = defineFeatureFlag(
- "centralized-authz", false,
+ "centralized-authz", true,
List.of("mortent"), "2023-11-27", "2024-02-01",
"Use centralized authorization checks",
"Takes effect immediately",
diff --git a/integration/intellij/build.gradle.kts b/integration/intellij/build.gradle.kts
index 502c09c58f8..980e8878efc 100644
--- a/integration/intellij/build.gradle.kts
+++ b/integration/intellij/build.gradle.kts
@@ -5,7 +5,7 @@ import org.jetbrains.grammarkit.tasks.GenerateParserTask
plugins {
id("java-library")
id("org.jetbrains.intellij") version "1.16.1"
- id("org.jetbrains.grammarkit") version "2022.3.2"
+ id("org.jetbrains.grammarkit") version "2022.3.2.1"
id("maven-publish") // to deploy the plugin into a Maven repo
}
diff --git a/jdisc_core/src/test/resources/exportPackages.properties b/jdisc_core/src/test/resources/exportPackages.properties
index dc6e4ab0962..aa93c919341 100644
--- a/jdisc_core/src/test/resources/exportPackages.properties
+++ b/jdisc_core/src/test/resources/exportPackages.properties
@@ -1,3 +1,3 @@
#generated by com.yahoo.jdisc.core.ExportPackages
#Fri Jul 07 16:04:11 CEST 2023
-exportPackages=org.osgi.framework; version\="1.10.0", org.osgi.framework.connect; version\="1.0.0", org.osgi.framework.dto; uses\:\="org.osgi.dto"; version\="1.8.0", org.osgi.framework.hooks.bundle; uses\:\="org.osgi.framework"; version\="1.1.0", org.osgi.framework.hooks.resolver; uses\:\="org.osgi.framework.wiring"; version\="1.0.0", org.osgi.framework.hooks.service; uses\:\="org.osgi.framework"; version\="1.1.0", org.osgi.framework.hooks.weaving; uses\:\="org.osgi.framework.wiring"; version\="1.1.0", org.osgi.framework.launch; uses\:\="org.osgi.framework"; version\="1.2.0", org.osgi.framework.namespace; uses\:\="org.osgi.resource"; version\="1.2.0", org.osgi.framework.startlevel; uses\:\="org.osgi.framework"; version\="1.0.0", org.osgi.framework.startlevel.dto; uses\:\="org.osgi.dto"; version\="1.0.0", org.osgi.framework.wiring; uses\:\="org.osgi.framework,org.osgi.resource"; version\="1.2.0", org.osgi.framework.wiring.dto; uses\:\="org.osgi.dto,org.osgi.resource.dto"; version\="1.3.0", org.osgi.resource; version\="1.0.1", org.osgi.resource.dto; uses\:\="org.osgi.dto"; version\="1.0.1", org.osgi.service.packageadmin; uses\:\="org.osgi.framework"; version\="1.2.1", org.osgi.service.startlevel; uses\:\="org.osgi.framework"; version\="1.1.1", org.osgi.service.url; version\="1.0.1", org.osgi.service.resolver; uses\:\="org.osgi.resource"; version\="1.1.1", org.osgi.util.tracker; uses\:\="org.osgi.framework"; version\="1.5.3", org.osgi.dto; version\="1.1.1", org.osgi.service.condition; version\="1.0.0", java.util.jar; version\="0.0.0.JavaSE_017", java.nio; version\="0.0.0.JavaSE_017", java.nio.file.spi; version\="0.0.0.JavaSE_017", java.security; version\="0.0.0.JavaSE_017", java.util; version\="0.0.0.JavaSE_017", javax.crypto.interfaces; version\="0.0.0.JavaSE_017", java.nio.charset.spi; version\="0.0.0.JavaSE_017", java.util.concurrent; version\="0.0.0.JavaSE_017", javax.security.auth.spi; version\="0.0.0.JavaSE_017", java.lang.annotation; version\="0.0.0.JavaSE_017", javax.security.cert; version\="0.0.0.JavaSE_017", java.net; version\="0.0.0.JavaSE_017", java.util.spi; version\="0.0.0.JavaSE_017", java.io; version\="0.0.0.JavaSE_017", java.nio.charset; version\="0.0.0.JavaSE_017", java.time.zone; version\="0.0.0.JavaSE_017", javax.crypto; version\="0.0.0.JavaSE_017", java.time.chrono; version\="0.0.0.JavaSE_017", java.nio.channels; version\="0.0.0.JavaSE_017", java.security.spec; version\="0.0.0.JavaSE_017", java.security.cert; version\="0.0.0.JavaSE_017", java.util.concurrent.atomic; version\="0.0.0.JavaSE_017", java.nio.file; version\="0.0.0.JavaSE_017", java.math; version\="0.0.0.JavaSE_017", java.nio.channels.spi; version\="0.0.0.JavaSE_017", java.text.spi; version\="0.0.0.JavaSE_017", java.security.interfaces; version\="0.0.0.JavaSE_017", java.lang.constant; version\="0.0.0.JavaSE_017", javax.net.ssl; version\="0.0.0.JavaSE_017", javax.security.auth.login; version\="0.0.0.JavaSE_017", javax.security.auth.callback; version\="0.0.0.JavaSE_017", java.lang.reflect; version\="0.0.0.JavaSE_017", javax.security.auth.x500; version\="0.0.0.JavaSE_017", javax.net; version\="0.0.0.JavaSE_017", java.util.function; version\="0.0.0.JavaSE_017", java.lang.runtime; version\="0.0.0.JavaSE_017", java.lang; version\="0.0.0.JavaSE_017", java.time; version\="0.0.0.JavaSE_017", java.util.stream; version\="0.0.0.JavaSE_017", javax.crypto.spec; version\="0.0.0.JavaSE_017", java.text; version\="0.0.0.JavaSE_017", java.util.random; version\="0.0.0.JavaSE_017", java.nio.file.attribute; version\="0.0.0.JavaSE_017", java.util.zip; version\="0.0.0.JavaSE_017", java.time.temporal; version\="0.0.0.JavaSE_017", java.util.concurrent.locks; version\="0.0.0.JavaSE_017", java.time.format; version\="0.0.0.JavaSE_017", java.lang.invoke; version\="0.0.0.JavaSE_017", java.lang.module; version\="0.0.0.JavaSE_017", java.net.spi; version\="0.0.0.JavaSE_017", java.util.regex; version\="0.0.0.JavaSE_017", java.lang.ref; version\="0.0.0.JavaSE_017", javax.security.auth; version\="0.0.0.JavaSE_017", javax.lang.model.element; version\="0.0.0.JavaSE_017", javax.annotation.processing; version\="0.0.0.JavaSE_017", javax.lang.model; version\="0.0.0.JavaSE_017", javax.lang.model.util; version\="0.0.0.JavaSE_017", javax.lang.model.type; version\="0.0.0.JavaSE_017", javax.tools; version\="0.0.0.JavaSE_017", java.awt.datatransfer; version\="0.0.0.JavaSE_017", java.awt.event; version\="0.0.0.JavaSE_017", javax.accessibility; version\="0.0.0.JavaSE_017", javax.swing.plaf.nimbus; version\="0.0.0.JavaSE_017", javax.print; version\="0.0.0.JavaSE_017", javax.print.attribute; version\="0.0.0.JavaSE_017", javax.sound.sampled; version\="0.0.0.JavaSE_017", javax.imageio.event; version\="0.0.0.JavaSE_017", javax.swing.filechooser; version\="0.0.0.JavaSE_017", javax.swing.plaf; version\="0.0.0.JavaSE_017", javax.swing.undo; version\="0.0.0.JavaSE_017", javax.swing.plaf.basic; version\="0.0.0.JavaSE_017", javax.swing.text; version\="0.0.0.JavaSE_017", java.awt.dnd; version\="0.0.0.JavaSE_017", javax.sound.midi; version\="0.0.0.JavaSE_017", java.applet; version\="0.0.0.JavaSE_017", java.awt.im.spi; version\="0.0.0.JavaSE_017", javax.imageio; version\="0.0.0.JavaSE_017", java.awt.font; version\="0.0.0.JavaSE_017", javax.swing.text.rtf; version\="0.0.0.JavaSE_017", javax.swing.text.html.parser; version\="0.0.0.JavaSE_017", java.beans; version\="0.0.0.JavaSE_017", javax.swing.plaf.synth; version\="0.0.0.JavaSE_017", java.awt.desktop; version\="0.0.0.JavaSE_017", javax.swing.event; version\="0.0.0.JavaSE_017", javax.imageio.stream; version\="0.0.0.JavaSE_017", java.awt; version\="0.0.0.JavaSE_017", java.beans.beancontext; version\="0.0.0.JavaSE_017", javax.swing.plaf.metal; version\="0.0.0.JavaSE_017", javax.print.event; version\="0.0.0.JavaSE_017", java.awt.im; version\="0.0.0.JavaSE_017", javax.swing.plaf.multi; version\="0.0.0.JavaSE_017", java.awt.image.renderable; version\="0.0.0.JavaSE_017", javax.swing; version\="0.0.0.JavaSE_017", javax.swing.colorchooser; version\="0.0.0.JavaSE_017", javax.print.attribute.standard; version\="0.0.0.JavaSE_017", javax.sound.midi.spi; version\="0.0.0.JavaSE_017", javax.swing.table; version\="0.0.0.JavaSE_017", javax.imageio.metadata; version\="0.0.0.JavaSE_017", java.awt.image; version\="0.0.0.JavaSE_017", java.awt.print; version\="0.0.0.JavaSE_017", javax.imageio.plugins.tiff; version\="0.0.0.JavaSE_017", javax.swing.tree; version\="0.0.0.JavaSE_017", javax.imageio.plugins.jpeg; version\="0.0.0.JavaSE_017", java.awt.geom; version\="0.0.0.JavaSE_017", java.awt.color; version\="0.0.0.JavaSE_017", javax.imageio.plugins.bmp; version\="0.0.0.JavaSE_017", javax.sound.sampled.spi; version\="0.0.0.JavaSE_017", javax.swing.border; version\="0.0.0.JavaSE_017", javax.imageio.spi; version\="0.0.0.JavaSE_017", javax.swing.text.html; version\="0.0.0.JavaSE_017", java.lang.instrument; version\="0.0.0.JavaSE_017", java.util.logging; version\="0.0.0.JavaSE_017", java.lang.management; version\="0.0.0.JavaSE_017", javax.management.openmbean; version\="0.0.0.JavaSE_017", javax.management.loading; version\="0.0.0.JavaSE_017", javax.management.relation; version\="0.0.0.JavaSE_017", javax.management; version\="0.0.0.JavaSE_017", javax.management.timer; version\="0.0.0.JavaSE_017", javax.management.modelmbean; version\="0.0.0.JavaSE_017", javax.management.monitor; version\="0.0.0.JavaSE_017", javax.management.remote; version\="0.0.0.JavaSE_017", javax.management.remote.rmi; version\="0.0.0.JavaSE_017", javax.naming; version\="0.0.0.JavaSE_017", javax.naming.ldap.spi; version\="0.0.0.JavaSE_017", javax.naming.event; version\="0.0.0.JavaSE_017", javax.naming.directory; version\="0.0.0.JavaSE_017", javax.naming.ldap; version\="0.0.0.JavaSE_017", javax.naming.spi; version\="0.0.0.JavaSE_017", java.net.http; version\="0.0.0.JavaSE_017", java.util.prefs; version\="0.0.0.JavaSE_017", java.rmi.registry; version\="0.0.0.JavaSE_017", java.rmi.server; version\="0.0.0.JavaSE_017", java.rmi; version\="0.0.0.JavaSE_017", java.rmi.dgc; version\="0.0.0.JavaSE_017", javax.rmi.ssl; version\="0.0.0.JavaSE_017", javax.script; version\="0.0.0.JavaSE_017", org.ietf.jgss; version\="0.0.0.JavaSE_017", javax.security.auth.kerberos; version\="0.0.0.JavaSE_017", javax.security.sasl; version\="0.0.0.JavaSE_017", javax.smartcardio; version\="0.0.0.JavaSE_017", javax.sql; version\="0.0.0.JavaSE_017", java.sql; version\="0.0.0.JavaSE_017", javax.sql.rowset; version\="0.0.0.JavaSE_017", javax.sql.rowset.serial; version\="0.0.0.JavaSE_017", javax.sql.rowset.spi; version\="0.0.0.JavaSE_017", javax.transaction.xa; version\="0.0.0.JavaSE_017", javax.xml.xpath; version\="0.0.0.JavaSE_017", javax.xml.transform; version\="0.0.0.JavaSE_017", org.xml.sax; version\="0.0.0.JavaSE_017", javax.xml.stream; version\="0.0.0.JavaSE_017", javax.xml.stream.events; version\="0.0.0.JavaSE_017", org.w3c.dom.traversal; version\="0.0.0.JavaSE_017", javax.xml.catalog; version\="0.0.0.JavaSE_017", javax.xml.datatype; version\="0.0.0.JavaSE_017", javax.xml.transform.sax; version\="0.0.0.JavaSE_017", javax.xml; version\="0.0.0.JavaSE_017", org.xml.sax.ext; version\="0.0.0.JavaSE_017", javax.xml.parsers; version\="0.0.0.JavaSE_017", javax.xml.validation; version\="0.0.0.JavaSE_017", javax.xml.transform.dom; version\="0.0.0.JavaSE_017", javax.xml.transform.stream; version\="0.0.0.JavaSE_017", org.w3c.dom; version\="0.0.0.JavaSE_017", org.w3c.dom.bootstrap; version\="0.0.0.JavaSE_017", org.w3c.dom.views; version\="0.0.0.JavaSE_017", org.xml.sax.helpers; version\="0.0.0.JavaSE_017", javax.xml.transform.stax; version\="0.0.0.JavaSE_017", javax.xml.namespace; version\="0.0.0.JavaSE_017", javax.xml.stream.util; version\="0.0.0.JavaSE_017", org.w3c.dom.ls; version\="0.0.0.JavaSE_017", org.w3c.dom.ranges; version\="0.0.0.JavaSE_017", org.w3c.dom.events; version\="0.0.0.JavaSE_017", javax.xml.crypto.dom; version\="0.0.0.JavaSE_017", javax.xml.crypto.dsig.dom; version\="0.0.0.JavaSE_017", javax.xml.crypto.dsig.keyinfo; version\="0.0.0.JavaSE_017", javax.xml.crypto.dsig.spec; version\="0.0.0.JavaSE_017", javax.xml.crypto.dsig; version\="0.0.0.JavaSE_017", javax.xml.crypto; version\="0.0.0.JavaSE_017", com.sun.java.accessibility.util; version\="0.0.0.JavaSE_017", com.sun.tools.attach.spi; version\="0.0.0.JavaSE_017", com.sun.tools.attach; version\="0.0.0.JavaSE_017", com.sun.source.doctree; version\="0.0.0.JavaSE_017", com.sun.tools.javac; version\="0.0.0.JavaSE_017", com.sun.source.util; version\="0.0.0.JavaSE_017", com.sun.source.tree; version\="0.0.0.JavaSE_017", jdk.dynalink.linker.support; version\="0.0.0.JavaSE_017", jdk.dynalink.beans; version\="0.0.0.JavaSE_017", jdk.dynalink.linker; version\="0.0.0.JavaSE_017", jdk.dynalink; version\="0.0.0.JavaSE_017", jdk.dynalink.support; version\="0.0.0.JavaSE_017", com.sun.net.httpserver.spi; version\="0.0.0.JavaSE_017", com.sun.net.httpserver; version\="0.0.0.JavaSE_017", jdk.security.jarsigner; version\="0.0.0.JavaSE_017", com.sun.jarsigner; version\="0.0.0.JavaSE_017", jdk.javadoc.doclet; version\="0.0.0.JavaSE_017", com.sun.tools.jconsole; version\="0.0.0.JavaSE_017", com.sun.jdi.event; version\="0.0.0.JavaSE_017", com.sun.jdi.connect; version\="0.0.0.JavaSE_017", com.sun.jdi.request; version\="0.0.0.JavaSE_017", com.sun.jdi; version\="0.0.0.JavaSE_017", com.sun.jdi.connect.spi; version\="0.0.0.JavaSE_017", jdk.jfr; version\="0.0.0.JavaSE_017", jdk.jfr.consumer; version\="0.0.0.JavaSE_017", jdk.jshell.execution; version\="0.0.0.JavaSE_017", jdk.jshell; version\="0.0.0.JavaSE_017", jdk.jshell.tool; version\="0.0.0.JavaSE_017", jdk.jshell.spi; version\="0.0.0.JavaSE_017", netscape.javascript; version\="0.0.0.JavaSE_017", com.sun.management; version\="0.0.0.JavaSE_017", jdk.management.jfr; version\="0.0.0.JavaSE_017", jdk.nio; version\="0.0.0.JavaSE_017", jdk.net; version\="0.0.0.JavaSE_017", jdk.nio.mapmode; version\="0.0.0.JavaSE_017", com.sun.nio.sctp; version\="0.0.0.JavaSE_017", com.sun.security.auth.module; version\="0.0.0.JavaSE_017", com.sun.security.auth.callback; version\="0.0.0.JavaSE_017", com.sun.security.auth; version\="0.0.0.JavaSE_017", com.sun.security.auth.login; version\="0.0.0.JavaSE_017", com.sun.security.jgss; version\="0.0.0.JavaSE_017", sun.misc; version\="0.0.0.JavaSE_017", sun.reflect; version\="0.0.0.JavaSE_017", com.sun.nio.file; version\="0.0.0.JavaSE_017", jdk.swing.interop; version\="0.0.0.JavaSE_017", org.w3c.dom.html; version\="0.0.0.JavaSE_017", org.w3c.dom.stylesheets; version\="0.0.0.JavaSE_017", org.w3c.dom.css; version\="0.0.0.JavaSE_017", org.w3c.dom.xpath; version\="0.0.0.JavaSE_017", com.yahoo.jdisc, com.yahoo.jdisc.application, com.yahoo.jdisc.handler, com.yahoo.jdisc.service, com.yahoo.jdisc.statistics, com.yahoo.jdisc.refcount, javax.inject;version\=1.0.0, org.aopalliance.intercept, org.aopalliance.aop, com.google.common.annotations;version\="32.1.3",com.google.common.base;version\="32.1.3";uses\:\="javax.annotation",com.google.common.cache;version\="32.1.3";uses\:\="com.google.common.base,com.google.common.collect,com.google.common.util.concurrent,javax.annotation",com.google.common.collect;version\="32.1.3";uses\:\="com.google.common.base,javax.annotation",com.google.common.escape;version\="32.1.3";uses\:\="com.google.common.base,javax.annotation",com.google.common.eventbus;version\="32.1.3",com.google.common.graph;version\="32.1.3";uses\:\="com.google.common.collect,javax.annotation",com.google.common.hash;version\="32.1.3";uses\:\="com.google.common.base,javax.annotation",com.google.common.html;version\="32.1.3";uses\:\="com.google.common.escape",com.google.common.io;version\="32.1.3";uses\:\="com.google.common.base,com.google.common.collect,com.google.common.graph,com.google.common.hash,javax.annotation",com.google.common.math;version\="32.1.3";uses\:\="javax.annotation",com.google.common.net;version\="32.1.3";uses\:\="com.google.common.base,com.google.common.collect,com.google.common.escape,javax.annotation",com.google.common.primitives;version\="32.1.3";uses\:\="com.google.common.base,javax.annotation",com.google.common.reflect;version\="32.1.3";uses\:\="com.google.common.collect,com.google.common.io,javax.annotation",com.google.common.util.concurrent;version\="32.1.3";uses\:\="com.google.common.base,com.google.common.collect,com.google.common.util.concurrent.internal,javax.annotation",com.google.common.xml;version\="32.1.3";uses\:\="com.google.common.escape", com.google.inject;version\="1.4",com.google.inject.binder;version\="1.4",com.google.inject.matcher;version\="1.4",com.google.inject.multibindings;version\="1.4",com.google.inject.name;version\="1.4",com.google.inject.spi;version\="1.4",com.google.inject.util;version\="1.4", org.slf4j;version\=1.7.32, org.slf4j.spi;version\=1.7.32, org.slf4j.helpers;version\=1.7.32, org.slf4j.event;version\=1.7.32, org.slf4j.impl;version\=1.7.32, org.apache.commons.logging;version\=1.2, org.apache.commons.logging.impl;version\=1.2, com.sun.jna;version\=5.11.0, com.sun.jna.ptr;version\=5.11.0, com.sun.jna.win32;version\=5.11.0, org.apache.log4j;version\=1.2.17,org.apache.log4j.helpers;version\=1.2.17,org.apache.log4j.spi;version\=1.2.17,org.apache.log4j.xml;version\=1.2.17, com.yahoo.component.annotation;version\="1.0.0", com.yahoo.config;version\=1.0.0, com.yahoo.vespa.defaults;version\=1.0.0, ai.vespa.http;version\=1.0.0,ai.vespa.llm.client.openai;version\=1.0.0,ai.vespa.llm.completion;version\=1.0.0,ai.vespa.llm.test;version\=1.0.0,ai.vespa.llm;version\=1.0.0,ai.vespa.net;version\=1.0.0,ai.vespa.validation;version\=1.0.0,com.yahoo.binaryprefix;version\=1.0.0,com.yahoo.collections;version\=1.0.0,com.yahoo.compress;version\=1.0.0,com.yahoo.concurrent.classlock;version\=1.0.0,com.yahoo.concurrent.maintenance;version\=1.0.0,com.yahoo.concurrent;version\=1.0.0,com.yahoo.data.access.helpers;version\=1.0.0,com.yahoo.data.access.simple;version\=1.0.0,com.yahoo.data.access.slime;version\=1.0.0,com.yahoo.data.access;version\=1.0.0,com.yahoo.errorhandling;version\=1.0.0,com.yahoo.exception;version\=1.0.0,com.yahoo.geo;version\=1.0.0,com.yahoo.io.reader;version\=1.0.0,com.yahoo.io;version\=1.0.0,com.yahoo.javacc;version\=1.0.0,com.yahoo.lang;version\=1.0.0,com.yahoo.nativec;version\=1.0.0,com.yahoo.net;version\=1.0.0,com.yahoo.path;version\=1.0.0,com.yahoo.protect;version\=1.0.0,com.yahoo.reflection;version\=1.0.0,com.yahoo.slime;version\=1.0.0,com.yahoo.stream;version\=1.0.0,com.yahoo.system.execution;version\=1.0.0,com.yahoo.system;version\=1.0.0,com.yahoo.tensor.evaluation;version\=1.0.0,com.yahoo.tensor.functions;version\=1.0.0,com.yahoo.tensor.serialization;version\=1.0.0,com.yahoo.tensor;version\=1.0.0,com.yahoo.text.internal;version\=1.0.0,com.yahoo.text;version\=1.0.0,com.yahoo.time;version\=1.0.0,com.yahoo.transaction;version\=1.0.0,com.yahoo.vespa.objects;version\=1.0.0,com.yahoo.yolean.chain;version\=1.0.0,com.yahoo.yolean.concurrent;version\=1.0.0,com.yahoo.yolean.function;version\=1.0.0,com.yahoo.yolean.system;version\=1.0.0,com.yahoo.yolean.trace;version\=1.0.0,com.yahoo.yolean;version\=1.0.0, com.yahoo.log.event;version\=1.0.0,com.yahoo.log.impl;version\=1.0.0,com.yahoo.log;version\=1.0.0, javax.xml.bind;version\="2.3";uses\:\="javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.namespace,javax.xml.stream,javax.xml.transform,javax.xml.validation,org.w3c.dom,org.xml.sax",javax.xml.bind.annotation;version\="2.3";uses\:\="javax.xml.bind,javax.xml.parsers,javax.xml.transform,javax.xml.transform.dom,org.w3c.dom",javax.xml.bind.annotation.adapters;version\="2.3",javax.xml.bind.attachment;version\="2.3";uses\:\="javax.activation",javax.xml.bind.helpers;version\="2.3";uses\:\="javax.xml.bind,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.stream,javax.xml.transform,javax.xml.validation,org.w3c.dom,org.xml.sax",javax.xml.bind.util;version\="2.3";uses\:\="javax.xml.bind,javax.xml.transform.sax", com.sun.istack;version\="3.0.5";uses\:\="javax.activation,javax.xml.stream,org.xml.sax,org.xml.sax.helpers",com.sun.istack.localization;version\="3.0.5",com.sun.istack.logging;version\="3.0.5",com.sun.xml.bind;uses\:\="org.xml.sax";version\="2.3.0",com.sun.xml.bind.annotation;version\="2.3.0",com.sun.xml.bind.api;uses\:\="org.xml.sax";version\="2.3.0",com.sun.xml.bind.api.impl;version\="2.3.0",com.sun.xml.bind.marshaller;uses\:\="javax.xml.parsers,org.w3c.dom,org.xml.sax,org.xml.sax.helpers";version\="2.3.0",com.sun.xml.bind.unmarshaller;uses\:\="com.sun.xml.bind.v2.runtime.unmarshaller,javax.xml.bind,org.w3c.dom,org.xml.sax";version\="2.3.0",com.sun.xml.bind.util;version\="2.3.0",com.sun.xml.bind.v2;version\="2.3.0",com.sun.xml.bind.v2.model.annotation;uses\:\="com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.runtime";version\="2.3.0",com.sun.xml.bind.v2.model.core;uses\:\="com.sun.xml.bind.v2.model.annotation,com.sun.xml.bind.v2.model.impl,com.sun.xml.bind.v2.model.nav,com.sun.xml.bind.v2.runtime,javax.activation,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.namespace,javax.xml.transform";version\="2.3.0",com.sun.xml.bind.v2.model.impl;uses\:\="com.sun.xml.bind.v2.model.annotation,com.sun.xml.bind.v2.model.nav";version\="2.3.0",com.sun.xml.bind.v2.model.nav;uses\:\="com.sun.xml.bind.v2.runtime";version\="2.3.0",com.sun.xml.bind.v2.model.util;uses\:\="javax.xml.namespace";version\="2.3.0",com.sun.xml.bind.v2.runtime;uses\:\="com.sun.xml.bind.v2.model.annotation,javax.activation,javax.xml.bind,javax.xml.bind.annotation.adapters";version\="2.3.0",com.sun.xml.bind.v2.runtime.unmarshaller;uses\:\="javax.xml.bind,org.w3c.dom,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.schemagen.episode;uses\:\="com.sun.xml.txw2,com.sun.xml.txw2.annotation";version\="2.3.0",com.sun.xml.bind.v2.util;uses\:\="javax.xml.parsers,javax.xml.transform,javax.xml.validation,javax.xml.xpath";version\="2.3.0",com.sun.xml.txw2;uses\:\="com.sun.xml.txw2.output,javax.xml.namespace";version\="2.3.0",com.sun.xml.txw2.annotation;version\="2.3.0",com.sun.xml.txw2.output;uses\:\="com.sun.xml.txw2,javax.xml.namespace,javax.xml.stream,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.sax,javax.xml.transform.stream,org.w3c.dom,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers";version\="2.3.0", com.sun.xml.bind;uses\:\="com.sun.xml.bind.v2.runtime.reflect,javax.xml.bind,javax.xml.bind.annotation.adapters,javax.xml.datatype,javax.xml.namespace,javax.xml.stream,org.xml.sax";version\="2.3.0",com.sun.xml.bind.api;uses\:\="com.sun.xml.bind.v2.model.annotation,com.sun.xml.bind.v2.model.runtime,com.sun.xml.bind.v2.runtime,javax.xml.bind,javax.xml.bind.attachment,javax.xml.namespace,javax.xml.stream,javax.xml.transform,org.w3c.dom,org.xml.sax";version\="2.3.0",com.sun.xml.bind.marshaller;version\="2.3.0",com.sun.xml.bind.unmarshaller;uses\:\="org.xml.sax";version\="2.3.0",com.sun.xml.bind.util;uses\:\="com.sun.xml.bind,javax.xml.bind.helpers,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2;uses\:\="com.sun.xml.bind.api,com.sun.xml.bind.v2.model.annotation,javax.xml.bind";version\="2.3.0",com.sun.xml.bind.v2.bytecode;version\="2.3.0",com.sun.xml.bind.v2.model.annotation;uses\:\="com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.model.nav,com.sun.xml.bind.v2.runtime";version\="2.3.0",com.sun.xml.bind.v2.model.impl;uses\:\="com.sun.xml.bind.api,com.sun.xml.bind.v2.model.annotation,com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.model.nav,com.sun.xml.bind.v2.model.runtime,com.sun.xml.bind.v2.runtime,javax.activation,javax.xml.namespace";version\="2.3.0",com.sun.xml.bind.v2.model.runtime;uses\:\="com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.runtime,com.sun.xml.bind.v2.runtime.reflect,javax.xml.bind,javax.xml.namespace,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.runtime;uses\:\="com.sun.istack,com.sun.xml.bind.api,com.sun.xml.bind.marshaller,com.sun.xml.bind.v2.model.annotation,com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.model.runtime,com.sun.xml.bind.v2.runtime.output,com.sun.xml.bind.v2.runtime.property,com.sun.xml.bind.v2.runtime.unmarshaller,javax.activation,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.bind.helpers,javax.xml.namespace,javax.xml.stream,javax.xml.transform,javax.xml.transform.sax,javax.xml.validation,org.w3c.dom,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.runtime.output;uses\:\="com.sun.xml.bind.marshaller,com.sun.xml.bind.v2.runtime,com.sun.xml.fastinfoset.stax,javax.xml.stream,org.jvnet.staxex,org.w3c.dom,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.runtime.property;uses\:\="com.sun.xml.bind.api,com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.model.runtime,com.sun.xml.bind.v2.runtime,com.sun.xml.bind.v2.runtime.reflect,com.sun.xml.bind.v2.runtime.unmarshaller,com.sun.xml.bind.v2.util,javax.xml.namespace,javax.xml.stream,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.runtime.reflect;uses\:\="com.sun.xml.bind.api,com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.model.runtime,com.sun.xml.bind.v2.runtime,com.sun.xml.bind.v2.runtime.unmarshaller,javax.xml.bind,javax.xml.bind.annotation.adapters,javax.xml.stream,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.runtime.reflect.opt;uses\:\="com.sun.xml.bind.api,com.sun.xml.bind.v2.model.runtime,com.sun.xml.bind.v2.runtime,com.sun.xml.bind.v2.runtime.reflect,javax.xml.stream,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.runtime.unmarshaller;uses\:\="com.sun.xml.bind,com.sun.xml.bind.api,com.sun.xml.bind.unmarshaller,com.sun.xml.bind.util,com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.runtime,com.sun.xml.bind.v2.runtime.output,com.sun.xml.bind.v2.runtime.reflect,javax.activation,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.bind.helpers,javax.xml.namespace,javax.xml.stream,javax.xml.transform,javax.xml.transform.sax,javax.xml.validation,org.w3c.dom,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.schemagen;uses\:\="com.sun.xml.bind.api,com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.model.nav,com.sun.xml.txw2.output,javax.xml.bind,javax.xml.namespace";version\="2.3.0",com.sun.xml.bind.v2.schemagen.xmlschema;uses\:\="com.sun.xml.txw2,com.sun.xml.txw2.annotation,javax.xml.namespace";version\="2.3.0",com.sun.xml.bind.v2.util;uses\:\="com.sun.xml.bind.v2.runtime,com.sun.xml.bind.v2.runtime.unmarshaller,javax.activation,javax.xml.namespace,javax.xml.transform.stream,org.xml.sax";version\="2.3.0", javax.activation;uses\:\="com.sun.activation.registries";version\="1.2",com.sun.activation.viewers;uses\:\="javax.activation";version\="1.2.0",com.sun.activation.registries;version\="1.2.0"
+exportPackages=org.osgi.framework; version\="1.10.0", org.osgi.framework.connect; version\="1.0.0", org.osgi.framework.dto; uses\:\="org.osgi.dto"; version\="1.8.0", org.osgi.framework.hooks.bundle; uses\:\="org.osgi.framework"; version\="1.1.0", org.osgi.framework.hooks.resolver; uses\:\="org.osgi.framework.wiring"; version\="1.0.0", org.osgi.framework.hooks.service; uses\:\="org.osgi.framework"; version\="1.1.0", org.osgi.framework.hooks.weaving; uses\:\="org.osgi.framework.wiring"; version\="1.1.0", org.osgi.framework.launch; uses\:\="org.osgi.framework"; version\="1.2.0", org.osgi.framework.namespace; uses\:\="org.osgi.resource"; version\="1.2.0", org.osgi.framework.startlevel; uses\:\="org.osgi.framework"; version\="1.0.0", org.osgi.framework.startlevel.dto; uses\:\="org.osgi.dto"; version\="1.0.0", org.osgi.framework.wiring; uses\:\="org.osgi.framework,org.osgi.resource"; version\="1.2.0", org.osgi.framework.wiring.dto; uses\:\="org.osgi.dto,org.osgi.resource.dto"; version\="1.3.0", org.osgi.resource; version\="1.0.1", org.osgi.resource.dto; uses\:\="org.osgi.dto"; version\="1.0.1", org.osgi.service.packageadmin; uses\:\="org.osgi.framework"; version\="1.2.1", org.osgi.service.startlevel; uses\:\="org.osgi.framework"; version\="1.1.1", org.osgi.service.url; version\="1.0.1", org.osgi.service.resolver; uses\:\="org.osgi.resource"; version\="1.1.1", org.osgi.util.tracker; uses\:\="org.osgi.framework"; version\="1.5.3", org.osgi.dto; version\="1.1.1", org.osgi.service.condition; version\="1.0.0", java.util.jar; version\="0.0.0.JavaSE_017", java.nio; version\="0.0.0.JavaSE_017", java.nio.file.spi; version\="0.0.0.JavaSE_017", java.security; version\="0.0.0.JavaSE_017", java.util; version\="0.0.0.JavaSE_017", javax.crypto.interfaces; version\="0.0.0.JavaSE_017", java.nio.charset.spi; version\="0.0.0.JavaSE_017", java.util.concurrent; version\="0.0.0.JavaSE_017", javax.security.auth.spi; version\="0.0.0.JavaSE_017", java.lang.annotation; version\="0.0.0.JavaSE_017", javax.security.cert; version\="0.0.0.JavaSE_017", java.net; version\="0.0.0.JavaSE_017", java.util.spi; version\="0.0.0.JavaSE_017", java.io; version\="0.0.0.JavaSE_017", java.nio.charset; version\="0.0.0.JavaSE_017", java.time.zone; version\="0.0.0.JavaSE_017", javax.crypto; version\="0.0.0.JavaSE_017", java.time.chrono; version\="0.0.0.JavaSE_017", java.nio.channels; version\="0.0.0.JavaSE_017", java.security.spec; version\="0.0.0.JavaSE_017", java.security.cert; version\="0.0.0.JavaSE_017", java.util.concurrent.atomic; version\="0.0.0.JavaSE_017", java.nio.file; version\="0.0.0.JavaSE_017", java.math; version\="0.0.0.JavaSE_017", java.nio.channels.spi; version\="0.0.0.JavaSE_017", java.text.spi; version\="0.0.0.JavaSE_017", java.security.interfaces; version\="0.0.0.JavaSE_017", java.lang.constant; version\="0.0.0.JavaSE_017", javax.net.ssl; version\="0.0.0.JavaSE_017", javax.security.auth.login; version\="0.0.0.JavaSE_017", javax.security.auth.callback; version\="0.0.0.JavaSE_017", java.lang.reflect; version\="0.0.0.JavaSE_017", javax.security.auth.x500; version\="0.0.0.JavaSE_017", javax.net; version\="0.0.0.JavaSE_017", java.util.function; version\="0.0.0.JavaSE_017", java.lang.runtime; version\="0.0.0.JavaSE_017", java.lang; version\="0.0.0.JavaSE_017", java.time; version\="0.0.0.JavaSE_017", java.util.stream; version\="0.0.0.JavaSE_017", javax.crypto.spec; version\="0.0.0.JavaSE_017", java.text; version\="0.0.0.JavaSE_017", java.util.random; version\="0.0.0.JavaSE_017", java.nio.file.attribute; version\="0.0.0.JavaSE_017", java.util.zip; version\="0.0.0.JavaSE_017", java.time.temporal; version\="0.0.0.JavaSE_017", java.util.concurrent.locks; version\="0.0.0.JavaSE_017", java.time.format; version\="0.0.0.JavaSE_017", java.lang.invoke; version\="0.0.0.JavaSE_017", java.lang.module; version\="0.0.0.JavaSE_017", java.net.spi; version\="0.0.0.JavaSE_017", java.util.regex; version\="0.0.0.JavaSE_017", java.lang.ref; version\="0.0.0.JavaSE_017", javax.security.auth; version\="0.0.0.JavaSE_017", javax.lang.model.element; version\="0.0.0.JavaSE_017", javax.annotation.processing; version\="0.0.0.JavaSE_017", javax.lang.model; version\="0.0.0.JavaSE_017", javax.lang.model.util; version\="0.0.0.JavaSE_017", javax.lang.model.type; version\="0.0.0.JavaSE_017", javax.tools; version\="0.0.0.JavaSE_017", java.awt.datatransfer; version\="0.0.0.JavaSE_017", java.awt.event; version\="0.0.0.JavaSE_017", javax.accessibility; version\="0.0.0.JavaSE_017", javax.swing.plaf.nimbus; version\="0.0.0.JavaSE_017", javax.print; version\="0.0.0.JavaSE_017", javax.print.attribute; version\="0.0.0.JavaSE_017", javax.sound.sampled; version\="0.0.0.JavaSE_017", javax.imageio.event; version\="0.0.0.JavaSE_017", javax.swing.filechooser; version\="0.0.0.JavaSE_017", javax.swing.plaf; version\="0.0.0.JavaSE_017", javax.swing.undo; version\="0.0.0.JavaSE_017", javax.swing.plaf.basic; version\="0.0.0.JavaSE_017", javax.swing.text; version\="0.0.0.JavaSE_017", java.awt.dnd; version\="0.0.0.JavaSE_017", javax.sound.midi; version\="0.0.0.JavaSE_017", java.applet; version\="0.0.0.JavaSE_017", java.awt.im.spi; version\="0.0.0.JavaSE_017", javax.imageio; version\="0.0.0.JavaSE_017", java.awt.font; version\="0.0.0.JavaSE_017", javax.swing.text.rtf; version\="0.0.0.JavaSE_017", javax.swing.text.html.parser; version\="0.0.0.JavaSE_017", java.beans; version\="0.0.0.JavaSE_017", javax.swing.plaf.synth; version\="0.0.0.JavaSE_017", java.awt.desktop; version\="0.0.0.JavaSE_017", javax.swing.event; version\="0.0.0.JavaSE_017", javax.imageio.stream; version\="0.0.0.JavaSE_017", java.awt; version\="0.0.0.JavaSE_017", java.beans.beancontext; version\="0.0.0.JavaSE_017", javax.swing.plaf.metal; version\="0.0.0.JavaSE_017", javax.print.event; version\="0.0.0.JavaSE_017", java.awt.im; version\="0.0.0.JavaSE_017", javax.swing.plaf.multi; version\="0.0.0.JavaSE_017", java.awt.image.renderable; version\="0.0.0.JavaSE_017", javax.swing; version\="0.0.0.JavaSE_017", javax.swing.colorchooser; version\="0.0.0.JavaSE_017", javax.print.attribute.standard; version\="0.0.0.JavaSE_017", javax.sound.midi.spi; version\="0.0.0.JavaSE_017", javax.swing.table; version\="0.0.0.JavaSE_017", javax.imageio.metadata; version\="0.0.0.JavaSE_017", java.awt.image; version\="0.0.0.JavaSE_017", java.awt.print; version\="0.0.0.JavaSE_017", javax.imageio.plugins.tiff; version\="0.0.0.JavaSE_017", javax.swing.tree; version\="0.0.0.JavaSE_017", javax.imageio.plugins.jpeg; version\="0.0.0.JavaSE_017", java.awt.geom; version\="0.0.0.JavaSE_017", java.awt.color; version\="0.0.0.JavaSE_017", javax.imageio.plugins.bmp; version\="0.0.0.JavaSE_017", javax.sound.sampled.spi; version\="0.0.0.JavaSE_017", javax.swing.border; version\="0.0.0.JavaSE_017", javax.imageio.spi; version\="0.0.0.JavaSE_017", javax.swing.text.html; version\="0.0.0.JavaSE_017", java.lang.instrument; version\="0.0.0.JavaSE_017", java.util.logging; version\="0.0.0.JavaSE_017", java.lang.management; version\="0.0.0.JavaSE_017", javax.management.openmbean; version\="0.0.0.JavaSE_017", javax.management.loading; version\="0.0.0.JavaSE_017", javax.management.relation; version\="0.0.0.JavaSE_017", javax.management; version\="0.0.0.JavaSE_017", javax.management.timer; version\="0.0.0.JavaSE_017", javax.management.modelmbean; version\="0.0.0.JavaSE_017", javax.management.monitor; version\="0.0.0.JavaSE_017", javax.management.remote; version\="0.0.0.JavaSE_017", javax.management.remote.rmi; version\="0.0.0.JavaSE_017", javax.naming; version\="0.0.0.JavaSE_017", javax.naming.ldap.spi; version\="0.0.0.JavaSE_017", javax.naming.event; version\="0.0.0.JavaSE_017", javax.naming.directory; version\="0.0.0.JavaSE_017", javax.naming.ldap; version\="0.0.0.JavaSE_017", javax.naming.spi; version\="0.0.0.JavaSE_017", java.net.http; version\="0.0.0.JavaSE_017", java.util.prefs; version\="0.0.0.JavaSE_017", java.rmi.registry; version\="0.0.0.JavaSE_017", java.rmi.server; version\="0.0.0.JavaSE_017", java.rmi; version\="0.0.0.JavaSE_017", java.rmi.dgc; version\="0.0.0.JavaSE_017", javax.rmi.ssl; version\="0.0.0.JavaSE_017", javax.script; version\="0.0.0.JavaSE_017", org.ietf.jgss; version\="0.0.0.JavaSE_017", javax.security.auth.kerberos; version\="0.0.0.JavaSE_017", javax.security.sasl; version\="0.0.0.JavaSE_017", javax.smartcardio; version\="0.0.0.JavaSE_017", javax.sql; version\="0.0.0.JavaSE_017", java.sql; version\="0.0.0.JavaSE_017", javax.sql.rowset; version\="0.0.0.JavaSE_017", javax.sql.rowset.serial; version\="0.0.0.JavaSE_017", javax.sql.rowset.spi; version\="0.0.0.JavaSE_017", javax.transaction.xa; version\="0.0.0.JavaSE_017", javax.xml.xpath; version\="0.0.0.JavaSE_017", javax.xml.transform; version\="0.0.0.JavaSE_017", org.xml.sax; version\="0.0.0.JavaSE_017", javax.xml.stream; version\="0.0.0.JavaSE_017", javax.xml.stream.events; version\="0.0.0.JavaSE_017", org.w3c.dom.traversal; version\="0.0.0.JavaSE_017", javax.xml.catalog; version\="0.0.0.JavaSE_017", javax.xml.datatype; version\="0.0.0.JavaSE_017", javax.xml.transform.sax; version\="0.0.0.JavaSE_017", javax.xml; version\="0.0.0.JavaSE_017", org.xml.sax.ext; version\="0.0.0.JavaSE_017", javax.xml.parsers; version\="0.0.0.JavaSE_017", javax.xml.validation; version\="0.0.0.JavaSE_017", javax.xml.transform.dom; version\="0.0.0.JavaSE_017", javax.xml.transform.stream; version\="0.0.0.JavaSE_017", org.w3c.dom; version\="0.0.0.JavaSE_017", org.w3c.dom.bootstrap; version\="0.0.0.JavaSE_017", org.w3c.dom.views; version\="0.0.0.JavaSE_017", org.xml.sax.helpers; version\="0.0.0.JavaSE_017", javax.xml.transform.stax; version\="0.0.0.JavaSE_017", javax.xml.namespace; version\="0.0.0.JavaSE_017", javax.xml.stream.util; version\="0.0.0.JavaSE_017", org.w3c.dom.ls; version\="0.0.0.JavaSE_017", org.w3c.dom.ranges; version\="0.0.0.JavaSE_017", org.w3c.dom.events; version\="0.0.0.JavaSE_017", javax.xml.crypto.dom; version\="0.0.0.JavaSE_017", javax.xml.crypto.dsig.dom; version\="0.0.0.JavaSE_017", javax.xml.crypto.dsig.keyinfo; version\="0.0.0.JavaSE_017", javax.xml.crypto.dsig.spec; version\="0.0.0.JavaSE_017", javax.xml.crypto.dsig; version\="0.0.0.JavaSE_017", javax.xml.crypto; version\="0.0.0.JavaSE_017", com.sun.java.accessibility.util; version\="0.0.0.JavaSE_017", com.sun.tools.attach.spi; version\="0.0.0.JavaSE_017", com.sun.tools.attach; version\="0.0.0.JavaSE_017", com.sun.source.doctree; version\="0.0.0.JavaSE_017", com.sun.tools.javac; version\="0.0.0.JavaSE_017", com.sun.source.util; version\="0.0.0.JavaSE_017", com.sun.source.tree; version\="0.0.0.JavaSE_017", jdk.dynalink.linker.support; version\="0.0.0.JavaSE_017", jdk.dynalink.beans; version\="0.0.0.JavaSE_017", jdk.dynalink.linker; version\="0.0.0.JavaSE_017", jdk.dynalink; version\="0.0.0.JavaSE_017", jdk.dynalink.support; version\="0.0.0.JavaSE_017", com.sun.net.httpserver.spi; version\="0.0.0.JavaSE_017", com.sun.net.httpserver; version\="0.0.0.JavaSE_017", jdk.security.jarsigner; version\="0.0.0.JavaSE_017", com.sun.jarsigner; version\="0.0.0.JavaSE_017", jdk.javadoc.doclet; version\="0.0.0.JavaSE_017", com.sun.tools.jconsole; version\="0.0.0.JavaSE_017", com.sun.jdi.event; version\="0.0.0.JavaSE_017", com.sun.jdi.connect; version\="0.0.0.JavaSE_017", com.sun.jdi.request; version\="0.0.0.JavaSE_017", com.sun.jdi; version\="0.0.0.JavaSE_017", com.sun.jdi.connect.spi; version\="0.0.0.JavaSE_017", jdk.jfr; version\="0.0.0.JavaSE_017", jdk.jfr.consumer; version\="0.0.0.JavaSE_017", jdk.jshell.execution; version\="0.0.0.JavaSE_017", jdk.jshell; version\="0.0.0.JavaSE_017", jdk.jshell.tool; version\="0.0.0.JavaSE_017", jdk.jshell.spi; version\="0.0.0.JavaSE_017", netscape.javascript; version\="0.0.0.JavaSE_017", com.sun.management; version\="0.0.0.JavaSE_017", jdk.management.jfr; version\="0.0.0.JavaSE_017", jdk.nio; version\="0.0.0.JavaSE_017", jdk.net; version\="0.0.0.JavaSE_017", jdk.nio.mapmode; version\="0.0.0.JavaSE_017", com.sun.nio.sctp; version\="0.0.0.JavaSE_017", com.sun.security.auth.module; version\="0.0.0.JavaSE_017", com.sun.security.auth.callback; version\="0.0.0.JavaSE_017", com.sun.security.auth; version\="0.0.0.JavaSE_017", com.sun.security.auth.login; version\="0.0.0.JavaSE_017", com.sun.security.jgss; version\="0.0.0.JavaSE_017", sun.misc; version\="0.0.0.JavaSE_017", sun.reflect; version\="0.0.0.JavaSE_017", com.sun.nio.file; version\="0.0.0.JavaSE_017", jdk.swing.interop; version\="0.0.0.JavaSE_017", org.w3c.dom.html; version\="0.0.0.JavaSE_017", org.w3c.dom.stylesheets; version\="0.0.0.JavaSE_017", org.w3c.dom.css; version\="0.0.0.JavaSE_017", org.w3c.dom.xpath; version\="0.0.0.JavaSE_017", com.yahoo.jdisc, com.yahoo.jdisc.application, com.yahoo.jdisc.handler, com.yahoo.jdisc.service, com.yahoo.jdisc.statistics, com.yahoo.jdisc.refcount, javax.inject;version\=1.0.0, org.aopalliance.intercept, org.aopalliance.aop, com.google.common.annotations;version\="33.0.0",com.google.common.base;version\="33.0.0";uses\:\="javax.annotation",com.google.common.cache;version\="33.0.0";uses\:\="com.google.common.base,com.google.common.collect,com.google.common.util.concurrent,javax.annotation",com.google.common.collect;version\="33.0.0";uses\:\="com.google.common.base,javax.annotation",com.google.common.escape;version\="33.0.0";uses\:\="com.google.common.base,javax.annotation",com.google.common.eventbus;version\="33.0.0",com.google.common.graph;version\="33.0.0";uses\:\="com.google.common.collect,javax.annotation",com.google.common.hash;version\="33.0.0";uses\:\="com.google.common.base,javax.annotation",com.google.common.html;version\="33.0.0";uses\:\="com.google.common.escape",com.google.common.io;version\="33.0.0";uses\:\="com.google.common.base,com.google.common.collect,com.google.common.graph,com.google.common.hash,javax.annotation",com.google.common.math;version\="33.0.0";uses\:\="javax.annotation",com.google.common.net;version\="33.0.0";uses\:\="com.google.common.base,com.google.common.collect,com.google.common.escape,javax.annotation",com.google.common.primitives;version\="33.0.0";uses\:\="com.google.common.base,javax.annotation",com.google.common.reflect;version\="33.0.0";uses\:\="com.google.common.collect,com.google.common.io,javax.annotation",com.google.common.util.concurrent;version\="33.0.0";uses\:\="com.google.common.base,com.google.common.collect,com.google.common.util.concurrent.internal,javax.annotation",com.google.common.xml;version\="33.0.0";uses\:\="com.google.common.escape", com.google.inject;version\="1.4",com.google.inject.binder;version\="1.4",com.google.inject.matcher;version\="1.4",com.google.inject.multibindings;version\="1.4",com.google.inject.name;version\="1.4",com.google.inject.spi;version\="1.4",com.google.inject.util;version\="1.4", org.slf4j;version\=1.7.32, org.slf4j.spi;version\=1.7.32, org.slf4j.helpers;version\=1.7.32, org.slf4j.event;version\=1.7.32, org.slf4j.impl;version\=1.7.32, org.apache.commons.logging;version\=1.2, org.apache.commons.logging.impl;version\=1.2, com.sun.jna;version\=5.11.0, com.sun.jna.ptr;version\=5.11.0, com.sun.jna.win32;version\=5.11.0, org.apache.log4j;version\=1.2.17,org.apache.log4j.helpers;version\=1.2.17,org.apache.log4j.spi;version\=1.2.17,org.apache.log4j.xml;version\=1.2.17, com.yahoo.component.annotation;version\="1.0.0", com.yahoo.config;version\=1.0.0, com.yahoo.vespa.defaults;version\=1.0.0, ai.vespa.http;version\=1.0.0,ai.vespa.llm.client.openai;version\=1.0.0,ai.vespa.llm.completion;version\=1.0.0,ai.vespa.llm.test;version\=1.0.0,ai.vespa.llm;version\=1.0.0,ai.vespa.net;version\=1.0.0,ai.vespa.validation;version\=1.0.0,com.yahoo.binaryprefix;version\=1.0.0,com.yahoo.collections;version\=1.0.0,com.yahoo.compress;version\=1.0.0,com.yahoo.concurrent.classlock;version\=1.0.0,com.yahoo.concurrent.maintenance;version\=1.0.0,com.yahoo.concurrent;version\=1.0.0,com.yahoo.data.access.helpers;version\=1.0.0,com.yahoo.data.access.simple;version\=1.0.0,com.yahoo.data.access.slime;version\=1.0.0,com.yahoo.data.access;version\=1.0.0,com.yahoo.errorhandling;version\=1.0.0,com.yahoo.exception;version\=1.0.0,com.yahoo.geo;version\=1.0.0,com.yahoo.io.reader;version\=1.0.0,com.yahoo.io;version\=1.0.0,com.yahoo.javacc;version\=1.0.0,com.yahoo.lang;version\=1.0.0,com.yahoo.nativec;version\=1.0.0,com.yahoo.net;version\=1.0.0,com.yahoo.path;version\=1.0.0,com.yahoo.protect;version\=1.0.0,com.yahoo.reflection;version\=1.0.0,com.yahoo.slime;version\=1.0.0,com.yahoo.stream;version\=1.0.0,com.yahoo.system.execution;version\=1.0.0,com.yahoo.system;version\=1.0.0,com.yahoo.tensor.evaluation;version\=1.0.0,com.yahoo.tensor.functions;version\=1.0.0,com.yahoo.tensor.serialization;version\=1.0.0,com.yahoo.tensor;version\=1.0.0,com.yahoo.text.internal;version\=1.0.0,com.yahoo.text;version\=1.0.0,com.yahoo.time;version\=1.0.0,com.yahoo.transaction;version\=1.0.0,com.yahoo.vespa.objects;version\=1.0.0,com.yahoo.yolean.chain;version\=1.0.0,com.yahoo.yolean.concurrent;version\=1.0.0,com.yahoo.yolean.function;version\=1.0.0,com.yahoo.yolean.system;version\=1.0.0,com.yahoo.yolean.trace;version\=1.0.0,com.yahoo.yolean;version\=1.0.0, com.yahoo.log.event;version\=1.0.0,com.yahoo.log.impl;version\=1.0.0,com.yahoo.log;version\=1.0.0, javax.xml.bind;version\="2.3";uses\:\="javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.namespace,javax.xml.stream,javax.xml.transform,javax.xml.validation,org.w3c.dom,org.xml.sax",javax.xml.bind.annotation;version\="2.3";uses\:\="javax.xml.bind,javax.xml.parsers,javax.xml.transform,javax.xml.transform.dom,org.w3c.dom",javax.xml.bind.annotation.adapters;version\="2.3",javax.xml.bind.attachment;version\="2.3";uses\:\="javax.activation",javax.xml.bind.helpers;version\="2.3";uses\:\="javax.xml.bind,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.stream,javax.xml.transform,javax.xml.validation,org.w3c.dom,org.xml.sax",javax.xml.bind.util;version\="2.3";uses\:\="javax.xml.bind,javax.xml.transform.sax", com.sun.istack;version\="3.0.5";uses\:\="javax.activation,javax.xml.stream,org.xml.sax,org.xml.sax.helpers",com.sun.istack.localization;version\="3.0.5",com.sun.istack.logging;version\="3.0.5",com.sun.xml.bind;uses\:\="org.xml.sax";version\="2.3.0",com.sun.xml.bind.annotation;version\="2.3.0",com.sun.xml.bind.api;uses\:\="org.xml.sax";version\="2.3.0",com.sun.xml.bind.api.impl;version\="2.3.0",com.sun.xml.bind.marshaller;uses\:\="javax.xml.parsers,org.w3c.dom,org.xml.sax,org.xml.sax.helpers";version\="2.3.0",com.sun.xml.bind.unmarshaller;uses\:\="com.sun.xml.bind.v2.runtime.unmarshaller,javax.xml.bind,org.w3c.dom,org.xml.sax";version\="2.3.0",com.sun.xml.bind.util;version\="2.3.0",com.sun.xml.bind.v2;version\="2.3.0",com.sun.xml.bind.v2.model.annotation;uses\:\="com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.runtime";version\="2.3.0",com.sun.xml.bind.v2.model.core;uses\:\="com.sun.xml.bind.v2.model.annotation,com.sun.xml.bind.v2.model.impl,com.sun.xml.bind.v2.model.nav,com.sun.xml.bind.v2.runtime,javax.activation,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.namespace,javax.xml.transform";version\="2.3.0",com.sun.xml.bind.v2.model.impl;uses\:\="com.sun.xml.bind.v2.model.annotation,com.sun.xml.bind.v2.model.nav";version\="2.3.0",com.sun.xml.bind.v2.model.nav;uses\:\="com.sun.xml.bind.v2.runtime";version\="2.3.0",com.sun.xml.bind.v2.model.util;uses\:\="javax.xml.namespace";version\="2.3.0",com.sun.xml.bind.v2.runtime;uses\:\="com.sun.xml.bind.v2.model.annotation,javax.activation,javax.xml.bind,javax.xml.bind.annotation.adapters";version\="2.3.0",com.sun.xml.bind.v2.runtime.unmarshaller;uses\:\="javax.xml.bind,org.w3c.dom,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.schemagen.episode;uses\:\="com.sun.xml.txw2,com.sun.xml.txw2.annotation";version\="2.3.0",com.sun.xml.bind.v2.util;uses\:\="javax.xml.parsers,javax.xml.transform,javax.xml.validation,javax.xml.xpath";version\="2.3.0",com.sun.xml.txw2;uses\:\="com.sun.xml.txw2.output,javax.xml.namespace";version\="2.3.0",com.sun.xml.txw2.annotation;version\="2.3.0",com.sun.xml.txw2.output;uses\:\="com.sun.xml.txw2,javax.xml.namespace,javax.xml.stream,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.sax,javax.xml.transform.stream,org.w3c.dom,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers";version\="2.3.0", com.sun.xml.bind;uses\:\="com.sun.xml.bind.v2.runtime.reflect,javax.xml.bind,javax.xml.bind.annotation.adapters,javax.xml.datatype,javax.xml.namespace,javax.xml.stream,org.xml.sax";version\="2.3.0",com.sun.xml.bind.api;uses\:\="com.sun.xml.bind.v2.model.annotation,com.sun.xml.bind.v2.model.runtime,com.sun.xml.bind.v2.runtime,javax.xml.bind,javax.xml.bind.attachment,javax.xml.namespace,javax.xml.stream,javax.xml.transform,org.w3c.dom,org.xml.sax";version\="2.3.0",com.sun.xml.bind.marshaller;version\="2.3.0",com.sun.xml.bind.unmarshaller;uses\:\="org.xml.sax";version\="2.3.0",com.sun.xml.bind.util;uses\:\="com.sun.xml.bind,javax.xml.bind.helpers,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2;uses\:\="com.sun.xml.bind.api,com.sun.xml.bind.v2.model.annotation,javax.xml.bind";version\="2.3.0",com.sun.xml.bind.v2.bytecode;version\="2.3.0",com.sun.xml.bind.v2.model.annotation;uses\:\="com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.model.nav,com.sun.xml.bind.v2.runtime";version\="2.3.0",com.sun.xml.bind.v2.model.impl;uses\:\="com.sun.xml.bind.api,com.sun.xml.bind.v2.model.annotation,com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.model.nav,com.sun.xml.bind.v2.model.runtime,com.sun.xml.bind.v2.runtime,javax.activation,javax.xml.namespace";version\="2.3.0",com.sun.xml.bind.v2.model.runtime;uses\:\="com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.runtime,com.sun.xml.bind.v2.runtime.reflect,javax.xml.bind,javax.xml.namespace,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.runtime;uses\:\="com.sun.istack,com.sun.xml.bind.api,com.sun.xml.bind.marshaller,com.sun.xml.bind.v2.model.annotation,com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.model.runtime,com.sun.xml.bind.v2.runtime.output,com.sun.xml.bind.v2.runtime.property,com.sun.xml.bind.v2.runtime.unmarshaller,javax.activation,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.bind.helpers,javax.xml.namespace,javax.xml.stream,javax.xml.transform,javax.xml.transform.sax,javax.xml.validation,org.w3c.dom,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.runtime.output;uses\:\="com.sun.xml.bind.marshaller,com.sun.xml.bind.v2.runtime,com.sun.xml.fastinfoset.stax,javax.xml.stream,org.jvnet.staxex,org.w3c.dom,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.runtime.property;uses\:\="com.sun.xml.bind.api,com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.model.runtime,com.sun.xml.bind.v2.runtime,com.sun.xml.bind.v2.runtime.reflect,com.sun.xml.bind.v2.runtime.unmarshaller,com.sun.xml.bind.v2.util,javax.xml.namespace,javax.xml.stream,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.runtime.reflect;uses\:\="com.sun.xml.bind.api,com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.model.runtime,com.sun.xml.bind.v2.runtime,com.sun.xml.bind.v2.runtime.unmarshaller,javax.xml.bind,javax.xml.bind.annotation.adapters,javax.xml.stream,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.runtime.reflect.opt;uses\:\="com.sun.xml.bind.api,com.sun.xml.bind.v2.model.runtime,com.sun.xml.bind.v2.runtime,com.sun.xml.bind.v2.runtime.reflect,javax.xml.stream,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.runtime.unmarshaller;uses\:\="com.sun.xml.bind,com.sun.xml.bind.api,com.sun.xml.bind.unmarshaller,com.sun.xml.bind.util,com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.runtime,com.sun.xml.bind.v2.runtime.output,com.sun.xml.bind.v2.runtime.reflect,javax.activation,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.bind.helpers,javax.xml.namespace,javax.xml.stream,javax.xml.transform,javax.xml.transform.sax,javax.xml.validation,org.w3c.dom,org.xml.sax";version\="2.3.0",com.sun.xml.bind.v2.schemagen;uses\:\="com.sun.xml.bind.api,com.sun.xml.bind.v2.model.core,com.sun.xml.bind.v2.model.nav,com.sun.xml.txw2.output,javax.xml.bind,javax.xml.namespace";version\="2.3.0",com.sun.xml.bind.v2.schemagen.xmlschema;uses\:\="com.sun.xml.txw2,com.sun.xml.txw2.annotation,javax.xml.namespace";version\="2.3.0",com.sun.xml.bind.v2.util;uses\:\="com.sun.xml.bind.v2.runtime,com.sun.xml.bind.v2.runtime.unmarshaller,javax.activation,javax.xml.namespace,javax.xml.transform.stream,org.xml.sax";version\="2.3.0", javax.activation;uses\:\="com.sun.activation.registries";version\="1.2",com.sun.activation.viewers;uses\:\="javax.activation";version\="1.2.0",com.sun.activation.registries;version\="1.2.0"
diff --git a/maven-plugins/allowed-maven-dependencies.txt b/maven-plugins/allowed-maven-dependencies.txt
index 1c66b81b448..85531c74863 100644
--- a/maven-plugins/allowed-maven-dependencies.txt
+++ b/maven-plugins/allowed-maven-dependencies.txt
@@ -6,7 +6,7 @@ com.fasterxml.jackson.core:jackson-core:${jackson2.vespa.version}
com.fasterxml.jackson.core:jackson-databind:${jackson-databind.vespa.version}
com.github.luben:zstd-jni:${luben.zstd.vespa.version}
com.google.errorprone:error_prone_annotations:${error-prone-annotations.vespa.version}
-com.google.guava:failureaccess:1.0.1
+com.google.guava:failureaccess:${failureaccess.vespa.version}
com.google.guava:guava:${guava.vespa.version}
com.google.inject:guice:${guice.vespa.version}
com.google.j2objc:j2objc-annotations:2.8
@@ -49,7 +49,7 @@ org.codehaus.plexus:plexus-archiver:4.8.0
org.codehaus.plexus:plexus-cipher:2.0
org.codehaus.plexus:plexus-classworlds:2.7.0
org.codehaus.plexus:plexus-component-annotations:2.1.0
-org.codehaus.plexus:plexus-interpolation:1.26
+org.codehaus.plexus:plexus-interpolation:${plexus-interpolation.vespa.version}
org.codehaus.plexus:plexus-io:${maven-enforcer-plugin.vespa.version}
org.codehaus.plexus:plexus-sec-dispatcher:2.0
org.codehaus.plexus:plexus-utils:${maven-shade-plugin.vespa.version}
diff --git a/metrics/src/main/java/ai/vespa/metrics/set/InfrastructureMetricSet.java b/metrics/src/main/java/ai/vespa/metrics/set/InfrastructureMetricSet.java
index bca52c03892..db70aaa63c7 100644
--- a/metrics/src/main/java/ai/vespa/metrics/set/InfrastructureMetricSet.java
+++ b/metrics/src/main/java/ai/vespa/metrics/set/InfrastructureMetricSet.java
@@ -116,6 +116,7 @@ public class InfrastructureMetricSet {
addMetric(metrics, ConfigServerMetrics.THROTTLED_HOST_FAILURES.max());
addMetric(metrics, ConfigServerMetrics.THROTTLED_NODE_FAILURES.max());
addMetric(metrics, ConfigServerMetrics.NODE_FAIL_THROTTLING.max());
+ addMetric(metrics, ConfigServerMetrics.CLUSTER_AUTOSCALED.max());
addMetric(metrics, ConfigServerMetrics.ORCHESTRATOR_LOCK_ACQUIRE_SUCCESS.count());
addMetric(metrics, ConfigServerMetrics.ORCHESTRATOR_LOCK_ACQUIRE_TIMEOUT.count());
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
index 52b68708eee..539f3128091 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
@@ -137,7 +137,7 @@ public class NodeRepository extends AbstractComponent implements HealthCheckerPr
this.resourcesCalculator = provisionServiceProvider.getHostResourcesCalculator();
this.nodeResourceLimits = new NodeResourceLimits(this);
this.nameResolver = nameResolver;
- this.osVersions = new OsVersions(this);
+ this.osVersions = new OsVersions(this, provisionServiceProvider.getHostProvisioner());
this.infrastructureVersions = new InfrastructureVersions(db);
this.firmwareChecks = new FirmwareChecks(db, clock);
this.containerImages = new ContainerImages(containerImage, tenantContainerImage, tenantGpuContainerImage);
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/DelegatingOsUpgrader.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/DelegatingOsUpgrader.java
index c2d3f511711..5d8296d6f9d 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/DelegatingOsUpgrader.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/DelegatingOsUpgrader.java
@@ -35,7 +35,7 @@ public class DelegatingOsUpgrader extends OsUpgrader {
// This upgrader cannot downgrade nodes. We therefore consider only nodes
// on a lower version than the target
.osVersionIsBefore(target.version())
- .matching(node -> canUpgradeAt(now, node))
+ .matching(node -> canUpgradeTo(target.version(), now, node))
.byIncreasingOsVersion()
.first(upgradeSlots(target, activeNodes));
if (nodesToUpgrade.size() == 0) return;
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsUpgrader.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsUpgrader.java
index 436181f99ba..f56e75518a3 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsUpgrader.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsUpgrader.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.hosted.provision.os;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.NodeType;
import com.yahoo.vespa.flags.IntFlag;
import com.yahoo.vespa.flags.PermanentFlags;
@@ -10,20 +11,27 @@ import com.yahoo.vespa.hosted.provision.NodeRepository;
import java.time.Duration;
import java.time.Instant;
+import java.util.Objects;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
- * Interface for an OS upgrader.
+ * Interface for an OS upgrader. Instances of this are created on-demand because multiple implementations may be used
+ * within a single zone. This and subclasses should not have any state.
*
* @author mpolden
*/
public abstract class OsUpgrader {
+ private final Logger LOG = Logger.getLogger(OsUpgrader.class.getName());
+
private final IntFlag maxActiveUpgrades;
final NodeRepository nodeRepository;
public OsUpgrader(NodeRepository nodeRepository) {
- this.nodeRepository = nodeRepository;
+ this.nodeRepository = Objects.requireNonNull(nodeRepository);
this.maxActiveUpgrades = PermanentFlags.MAX_OS_UPGRADES.bindTo(nodeRepository.flagSource());
}
@@ -43,10 +51,23 @@ public abstract class OsUpgrader {
return Math.max(0, max - upgrading);
}
- /** Returns whether node can change version at given instant */
- final boolean canUpgradeAt(Instant instant, Node node) {
- return node.status().osVersion().downgrading() || // Fast-track downgrades
- node.history().age(instant).compareTo(gracePeriod()) > 0;
+ /** Returns whether node can upgrade to version at given instant */
+ final boolean canUpgradeTo(Version version, Instant instant, Node node) {
+ if (deferringUpgrade(node, instant)) return false;
+ Set<Version> versions = nodeRepository.osVersions().availableTo(node, version);
+ boolean versionAvailable = versions.contains(version);
+ if (!versionAvailable) {
+ LOG.log(Level.WARNING, "Want to upgrade host " + node.hostname() + " to OS version " +
+ version.toFullString() + ", but this version does not exist in " +
+ node.cloudAccount() + ". Found " + versions.stream().sorted().toList());
+ }
+ return versionAvailable;
+ }
+
+ /** Returns whether node is deferring upgrade at given instant */
+ final boolean deferringUpgrade(Node node, Instant instant) {
+ return !node.status().osVersion().downgrading() && // Never defer downgrades
+ node.history().age(instant).compareTo(gracePeriod()) <= 0;
}
/** The duration this leaves new nodes alone before scheduling any upgrade */
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java
index daed86dc2ab..f5706d3b8c9 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java
@@ -1,8 +1,11 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.os;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
import com.yahoo.component.Version;
import com.yahoo.config.provision.Cloud;
+import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.CloudName;
import com.yahoo.config.provision.NodeType;
import com.yahoo.vespa.curator.Lock;
@@ -10,11 +13,17 @@ import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.node.Status;
import com.yahoo.vespa.hosted.provision.persistence.CuratorDb;
+import com.yahoo.vespa.hosted.provision.provisioning.HostProvisioner;
+import com.yahoo.yolean.Exceptions;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
import java.util.function.UnaryOperator;
+import java.util.logging.Level;
import java.util.logging.Logger;
/**
@@ -30,20 +39,27 @@ import java.util.logging.Logger;
*/
public class OsVersions {
- private static final Logger log = Logger.getLogger(OsVersions.class.getName());
+ private static final Logger LOG = Logger.getLogger(OsVersions.class.getName());
private final NodeRepository nodeRepository;
private final CuratorDb db;
private final Cloud cloud;
-
- public OsVersions(NodeRepository nodeRepository) {
- this(nodeRepository, nodeRepository.zone().cloud());
+ private final Optional<HostProvisioner> hostProvisioner;
+ // Version is queried for each host to upgrade, so we cache the results for a while to avoid excessive
+ // API calls to the host provisioner
+ private final Cache<CloudAccount, Set<Version>> availableVersions = CacheBuilder.newBuilder()
+ .expireAfterWrite(10, TimeUnit.MINUTES)
+ .build();
+
+ public OsVersions(NodeRepository nodeRepository, Optional<HostProvisioner> hostProvisioner) {
+ this(nodeRepository, nodeRepository.zone().cloud(), hostProvisioner);
}
- OsVersions(NodeRepository nodeRepository, Cloud cloud) {
+ OsVersions(NodeRepository nodeRepository, Cloud cloud, Optional<HostProvisioner> hostProvisioner) {
this.nodeRepository = Objects.requireNonNull(nodeRepository);
this.db = nodeRepository.database();
this.cloud = Objects.requireNonNull(cloud);
+ this.hostProvisioner = Objects.requireNonNull(hostProvisioner);
// Read and write all versions to make sure they are stored in the latest version of the serialized format
try (var lock = db.lockOsVersionChange()) {
@@ -104,11 +120,30 @@ public class OsVersions {
+ currentTarget.get().version().toFullString());
}
- log.info("Set OS target version for " + nodeType + " nodes to " + version.toFullString());
+ LOG.info("Set OS target version for " + nodeType + " nodes to " + version.toFullString());
return change.withTarget(version, nodeType);
});
}
+ /** Returns the versions available to given host */
+ public Set<Version> availableTo(Node host, Version requestedVersion) {
+ if (hostProvisioner.isEmpty()) {
+ return Set.of(requestedVersion);
+ }
+ try {
+ return availableVersions.get(host.cloudAccount(),
+ () -> hostProvisioner.get().osVersions(host, requestedVersion.getMajor()));
+ } catch (ExecutionException e) {
+ LOG.log(Level.WARNING, "Failed to list supported OS versions in " + host.cloudAccount() + ": " + Exceptions.toMessageString(e));
+ return Set.of();
+ }
+ }
+
+ /** Invalidate cached versions. For testing purposes */
+ void invalidate() {
+ availableVersions.invalidateAll();
+ }
+
/** Resume or halt upgrade of given node type */
public void resumeUpgradeOf(NodeType nodeType, boolean resume) {
require(nodeType);
@@ -124,9 +159,9 @@ public class OsVersions {
}
}
- /** Returns whether node can be upgraded now */
- public boolean canUpgrade(Node node) {
- return chooseUpgrader(node.type(), Optional.empty()).canUpgradeAt(nodeRepository.clock().instant(), node);
+ /** Returns whether node is currently deferring its upgrade */
+ public boolean deferringUpgrade(Node node) {
+ return chooseUpgrader(node.type(), Optional.empty()).deferringUpgrade(node, nodeRepository.clock().instant());
}
/** Returns the upgrader to use when upgrading given node type to target */
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/RebuildingOsUpgrader.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/RebuildingOsUpgrader.java
index 108093d8379..a5565a6accb 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/RebuildingOsUpgrader.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/RebuildingOsUpgrader.java
@@ -71,7 +71,7 @@ public class RebuildingOsUpgrader extends OsUpgrader {
List<Node> hostsToRebuild = new ArrayList<>(rebuildLimit);
NodeList candidates = hosts.not().rebuilding(softRebuild)
.not().onOsVersion(target.version())
- .matching(node -> canUpgradeAt(now, node))
+ .matching(node -> canUpgradeTo(target.version(), now, node))
.byIncreasingOsVersion();
for (Node host : candidates) {
if (hostsToRebuild.size() == rebuildLimit) break;
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/RetiringOsUpgrader.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/RetiringOsUpgrader.java
index c1e8f2b6fa4..cb6c7683f23 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/RetiringOsUpgrader.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/RetiringOsUpgrader.java
@@ -54,7 +54,7 @@ public class RetiringOsUpgrader extends OsUpgrader {
}
return nodes.not().deprovisioning()
.not().onOsVersion(target.version())
- .matching(node -> canUpgradeAt(instant, node))
+ .matching(node -> canUpgradeTo(target.version(), instant, node))
.byIncreasingOsVersion()
.first(upgradeSlots(target, nodes.deprovisioning()));
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java
index 8ef4b6c8bd1..4214f543c60 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.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.hosted.provision.provisioning;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.HostEvent;
@@ -11,6 +12,7 @@ import com.yahoo.vespa.hosted.provision.Node;
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -94,6 +96,9 @@ public interface HostProvisioner {
/** Returns whether flavor for given host can be upgraded to a newer generation */
boolean canUpgradeFlavor(Node host, Node child, Predicate<NodeResources> realHostResourcesWithinLimits);
+ /** Returns all OS versions available to host for the given major version */
+ Set<Version> osVersions(Node host, int majorVersion);
+
/** Updates the given hosts to indicate that they are allocated to the given application. */
default void updateAllocation(Collection<Node> hosts, ApplicationId owner) { }
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java
index 5c379fb1608..b8c841771f5 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java
@@ -167,7 +167,7 @@ class NodesResponse extends SlimeJsonResponse {
node.status().osVersion().current().ifPresent(version -> object.setString("currentOsVersion", version.toFullString()));
node.status().osVersion().wanted().ifPresent(version -> object.setString("wantedOsVersion", version.toFullString()));
if (node.type().isHost()) {
- object.setBool("deferOsUpgrade", !nodeRepository.osVersions().canUpgrade(node));
+ object.setBool("deferOsUpgrade", nodeRepository.osVersions().deferringUpgrade(node));
}
node.status().firmwareVerifiedAt().ifPresent(instant -> object.setLong("currentFirmwareCheck", instant.toEpochMilli()));
if (node.type().isHost())
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java
index b5bb91af71a..73985075319 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.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.hosted.provision.testutils;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Flavor;
@@ -32,6 +33,7 @@ import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
+import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static com.yahoo.config.provision.NodeType.host;
@@ -50,6 +52,7 @@ public class MockHostProvisioner implements HostProvisioner {
private final Map<ClusterSpec.Type, Flavor> hostFlavors = new HashMap<>();
private final Set<String> upgradableFlavors = new HashSet<>();
private final Map<Behaviour, Integer> behaviours = new HashMap<>();
+ private final Set<Version> osVersions = new HashSet<>();
private int deprovisionedHosts = 0;
@@ -146,6 +149,11 @@ public class MockHostProvisioner implements HostProvisioner {
return upgradableFlavors.contains(host.flavor().name());
}
+ @Override
+ public Set<Version> osVersions(Node host, int majorVersion) {
+ return osVersions.stream().filter(v -> v.getMajor() == majorVersion).collect(Collectors.toUnmodifiableSet());
+ }
+
/** Returns the hosts that have been provisioned by this */
public List<ProvisionedHost> provisionedHosts() {
return Collections.unmodifiableList(provisionedHosts);
@@ -214,6 +222,11 @@ public class MockHostProvisioner implements HostProvisioner {
return this;
}
+ public MockHostProvisioner addOsVersion(Version version) {
+ osVersions.add(version);
+ return this;
+ }
+
public boolean compatible(Flavor flavor, NodeResources resources) {
NodeResources resourcesToVerify = resources.withMemoryGb(resources.memoryGb() - memoryTaxGb);
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java
index 0be90dcb888..dcbac44a37f 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java
@@ -18,6 +18,7 @@ import com.yahoo.vespa.hosted.provision.node.Allocation;
import com.yahoo.vespa.hosted.provision.node.OsVersion;
import com.yahoo.vespa.hosted.provision.node.Status;
import com.yahoo.vespa.hosted.provision.provisioning.ProvisioningTester;
+import com.yahoo.vespa.hosted.provision.testutils.MockHostProvisioner;
import org.junit.Test;
import java.time.Duration;
@@ -41,7 +42,7 @@ public class OsVersionsTest {
@Test
public void upgrade() {
- var versions = new OsVersions(tester.nodeRepository());
+ var versions = new OsVersions(tester.nodeRepository(), Optional.ofNullable(tester.hostProvisioner()));
provisionInfraApplication(10);
Supplier<NodeList> hostNodes = () -> tester.nodeRepository().nodes().list().nodeType(NodeType.host);
@@ -94,7 +95,7 @@ public class OsVersionsTest {
public void max_active_upgrades() {
int totalNodes = 20;
int maxActiveUpgrades = 5;
- var versions = new OsVersions(tester.nodeRepository(), Cloud.defaultCloud());
+ var versions = new OsVersions(tester.nodeRepository(), Cloud.defaultCloud(), Optional.ofNullable(tester.hostProvisioner()));
setMaxActiveUpgrades(maxActiveUpgrades);
provisionInfraApplication(totalNodes);
Supplier<NodeList> hostNodes = () -> tester.nodeRepository().nodes().list().state(Node.State.active).hosts();
@@ -140,7 +141,7 @@ public class OsVersionsTest {
@Test
public void newer_upgrade_aborts_upgrade_to_stale_version() {
- var versions = new OsVersions(tester.nodeRepository());
+ var versions = new OsVersions(tester.nodeRepository(), Optional.ofNullable(tester.hostProvisioner()));
provisionInfraApplication(10);
Supplier<NodeList> hostNodes = () -> tester.nodeRepository().nodes().list().hosts();
@@ -160,7 +161,7 @@ public class OsVersionsTest {
@Test
public void upgrade_and_downgrade_by_retiring() {
int maxActiveUpgrades = 2;
- var versions = new OsVersions(tester.nodeRepository(), Cloud.builder().dynamicProvisioning(true).build());
+ var versions = new OsVersions(tester.nodeRepository(), Cloud.builder().dynamicProvisioning(true).build(), Optional.ofNullable(tester.hostProvisioner()));
setMaxActiveUpgrades(maxActiveUpgrades);
int hostCount = 10;
// Provision hosts and children
@@ -229,7 +230,7 @@ public class OsVersionsTest {
@Test
public void upgrade_by_retiring_everything_at_once() {
- var versions = new OsVersions(tester.nodeRepository(), Cloud.builder().dynamicProvisioning(true).build());
+ var versions = new OsVersions(tester.nodeRepository(), Cloud.builder().dynamicProvisioning(true).build(), Optional.ofNullable(tester.hostProvisioner()));
setMaxActiveUpgrades(Integer.MAX_VALUE);
int hostCount = 3;
provisionInfraApplication(hostCount, NodeType.host);
@@ -253,7 +254,7 @@ public class OsVersionsTest {
@Test
public void upgrade_by_rebuilding() {
- var versions = new OsVersions(tester.nodeRepository(), Cloud.defaultCloud());
+ var versions = new OsVersions(tester.nodeRepository(), Cloud.defaultCloud(), Optional.ofNullable(tester.hostProvisioner()));
setMaxActiveUpgrades(1);
int hostCount = 10;
provisionInfraApplication(hostCount + 1);
@@ -337,7 +338,8 @@ public class OsVersionsTest {
.dynamicProvisioning(true)
.name(CloudName.AWS)
.account(CloudAccount.from("000000000000"))
- .build());
+ .build(),
+ Optional.ofNullable(tester.hostProvisioner()));
provisionInfraApplication(hostCount, NodeType.host, NodeResources.StorageType.remote, NodeResources.Architecture.x86_64);
Supplier<NodeList> hostNodes = () -> tester.nodeRepository().nodes().list().nodeType(NodeType.host);
@@ -382,7 +384,7 @@ public class OsVersionsTest {
@Test
public void upgrade_by_rebuilding_multiple_host_types() {
setMaxActiveUpgrades(1);
- var versions = new OsVersions(tester.nodeRepository(), Cloud.defaultCloud());
+ var versions = new OsVersions(tester.nodeRepository(), Cloud.defaultCloud(), Optional.ofNullable(tester.hostProvisioner()));
int hostCount = 3;
provisionInfraApplication(hostCount, NodeType.host);
provisionInfraApplication(hostCount, NodeType.confighost);
@@ -415,7 +417,7 @@ public class OsVersionsTest {
@Test
public void upgrade_by_rebuilding_is_limited_by_stateful_clusters() {
setMaxActiveUpgrades(3);
- var versions = new OsVersions(tester.nodeRepository(), Cloud.defaultCloud());
+ var versions = new OsVersions(tester.nodeRepository(), Cloud.defaultCloud(), Optional.ofNullable(tester.hostProvisioner()));
int hostCount = 5;
ApplicationId app1 = ApplicationId.from("t1", "a1", "i1");
ApplicationId app2 = ApplicationId.from("t2", "a2", "i2");
@@ -493,7 +495,7 @@ public class OsVersionsTest {
public void upgrade_by_rebuilding_limits_infrastructure_host() {
int hostCount = 3;
setMaxActiveUpgrades(hostCount);
- var versions = new OsVersions(tester.nodeRepository(), Cloud.defaultCloud());
+ var versions = new OsVersions(tester.nodeRepository(), Cloud.defaultCloud(), Optional.ofNullable(tester.hostProvisioner()));
provisionInfraApplication(hostCount, NodeType.proxyhost);
Supplier<NodeList> hosts = () -> tester.nodeRepository().nodes().list().nodeType(NodeType.proxyhost);
@@ -515,6 +517,31 @@ public class OsVersionsTest {
}
}
+ @Test
+ public void skips_unavailable_version() {
+ MockHostProvisioner hostProvisioner = new MockHostProvisioner(List.of());
+ ProvisioningTester tester = new ProvisioningTester.Builder().dynamicProvisioning(true, false).hostProvisioner(hostProvisioner).build();
+ OsVersions versions = tester.nodeRepository().osVersions();
+ tester.makeReadyHosts(1, new NodeResources(2,4,8,100));
+ tester.activateTenantHosts();
+ Supplier<Node> host = () -> tester.nodeRepository().nodes().list().nodeType(NodeType.host).first().get();
+ tester.clock().advance(Duration.ofDays(1));
+
+ hostProvisioner.addOsVersion(Version.fromString("7.0"));
+ Version version0 = Version.fromString("8.0");
+ versions.setTarget(NodeType.host, version0, false);
+ versions.resumeUpgradeOf(NodeType.host, true);
+ assertTrue("Upgrade is not triggered to unavailable version", host.get().status().osVersion().wanted().isEmpty());
+
+ // Version becomes available, but is not used until cache expires
+ hostProvisioner.addOsVersion(version0);
+ versions.resumeUpgradeOf(NodeType.host, true);
+ assertTrue(host.get().status().osVersion().wanted().isEmpty());
+ versions.invalidate();
+ versions.resumeUpgradeOf(NodeType.host, true);
+ assertEquals("Host upgrade is triggered", version0, host.get().status().osVersion().wanted().get());
+ }
+
private void setMaxActiveUpgrades(int max) {
tester.flagSource().withIntFlag(PermanentFlags.MAX_OS_UPGRADES.id(), max);
}
diff --git a/parent/pom.xml b/parent/pom.xml
index 0506c87493c..3fc520c86c7 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -317,7 +317,7 @@
-->
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
- <version>5.17.0</version>
+ <version>5.17.1</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.testing.junit5.JUnit5BestPractices</recipe>
@@ -327,7 +327,7 @@
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-testing-frameworks</artifactId>
- <version>2.1.4</version>
+ <version>2.1.5</version>
</dependency>
</dependencies>
</plugin>
@@ -494,6 +494,14 @@
<artifactId>zookeeper</artifactId>
<version>${zookeeper.client.vespa.version}</version>
<exclusions>
+ <!--
+ Container provides wiring for all common log libraries
+ Duplicate embedding results in various warnings being printed to stderr
+ -->
+ <exclusion>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
@@ -529,6 +537,11 @@
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
+ <artifactId>failureaccess</artifactId>
+ <version>${failureaccess.vespa.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.vespa.version}</version>
<exclusions>
@@ -974,7 +987,7 @@
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-interpolation</artifactId>
- <version>1.26</version>
+ <version>${plexus-interpolation.vespa.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
@@ -1152,7 +1165,7 @@
See pluginManagement of rewrite-maven-plugin for more details -->
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-recipe-bom</artifactId>
- <version>2.5.3</version>
+ <version>2.5.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
diff --git a/searchlib/src/tests/attribute/direct_posting_store/CMakeLists.txt b/searchlib/src/tests/attribute/direct_posting_store/CMakeLists.txt
index 0cb45e6b18f..3c8e76bc9b2 100644
--- a/searchlib/src/tests/attribute/direct_posting_store/CMakeLists.txt
+++ b/searchlib/src/tests/attribute/direct_posting_store/CMakeLists.txt
@@ -5,5 +5,6 @@ vespa_add_executable(searchlib_direct_posting_store_test_app TEST
DEPENDS
searchlib
searchlib_test
+ GTest::GTest
)
vespa_add_test(NAME searchlib_direct_posting_store_test_app COMMAND searchlib_direct_posting_store_test_app)
diff --git a/searchlib/src/tests/attribute/direct_posting_store/direct_posting_store_test.cpp b/searchlib/src/tests/attribute/direct_posting_store/direct_posting_store_test.cpp
index d6b0ff2a4b6..28039d30bfe 100644
--- a/searchlib/src/tests/attribute/direct_posting_store/direct_posting_store_test.cpp
+++ b/searchlib/src/tests/attribute/direct_posting_store/direct_posting_store_test.cpp
@@ -9,10 +9,11 @@
#include <vespa/searchlib/attribute/i_docid_with_weight_posting_store.h>
#include <vespa/searchlib/index/dummyfileheadercontext.h>
#include <vespa/searchlib/queryeval/docid_with_weight_search_iterator.h>
+#define ENABLE_GTEST_MIGRATION
#include <vespa/searchlib/test/searchiteratorverifier.h>
#include <vespa/searchlib/util/randomgenerator.h>
+#include <vespa/vespalib/gtest/gtest.h>
#include <vespa/vespalib/test/insertion_operators.h>
-#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/log/log.h>
LOG_SETUP("direct_posting_store_test");
@@ -32,7 +33,7 @@ void add_docs(AttributeVector::SP attr_ptr, size_t limit = 1000) {
attr_ptr->addDoc(docid);
}
attr_ptr->commit();
- ASSERT_EQUAL((limit - 1), docid);
+ ASSERT_EQ((limit - 1), docid);
}
template <typename ATTR, typename KEY>
@@ -56,36 +57,40 @@ void populate_string(AttributeVector::SP attr_ptr) {
set_doc(attr, 7, "foo", 10);
}
-struct LongFixture {
+struct DirectPostingStoreTest : public ::testing::Test {
AttributeVector::SP attr;
const IDocidWithWeightPostingStore *api;
- LongFixture() : attr(make_attribute(BasicType::INT64, CollectionType::WSET, true)),
- api(attr->as_docid_with_weight_posting_store())
+
+ DirectPostingStoreTest(BasicType type, CollectionType col_type)
+ : attr(make_attribute(type, col_type, true)),
+ api(attr->as_docid_with_weight_posting_store())
{
- ASSERT_TRUE(api != nullptr);
+ assert(api != nullptr);
add_docs(attr);
+ }
+ ~DirectPostingStoreTest() {}
+};
+
+struct DirectIntegerTest : public DirectPostingStoreTest {
+ DirectIntegerTest() : DirectPostingStoreTest(BasicType::INT64, CollectionType::WSET)
+ {
populate_long(attr);
}
};
-struct StringFixture {
- AttributeVector::SP attr;
- const IDocidWithWeightPostingStore *api;
- StringFixture() : attr(make_attribute(BasicType::STRING, CollectionType::WSET, true)),
- api(attr->as_docid_with_weight_posting_store())
+struct DirectStringTest : public DirectPostingStoreTest {
+ DirectStringTest() : DirectPostingStoreTest(BasicType::STRING, CollectionType::WSET)
{
- ASSERT_TRUE(api != nullptr);
- add_docs(attr);
populate_string(attr);
}
};
-TEST("require that appropriate attributes support the IDocidWithWeightPostingStore interface") {
+TEST(DirectPostingStoreApiTest, attributes_support_IDocidWithWeightPostingStore_interface) {
EXPECT_TRUE(make_attribute(BasicType::INT64, CollectionType::WSET, true)->as_docid_with_weight_posting_store() != nullptr);
EXPECT_TRUE(make_attribute(BasicType::STRING, CollectionType::WSET, true)->as_docid_with_weight_posting_store() != nullptr);
}
-TEST("require that inappropriate attributes do not support the IDocidWithWeightPostingStore interface") {
+TEST(DirectPostingStoreApiTest, attributes_do_not_support_IDocidWithWeightPostingStore_interface) {
EXPECT_TRUE(make_attribute(BasicType::INT64, CollectionType::SINGLE, false)->as_docid_with_weight_posting_store() == nullptr);
EXPECT_TRUE(make_attribute(BasicType::INT64, CollectionType::ARRAY, false)->as_docid_with_weight_posting_store() == nullptr);
EXPECT_TRUE(make_attribute(BasicType::INT64, CollectionType::WSET, false)->as_docid_with_weight_posting_store() == nullptr);
@@ -102,26 +107,26 @@ TEST("require that inappropriate attributes do not support the IDocidWithWeightP
void verify_valid_lookup(IDirectPostingStore::LookupResult result) {
EXPECT_TRUE(result.posting_idx.valid());
- EXPECT_EQUAL(3u, result.posting_size);
- EXPECT_EQUAL(5, result.min_weight);
- EXPECT_EQUAL(20, result.max_weight);
+ EXPECT_EQ(3u, result.posting_size);
+ EXPECT_EQ(5, result.min_weight);
+ EXPECT_EQ(20, result.max_weight);
}
void verify_invalid_lookup(IDirectPostingStore::LookupResult result) {
EXPECT_FALSE(result.posting_idx.valid());
- EXPECT_EQUAL(0u, result.posting_size);
- EXPECT_EQUAL(0, result.min_weight);
- EXPECT_EQUAL(0, result.max_weight);
+ EXPECT_EQ(0u, result.posting_size);
+ EXPECT_EQ(0, result.min_weight);
+ EXPECT_EQ(0, result.max_weight);
}
-TEST_F("require that integer lookup works correctly", LongFixture) {
- verify_valid_lookup(f1.api->lookup("111", f1.api->get_dictionary_snapshot()));
- verify_invalid_lookup(f1.api->lookup("222", f1.api->get_dictionary_snapshot()));
+TEST_F(DirectIntegerTest, lookup_works_correctly) {
+ verify_valid_lookup(api->lookup("111", api->get_dictionary_snapshot()));
+ verify_invalid_lookup(api->lookup("222", api->get_dictionary_snapshot()));
}
-TEST_F("require string lookup works correctly", StringFixture) {
- verify_valid_lookup(f1.api->lookup("foo", f1.api->get_dictionary_snapshot()));
- verify_invalid_lookup(f1.api->lookup("bar", f1.api->get_dictionary_snapshot()));
+TEST_F(DirectStringTest, lookup_works_correctly) {
+ verify_valid_lookup(api->lookup("foo", api->get_dictionary_snapshot()));
+ verify_invalid_lookup(api->lookup("bar", api->get_dictionary_snapshot()));
}
void verify_posting(const IDocidWithWeightPostingStore &api, const char *term) {
@@ -129,64 +134,64 @@ void verify_posting(const IDocidWithWeightPostingStore &api, const char *term) {
ASSERT_TRUE(result.posting_idx.valid());
std::vector<DocidWithWeightIterator> itr_store;
api.create(result.posting_idx, itr_store);
- ASSERT_EQUAL(1u, itr_store.size());
+ ASSERT_EQ(1u, itr_store.size());
{
DocidWithWeightIterator &itr = itr_store[0];
if (itr.valid() && itr.getKey() < 1) {
itr.linearSeek(1);
}
ASSERT_TRUE(itr.valid());
- EXPECT_EQUAL(1u, itr.getKey()); // docid
- EXPECT_EQUAL(20, itr.getData()); // weight
+ EXPECT_EQ(1u, itr.getKey()); // docid
+ EXPECT_EQ(20, itr.getData()); // weight
itr.linearSeek(2);
ASSERT_TRUE(itr.valid());
- EXPECT_EQUAL(5u, itr.getKey()); // docid
- EXPECT_EQUAL(5, itr.getData()); // weight
+ EXPECT_EQ(5u, itr.getKey()); // docid
+ EXPECT_EQ(5, itr.getData()); // weight
itr.linearSeek(6);
ASSERT_TRUE(itr.valid());
- EXPECT_EQUAL(7u, itr.getKey()); // docid
- EXPECT_EQUAL(10, itr.getData()); // weight
+ EXPECT_EQ(7u, itr.getKey()); // docid
+ EXPECT_EQ(10, itr.getData()); // weight
itr.linearSeek(8);
EXPECT_FALSE(itr.valid());
}
}
-TEST_F("require that integer iterators are created correctly", LongFixture) {
- verify_posting(*f1.api, "111");
+TEST_F(DirectIntegerTest, iterators_are_created_correctly) {
+ verify_posting(*api, "111");
}
-TEST_F("require that string iterators are created correctly", StringFixture) {
- verify_posting(*f1.api, "foo");
+TEST_F(DirectStringTest, iterators_are_created_correctly) {
+ verify_posting(*api, "foo");
}
-TEST_F("require that collect_folded works for string", StringFixture)
+TEST_F(DirectStringTest, collect_folded_works)
{
- StringAttribute *attr = static_cast<StringAttribute *>(f1.attr.get());
- set_doc(attr, 2, "bar", 30);
+ auto* sa = static_cast<StringAttribute*>(attr.get());
+ set_doc(sa, 2, "bar", 30);
attr->commit();
- set_doc(attr, 3, "FOO", 30);
+ set_doc(sa, 3, "FOO", 30);
attr->commit();
- auto dictionary_snapshot = f1.api->get_dictionary_snapshot();
- auto lookup1 = f1.api->lookup("foo", dictionary_snapshot);
+ auto dictionary_snapshot = api->get_dictionary_snapshot();
+ auto lookup1 = api->lookup("foo", dictionary_snapshot);
std::vector<vespalib::string> folded;
- std::function<void(vespalib::datastore::EntryRef)> save_folded = [&folded,attr](vespalib::datastore::EntryRef enum_idx) { folded.emplace_back(attr->getFromEnum(enum_idx.ref())); };
- f1.api->collect_folded(lookup1.enum_idx, dictionary_snapshot, save_folded);
+ std::function<void(vespalib::datastore::EntryRef)> save_folded = [&folded,sa](vespalib::datastore::EntryRef enum_idx) { folded.emplace_back(sa->getFromEnum(enum_idx.ref())); };
+ api->collect_folded(lookup1.enum_idx, dictionary_snapshot, save_folded);
std::vector<vespalib::string> expected_folded{"FOO", "foo"};
- EXPECT_EQUAL(expected_folded, folded);
+ EXPECT_EQ(expected_folded, folded);
}
-TEST_F("require that collect_folded works for integers", LongFixture)
+TEST_F(DirectIntegerTest, collect_folded_works)
{
- IntegerAttributeTemplate<int64_t> *attr = dynamic_cast<IntegerAttributeTemplate<int64_t> *>(f1.attr.get());
- set_doc(attr, 2, int64_t(112), 30);
+ auto* ia = dynamic_cast<IntegerAttributeTemplate<int64_t>*>(attr.get());
+ set_doc(ia, 2, int64_t(112), 30);
attr->commit();
- auto dictionary_snapshot = f1.api->get_dictionary_snapshot();
- auto lookup1 = f1.api->lookup("111", dictionary_snapshot);
+ auto dictionary_snapshot = api->get_dictionary_snapshot();
+ auto lookup1 = api->lookup("111", dictionary_snapshot);
std::vector<int64_t> folded;
- std::function<void(vespalib::datastore::EntryRef)> save_folded = [&folded,attr](vespalib::datastore::EntryRef enum_idx) { folded.emplace_back(attr->getFromEnum(enum_idx.ref())); };
- f1.api->collect_folded(lookup1.enum_idx, dictionary_snapshot, save_folded);
+ std::function<void(vespalib::datastore::EntryRef)> save_folded = [&folded,ia](vespalib::datastore::EntryRef enum_idx) { folded.emplace_back(ia->getFromEnum(enum_idx.ref())); };
+ api->collect_folded(lookup1.enum_idx, dictionary_snapshot, save_folded);
std::vector<int64_t> expected_folded{int64_t(111)};
- EXPECT_EQUAL(expected_folded, folded);
+ EXPECT_EQ(expected_folded, folded);
}
class Verifier : public search::test::SearchIteratorVerifier {
@@ -196,9 +201,9 @@ public:
SearchIterator::UP create(bool strict) const override {
(void) strict;
const auto* api = _attr->as_docid_with_weight_posting_store();
- ASSERT_TRUE(api != nullptr);
+ assert(api != nullptr);
auto dict_entry = api->lookup("123", api->get_dictionary_snapshot());
- ASSERT_TRUE(dict_entry.posting_idx.valid());
+ assert(dict_entry.posting_idx.valid());
return std::make_unique<queryeval::DocidWithWeightSearchIterator>(_tfmd, *api, dict_entry);
}
private:
@@ -218,9 +223,9 @@ Verifier::Verifier()
}
Verifier::~Verifier() {}
-TEST("verify document weight search iterator") {
+TEST(VerifierTest, verify_document_weight_search_iterator) {
Verifier verifier;
verifier.verify();
}
-TEST_MAIN() { TEST_RUN_ALL(); }
+GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp b/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp
index 1beb2b1e501..1bfb9fb41f9 100644
--- a/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp
+++ b/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp
@@ -1,5 +1,6 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/testkit/testapp.h>
+#include <vespa/searchcommon/attribute/config.h>
#include <vespa/searchlib/attribute/enumstore.h>
#include <vespa/searchlib/attribute/singlestringattribute.h>
#include <vespa/searchlib/attribute/singlestringpostattribute.h>
@@ -8,7 +9,6 @@
#include <vespa/searchlib/attribute/enumstore.hpp>
#include <vespa/searchlib/attribute/single_string_enum_search_context.h>
-#include <vespa/searchlib/attribute/multistringpostattribute.hpp>
#include <vespa/log/log.h>
LOG_SETUP("stringattribute_test");
diff --git a/searchlib/src/tests/query/streaming_query_test.cpp b/searchlib/src/tests/query/streaming_query_test.cpp
index 306456518b7..f5370785167 100644
--- a/searchlib/src/tests/query/streaming_query_test.cpp
+++ b/searchlib/src/tests/query/streaming_query_test.cpp
@@ -38,7 +38,7 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, 7);
EXPECT_EQ(ib, 7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, 7);
EXPECT_EQ(db, 7);
}
@@ -48,15 +48,24 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, -7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7);
EXPECT_EQ(db, -7);
}
+ {
+ QueryTerm q(factory.create(), "+7", "index", TermType::WORD);
+ EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
+ EXPECT_EQ(ia, 7);
+ EXPECT_EQ(ib, 7);
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, 7);
+ EXPECT_EQ(db, 7);
+ }
{
QueryTerm q(factory.create(), "7.5", "index", TermType::WORD);
EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib));
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, 7.5);
EXPECT_EQ(db, 7.5);
}
@@ -64,7 +73,7 @@ TEST(StreamingQueryTest, test_query_language)
{
QueryTerm q(factory.create(), "-7.5", "index", TermType::WORD);
EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib));
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7.5);
EXPECT_EQ(db, -7.5);
}
@@ -74,8 +83,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, 6);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_LT(db, 7);
EXPECT_GT(db, 6.99);
}
@@ -85,8 +94,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, 7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_EQ(db, 7);
}
@@ -95,10 +104,10 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, 8);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_GT(da, 7);
EXPECT_LT(da, 7.01);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
@@ -106,9 +115,9 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, 7);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, 7);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
@@ -116,7 +125,7 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, 7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7);
EXPECT_EQ(db, 7);
}
@@ -126,7 +135,7 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_FALSE(q.getAsIntegerTerm(ia, ib)); // This is dubious and perhaps a regression.
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7.1);
EXPECT_EQ(db, 7.1);
}
@@ -136,7 +145,7 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_FALSE(q.getAsIntegerTerm(ia, ib)); // This is dubious and perhaps a regression.
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, 500.0);
EXPECT_EQ(db, std::numeric_limits<double>::max());
}
@@ -147,8 +156,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -6);
EXPECT_EQ(ib, 7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, std::nextafterf(minusSeven, seven));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, std::nextafter(minusSeven, seven));
EXPECT_EQ(db, seven);
}
@@ -157,9 +166,9 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -6);
EXPECT_EQ(ib, 6);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, std::nextafterf(minusSeven, seven));
- EXPECT_EQ(db, std::nextafterf(seven, minusSeven));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, std::nextafter(minusSeven, seven));
+ EXPECT_EQ(db, std::nextafter(seven, minusSeven));
}
{
@@ -174,9 +183,9 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, 6);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, minusSeven);
- EXPECT_EQ(db, std::nextafterf(seven, minusSeven));
+ EXPECT_EQ(db, std::nextafter(seven, minusSeven));
}
{
@@ -184,8 +193,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, -8);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_LT(db, -7);
EXPECT_GT(db, -7.01);
}
@@ -195,8 +204,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, -7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_EQ(db, -7);
}
@@ -205,8 +214,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, -7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_EQ(db, -7);
}
@@ -215,10 +224,10 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -6);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_GT(da, -7);
EXPECT_LT(da, -6.99);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
@@ -226,9 +235,9 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
@@ -236,15 +245,15 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
QueryTerm q(factory.create(), "a", "index", TermType::WORD);
EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib));
- EXPECT_TRUE(!q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(!q.getAsFloatTerm(da, db));
}
{
@@ -287,7 +296,10 @@ TEST(StreamingQueryTest, test_query_language)
class AllowRewrite : public QueryNodeResultFactory
{
public:
- virtual bool getRewriteFloatTerms() const override { return true; }
+ explicit AllowRewrite(vespalib::stringref index) noexcept : _allowedIndex(index) {}
+ bool getRewriteFloatTerms(vespalib::stringref index) const noexcept override { return index == _allowedIndex; }
+private:
+ vespalib::string _allowedIndex;
};
const char TERM_UNIQ = static_cast<char>(ParseItem::ITEM_TERM) | static_cast<char>(ParseItem::IF_UNIQUEID);
@@ -297,12 +309,12 @@ TEST(StreamingQueryTest, e_is_not_rewritten_even_if_allowed)
const char term[6] = {TERM_UNIQ, 3, 1, 'c', 1, 'e'};
vespalib::stringref stackDump(term, sizeof(term));
EXPECT_EQ(6u, stackDump.size());
- AllowRewrite allowRewrite;
+ AllowRewrite allowRewrite("c");
const Query q(allowRewrite, stackDump);
EXPECT_TRUE(q.valid());
const QueryNode & root = q.getRoot();
EXPECT_TRUE(dynamic_cast<const QueryTerm *>(&root) != nullptr);
- const QueryTerm & qt = static_cast<const QueryTerm &>(root);
+ const auto & qt = static_cast<const QueryTerm &>(root);
EXPECT_EQ("c", qt.index());
EXPECT_EQ(vespalib::stringref("e"), qt.getTerm());
EXPECT_EQ(3u, qt.uniqueId());
@@ -313,12 +325,12 @@ TEST(StreamingQueryTest, onedot0e_is_not_rewritten_by_default)
const char term[9] = {TERM_UNIQ, 3, 1, 'c', 4, '1', '.', '0', 'e'};
vespalib::stringref stackDump(term, sizeof(term));
EXPECT_EQ(9u, stackDump.size());
- QueryNodeResultFactory empty;
+ AllowRewrite empty("nix");
const Query q(empty, stackDump);
EXPECT_TRUE(q.valid());
const QueryNode & root = q.getRoot();
EXPECT_TRUE(dynamic_cast<const QueryTerm *>(&root) != nullptr);
- const QueryTerm & qt = static_cast<const QueryTerm &>(root);
+ const auto & qt = static_cast<const QueryTerm &>(root);
EXPECT_EQ("c", qt.index());
EXPECT_EQ(vespalib::stringref("1.0e"), qt.getTerm());
EXPECT_EQ(3u, qt.uniqueId());
@@ -329,34 +341,34 @@ TEST(StreamingQueryTest, onedot0e_is_rewritten_if_allowed_too)
const char term[9] = {TERM_UNIQ, 3, 1, 'c', 4, '1', '.', '0', 'e'};
vespalib::stringref stackDump(term, sizeof(term));
EXPECT_EQ(9u, stackDump.size());
- AllowRewrite empty;
+ AllowRewrite empty("c");
const Query q(empty, stackDump);
EXPECT_TRUE(q.valid());
const QueryNode & root = q.getRoot();
EXPECT_TRUE(dynamic_cast<const EquivQueryNode *>(&root) != nullptr);
- const EquivQueryNode & equiv = static_cast<const EquivQueryNode &>(root);
+ const auto & equiv = static_cast<const EquivQueryNode &>(root);
EXPECT_EQ(2u, equiv.size());
EXPECT_TRUE(dynamic_cast<const QueryTerm *>(equiv[0].get()) != nullptr);
{
- const QueryTerm & qt = static_cast<const QueryTerm &>(*equiv[0]);
+ const auto & qt = static_cast<const QueryTerm &>(*equiv[0]);
EXPECT_EQ("c", qt.index());
EXPECT_EQ(vespalib::stringref("1.0e"), qt.getTerm());
EXPECT_EQ(3u, qt.uniqueId());
}
EXPECT_TRUE(dynamic_cast<const PhraseQueryNode *>(equiv[1].get()) != nullptr);
{
- const PhraseQueryNode & phrase = static_cast<const PhraseQueryNode &>(*equiv[1]);
+ const auto & phrase = static_cast<const PhraseQueryNode &>(*equiv[1]);
EXPECT_EQ(2u, phrase.size());
EXPECT_TRUE(dynamic_cast<const QueryTerm *>(phrase[0].get()) != nullptr);
{
- const QueryTerm & qt = static_cast<const QueryTerm &>(*phrase[0]);
+ const auto & qt = static_cast<const QueryTerm &>(*phrase[0]);
EXPECT_EQ("c", qt.index());
EXPECT_EQ(vespalib::stringref("1"), qt.getTerm());
EXPECT_EQ(0u, qt.uniqueId());
}
EXPECT_TRUE(dynamic_cast<const QueryTerm *>(phrase[1].get()) != nullptr);
{
- const QueryTerm & qt = static_cast<const QueryTerm &>(*phrase[1]);
+ const auto & qt = static_cast<const QueryTerm &>(*phrase[1]);
EXPECT_EQ("c", qt.index());
EXPECT_EQ(vespalib::stringref("0e"), qt.getTerm());
EXPECT_EQ(0u, qt.uniqueId());
@@ -460,7 +472,7 @@ TEST(StreamingQueryTest, test_phrase_evaluate)
terms[1]->add(1, 5, 0, 1);
terms[2]->add(0, 5, 0, 1);
HitList hits;
- PhraseQueryNode * p = static_cast<PhraseQueryNode *>(phrases[0]);
+ auto * p = static_cast<PhraseQueryNode *>(phrases[0]);
p->evaluateHits(hits);
ASSERT_EQ(3u, hits.size());
EXPECT_EQ(hits[0].wordpos(), 2u);
@@ -522,6 +534,7 @@ void assertInt64Range(const std::string &term, bool expAdjusted, int64_t expLow,
EXPECT_EQ(expHigh, (int64_t)res.high);
}
+
TEST(StreamingQueryTest, require_that_int8_limits_are_enforced)
{
//std::numeric_limits<int8_t>::min() -> -128
@@ -607,6 +620,20 @@ TEST(StreamingQueryTest, require_that_we_can_take_floating_point_values_in_range
assertInt64Range("[1.7976931348623157E308;-1.7976931348623157E308]", false, std::numeric_limits<int64_t>::max(), std::numeric_limits<int64_t>::min());
}
+void assertIllegalRangeQueries(const QueryTermSimple & qt) {
+ QueryTermSimple::RangeResult<int64_t> ires = qt.getRange<int64_t>();
+ EXPECT_EQ(false, ires.valid);
+ QueryTermSimple::RangeResult<double> fres = qt.getRange<double>();
+ EXPECT_EQ(false, fres.valid);
+}
+
+TEST(StreamingQueryTest, require_safe_parsing_of_illegal_ranges) {
+ // The 2 below are created when naively splitting numeric terms by dot.
+ // T=A.B => T EQUIV PHRASE(A, B)
+ assertIllegalRangeQueries(QueryTermSimple("[1", TermType::WORD));
+ assertIllegalRangeQueries(QueryTermSimple(".1;2.1]", TermType::WORD));
+}
+
TEST(StreamingQueryTest, require_that_we_handle_empty_range_as_expected)
{
assertInt64Range("[1;1]", false, 1, 1);
@@ -627,11 +654,11 @@ TEST(StreamingQueryTest, require_that_ascending_range_can_be_specified_with_limi
QueryTerm ascending_query(eqnr.create(), "[;;500]", "index", TermType::WORD);
EXPECT_TRUE(ascending_query.getAsIntegerTerm(low_integer, high_integer));
- EXPECT_TRUE(ascending_query.getAsDoubleTerm(low_double, high_double));
+ EXPECT_TRUE(ascending_query.getAsFloatTerm(low_double, high_double));
EXPECT_EQ(std::numeric_limits<int64_t>::min(), low_integer);
EXPECT_EQ(std::numeric_limits<int64_t>::max(), high_integer);
- EXPECT_EQ(-std::numeric_limits<double>::max(), low_double);
- EXPECT_EQ(std::numeric_limits<double>::max(), high_double);
+ EXPECT_EQ(-std::numeric_limits<double>::infinity(), low_double);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), high_double);
EXPECT_EQ(500, ascending_query.getRangeLimit());
}
@@ -646,11 +673,11 @@ TEST(StreamingQueryTest, require_that_descending_range_can_be_specified_with_lim
QueryTerm descending_query(eqnr.create(), "[;;-500]", "index", TermType::WORD);
EXPECT_TRUE(descending_query.getAsIntegerTerm(low_integer, high_integer));
- EXPECT_TRUE(descending_query.getAsDoubleTerm(low_double, high_double));
+ EXPECT_TRUE(descending_query.getAsFloatTerm(low_double, high_double));
EXPECT_EQ(std::numeric_limits<int64_t>::min(), low_integer);
EXPECT_EQ(std::numeric_limits<int64_t>::max(), high_integer);
- EXPECT_EQ(-std::numeric_limits<double>::max(), low_double);
- EXPECT_EQ(std::numeric_limits<double>::max(), high_double);
+ EXPECT_EQ(-std::numeric_limits<double>::infinity(), low_double);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), high_double);
EXPECT_EQ(-500, descending_query.getRangeLimit());
}
@@ -735,7 +762,7 @@ TEST(StreamingQueryTest, require_that_incorrectly_specified_diversity_can_be_par
TEST(StreamingQueryTest, require_that_we_do_not_break_the_stack_on_bad_query)
{
- QueryTermSimple term("<form><iframe+&#09;&#10;&#11;+src=\\\"javascript&#58;alert(1)\\\"&#11;&#10;&#09;;>", TermType::WORD);
+ QueryTermSimple term(R"(<form><iframe+&#09;&#10;&#11;+src=\"javascript&#58;alert(1)\"&#11;&#10;&#09;;>)", TermType::WORD);
EXPECT_FALSE(term.isValid());
}
@@ -744,7 +771,7 @@ TEST(StreamingQueryTest, a_unhandled_sameElement_stack)
const char * stack = "\022\002\026xyz_abcdefghij_xyzxyzxQ\001\vxxxxxx_name\034xxxxxx_xxxx_xxxxxxx_xxxxxxxxE\002\005delta\b<0.00393";
vespalib::stringref stackDump(stack);
EXPECT_EQ(85u, stackDump.size());
- AllowRewrite empty;
+ AllowRewrite empty("");
const Query q(empty, stackDump);
EXPECT_TRUE(q.valid());
const QueryNode & root = q.getRoot();
@@ -778,7 +805,7 @@ TEST(StreamingQueryTest, test_same_element_evaluate)
vespalib::string stackDump = StackDumpCreator::create(*node);
QueryNodeResultFactory empty;
Query q(empty, stackDump);
- SameElementQueryNode * sameElem = dynamic_cast<SameElementQueryNode *>(&q.getRoot());
+ auto * sameElem = dynamic_cast<SameElementQueryNode *>(&q.getRoot());
EXPECT_TRUE(sameElem != nullptr);
EXPECT_EQ("field", sameElem->getIndex());
EXPECT_EQ(3u, sameElem->size());
diff --git a/searchlib/src/vespa/searchlib/query/query_term_simple.cpp b/searchlib/src/vespa/searchlib/query/query_term_simple.cpp
index b7a1719fb5f..e6cea9c752b 100644
--- a/searchlib/src/vespa/searchlib/query/query_term_simple.cpp
+++ b/searchlib/src/vespa/searchlib/query/query_term_simple.cpp
@@ -4,18 +4,66 @@
#include "base.h"
#include <vespa/vespalib/objects/visit.h>
#include <vespa/vespalib/util/classname.h>
-#include <vespa/vespalib/locale/c.h>
#include <cmath>
#include <limits>
+#include <charconv>
namespace {
template <typename N>
-bool isValidInteger(int64_t value)
+constexpr bool isValidInteger(int64_t value) noexcept
{
- return value >= std::numeric_limits<N>::min() && value <= std::numeric_limits<N>::max();
+ return (value >= std::numeric_limits<N>::min()) &&
+ (value <= std::numeric_limits<N>::max());
}
+constexpr bool isRepresentableByInt64(double d) noexcept {
+ return (d > double(std::numeric_limits<int64_t>::min())) &&
+ (d < double(std::numeric_limits<int64_t>::max()));
+}
+
+bool isFullRange(vespalib::stringref s) noexcept {
+ const size_t sz(s.size());
+ return (sz >= 3u) &&
+ (s[0] == '<' || s[0] == '[') &&
+ (s[sz-1] == '>' || s[sz-1] == ']');
+}
+
+struct IntDecoder {
+ static int64_t fromstr(const char * q, const char * qend, const char ** end) noexcept {
+ int64_t v(0);
+ for (;q < qend && (isspace(*q) || (*q == '+')); q++);
+ std::from_chars_result err = std::from_chars(q, qend, v, 10);
+ if (err.ec == std::errc::result_out_of_range) {
+ v = (*q == '-') ? std::numeric_limits<int64_t>::min() : std::numeric_limits<int64_t>::max();
+ }
+ *end = err.ptr;
+ return v;
+ }
+ static int64_t nearestDownwd(int64_t n, int64_t min) noexcept { return (n > min ? n - 1 : n); }
+ static int64_t nearestUpward(int64_t n, int64_t max) noexcept { return (n < max ? n + 1 : n); }
+};
+
+template <typename T>
+struct FloatDecoder {
+ static T fromstr(const char * q, const char * qend, const char ** end) noexcept {
+ T v(0);
+ for (;q < qend && (isspace(*q) || (*q == '+')); q++);
+ std::from_chars_result err = std::from_chars(q, qend, v);
+ if (err.ec == std::errc::result_out_of_range) {
+ v = (*q == '-') ? -std::numeric_limits<T>::infinity() : std::numeric_limits<T>::infinity();
+ }
+ *end = err.ptr;
+ return v;
+ }
+ static T nearestDownwd(T n, T min) noexcept {
+ return std::nextafter(n, min);
+ }
+ static T nearestUpward(T n, T max) noexcept {
+ return std::nextafter(n, max);
+ }
+};
+
}
namespace search {
@@ -29,15 +77,15 @@ QueryTermSimple::visitMembers(vespalib::ObjectVisitor & visitor) const
template <typename N>
QueryTermSimple::RangeResult<N>
-QueryTermSimple::getFloatRange() const
+QueryTermSimple::getFloatRange() const noexcept
{
- double lowRaw, highRaw;
- bool valid = getAsDoubleTerm(lowRaw, highRaw);
+ N lowRaw, highRaw;
+ bool valid = getAsFloatTerm(lowRaw, highRaw);
RangeResult<N> res;
res.valid = valid;
if (!valid) {
- res.low = std::numeric_limits<N>::max();
- res.high = - std::numeric_limits<N>::max();
+ res.low = std::numeric_limits<N>::infinity();
+ res.high = -std::numeric_limits<N>::infinity();
res.adjusted = true;
} else {
res.low = lowRaw;
@@ -46,25 +94,16 @@ QueryTermSimple::getFloatRange() const
return res;
}
-namespace {
-
-bool isRepresentableByInt64(double d) {
- return (d > double(std::numeric_limits<int64_t>::min()))
- && (d < double(std::numeric_limits<int64_t>::max()));
-}
-
-}
-
bool
-QueryTermSimple::getRangeInternal(int64_t & low, int64_t & high) const
+QueryTermSimple::getRangeInternal(int64_t & low, int64_t & high) const noexcept
{
bool valid = getAsIntegerTerm(low, high);
if ( ! valid ) {
double l(0), h(0);
- valid = getAsDoubleTerm(l, h);
+ valid = getAsFloatTerm(l, h);
if (valid) {
if ((l == h) && isRepresentableByInt64(l)) {
- low = high = std::round(l);
+ low = high = static_cast<int64_t>(std::round(l));
} else {
if (l > double(std::numeric_limits<int64_t>::min())) {
if (l < double(std::numeric_limits<int64_t>::max())) {
@@ -88,7 +127,7 @@ QueryTermSimple::getRangeInternal(int64_t & low, int64_t & high) const
template <typename N>
QueryTermSimple::RangeResult<N>
-QueryTermSimple::getIntegerRange() const
+QueryTermSimple::getIntegerRange() const noexcept
{
int64_t lowRaw, highRaw;
bool valid = getRangeInternal(lowRaw, highRaw);
@@ -121,83 +160,72 @@ QueryTermSimple::getIntegerRange() const
template <>
QueryTermSimple::RangeResult<float>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getFloatRange<float>();
}
template <>
QueryTermSimple::RangeResult<double>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getFloatRange<double>();
}
template <>
QueryTermSimple::RangeResult<int8_t>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getIntegerRange<int8_t>();
}
template <>
QueryTermSimple::RangeResult<int16_t>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getIntegerRange<int16_t>();
}
template <>
QueryTermSimple::RangeResult<int32_t>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getIntegerRange<int32_t>();
}
template <>
QueryTermSimple::RangeResult<int64_t>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getIntegerRange<int64_t>();
}
-template <int B>
-struct IntDecoder {
- static int64_t fromstr(const char * v, char ** end) { return strtoll(v, end, B); }
- static int64_t nearestDownwd(int64_t n, int64_t min) { return (n > min ? n - 1 : n); }
- static int64_t nearestUpward(int64_t n, int64_t max) { return (n < max ? n + 1 : n); }
-};
-
-struct DoubleDecoder {
- static double fromstr(const char * v, char ** end) { return vespalib::locale::c::strtod(v, end); }
- static double nearestDownwd(double n, double min) { return std::nextafterf(n, min); }
- static double nearestUpward(double n, double max) { return std::nextafterf(n, max); }
-};
-
-bool QueryTermSimple::getAsIntegerTerm(int64_t & lower, int64_t & upper) const
+bool QueryTermSimple::getAsIntegerTerm(int64_t & lower, int64_t & upper) const noexcept
{
lower = std::numeric_limits<int64_t>::min();
upper = std::numeric_limits<int64_t>::max();
- return getAsNumericTerm(lower, upper, IntDecoder<10>());
+ return getAsNumericTerm(lower, upper, IntDecoder());
}
-bool QueryTermSimple::getAsDoubleTerm(double & lower, double & upper) const
+bool QueryTermSimple::getAsFloatTerm(double & lower, double & upper) const noexcept
{
- lower = - std::numeric_limits<double>::max();
- upper = std::numeric_limits<double>::max();
- return getAsNumericTerm(lower, upper, DoubleDecoder());
+ lower = -std::numeric_limits<double>::infinity();
+ upper = std::numeric_limits<double>::infinity();
+ return getAsNumericTerm(lower, upper, FloatDecoder<double>());
+}
+
+bool QueryTermSimple::getAsFloatTerm(float & lower, float & upper) const noexcept
+{
+ lower = -std::numeric_limits<float>::infinity();
+ upper = std::numeric_limits<float>::infinity();
+ return getAsNumericTerm(lower, upper, FloatDecoder<float>());
}
QueryTermSimple::~QueryTermSimple() = default;
namespace {
-bool isFullRange(vespalib::stringref s) {
- const size_t sz(s.size());
- return (sz >= 3u) &&
- (s[0] == '<' || s[0] == '[') &&
- (s[sz-1] == '>' || s[sz-1] == ']');
-}
+
}
@@ -232,7 +260,7 @@ QueryTermSimple::QueryTermSimple(const string & term_, Type type)
}
_valid = (numParts >= 2) && (numParts < NELEMS(parts));
if (_valid && numParts > 2) {
- _rangeLimit = strtol(parts[2].data(), nullptr, 0);
+ _rangeLimit = static_cast<int32_t>(strtol(parts[2].data(), nullptr, 0));
if (numParts > 3) {
_valid = (numParts >= 5);
if (_valid) {
@@ -257,48 +285,56 @@ QueryTermSimple::QueryTermSimple(const string & term_, Type type)
template <typename T, typename D>
bool
-QueryTermSimple::getAsNumericTerm(T & lower, T & upper, D d) const
+QueryTermSimple::getAsNumericTerm(T & lower, T & upper, D d) const noexcept
{
- bool valid(empty());
+ if (empty()) return false;
+
size_t sz(_term.size());
- if (sz) {
- char *err(nullptr);
- T low(lower);
- T high(upper);
- const char * q = _term.c_str();
- const char first(q[0]);
- const char last(q[sz-1]);
- q += ((first == '<') || (first == '>') || (first == '[')) ? 1 : 0;
- T ll = d.fromstr(q, &err);
- valid = isValid() && ((*err == 0) || (*err == ';'));
- if (valid) {
- if (first == '<' && (*err == 0)) {
- high = d.nearestDownwd(ll, lower);
- } else if (first == '>' && (*err == 0)) {
- low = d.nearestUpward(ll, upper);
- } else if ((first == '[') || (first == '<')) {
- if (q != err) {
- low = (first == '[') ? ll : d.nearestUpward(ll, upper);
- }
- q = err + 1;
- T hh = d.fromstr(q, &err);
- bool hasUpperLimit(q != err);
- if (*err == ';') {
- err = const_cast<char *>(_term.end() - 1);
- }
- valid = (*err == last) && ((last == ']') || (last == '>'));
- if (hasUpperLimit) {
- high = (last == ']') ? hh : d.nearestDownwd(hh, lower);
- }
- } else {
- low = high = ll;
- }
+ const char *err(nullptr);
+ T low(lower);
+ T high(upper);
+ const char * q = _term.c_str();
+ const char * qend = q + sz;
+ const char first(q[0]);
+ const char last(q[sz-1]);
+ bool isRange = (first == '<') || (first == '>') || (first == '[');
+ q += isRange ? 1 : 0;
+ T ll = d.fromstr(q, qend, &err);
+ bool valid = isValid() && ((*err == 0) || (*err == ';'));
+ if (!valid) return false;
+
+ if (*err == 0) {
+ if (first == '<') {
+ high = d.nearestDownwd(ll, lower);
+ } else if (first == '>') {
+ low = d.nearestUpward(ll, upper);
+ } else {
+ low = high = ll;
+ valid = ! isRange;
}
- if (valid) {
- lower = low;
- upper = high;
+ } else {
+ if ((first == '[') || (first == '<')) {
+ if (q != err) {
+ low = (first == '[') ? ll : d.nearestUpward(ll, upper);
+ }
+ q = err + 1;
+ T hh = d.fromstr(q, qend, &err);
+ bool hasUpperLimit(q != err);
+ if (*err == ';') {
+ err = const_cast<char *>(_term.end() - 1);
+ }
+ valid = (*err == last) && ((last == ']') || (last == '>'));
+ if (hasUpperLimit) {
+ high = (last == ']') ? hh : d.nearestDownwd(hh, lower);
+ }
+ } else {
+ valid = false;
}
}
+ if (valid) {
+ lower = low;
+ upper = high;
+ }
return valid;
}
diff --git a/searchlib/src/vespa/searchlib/query/query_term_simple.h b/searchlib/src/vespa/searchlib/query/query_term_simple.h
index 2b64e3812ab..87bf7c26b80 100644
--- a/searchlib/src/vespa/searchlib/query/query_term_simple.h
+++ b/searchlib/src/vespa/searchlib/query/query_term_simple.h
@@ -33,8 +33,8 @@ public:
N high;
bool valid; // Whether parsing of the range was successful
bool adjusted; // Whether the low and high was adjusted according to min and max limits of the given type.
- RangeResult() : low(), high(), valid(true), adjusted(false) {}
- bool isEqual() const { return low == high; }
+ RangeResult() noexcept : low(), high(), valid(true), adjusted(false) {}
+ bool isEqual() const noexcept { return low == high; }
};
QueryTermSimple(const QueryTermSimple &) = delete;
@@ -47,39 +47,40 @@ public:
* Extracts the content of this query term as a range with low and high values.
*/
template <typename N>
- RangeResult<N> getRange() const;
- int getRangeLimit() const { return _rangeLimit; }
- size_t getMaxPerGroup() const { return _maxPerGroup; }
- size_t getDiversityCutoffGroups() const { return _diversityCutoffGroups; }
- bool getDiversityCutoffStrict() const { return _diversityCutoffStrict; }
- vespalib::stringref getDiversityAttribute() const { return _diversityAttribute; }
- size_t getFuzzyMaxEditDistance() const { return _fuzzyMaxEditDistance; }
- size_t getFuzzyPrefixLength() const { return _fuzzyPrefixLength; }
- bool getAsIntegerTerm(int64_t & lower, int64_t & upper) const;
- bool getAsDoubleTerm(double & lower, double & upper) const;
- const char * getTerm() const { return _term.c_str(); }
- bool isPrefix() const { return (_type == Type::PREFIXTERM); }
- bool isSubstring() const { return (_type == Type::SUBSTRINGTERM); }
- bool isExactstring() const { return (_type == Type::EXACTSTRINGTERM); }
- bool isSuffix() const { return (_type == Type::SUFFIXTERM); }
- bool isWord() const { return (_type == Type::WORD); }
- bool isRegex() const { return (_type == Type::REGEXP); }
- bool isGeoLoc() const { return (_type == Type::GEO_LOCATION); }
- bool isFuzzy() const { return (_type == Type::FUZZYTERM); }
+ RangeResult<N> getRange() const noexcept;
+ int getRangeLimit() const noexcept { return _rangeLimit; }
+ size_t getMaxPerGroup() const noexcept { return _maxPerGroup; }
+ size_t getDiversityCutoffGroups() const noexcept { return _diversityCutoffGroups; }
+ bool getDiversityCutoffStrict() const noexcept { return _diversityCutoffStrict; }
+ vespalib::stringref getDiversityAttribute() const noexcept { return _diversityAttribute; }
+ size_t getFuzzyMaxEditDistance() const noexcept { return _fuzzyMaxEditDistance; }
+ size_t getFuzzyPrefixLength() const noexcept { return _fuzzyPrefixLength; }
+ bool getAsIntegerTerm(int64_t & lower, int64_t & upper) const noexcept;
+ bool getAsFloatTerm(double & lower, double & upper) const noexcept;
+ bool getAsFloatTerm(float & lower, float & upper) const noexcept;
+ const char * getTerm() const noexcept { return _term.c_str(); }
+ bool isPrefix() const noexcept { return (_type == Type::PREFIXTERM); }
+ bool isSubstring() const noexcept { return (_type == Type::SUBSTRINGTERM); }
+ bool isExactstring() const noexcept { return (_type == Type::EXACTSTRINGTERM); }
+ bool isSuffix() const noexcept { return (_type == Type::SUFFIXTERM); }
+ bool isWord() const noexcept { return (_type == Type::WORD); }
+ bool isRegex() const noexcept { return (_type == Type::REGEXP); }
+ bool isGeoLoc() const noexcept { return (_type == Type::GEO_LOCATION); }
+ bool isFuzzy() const noexcept { return (_type == Type::FUZZYTERM); }
bool is_nearest_neighbor() const noexcept { return (_type == Type::NEAREST_NEIGHBOR); }
- bool empty() const { return _term.empty(); }
+ bool empty() const noexcept { return _term.empty(); }
virtual void visitMembers(vespalib::ObjectVisitor &visitor) const;
vespalib::string getClassName() const;
- bool isValid() const { return _valid; }
- const string & getTermString() const { return _term; }
+ bool isValid() const noexcept { return _valid; }
+ const string & getTermString() const noexcept { return _term; }
private:
- bool getRangeInternal(int64_t & low, int64_t & high) const;
+ bool getRangeInternal(int64_t & low, int64_t & high) const noexcept;
template <typename N>
- RangeResult<N> getIntegerRange() const;
+ RangeResult<N> getIntegerRange() const noexcept;
template <typename N>
- RangeResult<N> getFloatRange() const;
- int _rangeLimit;
+ RangeResult<N> getFloatRange() const noexcept;
+ int32_t _rangeLimit;
uint32_t _maxPerGroup;
uint32_t _diversityCutoffGroups;
Type _type;
@@ -88,7 +89,7 @@ private:
string _term;
stringref _diversityAttribute;
template <typename T, typename D>
- bool getAsNumericTerm(T & lower, T & upper, D d) const;
+ bool getAsNumericTerm(T & lower, T & upper, D d) const noexcept;
protected:
uint32_t _fuzzyMaxEditDistance; // set in QueryTerm
diff --git a/searchlib/src/vespa/searchlib/query/streaming/query.cpp b/searchlib/src/vespa/searchlib/query/streaming/query.cpp
index d2eee5d345f..3079ec31e8f 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/query.cpp
+++ b/searchlib/src/vespa/searchlib/query/streaming/query.cpp
@@ -12,7 +12,7 @@ QueryConnector::visitMembers(vespalib::ObjectVisitor &visitor) const
visit(visitor, "Operator", _opName);
}
-QueryConnector::QueryConnector(const char * opName)
+QueryConnector::QueryConnector(const char * opName) noexcept
: QueryNode(),
_opName(opName),
_index(),
@@ -31,7 +31,7 @@ const HitList &
QueryConnector::evaluateHits(HitList & hl) const
{
if (evaluate()) {
- hl.push_back(Hit(1, 0, 0, 1));
+ hl.emplace_back(1, 0, 0, 1);
}
return hl;
}
@@ -105,10 +105,10 @@ QueryConnector::create(ParseItem::ItemType type)
{
switch (type) {
case search::ParseItem::ITEM_AND: return std::make_unique<AndQueryNode>();
- case search::ParseItem::ITEM_OR: return std::make_unique<OrQueryNode>();
+ case search::ParseItem::ITEM_OR:
case search::ParseItem::ITEM_WEAK_AND: return std::make_unique<OrQueryNode>();
+ case search::ParseItem::ITEM_WEIGHTED_SET:
case search::ParseItem::ITEM_EQUIV: return std::make_unique<EquivQueryNode>();
- case search::ParseItem::ITEM_WEIGHTED_SET: return std::make_unique<EquivQueryNode>();
case search::ParseItem::ITEM_WAND: return std::make_unique<OrQueryNode>();
case search::ParseItem::ITEM_NOT: return std::make_unique<AndNotQueryNode>();
case search::ParseItem::ITEM_PHRASE: return std::make_unique<PhraseQueryNode>();
@@ -340,7 +340,7 @@ Query::Query(const QueryNodeResultFactory & factory, vespalib::stringref queryRe
bool
Query::evaluate() const {
- return valid() ? _root->evaluate() : false;
+ return valid() && _root->evaluate();
}
bool
diff --git a/searchlib/src/vespa/searchlib/query/streaming/query.h b/searchlib/src/vespa/searchlib/query/streaming/query.h
index 42c3b94002c..3904f743d26 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/query.h
+++ b/searchlib/src/vespa/searchlib/query/streaming/query.h
@@ -13,8 +13,8 @@ namespace search::streaming {
class QueryConnector : public QueryNode
{
public:
- QueryConnector(const char * opName);
- ~QueryConnector();
+ explicit QueryConnector(const char * opName) noexcept;
+ ~QueryConnector() override;
const HitList & evaluateHits(HitList & hl) const override;
void reset() override;
void getLeaves(QueryTermList & tl) override;
@@ -44,7 +44,7 @@ private:
class TrueNode : public QueryConnector
{
public:
- TrueNode() : QueryConnector("AND") { }
+ TrueNode() noexcept : QueryConnector("AND") { }
bool evaluate() const override;
};
@@ -52,7 +52,7 @@ public:
class FalseNode : public QueryConnector
{
public:
- FalseNode() : QueryConnector("AND") { }
+ FalseNode() noexcept : QueryConnector("AND") { }
bool evaluate() const override;
};
@@ -62,8 +62,8 @@ public:
class AndQueryNode : public QueryConnector
{
public:
- AndQueryNode() : QueryConnector("AND") { }
- AndQueryNode(const char * opName) : QueryConnector(opName) { }
+ AndQueryNode() noexcept : QueryConnector("AND") { }
+ explicit AndQueryNode(const char * opName) noexcept : QueryConnector(opName) { }
bool evaluate() const override;
bool isFlattenable(ParseItem::ItemType type) const override { return type == ParseItem::ITEM_AND; }
};
@@ -74,7 +74,7 @@ public:
class AndNotQueryNode : public QueryConnector
{
public:
- AndNotQueryNode() : QueryConnector("ANDNOT") { }
+ AndNotQueryNode() noexcept : QueryConnector("ANDNOT") { }
bool evaluate() const override;
bool isFlattenable(ParseItem::ItemType type) const override { return type == ParseItem::ITEM_NOT; }
};
@@ -85,8 +85,8 @@ public:
class OrQueryNode : public QueryConnector
{
public:
- OrQueryNode() : QueryConnector("OR") { }
- OrQueryNode(const char * opName) : QueryConnector(opName) { }
+ OrQueryNode() noexcept : QueryConnector("OR") { }
+ explicit OrQueryNode(const char * opName) noexcept : QueryConnector(opName) { }
bool evaluate() const override;
bool isFlattenable(ParseItem::ItemType type) const override {
return (type == ParseItem::ITEM_OR) ||
@@ -102,7 +102,7 @@ public:
class EquivQueryNode : public OrQueryNode
{
public:
- EquivQueryNode() : OrQueryNode("EQUIV") { }
+ EquivQueryNode() noexcept : OrQueryNode("EQUIV") { }
bool evaluate() const override;
bool isFlattenable(ParseItem::ItemType type) const override {
return (type == ParseItem::ITEM_EQUIV) ||
@@ -117,7 +117,7 @@ public:
class PhraseQueryNode : public AndQueryNode
{
public:
- PhraseQueryNode() : AndQueryNode("PHRASE"), _fieldInfo(32) { }
+ PhraseQueryNode() noexcept : AndQueryNode("PHRASE"), _fieldInfo(32) { }
bool evaluate() const override;
const HitList & evaluateHits(HitList & hl) const override;
void getPhrases(QueryNodeRefList & tl) override;
@@ -138,7 +138,7 @@ private:
class SameElementQueryNode : public AndQueryNode
{
public:
- SameElementQueryNode() : AndQueryNode("SAME_ELEMENT") { }
+ SameElementQueryNode() noexcept : AndQueryNode("SAME_ELEMENT") { }
bool evaluate() const override;
const HitList & evaluateHits(HitList & hl) const override;
bool isFlattenable(ParseItem::ItemType type) const override { return type == ParseItem::ITEM_NOT; }
@@ -151,8 +151,8 @@ public:
class NearQueryNode : public AndQueryNode
{
public:
- NearQueryNode() : AndQueryNode("NEAR"), _distance(0) { }
- NearQueryNode(const char * opName) : AndQueryNode(opName), _distance(0) { }
+ NearQueryNode() noexcept : AndQueryNode("NEAR"), _distance(0) { }
+ explicit NearQueryNode(const char * opName) noexcept : AndQueryNode(opName), _distance(0) { }
bool evaluate() const override;
void distance(size_t dist) { _distance = dist; }
size_t distance() const { return _distance; }
@@ -169,8 +169,7 @@ private:
class ONearQueryNode : public NearQueryNode
{
public:
- ONearQueryNode() : NearQueryNode("ONEAR") { }
- ~ONearQueryNode() { }
+ ONearQueryNode() noexcept : NearQueryNode("ONEAR") { }
bool evaluate() const override;
};
diff --git a/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp b/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp
index db0fbd5b98e..9484999f45a 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp
+++ b/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp
@@ -13,12 +13,18 @@ LOG_SETUP(".vsm.querynode");
namespace search::streaming {
namespace {
- vespalib::stringref DEFAULT("default");
- bool disableRewrite(const QueryNode * qn) {
- return dynamic_cast<const NearQueryNode *> (qn) ||
- dynamic_cast<const PhraseQueryNode *> (qn) ||
- dynamic_cast<const SameElementQueryNode *>(qn);
- }
+
+vespalib::stringref DEFAULT("default");
+bool disableRewrite(const QueryNode * qn) {
+ return dynamic_cast<const NearQueryNode *> (qn) ||
+ dynamic_cast<const PhraseQueryNode *> (qn) ||
+ dynamic_cast<const SameElementQueryNode *>(qn);
+}
+
+bool possibleFloat(const QueryTerm & qt, const QueryTerm::string & term) {
+ return !qt.encoding().isBase10Integer() && qt.encoding().isFloat() && (term.find('.') != QueryTerm::string::npos);
+}
+
}
QueryNode::UP
@@ -43,8 +49,8 @@ QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factor
{
qn = QueryConnector::create(type);
if (qn) {
- QueryConnector * qc = dynamic_cast<QueryConnector *> (qn.get());
- NearQueryNode * nqn = dynamic_cast<NearQueryNode *> (qc);
+ auto * qc = dynamic_cast<QueryConnector *> (qn.get());
+ auto * nqn = dynamic_cast<NearQueryNode *> (qc);
if (nqn) {
nqn->distance(queryRep.getNearDistance());
}
@@ -150,21 +156,17 @@ QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factor
qt->setFuzzyMaxEditDistance(queryRep.getFuzzyMaxEditDistance());
qt->setFuzzyPrefixLength(queryRep.getFuzzyPrefixLength());
}
- if (qt->encoding().isBase10Integer() ||
- ! qt->encoding().isFloat() ||
- ! factory.getRewriteFloatTerms() ||
- ! allowRewrite ||
- (ssTerm.find('.') == vespalib::string::npos))
- {
- qn = std::move(qt);
- } else {
+ if (allowRewrite && possibleFloat(*qt, ssTerm) && factory.getRewriteFloatTerms(ssIndex)) {
auto phrase = std::make_unique<PhraseQueryNode>();
- phrase->addChild(std::make_unique<QueryTerm>(factory.create(), ssTerm.substr(0, ssTerm.find('.')), ssIndex, TermType::WORD));
- phrase->addChild(std::make_unique<QueryTerm>(factory.create(), ssTerm.substr(ssTerm.find('.') + 1), ssIndex, TermType::WORD));
+ auto dotPos = ssTerm.find('.');
+ phrase->addChild(std::make_unique<QueryTerm>(factory.create(), ssTerm.substr(0, dotPos), ssIndex, TermType::WORD));
+ phrase->addChild(std::make_unique<QueryTerm>(factory.create(), ssTerm.substr(dotPos + 1), ssIndex, TermType::WORD));
auto orqn = std::make_unique<EquivQueryNode>();
orqn->addChild(std::move(qt));
orqn->addChild(std::move(phrase));
qn = std::move(orqn);
+ } else {
+ qn = std::move(qt);
}
}
}
diff --git a/searchlib/src/vespa/searchlib/query/streaming/querynode.h b/searchlib/src/vespa/searchlib/query/streaming/querynode.h
index 09c44d951d3..bfc840e4603 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/querynode.h
+++ b/searchlib/src/vespa/searchlib/query/streaming/querynode.h
@@ -36,7 +36,7 @@ class QueryNode
public:
using UP = std::unique_ptr<QueryNode>;
- virtual ~QueryNode() { }
+ virtual ~QueryNode() = default;
/// This evalutes if the subtree starting here evaluates to true.
virtual bool evaluate() const = 0;
/// This return the hitList for this subtree. Does only give meaning in a
diff --git a/searchlib/src/vespa/searchlib/query/streaming/querynoderesultbase.h b/searchlib/src/vespa/searchlib/query/streaming/querynoderesultbase.h
index 62fc32a4575..d7704fb60e1 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/querynoderesultbase.h
+++ b/searchlib/src/vespa/searchlib/query/streaming/querynoderesultbase.h
@@ -1,6 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
+#include <vespa/vespalib/stllike/string.h>
#include <memory>
namespace search::streaming {
@@ -20,8 +21,8 @@ public:
class QueryNodeResultFactory {
public:
virtual ~QueryNodeResultFactory() = default;
- virtual bool getRewriteFloatTerms() const { return false; }
- virtual std::unique_ptr<QueryNodeResultBase> create() const { return std::unique_ptr<QueryNodeResultBase>(); }
+ virtual bool getRewriteFloatTerms(vespalib::stringref index) const noexcept { (void) index; return false; }
+ virtual std::unique_ptr<QueryNodeResultBase> create() const { return {}; }
};
}
diff --git a/searchlib/src/vespa/searchlib/query/streaming/queryterm.cpp b/searchlib/src/vespa/searchlib/query/streaming/queryterm.cpp
index 9c45427d07d..a658ff5f3d6 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/queryterm.cpp
+++ b/searchlib/src/vespa/searchlib/query/streaming/queryterm.cpp
@@ -15,6 +15,7 @@ private:
};
CharInfo::CharInfo()
+ : _charInfo()
{
// XXX: Should refactor to reduce number of magic constants.
memset(_charInfo, 0x01, 128); // All 7 bits are ascii7bit
@@ -33,7 +34,7 @@ CharInfo::CharInfo()
_charInfo[uint8_t('E')] = 0x05;
}
-static CharInfo _G_charTable;
+CharInfo _G_charTable;
}
@@ -65,10 +66,10 @@ QueryTerm::QueryTerm(std::unique_ptr<QueryNodeResultBase> org, const string & te
{
if (!termS.empty()) {
uint8_t enc(0xff);
- for (size_t i(0), m(termS.size()); i < m; i++) {
- enc &= _G_charTable.get(termS[i]);
+ for (char c : termS) {
+ enc &= _G_charTable.get(c);
}
- _encoding = enc;
+ _encoding = EncodingBitMap(enc);
}
}
diff --git a/searchlib/src/vespa/searchlib/query/streaming/queryterm.h b/searchlib/src/vespa/searchlib/query/streaming/queryterm.h
index 6e91437b1f9..2d1156a9c51 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/queryterm.h
+++ b/searchlib/src/vespa/searchlib/query/streaming/queryterm.h
@@ -27,7 +27,7 @@ public:
class EncodingBitMap
{
public:
- EncodingBitMap(uint8_t bm=0) : _enc(bm) { }
+ explicit EncodingBitMap(uint8_t bm) : _enc(bm) { }
bool isFloat() const { return _enc & Float; }
bool isBase10Integer() const { return _enc & Base10Integer; }
bool isAscii7Bit() const { return _enc & Ascii7Bit; }
diff --git a/storage/src/vespa/storage/visiting/countvisitor.cpp b/storage/src/vespa/storage/visiting/countvisitor.cpp
index b8b415402d6..fe1569f84da 100644
--- a/storage/src/vespa/storage/visiting/countvisitor.cpp
+++ b/storage/src/vespa/storage/visiting/countvisitor.cpp
@@ -26,10 +26,9 @@ CountVisitor::handleDocuments(const document::BucketId& /*bucketId*/,
DocEntryList& entries,
HitCounter& hitCounter)
{
- for (size_t i = 0; i < entries.size(); ++i) {
- const spi::DocEntry& entry(*entries[i]);
- if (!entry.isRemove()) {
- const document::Document* doc = entry.getDocument();
+ for (const auto & entry : entries) {
+ if (!entry->isRemove()) {
+ const document::Document* doc = entry->getDocument();
if (doc) {
const document::IdString& idString = doc->getId().getScheme();
@@ -57,33 +56,25 @@ CountVisitor::handleDocuments(const document::BucketId& /*bucketId*/,
}
void CountVisitor::completedVisiting(HitCounter&) {
- documentapi::MapVisitorMessage* cmd(new documentapi::MapVisitorMessage());
+ auto cmd = std::make_unique<documentapi::MapVisitorMessage>();
- for (std::map<std::string, int>::iterator iter = _schemeCount.begin();
- iter != _schemeCount.end();
- iter++) {
- cmd->getData().set(vespalib::make_string("scheme.%s", iter->first.c_str()), iter->second);
+ for (const auto & count : _schemeCount) {
+ cmd->getData().set(vespalib::make_string("scheme.%s", count.first.c_str()), count.second);
}
- for (NamespaceCountMap::const_iterator iter = _namespaceCount.begin();
- iter != _namespaceCount.end();
- iter++) {
- cmd->getData().set(vespalib::make_string("namespace.%s", iter->first.c_str()), iter->second);
+ for (const auto & count : _namespaceCount) {
+ cmd->getData().set(vespalib::make_string("namespace.%s", count.first.c_str()), count.second);
}
- for (GroupCountMap::const_iterator iter = _groupCount.begin();
- iter != _groupCount.end();
- iter++) {
- cmd->getData().set(vespalib::make_string("group.%s", iter->first.c_str()), iter->second);
+ for (const auto & count : _groupCount) {
+ cmd->getData().set(vespalib::make_string("group.%s", count.first.c_str()), count.second);
}
- for (std::map<uint64_t, int>::iterator iter = _userCount.begin();
- iter != _userCount.end();
- iter++) {
- cmd->getData().set(vespalib::make_string("user.%" PRIu64, iter->first), iter->second);
+ for (const auto & count : _userCount) {
+ cmd->getData().set(vespalib::make_string("user.%" PRIu64, count.first), count.second);
}
- sendMessage(documentapi::DocumentMessage::UP(cmd));
+ sendMessage(std::move(cmd));
}
}
diff --git a/storage/src/vespa/storageapi/mbusprot/protocolserialization7.cpp b/storage/src/vespa/storageapi/mbusprot/protocolserialization7.cpp
index efbe8c9b42d..57047be6037 100644
--- a/storage/src/vespa/storageapi/mbusprot/protocolserialization7.cpp
+++ b/storage/src/vespa/storageapi/mbusprot/protocolserialization7.cpp
@@ -56,8 +56,8 @@ void set_bucket_info(protobuf::BucketInfo& dest, const api::BucketInfo& src) {
}
document::Bucket get_bucket(const protobuf::Bucket& src) {
- return document::Bucket(document::BucketSpace(src.space_id()),
- document::BucketId(src.raw_bucket_id()));
+ return {document::BucketSpace(src.space_id()),
+ document::BucketId(src.raw_bucket_id())};
}
api::BucketInfo get_bucket_info(const protobuf::BucketInfo& src) {
@@ -953,11 +953,11 @@ void fill_api_apply_diff_vector(std::vector<api::ApplyBucketDiffCommand::Entry>&
dest._docName = proto_entry.document_id();
// TODO consider making buffers std::strings instead to avoid explicit zeroing-on-resize overhead
dest._headerBlob.resize(proto_entry.header_blob().size());
- if (proto_entry.header_blob().size() > 0) {
+ if (!proto_entry.header_blob().empty()) {
memcpy(dest._headerBlob.data(), proto_entry.header_blob().data(), proto_entry.header_blob().size());
}
dest._bodyBlob.resize(proto_entry.body_blob().size());
- if (proto_entry.body_blob().size() > 0) {
+ if (!proto_entry.body_blob().empty()) {
memcpy(dest._bodyBlob.data(), proto_entry.body_blob().data(), proto_entry.body_blob().size());
}
}
diff --git a/storage/src/vespa/storageapi/message/datagram.cpp b/storage/src/vespa/storageapi/message/datagram.cpp
index d2ced1d4b7b..103b7ead08c 100644
--- a/storage/src/vespa/storageapi/message/datagram.cpp
+++ b/storage/src/vespa/storageapi/message/datagram.cpp
@@ -5,8 +5,7 @@
using document::BucketSpace;
-namespace storage {
-namespace api {
+namespace storage::api {
IMPLEMENT_COMMAND(MapVisitorCommand, MapVisitorReply)
IMPLEMENT_REPLY(MapVisitorReply)
@@ -24,11 +23,9 @@ MapVisitorCommand::print(std::ostream& out, bool verbose,
{
out << "MapVisitor(" << _statistics.size() << " entries";
if (verbose) {
- for (vdslib::Parameters::ParametersMap::const_iterator it
- = _statistics.begin(); it != _statistics.end(); ++it)
- {
- out << ",\n" << indent << " " << it->first << ": "
- << vespalib::stringref(it->second.c_str(), it->second.length());
+ for (const auto & stat : _statistics) {
+ out << ",\n" << indent << " " << stat.first << ": "
+ << vespalib::stringref(stat.second.c_str(), stat.second.length());
}
out << ") : ";
StorageCommand::print(out, verbose, indent);
@@ -66,9 +63,9 @@ EmptyBucketsCommand::print(std::ostream& out, bool verbose,
{
out << "EmptyBuckets(";
if (verbose) {
- for (uint32_t i=0; i<_buckets.size(); ++i) {
+ for (const auto & bucket : _buckets) {
out << "\n" << indent << " ";
- out << _buckets[i];
+ out << bucket;
}
} else {
out << _buckets.size() << " buckets";
@@ -96,5 +93,4 @@ EmptyBucketsReply::print(std::ostream& out, bool verbose,
}
}
-} // api
-} // storage
+}
diff --git a/storage/src/vespa/storageapi/message/visitor.h b/storage/src/vespa/storageapi/message/visitor.h
index fddb7604eff..979b8064bd8 100644
--- a/storage/src/vespa/storageapi/message/visitor.h
+++ b/storage/src/vespa/storageapi/message/visitor.h
@@ -58,7 +58,7 @@ public:
/** Create another command with similar visitor settings. */
CreateVisitorCommand(const CreateVisitorCommand& template_);
- ~CreateVisitorCommand();
+ ~CreateVisitorCommand() override;
void setVisitorCmdId(uint32_t id) { _visitorCmdId = id; }
void setControlDestination(vespalib::stringref d) { _controlDestination = d; }
@@ -211,7 +211,7 @@ public:
void setErrorCode(ReturnCode && code) { _error = std::move(code); }
void setCompleted() { _completed = true; }
void setBucketCompleted(const document::BucketId& id, Timestamp lastVisited) {
- _bucketsCompleted.push_back(BucketTimestampPair(id, lastVisited));
+ _bucketsCompleted.emplace_back(id, lastVisited);
}
void setBucketsCompleted(const std::vector<BucketTimestampPair>& bc) {
_bucketsCompleted = bc;
@@ -234,7 +234,7 @@ class VisitorInfoReply : public StorageReply {
bool _completed;
public:
- VisitorInfoReply(const VisitorInfoCommand& cmd);
+ explicit VisitorInfoReply(const VisitorInfoCommand& cmd);
bool visitorCompleted() const { return _completed; }
void print(std::ostream& out, bool verbose, const std::string& indent) const override;
diff --git a/streamingvisitors/src/tests/rank_processor/rank_processor_test.cpp b/streamingvisitors/src/tests/rank_processor/rank_processor_test.cpp
index 2d138d1d336..93e35e4c6d2 100644
--- a/streamingvisitors/src/tests/rank_processor/rank_processor_test.cpp
+++ b/streamingvisitors/src/tests/rank_processor/rank_processor_test.cpp
@@ -40,7 +40,7 @@ protected:
RankProcessorTest::RankProcessorTest()
: testing::Test(),
- _factory(),
+ _factory(nullptr),
_query(),
_query_wrapper()
{
diff --git a/streamingvisitors/src/vespa/searchvisitor/querytermdata.h b/streamingvisitors/src/vespa/searchvisitor/querytermdata.h
index 8c1c3771917..36176f70d1d 100644
--- a/streamingvisitors/src/vespa/searchvisitor/querytermdata.h
+++ b/streamingvisitors/src/vespa/searchvisitor/querytermdata.h
@@ -17,15 +17,26 @@ private:
search::fef::SimpleTermData _termData;
public:
QueryTermData * clone() const override { return new QueryTermData(); }
- search::fef::SimpleTermData &getTermData() { return _termData; }
+ search::fef::SimpleTermData &getTermData() noexcept { return _termData; }
+};
+
+class SearchMethodInfo {
+public:
+ virtual ~SearchMethodInfo() = default;
+ virtual bool is_text_matching(vespalib::stringref index) const noexcept = 0;
};
class QueryTermDataFactory final : public search::streaming::QueryNodeResultFactory {
public:
+ QueryTermDataFactory(const SearchMethodInfo * searchMethodInfo) noexcept : _searchMethodInfo(searchMethodInfo) {}
std::unique_ptr<search::streaming::QueryNodeResultBase> create() const override {
return std::make_unique<QueryTermData>();
}
- bool getRewriteFloatTerms() const override { return true; }
+ bool getRewriteFloatTerms(vespalib::stringref index ) const noexcept override {
+ return _searchMethodInfo && _searchMethodInfo->is_text_matching(index);
+ }
+private:
+ const SearchMethodInfo * _searchMethodInfo;
};
diff --git a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp
index 4d31c71c0a0..49604135afc 100644
--- a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp
+++ b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp
@@ -91,7 +91,7 @@ ForceWordfolderInit::ForceWordfolderInit()
Fast_NormalizeWordFolder::DO_MULTICHAR_EXPANSION);
}
-static ForceWordfolderInit _G_forceNormWordFolderInit;
+static ForceWordfolderInit G_forceNormWordFolderInit;
// Leftovers from FS4 protocol with limited use here.
enum queryflags {
@@ -238,14 +238,16 @@ SearchVisitor::SummaryGenerator::fillSummary(AttributeVector::DocId lid, const H
return {};
}
-void SearchVisitor::HitsResultPreparator::execute(vespalib::Identifiable & obj)
+void
+SearchVisitor::HitsResultPreparator::execute(vespalib::Identifiable & obj)
{
auto & hitsAggr(static_cast<HitsAggregationResult &>(obj));
hitsAggr.setSummaryGenerator(_summaryGenerator);
_numHitsAggregators++;
}
-bool SearchVisitor::HitsResultPreparator::check(const vespalib::Identifiable & obj) const
+bool
+SearchVisitor::HitsResultPreparator::check(const vespalib::Identifiable & obj) const
{
return obj.getClass().inherits(HitsAggregationResult::classId);
}
@@ -259,7 +261,8 @@ SearchVisitor::GroupingEntry::GroupingEntry(Grouping * grouping) :
SearchVisitor::GroupingEntry::~GroupingEntry() = default;
-void SearchVisitor::GroupingEntry::aggregate(const document::Document & doc, search::HitRank rank)
+void
+SearchVisitor::GroupingEntry::aggregate(const document::Document & doc, search::HitRank rank)
{
if (_count < _limit) {
_grouping->aggregate(doc, rank);
@@ -310,7 +313,21 @@ SearchVisitor::SearchVisitor(StorageComponent& component,
LOG(debug, "Created SearchVisitor");
}
-void SearchVisitor::init(const Parameters & params)
+bool
+SearchVisitor::is_text_matching(vespalib::stringref index) const noexcept {
+ StringFieldIdTMap fieldIdMap;
+ _fieldSearchSpecMap.addFieldsFromIndex(index, fieldIdMap);
+ for (const auto & fieldId : fieldIdMap.map()) {
+ auto found = _fieldSearchSpecMap.specMap().find(fieldId.second);
+ if ((found != _fieldSearchSpecMap.specMap().end()) && found->second.uses_string_search_method()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+SearchVisitor::init(const Parameters & params)
{
VISITOR_TRACE(6, "About to lazily init VSM adapter");
_attrMan.add(_documentIdAttributeBacking);
@@ -397,7 +414,14 @@ void SearchVisitor::init(const Parameters & params)
if ( params.lookup("query", queryBlob) ) {
LOG(spam, "Received query blob of %zu bytes", queryBlob.size());
VISITOR_TRACE(9, vespalib::make_string("Setting up for query blob of %zu bytes", queryBlob.size()));
- QueryTermDataFactory addOnFactory;
+ // Create mapping from field name to field id, from field id to search spec,
+ // and from index name to list of field ids
+ _fieldSearchSpecMap.buildFromConfig(_env->get_vsm_fields_config());
+ auto additionalFields = registerAdditionalFields(_env->get_docsum_tools()->getFieldSpecs());
+ // Add extra elements to mapping from field name to field id
+ _fieldSearchSpecMap.buildFromConfig(additionalFields);
+
+ QueryTermDataFactory addOnFactory(this);
_query = Query(addOnFactory, vespalib::stringref(queryBlob.data(), queryBlob.size()));
_searchBuffer->reserve(0x10000);
@@ -408,19 +432,11 @@ void SearchVisitor::init(const Parameters & params)
LOG(warning, "Request without query stack count");
}
- std::vector<vespalib::string> additionalFields;
- registerAdditionalFields(_env->get_docsum_tools()->getFieldSpecs(), additionalFields);
-
- StringFieldIdTMap fieldsInQuery;
- setupFieldSearchers(additionalFields, fieldsInQuery);
-
-
+ StringFieldIdTMap fieldsInQuery = setupFieldSearchers();
setupScratchDocument(fieldsInQuery);
-
_syntheticFieldsController.setup(_fieldSearchSpecMap.nameIdMap(), fieldsInQuery);
setupAttributeVectors();
-
setupAttributeVectorsForSorting(_sortSpec);
_rankController.setRankManagerSnapshot(_env->get_rank_manager_snapshot());
@@ -436,7 +452,6 @@ void SearchVisitor::init(const Parameters & params)
// This depends on _fieldPathMap (from setupScratchDocument),
// and IQueryEnvironment (from setupRankProcessors).
prepare_field_searchers();
-
} else {
LOG(warning, "No query received");
}
@@ -529,10 +544,7 @@ SearchVisitor::PositionInserter::PositionInserter(AttributeVector & attribute, A
SearchVisitor::PositionInserter::~PositionInserter() = default;
void
-SearchVisitor::PositionInserter::onPrimitive(uint32_t, const Content & c)
-{
- (void) c;
-}
+SearchVisitor::PositionInserter::onPrimitive(uint32_t, const Content &) { }
void
SearchVisitor::PositionInserter::onStructStart(const Content & c)
@@ -605,7 +617,6 @@ SearchVisitor::RankController::setupRankProcessors(Query & query,
{
_rankSetup = &_rankManagerSnapshot->getRankSetup(_rankProfile);
_rankProcessor = std::make_unique<RankProcessor>(_rankManagerSnapshot, _rankProfile, query, location, _queryProperties, &attrMan);
- LOG(debug, "Initialize rank processor");
_rankProcessor->initForRanking(wantedHitCount);
// register attribute vectors needed for ranking
processAccessedAttributes(_rankProcessor->get_real_query_env(), true, attrMan, attributeFields);
@@ -637,8 +648,7 @@ SearchVisitor::RankController::rankMatchedDocument(uint32_t docId)
{
_rankProcessor->runRankProgram(docId);
LOG(debug, "Rank score for matched document %u: %f",
- docId,
- _rankProcessor->getRankScore());
+ docId, _rankProcessor->getRankScore());
if (_dumpFeatures) {
_dumpProcessor->runRankProgram(docId);
// we must transfer the score to this match data to make sure that the same hits
@@ -718,9 +728,8 @@ SearchVisitor::SyntheticFieldsController::setup(const StringFieldIdTMap & fieldR
}
void
-SearchVisitor::SyntheticFieldsController::onDocument(StorageDocument & document)
+SearchVisitor::SyntheticFieldsController::onDocument(StorageDocument &)
{
- (void) document;
}
void
@@ -730,10 +739,10 @@ SearchVisitor::SyntheticFieldsController::onDocumentMatch(StorageDocument & docu
document.setField(_documentIdFId, std::make_unique<document::StringFieldValue>(documentId));
}
-void
-SearchVisitor::registerAdditionalFields(const std::vector<vsm::DocsumTools::FieldSpec> & docsumSpec,
- std::vector<vespalib::string> & fieldList)
+std::vector<vespalib::string>
+SearchVisitor::registerAdditionalFields(const std::vector<vsm::DocsumTools::FieldSpec> & docsumSpec)
{
+ std::vector<vespalib::string> fieldList;
for (const vsm::DocsumTools::FieldSpec & spec : docsumSpec) {
fieldList.push_back(spec.getOutputName());
const std::vector<vespalib::string> & inputNames = spec.getInputNames();
@@ -748,25 +757,20 @@ SearchVisitor::registerAdditionalFields(const std::vector<vsm::DocsumTools::Fiel
fieldList.emplace_back("[docid]");
fieldList.emplace_back("[rank]");
fieldList.emplace_back("documentid");
+ return fieldList;
}
-void
-SearchVisitor::setupFieldSearchers(const std::vector<vespalib::string> & additionalFields,
- StringFieldIdTMap & fieldsInQuery)
+StringFieldIdTMap
+SearchVisitor::setupFieldSearchers()
{
- // Create mapping from field name to field id, from field id to search spec,
- // and from index name to list of field ids
- _fieldSearchSpecMap.buildFromConfig(_env->get_vsm_fields_config());
- // Add extra elements to mapping from field name to field id
- _fieldSearchSpecMap.buildFromConfig(additionalFields);
-
// Reconfig field searchers based on the query
_fieldSearchSpecMap.reconfigFromQuery(_query);
// Map field name to field id for all fields in the query
- _fieldSearchSpecMap.buildFieldsInQuery(_query, fieldsInQuery);
+ StringFieldIdTMap fieldsInQuery = _fieldSearchSpecMap.buildFieldsInQuery(_query);
// Connect field names in the query to field searchers
_fieldSearchSpecMap.buildSearcherMap(fieldsInQuery.map(), _fieldSearcherMap);
+ return fieldsInQuery;
}
void
@@ -947,8 +951,7 @@ class SingleDocumentStore : public vsm::IDocSumCache
{
public:
explicit SingleDocumentStore(const StorageDocument & doc) : _doc(doc) { }
- const vsm::Document & getDocSum(const search::DocumentIdT & docId) const override {
- (void) docId;
+ const vsm::Document & getDocSum(const search::DocumentIdT &) const override {
return _doc;
}
private:
@@ -959,19 +962,12 @@ bool
SearchVisitor::compatibleDocumentTypes(const document::DocumentType& typeA,
const document::DocumentType& typeB)
{
- if (&typeA == &typeB) {
- return true;
- } else {
- return (typeA.getName() == typeB.getName());
- }
+ return (&typeA == &typeB) || (typeA.getName() == typeB.getName());
}
void
-SearchVisitor::handleDocuments(const document::BucketId&,
- DocEntryList & entries,
- HitCounter& hitCounter)
+SearchVisitor::handleDocuments(const document::BucketId&, DocEntryList & entries, HitCounter& )
{
- (void) hitCounter;
if (!_init_called) {
init(_params);
}
@@ -1016,37 +1012,25 @@ SearchVisitor::handleDocument(StorageDocument & document)
RankProcessor & rp = *_rankController.getRankProcessor();
vespalib::string documentId(document.docDoc().getId().getScheme().toString());
LOG(debug, "Matched document with id '%s'", documentId.c_str());
-
document.setDocId(rp.getDocId());
-
fillAttributeVectors(documentId, document);
-
_rankController.rankMatchedDocument(rp.getDocId());
-
if (_shouldFillRankAttribute) {
_rankAttribute.add(rp.getRankScore());
}
-
if (_rankController.keepMatchedDocument()) {
-
bool amongTheBest = _rankController.collectMatchedDocument(!_sortList.empty(), *this, _tmpSortBuffer, &document);
-
_syntheticFieldsController.onDocumentMatch(document, documentId);
-
SingleDocumentStore single(document);
_summaryGenerator.setDocsumCache(single);
group(document.docDoc(), rp.getRankScore(), false);
-
if (amongTheBest) {
needToKeepDocument = true;
}
-
} else {
_hitsRejectedCount++;
LOG(debug, "Do not keep document with id '%s' because rank score (%f) <= rank score drop limit (%f)",
- documentId.c_str(),
- rp.getRankScore(),
- _rankController.getRankSetup()->getRankScoreDropLimit());
+ documentId.c_str(), rp.getRankScore(), _rankController.getRankSetup()->getRankScoreDropLimit());
}
} else {
LOG(debug, "Did not match document with id '%s'", document.docDoc().getId().getScheme().toString().c_str());
@@ -1145,7 +1129,8 @@ SearchVisitor::fillSortBuffer()
return pos;
}
-void SearchVisitor::completedBucket(const document::BucketId&, HitCounter&)
+void
+SearchVisitor::completedBucket(const document::BucketId&, HitCounter&)
{
LOG(debug, "Completed bucket");
}
@@ -1157,7 +1142,8 @@ SearchVisitor::generate_query_result(HitCounter& counter)
return std::move(_queryResult);
}
-void SearchVisitor::completedVisitingInternal(HitCounter& hitCounter)
+void
+SearchVisitor::completedVisitingInternal(HitCounter& hitCounter)
{
if (!_init_called) {
init(_params);
diff --git a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h
index ef7a41f23a5..709564bcf02 100644
--- a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h
+++ b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h
@@ -8,6 +8,7 @@
#include "rankmanager.h"
#include "rankprocessor.h"
#include "searchenvironment.h"
+#include "querytermdata.h"
#include <vespa/vsm/common/docsum.h>
#include <vespa/vsm/common/documenttypemapping.h>
#include <vespa/vsm/common/storagedocument.h>
@@ -42,7 +43,8 @@ class SearchEnvironmentSnapshot;
* @brief Visitor that applies a search query to visitor data and
* converts them to a QueryResultCommand.
**/
-class SearchVisitor : public storage::Visitor {
+class SearchVisitor : public storage::Visitor,
+ public SearchMethodInfo {
public:
SearchVisitor(storage::StorageComponent&, storage::VisitorEnvironment& vEnv,
const vdslib::Parameters & params);
@@ -253,19 +255,15 @@ private:
* @param docsumSpec config with the field names used by the docsum setup.
* @param fieldList list of field names that are built.
**/
- static void registerAdditionalFields(const std::vector<vsm::DocsumTools::FieldSpec> & docsumSpec,
- std::vector<vespalib::string> & fieldList);
+ static std::vector<vespalib::string> registerAdditionalFields(const std::vector<vsm::DocsumTools::FieldSpec> & docsumSpec);
/**
* Setup the field searchers used when matching the query with the stream of documents.
* This includes setting up various mappings in FieldSearchSpecMap and building mapping
* for fields used by the query.
*
- * @param additionalFields list of additional field names used when setting up the mappings.
- * @param fieldsInQuery mapping from field name to field id that are built based on the query.
**/
- void setupFieldSearchers(const std::vector<vespalib::string> & additionalFields,
- vsm::StringFieldIdTMap & fieldsInQuery);
+ vsm::StringFieldIdTMap setupFieldSearchers();
/**
* Prepare the field searchers for the given query.
@@ -488,6 +486,7 @@ private:
vsm::StringFieldIdTMapT _fieldsUnion;
void setupAttributeVector(const vsm::FieldPath &fieldPath);
+ bool is_text_matching(vespalib::stringref index) const noexcept override;
};
class SearchVisitorFactory : public storage::VisitorFactory {
diff --git a/streamingvisitors/src/vespa/vsm/searcher/floatfieldsearcher.cpp b/streamingvisitors/src/vespa/vsm/searcher/floatfieldsearcher.cpp
index 7dd40348f47..8558522003f 100644
--- a/streamingvisitors/src/vespa/vsm/searcher/floatfieldsearcher.cpp
+++ b/streamingvisitors/src/vespa/vsm/searcher/floatfieldsearcher.cpp
@@ -37,7 +37,7 @@ void FloatFieldSearcherT<T>::prepare(search::streaming::QueryTermList& qtl,
_floatTerm.clear();
FieldSearcher::prepare(qtl, buf, field_paths, query_env);
for (auto qt : qtl) {
- size_t sz(qt->termLen());
+ size_t sz(qt->termLen());
if (sz) {
auto range = qt->getRange<T>();
_floatTerm.emplace_back(range.low, range.high, range.valid);
diff --git a/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp b/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp
index e33408a2e26..4b0efd58a56 100644
--- a/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp
+++ b/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp
@@ -28,7 +28,8 @@ namespace vsm {
namespace {
-void setMatchType(FieldSearcherContainer & searcher, vespalib::stringref arg1) {
+void
+setMatchType(FieldSearcherContainer & searcher, vespalib::stringref arg1) {
if (arg1 == "prefix") {
searcher->setMatchType(FieldSearcher::PREFIX);
} else if (arg1 == "substring") {
@@ -44,14 +45,14 @@ void setMatchType(FieldSearcherContainer & searcher, vespalib::stringref arg1) {
}
-FieldSearchSpec::FieldSearchSpec() :
- _id(0),
- _name(),
- _maxLength(0x100000),
- _searcher(),
- _searchMethod(VsmfieldsConfig::Fieldspec::Searchmethod::NONE),
- _arg1(),
- _reconfigured(false)
+FieldSearchSpec::FieldSearchSpec()
+ : _id(0),
+ _name(),
+ _maxLength(0x100000),
+ _searcher(),
+ _searchMethod(VsmfieldsConfig::Fieldspec::Searchmethod::NONE),
+ _arg1(),
+ _reconfigured(false)
{
}
FieldSearchSpec::~FieldSearchSpec() = default;
@@ -150,7 +151,8 @@ FieldSearchSpec::reconfig(const QueryTerm & term)
}
}
-vespalib::asciistream & operator <<(vespalib::asciistream & os, const FieldSearchSpec & f)
+vespalib::asciistream &
+operator <<(vespalib::asciistream & os, const FieldSearchSpec & f)
{
os << f._id << ' ' << f._name << ' ';
if ( ! f._searcher) {
@@ -171,7 +173,8 @@ namespace {
const std::regex _G_array("\\[[0-9]+\\]");
}
-vespalib::string FieldSearchSpecMap::stripNonFields(const vespalib::string & rawIndex)
+vespalib::string
+FieldSearchSpecMap::stripNonFields(vespalib::stringref rawIndex)
{
if ((rawIndex.find('[') != vespalib::string::npos) || (rawIndex.find('{') != vespalib::string::npos)) {
std::string index = std::regex_replace(std::string(rawIndex), _G_map1, _G_value);
@@ -182,44 +185,48 @@ vespalib::string FieldSearchSpecMap::stripNonFields(const vespalib::string & raw
return rawIndex;
}
-bool FieldSearchSpecMap::buildFieldsInQuery(const Query & query, StringFieldIdTMap & fieldsInQuery) const
+void
+FieldSearchSpecMap::addFieldsFromIndex(vespalib::stringref rawIndex, StringFieldIdTMap & fieldIdMap) const {
+ for (const auto & dtm : documentTypeMap()) {
+ const IndexFieldMapT & fim = dtm.second;
+ vespalib::string index(stripNonFields(rawIndex));
+ auto fIt = fim.find(index);
+ if (fIt != fim.end()) {
+ for(FieldIdT fid : fIt->second) {
+ const FieldSearchSpec & spec = specMap().find(fid)->second;
+ LOG(debug, "buildFieldsInQuery = rawIndex='%s', index='%s'", rawIndex.data(), index.c_str());
+ if ((rawIndex != index) && (spec.name().find(index) == 0)) {
+ vespalib::string modIndex(rawIndex);
+ modIndex.append(spec.name().substr(index.size()));
+ fieldIdMap.add(modIndex, spec.id());
+ } else {
+ fieldIdMap.add(spec.name(),spec.id());
+ }
+ }
+ } else {
+ LOG(warning, "No valid indexes registered for index %s", rawIndex.data());
+ }
+ }
+}
+
+StringFieldIdTMap
+FieldSearchSpecMap::buildFieldsInQuery(const Query & query) const
{
- bool retval(true);
+ StringFieldIdTMap fieldsInQuery;
ConstQueryTermList qtl;
query.getLeaves(qtl);
for (const auto & term : qtl) {
- for (const auto & dtm : documentTypeMap()) {
- const IndexFieldMapT & fim = dtm.second;
- vespalib::string rawIndex(term->index());
- vespalib::string index(stripNonFields(rawIndex));
- auto fIt = fim.find(index);
- if (fIt != fim.end()) {
- for(FieldIdT fid : fIt->second) {
- const FieldSearchSpec & spec = specMap().find(fid)->second;
- LOG(debug, "buildFieldsInQuery = rawIndex='%s', index='%s'", rawIndex.c_str(), index.c_str());
- if ((rawIndex != index) && (spec.name().find(index) == 0)) {
- vespalib::string modIndex(rawIndex);
- modIndex.append(spec.name().substr(index.size()));
- fieldsInQuery.add(modIndex, spec.id());
- } else {
- fieldsInQuery.add(spec.name(),spec.id());
- }
- }
- } else {
- LOG(warning, "No valid indexes registered for index %s", term->index().c_str());
- retval = false;
- }
- }
+ addFieldsFromIndex(term->index(), fieldsInQuery);
}
- return retval;
+ return fieldsInQuery;
}
-void FieldSearchSpecMap::buildFromConfig(const std::vector<vespalib::string> & otherFieldsNeeded)
+void
+FieldSearchSpecMap::buildFromConfig(const std::vector<vespalib::string> & otherFieldsNeeded)
{
- for(size_t i(0), m(otherFieldsNeeded.size()); i < m; i++) {
- LOG(debug, "otherFieldsNeeded[%zd] = '%s'", i, otherFieldsNeeded[i].c_str());
- _nameIdMap.add(otherFieldsNeeded[i]);
+ for (const auto & i : otherFieldsNeeded) {
+ _nameIdMap.add(i);
}
}
@@ -253,7 +260,8 @@ buildFieldSet(const VsmfieldsConfig::Documenttype::Index & ci, const FieldSearch
}
-bool FieldSearchSpecMap::buildFromConfig(const VsmfieldsHandle & conf)
+bool
+FieldSearchSpecMap::buildFromConfig(const VsmfieldsHandle & conf)
{
bool retval(true);
LOG(spam, "Parsing %zd fields", conf->fieldspec.size());
@@ -297,12 +305,14 @@ FieldSearchSpecMap::reconfigFromQuery(const Query & query)
}
}
-bool lesserField(const FieldSearcherContainer & a, const FieldSearcherContainer & b)
+bool
+lesserField(const FieldSearcherContainer & a, const FieldSearcherContainer & b)
{
return a->field() < b->field();
}
-void FieldSearchSpecMap::buildSearcherMap(const StringFieldIdTMapT & fieldsInQuery, FieldIdTSearcherMap & fieldSearcherMap)
+void
+FieldSearchSpecMap::buildSearcherMap(const StringFieldIdTMapT & fieldsInQuery, FieldIdTSearcherMap & fieldSearcherMap) const
{
fieldSearcherMap.clear();
for (const auto & entry : fieldsInQuery) {
@@ -331,7 +341,8 @@ FieldSearchSpecMap::get_distance_metric(const vespalib::string& name) const
return vsm::NearestNeighborFieldSearcher::distance_metric_from_string(itr->second.get_arg1());
}
-vespalib::asciistream & operator <<(vespalib::asciistream & os, const FieldSearchSpecMap & df)
+vespalib::asciistream &
+operator <<(vespalib::asciistream & os, const FieldSearchSpecMap & df)
{
os << "DocumentTypeMap = \n";
for (const auto & dtm : df.documentTypeMap()) {
diff --git a/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.h b/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.h
index b0154a82dae..43bb5b04481 100644
--- a/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.h
+++ b/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.h
@@ -23,6 +23,11 @@ public:
bool valid() const { return static_cast<bool>(_searcher); }
size_t maxLength() const { return _maxLength; }
bool uses_nearest_neighbor_search_method() const noexcept { return _searchMethod == VsmfieldsConfig::Fieldspec::Searchmethod::NEAREST_NEIGHBOR; }
+ bool uses_string_search_method() const noexcept {
+ return (_searchMethod == VsmfieldsConfig::Fieldspec::Searchmethod::UTF8) ||
+ (_searchMethod == VsmfieldsConfig::Fieldspec::Searchmethod::AUTOUTF8) ||
+ (_searchMethod == VsmfieldsConfig::Fieldspec::Searchmethod::SSE2UTF8);
+ }
const vespalib::string& get_arg1() const noexcept { return _arg1; }
/**
@@ -71,17 +76,13 @@ public:
* Adds a [field name, field id] entry to the given mapping for each field name used in the given query.
* This is achieved by mapping from query term index name -> list of field ids -> [field name, field id] pairs.
**/
- bool buildFieldsInQuery(const search::streaming::Query & query, StringFieldIdTMap & fieldsInQuery) const;
-
- /**
- * Adds a [field name, field id] entry to the given mapping for each field name in the given vector.
- **/
- void buildFieldsInQuery(const std::vector<vespalib::string> & otherFieldsNeeded, StringFieldIdTMap & fieldsInQuery) const;
+ StringFieldIdTMap buildFieldsInQuery(const search::streaming::Query & query) const;
+ void addFieldsFromIndex(vespalib::stringref index, StringFieldIdTMap & fieldIdMap) const;
/**
* Adds a FieldSearcher object to the given field searcher map for each field name in the other map.
**/
- void buildSearcherMap(const StringFieldIdTMapT & fieldsInQuery, FieldIdTSearcherMap & fieldSearcherMap);
+ void buildSearcherMap(const StringFieldIdTMapT & fieldsInQuery, FieldIdTSearcherMap & fieldSearcherMap) const;
const FieldSearchSpecMapT & specMap() const { return _specMap; }
//const IndexFieldMapT & indexMap() const { return _documentTypeMap.begin()->second; }
@@ -89,7 +90,7 @@ public:
const StringFieldIdTMap & nameIdMap() const { return _nameIdMap; }
friend vespalib::asciistream & operator <<(vespalib::asciistream & os, const FieldSearchSpecMap & f);
- static vespalib::string stripNonFields(const vespalib::string & rawIndex);
+ static vespalib::string stripNonFields(vespalib::stringref rawIndex);
search::attribute::DistanceMetric get_distance_metric(const vespalib::string& name) const;
private:
diff --git a/vdslib/src/vespa/vdslib/container/parameters.cpp b/vdslib/src/vespa/vdslib/container/parameters.cpp
index 298f4f6c0d8..236b4970396 100644
--- a/vdslib/src/vespa/vdslib/container/parameters.cpp
+++ b/vdslib/src/vespa/vdslib/container/parameters.cpp
@@ -7,6 +7,7 @@
#include <vespa/vespalib/util/xmlstream.h>
#include <vespa/vespalib/util/growablebytebuffer.h>
#include <ostream>
+#include <charconv>
using namespace vdslib;
@@ -137,13 +138,35 @@ vespalib::string Parameters::toString() const
return ret;
}
-template void vdslib::Parameters::set(vespalib::stringref , int32_t);
-template void vdslib::Parameters::set(vespalib::stringref , int64_t);
-template void vdslib::Parameters::set(vespalib::stringref , uint64_t);
-template void vdslib::Parameters::set(vespalib::stringref , double);
-template void vdslib::Parameters::set(vespalib::stringref , const char *);
-template void vdslib::Parameters::set(vespalib::stringref , vespalib::string);
-template void vdslib::Parameters::set(vespalib::stringref , std::string);
+void
+Parameters::set(KeyT id, int32_t value) {
+ char tmp[16];
+ auto res = std::to_chars(tmp, tmp + sizeof(tmp), value, 10);
+ _parameters[id] = Value(tmp, size_t(res.ptr - tmp));
+}
+
+void
+Parameters::set(KeyT id, int64_t value) {
+ char tmp[32];
+ auto res = std::to_chars(tmp, tmp + sizeof(tmp), value, 10);
+ _parameters[id] = Value(tmp, size_t(res.ptr - tmp));
+}
+
+void
+Parameters::set(KeyT id, uint64_t value) {
+ char tmp[32];
+ auto res = std::to_chars(tmp, tmp + sizeof(tmp), value, 10);
+ _parameters[id] = Value(tmp, size_t(res.ptr - tmp));
+}
+
+void
+Parameters::set(KeyT id, double value) {
+ vespalib::asciistream ost;
+ ost << value;
+ _parameters[id] = Value(ost.str());
+}
+
+
template int32_t vdslib::Parameters::get(vespalib::stringref , int32_t) const;
template int64_t vdslib::Parameters::get(vespalib::stringref , int64_t) const;
template uint64_t vdslib::Parameters::get(vespalib::stringref , uint64_t) const;
diff --git a/vdslib/src/vespa/vdslib/container/parameters.h b/vdslib/src/vespa/vdslib/container/parameters.h
index 854aec4be20..d28e2cd9890 100644
--- a/vdslib/src/vespa/vdslib/container/parameters.h
+++ b/vdslib/src/vespa/vdslib/container/parameters.h
@@ -28,11 +28,11 @@ public:
class Value : public vespalib::string
{
public:
- Value() { }
- Value(vespalib::stringref s) : vespalib::string(s) { }
- Value(const vespalib::string & s) : vespalib::string(s) { }
- Value(const void *v, size_t sz) : vespalib::string(v, sz) { }
- size_t length() const { return size() - 1; }
+ Value() = default;
+ explicit Value(vespalib::stringref s) noexcept : vespalib::string(s) { }
+ explicit Value(const vespalib::string & s) noexcept : vespalib::string(s) { }
+ Value(const void *v, size_t sz) noexcept : vespalib::string(v, sz) { }
+ size_t length() const noexcept { return size() - 1; }
};
using ValueRef = vespalib::stringref;
using ParametersMap = vespalib::hash_map<vespalib::string, Value>;
@@ -43,8 +43,8 @@ private:
public:
Parameters();
- Parameters(document::ByteBuffer& buffer);
- ~Parameters();
+ explicit Parameters(document::ByteBuffer& buffer);
+ ~Parameters() override;
bool operator==(const Parameters &other) const;
@@ -53,7 +53,9 @@ public:
bool hasValue(KeyT id) const { return (_parameters.find(id) != _parameters.end()); }
unsigned int size() const { return _parameters.size(); }
bool lookup(KeyT id, ValueRef & v) const;
- void set(KeyT id, const void * v, size_t sz) { _parameters[id] = Value(v, sz); }
+ void set(KeyT id, const void * v, size_t sz) {
+ _parameters[id] = Value(v, sz);
+ }
void print(std::ostream& out, bool verbose, const std::string& indent) const;
void serialize(vespalib::GrowableByteBuffer& buffer) const;
@@ -63,17 +65,15 @@ public:
ParametersMap::const_iterator begin() const { return _parameters.begin(); }
ParametersMap::const_iterator end() const { return _parameters.end(); }
/// Convenience from earlier use.
- void set(KeyT id, vespalib::stringref value) { _parameters[id] = Value(value.data(), value.size()); }
+ void set(KeyT id, vespalib::stringref value) {
+ _parameters[id] = Value(value.data(), value.size());
+ }
+ void set(KeyT id, int32_t value);
+ void set(KeyT id, int64_t value);
+ void set(KeyT id, uint64_t value);
+ void set(KeyT id, double value);
vespalib::stringref get(KeyT id, vespalib::stringref def = "") const;
- /**
- * Set the value identified by the id given. This requires the type to be
- * convertible by stringstreams.
- *
- * @param id The value to get.
- * @param t The value to save. Will be converted to a string.
- */
- template<typename T>
- void set(KeyT id, T t);
+
/**
* Get the value identified by the id given, as the same type as the default
diff --git a/vdslib/src/vespa/vdslib/container/parameters.hpp b/vdslib/src/vespa/vdslib/container/parameters.hpp
index ae5706046d4..d91612bc094 100644
--- a/vdslib/src/vespa/vdslib/container/parameters.hpp
+++ b/vdslib/src/vespa/vdslib/container/parameters.hpp
@@ -7,14 +7,6 @@
namespace vdslib {
template<typename T>
-void
-Parameters::set(KeyT id, T t) {
- vespalib::asciistream ost;
- ost << t;
- _parameters[id] = ost.str();
-}
-
-template<typename T>
T
Parameters::get(KeyT id, T def) const {
vespalib::stringref ref;
diff --git a/vespa-dependencies-enforcer/allowed-maven-dependencies.txt b/vespa-dependencies-enforcer/allowed-maven-dependencies.txt
index 8ffb4582e5f..472b926b5a1 100644
--- a/vespa-dependencies-enforcer/allowed-maven-dependencies.txt
+++ b/vespa-dependencies-enforcer/allowed-maven-dependencies.txt
@@ -4,8 +4,6 @@ ai.djl.huggingface:tokenizers:${huggingface.vespa.version}
ai.djl:api:${huggingface.vespa.version}
aopalliance:aopalliance:${aopalliance.vespa.version}
backport-util-concurrent:backport-util-concurrent:3.1
-ch.qos.logback:logback-classic:1.2.10
-ch.qos.logback:logback-core:1.2.10
classworlds:classworlds:1.1-alpha-2
com.amazonaws:aws-java-sdk-core:${aws-sdk.vespa.version}
com.amazonaws:aws-java-sdk-kms:${aws-sdk.vespa.version}
@@ -24,7 +22,7 @@ com.github.luben:zstd-jni:${luben.zstd.vespa.version}
com.github.spotbugs:spotbugs-annotations:${spotbugs.vespa.version}
com.google.code.findbugs:jsr305:${findbugs.vespa.version}
com.google.errorprone:error_prone_annotations:${error-prone-annotations.vespa.version}
-com.google.guava:failureaccess:1.0.1
+com.google.guava:failureaccess:${failureaccess.vespa.version}
com.google.guava:guava:${guava.vespa.version}
com.google.inject:guice:${guice.vespa.version}
com.google.j2objc:j2objc-annotations:2.8
@@ -138,7 +136,7 @@ org.codehaus.plexus:plexus-archiver:4.8.0
org.codehaus.plexus:plexus-classworlds:2.7.0
org.codehaus.plexus:plexus-component-annotations:2.1.0
org.codehaus.plexus:plexus-container-default:1.0-alpha-9-stable-1
-org.codehaus.plexus:plexus-interpolation:1.26
+org.codehaus.plexus:plexus-interpolation:${plexus-interpolation.vespa.version}
org.codehaus.plexus:plexus-io:${maven-enforcer-plugin.vespa.version}
org.codehaus.plexus:plexus-utils:${maven-shade-plugin.vespa.version}
org.eclipse.angus:angus-activation:${jakarta.inject.vespa.version}
diff --git a/vespalib/src/vespa/vespalib/locale/locale.h b/vespalib/src/vespa/vespalib/locale/locale.h
index 10ac6144fe7..16aa7a77d98 100644
--- a/vespalib/src/vespa/vespalib/locale/locale.h
+++ b/vespalib/src/vespa/vespalib/locale/locale.h
@@ -14,7 +14,7 @@ public:
Locale(); // Standard C locale, NOT default locale.
Locale(int category, const char *locale);
~Locale();
- locale_t get() const { return _locale; }
+ locale_t get() const noexcept { return _locale; }
private:
locale_t _locale;
};
diff --git a/zookeeper-server/zookeeper-server/pom.xml b/zookeeper-server/zookeeper-server/pom.xml
index 77aec63a781..bb4a819b5ac 100644
--- a/zookeeper-server/zookeeper-server/pom.xml
+++ b/zookeeper-server/zookeeper-server/pom.xml
@@ -45,14 +45,6 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </exclusion>
- <exclusion>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </exclusion>
</exclusions>
</dependency>
<!-- snappy-java and metrics-core are included here