diff --git a/.run/nb --list-drivers.run.xml b/.run/nb --list-drivers.run.xml
new file mode 100644
index 000000000..55872229e
--- /dev/null
+++ b/.run/nb --list-drivers.run.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/nb --list-scenarios.run.xml b/.run/nb --list-scenarios.run.xml
new file mode 100644
index 000000000..f1a7a6734
--- /dev/null
+++ b/.run/nb --list-scenarios.run.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/qdrant_delete_collection_glove_25.run.xml b/.run/qdrant_delete_collection_glove_25.run.xml
new file mode 100644
index 000000000..291ad5032
--- /dev/null
+++ b/.run/qdrant_delete_collection_glove_25.run.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/qdrant_schema_collection_glove_25.run.xml b/.run/qdrant_schema_collection_glove_25.run.xml
new file mode 100644
index 000000000..d1f56cd9f
--- /dev/null
+++ b/.run/qdrant_schema_collection_glove_25.run.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/qdrant_search_points_glove_25.run.xml b/.run/qdrant_search_points_glove_25.run.xml
new file mode 100644
index 000000000..1a8e93b90
--- /dev/null
+++ b/.run/qdrant_search_points_glove_25.run.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/qdrant_upsert_points_glove_25.run.xml b/.run/qdrant_upsert_points_glove_25.run.xml
new file mode 100644
index 000000000..02fd9db2a
--- /dev/null
+++ b/.run/qdrant_upsert_points_glove_25.run.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mvn-defaults/pom.xml b/mvn-defaults/pom.xml
index a51a77576..bcfbe2a0b 100644
--- a/mvn-defaults/pom.xml
+++ b/mvn-defaults/pom.xml
@@ -41,6 +41,8 @@
nb5VERBOSE
+
+ 0.8.12${project.artifactId}
@@ -549,7 +551,7 @@
org.jacocojacoco-maven-plugin
- 0.8.10
+ ${jacoco.version}prepare-agent
@@ -782,7 +784,7 @@
org.jacocojacoco-maven-plugin
- 0.8.10
+ ${jacoco.version}org.apache.maven.plugins
diff --git a/nb-adapters/adapter-milvus/src/main/java/io/nosqlbench/adapter/milvus/MilvusSpace.java b/nb-adapters/adapter-milvus/src/main/java/io/nosqlbench/adapter/milvus/MilvusSpace.java
index 0553126e4..d212c495e 100644
--- a/nb-adapters/adapter-milvus/src/main/java/io/nosqlbench/adapter/milvus/MilvusSpace.java
+++ b/nb-adapters/adapter-milvus/src/main/java/io/nosqlbench/adapter/milvus/MilvusSpace.java
@@ -45,7 +45,7 @@ public class MilvusSpace implements AutoCloseable {
protected MilvusServiceClient client;
- private final Map connections = new HashMap<>();
+// private final Map connections = new HashMap<>();
/**
* Create a new MilvusSpace Object which stores all stateful contextual information needed to interact
diff --git a/nb-adapters/adapter-milvus/src/main/java/io/nosqlbench/adapter/milvus/ops/MilvusCreateCollectionOp.java b/nb-adapters/adapter-milvus/src/main/java/io/nosqlbench/adapter/milvus/ops/MilvusCreateCollectionOp.java
index a8d2bddda..164dc9fdd 100644
--- a/nb-adapters/adapter-milvus/src/main/java/io/nosqlbench/adapter/milvus/ops/MilvusCreateCollectionOp.java
+++ b/nb-adapters/adapter-milvus/src/main/java/io/nosqlbench/adapter/milvus/ops/MilvusCreateCollectionOp.java
@@ -24,7 +24,7 @@ import io.nosqlbench.adapters.api.templating.ParsedOp;
public class MilvusCreateCollectionOp extends MilvusBaseOp {
/**
- * Create a new {@link ParsedOp} encapsulating a call to the Milvus/Zilliz client delete method
+ * Create a new {@link ParsedOp} encapsulating a call to the Milvus/Zilliz client create method.
*
* @param client The associated {@link MilvusServiceClient} used to communicate with the database
* @param request The {@link CreateCollectionParam} built for this operation
diff --git a/nb-adapters/adapter-milvus/src/main/resources/milvus.md b/nb-adapters/adapter-milvus/src/main/resources/milvus.md
index 76e251d50..ed2563ba3 100644
--- a/nb-adapters/adapter-milvus/src/main/resources/milvus.md
+++ b/nb-adapters/adapter-milvus/src/main/resources/milvus.md
@@ -9,12 +9,15 @@ https://github.com/milvus-io/milvus-sdk-java.
The following parameters must be supplied to the adapter at runtime in order to successfully connect to an
instance of the Milvus/Zilliz database:
-* token - In order to use the pinecone database you must have an account. Once the account is created you can [request
+* `token` - In order to use the Milvus/Zilliz database you must have an account. Once the account is created you
+ can [request
an api key/token](https://milvus.io/docs/users_and_roles.md#Users-and-Roles). This key will need to be provided any
- time a
- database connection is desired.
-* uri - When an Index is created in the database the uri must be specified as well. The adapter will
- use the default value of localhost:19530 if none is provided at runtime.
+ time a database connection is desired. Alternatively,
+ the api key can be stored in a file securely and referenced via the `token_file` config option pointing to the path of
+ the file.
+* `uri` - When an index is created in the database the URI/endpoint must be specified as well. The adapter will
+ use the default value of `localhost:19530` if none is provided at runtime.
+* `database_name` or `database` - the name of the database to use. For Zilliz, only `default` is supported.
## Op Templates
diff --git a/nb-adapters/adapter-qdrant/pom.xml b/nb-adapters/adapter-qdrant/pom.xml
new file mode 100644
index 000000000..639a3fdcf
--- /dev/null
+++ b/nb-adapters/adapter-qdrant/pom.xml
@@ -0,0 +1,62 @@
+
+
+ 4.0.0
+
+ adapter-qdrant
+ jar
+
+
+ mvn-defaults
+ io.nosqlbench
+ ${revision}
+ ../../mvn-defaults
+
+
+ ${project.artifactId}
+
+ An nosqlbench adapter driver module for the Qdrant database.
+
+
+
+
+ io.nosqlbench
+ nb-annotations
+ ${revision}
+ compile
+
+
+ io.nosqlbench
+ adapters-api
+ ${revision}
+ compile
+
+
+ io.grpc
+ grpc-protobuf
+
+
+ 1.59.0
+
+
+ com.google.protobuf
+ protobuf-java-util
+
+
+ 3.24.0
+
+
+ com.google.guava
+ guava
+
+
+ 30.1-jre
+
+
+ io.qdrant
+ client
+ 1.9.0
+
+
+
diff --git a/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantAdapterUtils.java b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantAdapterUtils.java
new file mode 100644
index 000000000..1c5a7a5bd
--- /dev/null
+++ b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantAdapterUtils.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2020-2024 nosqlbench
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.nosqlbench.adapter.qdrant;
+
+import io.qdrant.client.grpc.Points.ScoredPoint;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class QdrantAdapterUtils {
+
+ public static final String QDRANT = "qdrant";
+
+ public static List splitNames(String input) {
+ assert StringUtils.isNotBlank(input) && StringUtils.isNotEmpty(input);
+ return Arrays.stream(input.split("( +| *, *)"))
+ .filter(StringUtils::isNotBlank)
+ .toList();
+ }
+
+ public static List splitLongs(String input) {
+ assert StringUtils.isNotBlank(input) && StringUtils.isNotEmpty(input);
+ return Arrays.stream(input.split("( +| *, *)"))
+ .filter(StringUtils::isNotBlank)
+ .map(Long::parseLong)
+ .toList();
+ }
+
+ /**
+ * Mask the digits in the given string with '*'
+ *
+ * @param unmasked The string to mask
+ * @return The masked string
+ */
+ protected static String maskDigits(String unmasked) {
+ assert StringUtils.isNotBlank(unmasked) && StringUtils.isNotEmpty(unmasked);
+ int inputLength = unmasked.length();
+ StringBuilder masked = new StringBuilder(inputLength);
+ for (char ch : unmasked.toCharArray()) {
+ if (Character.isDigit(ch)) {
+ masked.append("*");
+ } else {
+ masked.append(ch);
+ }
+ }
+ return masked.toString();
+ }
+
+ public static int[] searchPointsResponseIdNumToIntArray(List response) {
+ return response.stream().mapToInt(r -> ((Number) r.getId().getNum()).intValue()).toArray();
+ }
+}
diff --git a/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantDriverAdapter.java b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantDriverAdapter.java
new file mode 100644
index 000000000..49933789b
--- /dev/null
+++ b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantDriverAdapter.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020-2024 nosqlbench
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.nosqlbench.adapter.qdrant;
+
+import io.nosqlbench.adapter.qdrant.ops.QdrantBaseOp;
+import io.nosqlbench.adapters.api.activityimpl.OpMapper;
+import io.nosqlbench.adapters.api.activityimpl.uniform.BaseDriverAdapter;
+import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter;
+import io.nosqlbench.nb.annotations.Service;
+import io.nosqlbench.nb.api.components.core.NBComponent;
+import io.nosqlbench.nb.api.config.standard.NBConfigModel;
+import io.nosqlbench.nb.api.config.standard.NBConfiguration;
+import io.nosqlbench.nb.api.labels.NBLabels;
+
+import java.util.function.Function;
+
+import static io.nosqlbench.adapter.qdrant.QdrantAdapterUtils.QDRANT;
+
+@Service(value = DriverAdapter.class, selector = QDRANT)
+public class QdrantDriverAdapter extends BaseDriverAdapter, QdrantSpace> {
+
+ public QdrantDriverAdapter(NBComponent parentComponent, NBLabels labels) {
+ super(parentComponent, labels);
+ }
+
+ @Override
+ public OpMapper> getOpMapper() {
+ return new QdrantOpMapper(this);
+ }
+
+ @Override
+ public Function getSpaceInitializer(NBConfiguration cfg) {
+ return (s) -> new QdrantSpace(s, cfg);
+ }
+
+ @Override
+ public NBConfigModel getConfigModel() {
+ return super.getConfigModel().add(QdrantSpace.getConfigModel());
+ }
+}
diff --git a/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantDriverAdapterLoader.java b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantDriverAdapterLoader.java
new file mode 100644
index 000000000..b861c65c5
--- /dev/null
+++ b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantDriverAdapterLoader.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2020-2024 nosqlbench
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.nosqlbench.adapter.qdrant;
+
+import io.nosqlbench.adapter.diag.DriverAdapterLoader;
+import io.nosqlbench.nb.annotations.Service;
+import io.nosqlbench.nb.api.components.core.NBComponent;
+import io.nosqlbench.nb.api.labels.NBLabels;
+
+import static io.nosqlbench.adapter.qdrant.QdrantAdapterUtils.QDRANT;
+
+@Service(value = DriverAdapterLoader.class, selector = QDRANT)
+public class QdrantDriverAdapterLoader implements DriverAdapterLoader {
+ @Override
+ public QdrantDriverAdapter load(NBComponent parent, NBLabels childLabels) {
+ return new QdrantDriverAdapter(parent, childLabels);
+ }
+}
diff --git a/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantOpMapper.java b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantOpMapper.java
new file mode 100644
index 000000000..3e83cdf58
--- /dev/null
+++ b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantOpMapper.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2020-2024 nosqlbench
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.nosqlbench.adapter.qdrant;
+
+import io.nosqlbench.adapter.qdrant.opdispensers.*;
+import io.nosqlbench.adapter.qdrant.ops.QdrantBaseOp;
+import io.nosqlbench.adapter.qdrant.types.QdrantOpType;
+import io.nosqlbench.adapters.api.activityimpl.OpDispenser;
+import io.nosqlbench.adapters.api.activityimpl.OpMapper;
+import io.nosqlbench.adapters.api.templating.ParsedOp;
+import io.nosqlbench.engine.api.templating.TypeAndTarget;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class QdrantOpMapper implements OpMapper> {
+ private static final Logger logger = LogManager.getLogger(QdrantOpMapper.class);
+ private final QdrantDriverAdapter adapter;
+
+ /**
+ * Create a new QdrantOpMapper implementing the {@link OpMapper} interface.
+ *
+ * @param adapter The associated {@link QdrantDriverAdapter}
+ */
+ public QdrantOpMapper(QdrantDriverAdapter adapter) {
+ this.adapter = adapter;
+ }
+
+ /**
+ * Given an instance of a {@link ParsedOp} returns the appropriate {@link QdrantBaseOpDispenser} subclass
+ *
+ * @param op The {@link ParsedOp} to be evaluated
+ * @return The correct {@link QdrantBaseOpDispenser} subclass based on the op type
+ */
+ @Override
+ public OpDispenser extends QdrantBaseOp>> apply(ParsedOp op) {
+ TypeAndTarget typeAndTarget = op.getTypeAndTarget(
+ QdrantOpType.class,
+ String.class,
+ "type",
+ "target"
+ );
+ logger.info(() -> "Using '" + typeAndTarget.enumId + "' op type for op template '" + op.getName() + "'");
+
+ return switch (typeAndTarget.enumId) {
+ case delete_collection -> new QdrantDeleteCollectionOpDispenser(adapter, op, typeAndTarget.targetFunction);
+ case create_collection -> new QdrantCreateCollectionOpDispenser(adapter, op, typeAndTarget.targetFunction);
+ case create_payload_index ->
+ new QdrantCreatePayloadIndexOpDispenser(adapter, op, typeAndTarget.targetFunction);
+ case search_points -> new QdrantSearchPointsOpDispenser(adapter, op, typeAndTarget.targetFunction);
+ case upsert_points -> new QdrantUpsertPointsOpDispenser(adapter, op, typeAndTarget.targetFunction);
+ case count_points -> new QdrantCountPointsOpDispenser(adapter, op, typeAndTarget.targetFunction);
+// default -> throw new RuntimeException("Unrecognized op type '" + typeAndTarget.enumId.name() + "' while " +
+// "mapping parsed op " + op);
+ };
+ }
+}
diff --git a/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantSpace.java b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantSpace.java
new file mode 100644
index 000000000..32e2ce38f
--- /dev/null
+++ b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/QdrantSpace.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2020-2024 nosqlbench
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.nosqlbench.adapter.qdrant;
+
+import io.nosqlbench.nb.api.config.standard.ConfigModel;
+import io.nosqlbench.nb.api.config.standard.NBConfigModel;
+import io.nosqlbench.nb.api.config.standard.NBConfiguration;
+import io.nosqlbench.nb.api.config.standard.Param;
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.time.Duration;
+
+/**
+ * The {@code QdrantSpace} class is a context object which stores all stateful contextual information needed to interact
+ * with the Qdrant database instance.
+ *
+ * @see Qdrant cloud quick start guide
+ * @see Qdrant quick start guide
+ * @see Qdrant Java client
+ */
+public class QdrantSpace implements AutoCloseable {
+ private final static Logger logger = LogManager.getLogger(QdrantSpace.class);
+ private final String name;
+ private final NBConfiguration cfg;
+
+ protected QdrantClient client;
+
+ /**
+ * Create a new QdrantSpace Object which stores all stateful contextual information needed to interact
+ * with the Qdrant database instance.
+ *
+ * @param name The name of this space
+ * @param cfg The configuration ({@link NBConfiguration}) for this nb run
+ */
+ public QdrantSpace(String name, NBConfiguration cfg) {
+ this.name = name;
+ this.cfg = cfg;
+ }
+
+ public synchronized QdrantClient getClient() {
+ if (client == null) {
+ client = createClient();
+ }
+ return client;
+ }
+
+ private QdrantClient createClient() {
+ String uri = cfg.get("uri");
+ int grpcPort = cfg.getOptional("grpc_port").map(Integer::parseInt).orElse(6334);
+ boolean useTls = cfg.getOptional("use_tls").map(Boolean::parseBoolean).orElse(true);
+
+ var builder = QdrantGrpcClient.newBuilder(uri, grpcPort, useTls);
+ var requiredToken = cfg.getOptional("token_file")
+ .map(Paths::get)
+ .map(
+ tokenFilePath -> {
+ try {
+ return Files.readAllLines(tokenFilePath).getFirst();
+ } catch (IOException e) {
+ String error = "Error while reading token from file:" + tokenFilePath;
+ logger.error(error, e);
+ throw new RuntimeException(e);
+ }
+ }
+ ).orElseGet(
+ () -> cfg.getOptional("token")
+ .orElseThrow(() -> new RuntimeException("You must provide either a token_file or a token to " +
+ "configure a Qdrant client"))
+ );
+ builder = builder.withApiKey(requiredToken);
+ builder = builder.withTimeout(
+ Duration.ofMillis(NumberUtils.toInt(cfg.getOptional("timeout_ms").orElse("3000")))
+ );
+
+ logger.info("{}: Creating new Qdrant Client with (masked) token [{}], uri/endpoint [{}]",
+ this.name, QdrantAdapterUtils.maskDigits(requiredToken), cfg.get("uri").toString());
+ return new QdrantClient(builder.build());
+ }
+
+ public static NBConfigModel getConfigModel() {
+ return ConfigModel.of(QdrantSpace.class)
+ .add(
+ Param.optional("token_file", String.class, "the file to load the api token from")
+ )
+ .add(
+ Param.defaultTo("token", "qdrant")
+ .setDescription("the Qdrant api token to use to connect to the database")
+ )
+ .add(
+ Param.defaultTo("uri", "localhost")
+ .setDescription("the URI endpoint in which the database is running. Do not provide any suffix like https:// here.")
+ )
+ .add(
+ Param.defaultTo("use_tls", true)
+ .setDescription("whether to use TLS for the connection. Defaults to true.")
+ )
+ .add(
+ Param.defaultTo("timeout_ms", 3000)
+ .setDescription("sets the timeout in milliseconds for all requests. Defaults to 3000ms.")
+ )
+ .add(
+ Param.defaultTo("grpc_port", 6443)
+ .setDescription("the port to use for the gRPC connection. Defaults to 6334.")
+ )
+ .asReadOnly();
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (client != null) {
+ client.close();
+ }
+ }
+}
diff --git a/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/opdispensers/QdrantBaseOpDispenser.java b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/opdispensers/QdrantBaseOpDispenser.java
new file mode 100644
index 000000000..fc3937c74
--- /dev/null
+++ b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/opdispensers/QdrantBaseOpDispenser.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2020-2024 nosqlbench
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.nosqlbench.adapter.qdrant.opdispensers;
+
+import io.nosqlbench.adapter.qdrant.QdrantDriverAdapter;
+import io.nosqlbench.adapter.qdrant.QdrantSpace;
+import io.nosqlbench.adapter.qdrant.ops.QdrantBaseOp;
+import io.nosqlbench.adapters.api.activityimpl.BaseOpDispenser;
+import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter;
+import io.nosqlbench.adapters.api.templating.ParsedOp;
+import io.qdrant.client.QdrantClient;
+
+import java.util.function.LongFunction;
+
+public abstract class QdrantBaseOpDispenser extends BaseOpDispenser, QdrantSpace> {
+
+ protected final LongFunction qdrantSpaceFunction;
+ protected final LongFunction clientFunction;
+ private final LongFunction extends QdrantBaseOp> opF;
+ private final LongFunction paramF;
+
+ protected QdrantBaseOpDispenser(QdrantDriverAdapter adapter, ParsedOp op, LongFunction targetF) {
+ super((DriverAdapter)adapter, op);
+ this.qdrantSpaceFunction = adapter.getSpaceFunc(op);
+ this.clientFunction = (long l) -> this.qdrantSpaceFunction.apply(l).getClient();
+ this.paramF = getParamFunc(this.clientFunction,op,targetF);
+ this.opF = createOpFunc(paramF, this.clientFunction, op, targetF);
+ }
+ protected QdrantDriverAdapter getDriverAdapter() {
+ return (QdrantDriverAdapter) adapter;
+ }
+
+ public abstract LongFunction getParamFunc(
+ LongFunction clientF,
+ ParsedOp op,
+ LongFunction targetF
+ );
+
+ public abstract LongFunction> createOpFunc(
+ LongFunction paramF,
+ LongFunction clientF,
+ ParsedOp op,
+ LongFunction targetF
+ );
+
+ @Override
+ public QdrantBaseOp getOp(long value) {
+ return opF.apply(value);
+ }
+}
diff --git a/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/opdispensers/QdrantCountPointsOpDispenser.java b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/opdispensers/QdrantCountPointsOpDispenser.java
new file mode 100644
index 000000000..f0f4edbed
--- /dev/null
+++ b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/opdispensers/QdrantCountPointsOpDispenser.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2020-2024 nosqlbench
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.nosqlbench.adapter.qdrant.opdispensers;
+
+import io.nosqlbench.adapter.qdrant.QdrantDriverAdapter;
+import io.nosqlbench.adapter.qdrant.ops.QdrantBaseOp;
+import io.nosqlbench.adapter.qdrant.ops.QdrantCountPointsOp;
+import io.nosqlbench.adapters.api.templating.ParsedOp;
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.grpc.Points.CountPoints;
+
+import java.util.function.LongFunction;
+
+public class QdrantCountPointsOpDispenser extends QdrantBaseOpDispenser {
+ public QdrantCountPointsOpDispenser(QdrantDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) {
+ super(adapter, op, targetFunction);
+ }
+
+ @Override
+ public LongFunction getParamFunc(
+ LongFunction clientF, ParsedOp op, LongFunction targetF) {
+ LongFunction ebF =
+ l -> CountPoints.newBuilder().setCollectionName(targetF.apply(l));
+
+ final LongFunction lastF = ebF;
+ return l -> lastF.apply(l).build();
+ }
+
+ @Override
+ public LongFunction> createOpFunc(
+ LongFunction paramF,
+ LongFunction clientF,
+ ParsedOp op,
+ LongFunction targetF) {
+ return l -> new QdrantCountPointsOp(clientF.apply(l), paramF.apply(l));
+ }
+}
diff --git a/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/opdispensers/QdrantCreateCollectionOpDispenser.java b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/opdispensers/QdrantCreateCollectionOpDispenser.java
new file mode 100644
index 000000000..e9d162ed9
--- /dev/null
+++ b/nb-adapters/adapter-qdrant/src/main/java/io/nosqlbench/adapter/qdrant/opdispensers/QdrantCreateCollectionOpDispenser.java
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2020-2024 nosqlbench
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.nosqlbench.adapter.qdrant.opdispensers;
+
+import io.nosqlbench.adapter.qdrant.QdrantDriverAdapter;
+import io.nosqlbench.adapter.qdrant.ops.QdrantBaseOp;
+import io.nosqlbench.adapter.qdrant.ops.QdrantCreateCollectionOp;
+import io.nosqlbench.adapters.api.templating.ParsedOp;
+import io.nosqlbench.nb.api.errors.OpConfigError;
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.grpc.Collections.*;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.LongFunction;
+
+public class QdrantCreateCollectionOpDispenser extends QdrantBaseOpDispenser {
+ private static final Logger logger = LogManager.getLogger(QdrantCreateCollectionOpDispenser.class);
+
+ /**
+ * Create a new QdrantCreateCollectionOpDispenser subclassed from {@link QdrantBaseOpDispenser}.
+ *
+ * @param adapter The associated {@link QdrantDriverAdapter}
+ * @param op The {@link ParsedOp} encapsulating the activity for this cycle
+ * @param targetFunction A LongFunction that returns the specified Qdrant Index for this Op
+ * @see Qdrant Create Collection.
+ */
+ public QdrantCreateCollectionOpDispenser(QdrantDriverAdapter adapter,
+ ParsedOp op,
+ LongFunction targetFunction) {
+ super(adapter, op, targetFunction);
+ }
+
+ @Override
+ public LongFunction getParamFunc(
+ LongFunction clientF,
+ ParsedOp op,
+ LongFunction targetF
+ ) {
+ LongFunction ebF =
+ l -> CreateCollection.newBuilder().setCollectionName(targetF.apply(l));
+
+ LongFunction