diff --git a/.run/SCENARIO astra DAPI dapi_novector.run.xml b/.run/SCENARIO astra DAPI dapi_novector.run.xml new file mode 100644 index 000000000..4c2231ff5 --- /dev/null +++ b/.run/SCENARIO astra DAPI dapi_novector.run.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/.run/astra DAPI rampup threads=1.run.xml b/.run/astra DAPI rampup threads=1.run.xml new file mode 100644 index 000000000..e13f0c550 --- /dev/null +++ b/.run/astra DAPI rampup threads=1.run.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/.run/astra DAPI read.run.xml b/.run/astra DAPI read.run.xml new file mode 100644 index 000000000..ae12e2961 --- /dev/null +++ b/.run/astra DAPI read.run.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/nb-adapters/adapter-dataapi/README.md b/nb-adapters/adapter-dataapi/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/nb-adapters/adapter-dataapi/pom.xml b/nb-adapters/adapter-dataapi/pom.xml new file mode 100644 index 000000000..8cd1a0691 --- /dev/null +++ b/nb-adapters/adapter-dataapi/pom.xml @@ -0,0 +1,57 @@ + + + +4.0.0 + +adapter-dataapi +jar + + + mvn-defaults + io.nosqlbench + ${revision} + ../../mvn-defaults + + +${project.artifactId} + + An nosqlbench adapter driver module for the DataStax Data API + + + + + + io.nosqlbench + nb-annotations + ${revision} + compile + + + io.nosqlbench + adapters-api + ${revision} + compile + + + com.datastax.astra + astra-db-java + 1.0.0 + + + + + diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiDriverAdapter.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiDriverAdapter.java new file mode 100644 index 000000000..8c927784e --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiDriverAdapter.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 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.dataapi; + +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +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; + +@Service(value = DriverAdapter.class, selector = "dataapi") +public class DataApiDriverAdapter extends BaseDriverAdapter { + public DataApiDriverAdapter(NBComponent parent, NBLabels childLabels) { + super(parent, childLabels); + } + + @Override + public OpMapper getOpMapper() { + return new DataApiOpMapper(this); + } + + @Override + public Function getSpaceInitializer(NBConfiguration cfg) { + return (s) -> new DataApiSpace(s, cfg); + } + + @Override + public NBConfigModel getConfigModel() { + return super.getConfigModel().add(DataApiSpace.getConfigModel()); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiDriverAdapterLoader.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiDriverAdapterLoader.java new file mode 100644 index 000000000..71f4e8049 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiDriverAdapterLoader.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 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.dataapi; + +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; + +@Service(value = DriverAdapterLoader.class, selector = "dataapi") +public class DataApiDriverAdapterLoader implements DriverAdapterLoader { + @Override + public DataApiDriverAdapter load(NBComponent parent, NBLabels childLabels) { + return new DataApiDriverAdapter(parent, childLabels); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiFindVectorFilterOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiFindVectorFilterOpDispenser.java new file mode 100644 index 000000000..e6cfe4b5d --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiFindVectorFilterOpDispenser.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 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.dataapi; + +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Filter; +import com.datastax.astra.client.model.FindOptions; +import com.datastax.astra.client.model.Projection; +import com.datastax.astra.client.model.Sort; +import io.nosqlbench.adapter.dataapi.opdispensers.DataApiOpDispenser; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiFindVectorFilterOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.function.LongFunction; + +public class DataApiFindVectorFilterOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiFindVectorFilterOpDispenser.class); + private final LongFunction opFunction; + public DataApiFindVectorFilterOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + return (l) -> { + Database db = spaceFunction.apply(l).getDatabase(); + float[] vector = getVectorValues(op, l); + Filter filter = getFilterFromOp(op, l); + int limit = getLimit(op, l); + return new DataApiFindVectorFilterOp( + db, + db.getCollection(targetFunction.apply(l)), + vector, + limit, + filter + ); + }; + } + + private int getLimit(ParsedOp op, long l) { + return op.getConfigOr("limit", 100, l); + } + + private FindOptions getFindOptions(ParsedOp op, long l) { + FindOptions options = new FindOptions(); + Sort sort = getSortFromOp(op, l); + float[] vector = getVectorValues(op, l); + if (sort != null) { + options = vector != null ? options.sort(vector, sort) : options.sort(sort); + } else if (vector != null) { + options = options.sort(vector); + } + Projection[] projection = getProjectionFromOp(op, l); + if (projection != null) { + options = options.projection(projection); + } + options.setIncludeSimilarity(true); + return options; + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiOpMapper.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiOpMapper.java new file mode 100644 index 000000000..190b6f79f --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiOpMapper.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 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.dataapi; + +import io.nosqlbench.adapter.dataapi.opdispensers.*; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiOpType; +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 DataApiOpMapper implements OpMapper { + private static final Logger logger = LogManager.getLogger(DataApiOpMapper.class); + private final DataApiDriverAdapter adapter; + + public DataApiOpMapper(DataApiDriverAdapter dataApiDriverAdapter) { + this.adapter = dataApiDriverAdapter; + } + + @Override + public OpDispenser apply(ParsedOp op) { + TypeAndTarget typeAndTarget = op.getTypeAndTarget( + DataApiOpType.class, + String.class, + "type", + "collection" + ); + logger.debug(() -> "Using '" + typeAndTarget.enumId + "' op type for op template '" + op.getName() + "'"); + return switch (typeAndTarget.enumId) { + case create_collection -> new DataApiCreateCollectionOpDispenser(adapter, op, typeAndTarget.targetFunction); + case insert_many -> new DataApiInsertManyOpDispenser(adapter, op, typeAndTarget.targetFunction); + case insert_one -> new DataApiInsertOneOpDispenser(adapter, op, typeAndTarget.targetFunction); + case insert_one_vector -> new DataApiInsertOneVectorOpDispenser(adapter, op, typeAndTarget.targetFunction); + case find -> new DataApiFindOpDispenser(adapter, op, typeAndTarget.targetFunction); + case find_one -> new DataApiFindOneOpDispenser(adapter, op, typeAndTarget.targetFunction); + case find_one_and_delete -> new DataApiFindOneAndDeleteOpDispenser(adapter, op, typeAndTarget.targetFunction); + case find_one_and_update -> new DataApiFindOneAndUpdateOpDispenser(adapter, op, typeAndTarget.targetFunction); + case find_vector -> new DataApiFindVectorOpDispenser(adapter, op, typeAndTarget.targetFunction); + case find_vector_filter -> new DataApiFindVectorFilterOpDispenser(adapter, op, typeAndTarget.targetFunction); + case update_one -> new DataApiUpdateOneOpDispenser(adapter, op, typeAndTarget.targetFunction); + case update_many -> new DataApiUpdateManyOpDispenser(adapter, op, typeAndTarget.targetFunction); + case delete_one -> new DataApiDeleteOneOpDispenser(adapter, op, typeAndTarget.targetFunction); + case delete_many -> new DataApiDeleteManyOpDispenser(adapter, op, typeAndTarget.targetFunction); + case delete_collection -> new DataApiDropCollectionOpDispenser(adapter, op, typeAndTarget.targetFunction); + }; + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiSpace.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiSpace.java new file mode 100644 index 000000000..e1cd61d30 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/DataApiSpace.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 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.dataapi; + +import com.datastax.astra.client.DataAPIClient; +import com.datastax.astra.client.Database; +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.nosqlbench.nb.api.errors.BasicError; +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.Path; +import java.nio.file.Paths; +import java.util.Optional; + +public class DataApiSpace { + private final static Logger logger = LogManager.getLogger(DataApiSpace.class); + private final NBConfiguration config; + private final String name; + private String astraToken; + private String astraApiEndpoint; + private DataAPIClient dataAPIClient; + private Database database; + private String namespace; + + public DataApiSpace(String name, NBConfiguration cfg) { + this.config = cfg; + this.name = name; + setToken(); + setApiEndpoint(); + setNamespace(); + createClient(); + } + + public DataAPIClient getDataAPIClient() { + return dataAPIClient; + } + + public Database getDatabase() { + return database; + } + + private void createClient() { + this.dataAPIClient = new DataAPIClient(astraToken); + if (namespace != null) { + this.database = dataAPIClient.getDatabase(astraApiEndpoint, namespace); + } else { + this.database = dataAPIClient.getDatabase(astraApiEndpoint); + } + } + + private void setApiEndpoint() { + Optional epConfig = config.getOptional("astraApiEndpoint"); + Optional epFileConfig = config.getOptional("astraApiEndpointFile"); + if (epConfig.isPresent() && epFileConfig.isPresent()) { + throw new BasicError("You can only configure one of astraApiEndpoint or astraApiEndpointFile"); + } + if (epConfig.isEmpty() && epFileConfig.isEmpty()) { + throw new BasicError("You must configure one of astraApiEndpoint or astraApiEndpointFile"); + } + epFileConfig + .map(Path::of) + .map(p -> { + try { + return Files.readString(p); + } catch (IOException e) { + throw new RuntimeException(e); + } + }) + .map(String::trim) + .ifPresent(ep -> this.astraApiEndpoint = ep); + epConfig.ifPresent(ep -> this.astraApiEndpoint = ep); + } + + private void setNamespace() { + Optional maybeNamespace = config.getOptional("namespace"); + maybeNamespace.ifPresent(s -> this.namespace = s); + } + + private void setToken() { + String tokenFileContents = null; + Optional tokenFilePath = config.getOptional("astraTokenFile"); + if (tokenFilePath.isPresent()) { + Path path = Paths.get(tokenFilePath.get()); + try { + tokenFileContents = Files.readAllLines(path).getFirst(); + } catch (IOException e) { + String error = "Error while reading token from file:" + path; + logger.error(error, e); + throw new RuntimeException(e); + } + } + this.astraToken = (tokenFileContents != null) ? tokenFileContents : config.get("astraToken"); + } + + public static NBConfigModel getConfigModel() { + return ConfigModel.of(DataApiSpace.class) + .add( + Param.optional("astraTokenFile", String.class) + .setDescription("file to load the Astra token from") + ) + .add( + Param.optional("astraToken", String.class) + .setDescription("the Astra token used to connect to the database") + ) + .add( + Param.optional("astraApiEndpoint", String.class) + .setDescription("the API endpoint for the Astra database") + ) + .add( + Param.optional("astraApiEndpointFile", String.class) + .setDescription("file to load the API endpoint for the Astra database") + ) + + .add( + Param.defaultTo("namespace", "default_namespace") + .setDescription("The Astra namespace to use") + + ) + .asReadOnly(); + } + +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiCreateCollectionOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiCreateCollectionOpDispenser.java new file mode 100644 index 000000000..14e30e5f1 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiCreateCollectionOpDispenser.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import com.datastax.astra.client.model.CollectionOptions; +import com.datastax.astra.client.model.SimilarityMetric; +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiCreateCollectionOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Optional; +import java.util.function.LongFunction; + +public class DataApiCreateCollectionOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiCreateCollectionOpDispenser.class); + private final LongFunction opFunction; + + public DataApiCreateCollectionOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + return (l) -> { + CollectionOptions.CollectionOptionsBuilder optionsBldr = CollectionOptions.builder(); + Optional> dimFunc = op.getAsOptionalFunction("dimensions", Integer.class); + if (dimFunc.isPresent()) { + LongFunction af = dimFunc.get(); + optionsBldr.vectorDimension(af.apply(l)); + } +// COSINE("cosine"), +// EUCLIDEAN("euclidean"), +// DOT_PRODUCT("dot_product"); + Optional> simFunc = op.getAsOptionalFunction("similarity", String.class); + if (simFunc.isPresent()) { + LongFunction sf = simFunc.get(); + optionsBldr.vectorSimilarity(SimilarityMetric.fromValue(sf.apply(l))); + } + + DataApiCreateCollectionOp dataApiCreateCollectionOp = + new DataApiCreateCollectionOp( + spaceFunction.apply(l).getDatabase(), + targetFunction.apply(l), + optionsBldr.build()); + + return dataApiCreateCollectionOp; + }; + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } + + +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiDeleteManyOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiDeleteManyOpDispenser.java new file mode 100644 index 000000000..0c0ce0f56 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiDeleteManyOpDispenser.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Filter; +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiDeleteManyOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.function.LongFunction; + +public class DataApiDeleteManyOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiDeleteManyOpDispenser.class); + private final LongFunction opFunction; + + public DataApiDeleteManyOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + return (l) -> { + Database db = spaceFunction.apply(l).getDatabase(); + Filter filter = getFilterFromOp(op, l); + + return new DataApiDeleteManyOp( + db, + db.getCollection(targetFunction.apply(l)), + filter + ); + }; + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiDeleteOneOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiDeleteOneOpDispenser.java new file mode 100644 index 000000000..c5044a007 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiDeleteOneOpDispenser.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.DeleteOneOptions; +import com.datastax.astra.client.model.Filter; +import com.datastax.astra.client.model.Sort; +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiDeleteOneOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.function.LongFunction; + +public class DataApiDeleteOneOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiDeleteOneOpDispenser.class); + private final LongFunction opFunction; + + public DataApiDeleteOneOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + return (l) -> { + Database db = spaceFunction.apply(l).getDatabase(); + Filter filter = getFilterFromOp(op, l); + DeleteOneOptions options = getDeleteOneOptions(op, l); + + return new DataApiDeleteOneOp( + db, + db.getCollection(targetFunction.apply(l)), + filter, + options + ); + }; + } + + private DeleteOneOptions getDeleteOneOptions(ParsedOp op, long l) { + DeleteOneOptions options = new DeleteOneOptions(); + Sort sort = getSortFromOp(op, l); + if (sort != null) { + options = options.sort(sort); + } + float[] vector = getVectorFromOp(op, l); + if (vector != null) { + options = options.vector(vector); + } + return options; + } + + private float[] getVectorFromOp(ParsedOp op, long l) { + return getVectorValues(op.get("vector", l)); + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiDropCollectionOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiDropCollectionOpDispenser.java new file mode 100644 index 000000000..dd3748956 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiDropCollectionOpDispenser.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiDropCollectionOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.function.LongFunction; + +public class DataApiDropCollectionOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiDropCollectionOpDispenser.class); + private final LongFunction opFunction; + public DataApiDropCollectionOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + return (l) -> new DataApiDropCollectionOp( + spaceFunction.apply(l).getDatabase(), + targetFunction.apply(l) + ); + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindOneAndDeleteOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindOneAndDeleteOpDispenser.java new file mode 100644 index 000000000..7a85f9995 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindOneAndDeleteOpDispenser.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Filter; +import com.datastax.astra.client.model.FindOneAndDeleteOptions; +import com.datastax.astra.client.model.Projection; +import com.datastax.astra.client.model.Sort; +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiFindOneAndDeleteOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.function.LongFunction; + +public class DataApiFindOneAndDeleteOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiFindOneAndDeleteOpDispenser.class); + private final LongFunction opFunction; + + public DataApiFindOneAndDeleteOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + return (l) -> { + Database db = spaceFunction.apply(l).getDatabase(); + Filter filter = getFilterFromOp(op, l); + FindOneAndDeleteOptions options = getFindOneAndDeleteOptions(op, l); + + return new DataApiFindOneAndDeleteOp( + db, + db.getCollection(targetFunction.apply(l)), + filter, + options + ); + }; + } + + private FindOneAndDeleteOptions getFindOneAndDeleteOptions(ParsedOp op, long l) { + FindOneAndDeleteOptions options = new FindOneAndDeleteOptions(); + Sort sort = getSortFromOp(op, l); + if (sort != null) { + options = options.sort(sort); + } + Projection[] projection = getProjectionFromOp(op, l); + if (projection != null) { + options = options.projection(projection); + } + return options; + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindOneAndUpdateOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindOneAndUpdateOpDispenser.java new file mode 100644 index 000000000..1b2fffccd --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindOneAndUpdateOpDispenser.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Filter; +import com.datastax.astra.client.model.Update; +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiFindOneAndUpdateOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.function.LongFunction; + +public class DataApiFindOneAndUpdateOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiFindOneAndUpdateOpDispenser.class); + private final LongFunction opFunction; + public DataApiFindOneAndUpdateOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + return (l) -> { + Database db = spaceFunction.apply(l).getDatabase(); + Filter filter = getFilterFromOp(op, l); + Update update = getUpdates(op, l); + + return new DataApiFindOneAndUpdateOp( + db, + db.getCollection(targetFunction.apply(l)), + filter, + update + ); + }; + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindOneOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindOneOpDispenser.java new file mode 100644 index 000000000..687a9b91a --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindOneOpDispenser.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Filter; +import com.datastax.astra.client.model.FindOneOptions; +import com.datastax.astra.client.model.Projection; +import com.datastax.astra.client.model.Sort; +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiFindOneOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.function.LongFunction; + +public class DataApiFindOneOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiFindOneOpDispenser.class); + private final LongFunction opFunction; + public DataApiFindOneOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + return (l) -> { + Database db = spaceFunction.apply(l).getDatabase(); + Filter filter = getFilterFromOp(op, l); + FindOneOptions options = getFindOneOptions(op, l); + return new DataApiFindOneOp( + db, + db.getCollection(targetFunction.apply(l)), + filter, + options + ); + }; + } + + private FindOneOptions getFindOneOptions(ParsedOp op, long l) { + FindOneOptions options = new FindOneOptions(); + Sort sort = getSortFromOp(op, l); + float[] vector = getVectorValues(op, l); + if (sort != null) { + options = vector != null ? options.sort(vector, sort) : options.sort(sort); + } else if (vector != null) { + options = options.sort(vector); + } + Projection[] projection = getProjectionFromOp(op, l); + if (projection != null) { + options = options.projection(projection); + } + options.setIncludeSimilarity(true); + return options; + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindOpDispenser.java new file mode 100644 index 000000000..d615cc656 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindOpDispenser.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Filter; +import com.datastax.astra.client.model.FindOptions; +import com.datastax.astra.client.model.Projection; +import com.datastax.astra.client.model.Sort; +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiFindOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.function.LongFunction; + +public class DataApiFindOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiFindOpDispenser.class); + private final LongFunction opFunction; + public DataApiFindOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + return (l) -> { + Database db = spaceFunction.apply(l).getDatabase(); + Filter filter = getFilterFromOp(op, l); + FindOptions options = getFindOptions(op, l); + return new DataApiFindOp( + db, + db.getCollection(targetFunction.apply(l)), + filter, + options + ); + }; + } + + private FindOptions getFindOptions(ParsedOp op, long l) { + FindOptions options = new FindOptions(); + Sort sort = getSortFromOp(op, l); + if (op.isDefined("vector")) { + float[] vector = getVectorValues(op, l); + if (sort != null) { + options = vector != null ? options.sort(vector, sort) : options.sort(sort); + } else if (vector != null) { + options = options.sort(vector); + } + } + Projection[] projection = getProjectionFromOp(op, l); + if (projection != null) { + options = options.projection(projection); + } + options.setIncludeSimilarity(true); + return options; + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindVectorOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindVectorOpDispenser.java new file mode 100644 index 000000000..5aa65f912 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiFindVectorOpDispenser.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.FindOptions; +import com.datastax.astra.client.model.Projection; +import com.datastax.astra.client.model.Sort; +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiFindVectorOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.function.LongFunction; + +public class DataApiFindVectorOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiFindVectorOpDispenser.class); + private final LongFunction opFunction; + public DataApiFindVectorOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + return (l) -> { + Database db = spaceFunction.apply(l).getDatabase(); + float[] vector = getVectorValues(op, l); + int limit = getLimit(op, l); + return new DataApiFindVectorOp( + db, + db.getCollection(targetFunction.apply(l)), + vector, + limit + ); + }; + } + + private int getLimit(ParsedOp op, long l) { + return op.getConfigOr("limit", 100, l); + } + + private FindOptions getFindOptions(ParsedOp op, long l) { + FindOptions options = new FindOptions(); + Sort sort = getSortFromOp(op, l); + float[] vector = getVectorValues(op, l); + if (sort != null) { + options = vector != null ? options.sort(vector, sort) : options.sort(sort); + } else if (vector != null) { + options = options.sort(vector); + } + Projection[] projection = getProjectionFromOp(op, l); + if (projection != null) { + options = options.projection(projection); + } + options.setIncludeSimilarity(true); + return options; + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiInsertManyOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiInsertManyOpDispenser.java new file mode 100644 index 000000000..10788cfea --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiInsertManyOpDispenser.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import com.datastax.astra.client.model.Document; +import com.datastax.astra.client.model.InsertManyOptions; +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiInsertManyOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.LongFunction; + +public class DataApiInsertManyOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiInsertManyOpDispenser.class); + private final LongFunction opFunction; + + public DataApiInsertManyOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + return (l) -> { + List documents = new ArrayList<>(); + op.getAsRequiredFunction("documents", List.class).apply(l).forEach(o -> documents.add(Document.parse(o.toString()))); + return new DataApiInsertManyOp( + spaceFunction.apply(l).getDatabase(), + targetFunction.apply(l), + documents, + getInsertManyOptions(op, l) + ); + }; + } + + private InsertManyOptions getInsertManyOptions(ParsedOp op, long l) { + InsertManyOptions options = new InsertManyOptions(); + Optional> optionsFunction = op.getAsOptionalFunction("options", Map.class); + if (optionsFunction.isPresent()) { + Map optionFields = optionsFunction.get().apply(l); + for(Map.Entry entry: optionFields.entrySet()) { + switch(entry.getKey()) { + case "chunkSize"-> + options = options.chunkSize(Integer.parseInt(entry.getValue())); + case "concurrency" -> + options = options.concurrency(Integer.parseInt(entry.getValue())); + case "ordered" -> + options = options.ordered(Boolean.parseBoolean(entry.getValue())); + } + } + } + return options; + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiInsertOneOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiInsertOneOpDispenser.java new file mode 100644 index 000000000..3c24357c2 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiInsertOneOpDispenser.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import com.datastax.astra.client.model.Document; +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiInsertOneOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Map; +import java.util.function.LongFunction; + +public class DataApiInsertOneOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiInsertOneOpDispenser.class); + private final LongFunction opFunction; + + public DataApiInsertOneOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + LongFunction docMapFunc = op.getAsRequiredFunction("document", Map.class); + LongFunction docFunc = (long m) -> new Document(docMapFunc.apply(m)); + return (l) -> { + return new DataApiInsertOneOp( + spaceFunction.apply(l).getDatabase(), + targetFunction.apply(l), + docFunc.apply(l) + ); + }; + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiInsertOneVectorOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiInsertOneVectorOpDispenser.java new file mode 100644 index 000000000..a735bcf87 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiInsertOneVectorOpDispenser.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import com.datastax.astra.client.model.Document; +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiInsertOneOp; +import io.nosqlbench.adapter.dataapi.ops.DataApiInsertOneVectorOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Map; +import java.util.function.LongFunction; + +public class DataApiInsertOneVectorOpDispenser extends DataApiOpDispenser { + private static final Logger logger = LogManager.getLogger(DataApiInsertOneVectorOpDispenser.class); + private final LongFunction opFunction; + + public DataApiInsertOneVectorOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + this.opFunction = createOpFunction(op); + } + + private LongFunction createOpFunction(ParsedOp op) { + LongFunction docMapFunc = op.getAsRequiredFunction("document", Map.class); + LongFunction docFunc = (long m) -> new Document(docMapFunc.apply(m)); + LongFunction vectorF= op.getAsRequiredFunction("vector", float[].class); + return (l) -> { + return new DataApiInsertOneVectorOp( + spaceFunction.apply(l).getDatabase(), + targetFunction.apply(l), + docFunc.apply(l), + vectorF.apply(l) + ); + }; + } + + @Override + public DataApiBaseOp getOp(long value) { + return opFunction.apply(value); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiOpDispenser.java new file mode 100644 index 000000000..416db85df --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiOpDispenser.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import com.datastax.astra.client.model.*; +import io.nosqlbench.adapter.dataapi.DataApiSpace; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapters.api.activityimpl.BaseOpDispenser; +import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter; +import io.nosqlbench.adapters.api.templating.ParsedOp; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.LongFunction; + +public abstract class DataApiOpDispenser extends BaseOpDispenser { + protected final LongFunction targetFunction; + protected final LongFunction spaceFunction; + + protected DataApiOpDispenser(DriverAdapter adapter, ParsedOp op, + LongFunction targetFunction) { + super(adapter, op); + this.targetFunction = targetFunction; + this.spaceFunction = adapter.getSpaceFunc(op); + } + + protected Sort getSortFromOp(ParsedOp op, long l) { + Sort sort = null; + Optional> sortFunction = op.getAsOptionalFunction("sort", Map.class); + if (sortFunction.isPresent()) { + Map sortFields = sortFunction.get().apply(l); + String sortOrder = sortFields.get("type").toString(); + String sortField = sortFields.get("field").toString(); + switch(sortOrder) { + case "asc" -> sort = Sorts.ascending(sortField); + case "desc" -> sort = Sorts.descending(sortField); + } + } + return sort; + } + + protected Filter getFilterFromOp(ParsedOp op, long l) { + // TODO: Clarify 'filter' vs 'filters' or whether to support both uniformly + Filter filter = null; + Optional> filterFunction = op.getAsOptionalFunction("filters", List.class).or( + () -> op.getAsOptionalFunction("filter",List.class) + ); + if (filterFunction.isPresent()) { + List> filters = filterFunction.get().apply(l); + List andFilterList = new ArrayList<>(); + List orFilterList = new ArrayList<>(); + for (Map filterFields : filters) { + switch ((String)filterFields.get("conjunction")) { + case "and" -> { + switch (filterFields.get("operator").toString()) { + case "lt" -> + andFilterList.add(Filters.lt(filterFields.get("field").toString(), (long) filterFields.get("value"))); + case "gt" -> + andFilterList.add(Filters.gt(filterFields.get("field").toString(), (long) filterFields.get("value"))); + case "eq" -> + andFilterList.add(Filters.eq(filterFields.get("field").toString(), filterFields.get("value"))); + default -> logger.error(() -> "Operation " + filterFields.get("operator") + " not supported"); + } + } + case "or" -> { + switch (filterFields.get("operator").toString()) { + case "lt" -> + orFilterList.add(Filters.lt(filterFields.get("field").toString(), (long) filterFields.get("value"))); + case "gt" -> + orFilterList.add(Filters.gt(filterFields.get("field").toString(), (long) filterFields.get("value"))); + case "eq" -> + orFilterList.add(Filters.eq(filterFields.get("field").toString(), filterFields.get("value"))); + default -> logger.error(() -> "Operation " + filterFields.get("operator") + " not supported"); + } + } + default -> logger.error(() -> "Conjunction " + filterFields.get("conjunction") + " not supported"); + } + } + if (!andFilterList.isEmpty()) + filter = Filters.and(andFilterList.toArray(new Filter[0])); + if (!orFilterList.isEmpty()) + filter = Filters.or(orFilterList.toArray(new Filter[0])); + } + return filter; + } + + protected Update getUpdates(ParsedOp op, long l) { + Update update = new Update(); + Optional> updatesFunction = op.getAsOptionalFunction("updates", Map.class); + if (updatesFunction.isPresent()) { + Map updates = updatesFunction.get().apply(l); + for (Map.Entry entry : updates.entrySet()) { + if (entry.getKey().equalsIgnoreCase("update")) { + Map updateFields = (Map) entry.getValue(); + switch (updateFields.get("operation").toString()) { + case "set" -> + update = Updates.set(updateFields.get("field").toString(), updateFields.get("value")); + case "inc" -> + update = Updates.inc(updateFields.get("field").toString(), (double) updateFields.get("value")); + case "unset" -> update = Updates.unset(updateFields.get("field").toString()); + case "addToSet" -> + update = Updates.addToSet(updateFields.get("field").toString(), updateFields.get("value")); + case "min" -> + update = Updates.min(updateFields.get("field").toString(), (double) updateFields.get("value")); + case "rename" -> + update = Updates.rename(updateFields.get("field").toString(), updateFields.get("value").toString()); + default -> logger.error(() -> "Operation " + updateFields.get("operation") + " not supported"); + } + } else { + logger.error(() -> "Filter " + entry.getKey() + " not supported"); + } + } + } + return update; + } + + protected float[] getVectorValues(ParsedOp op, long l) { + Object rawVectorValues = op.get("vector", l); + return getVectorValues(rawVectorValues); + } + + protected float[] getVectorValues(Object rawVectorValues) { + float[] floatValues; + if (rawVectorValues instanceof float[] f) { + return f; + } + if (rawVectorValues instanceof String) { + String[] rawValues = (((String) rawVectorValues).split(",")); + floatValues = new float[rawValues.length]; + for (int i = 0; i < rawValues.length; i++) { + floatValues[i] = Float.parseFloat(rawValues[i]); + } + } else if (rawVectorValues instanceof List) { + return getVectorValuesList(rawVectorValues); + } else { + throw new RuntimeException("Invalid type specified for values (type: " + rawVectorValues.getClass().getSimpleName() + "), values: " + rawVectorValues.toString()); + } + return floatValues; + } + + protected float[] getVectorValuesList(Object rawVectorValues) { + float[] vectorValues = null; + List vectorValuesList = (List) rawVectorValues; + vectorValues = new float[vectorValuesList.size()]; + for (int i = 0; i < vectorValuesList.size(); i++) { + vectorValues[i] = Float.parseFloat(vectorValuesList.get(i).toString()); + } + return vectorValues; + } + + protected Projection[] getProjectionFromOp(ParsedOp op, long l) { + Projection[] projection = null; + Optional> projectionFunction = op.getAsOptionalFunction("projection", Map.class); + if (projectionFunction.isPresent()) { + Map> projectionFields = projectionFunction.get().apply(l); + for (Map.Entry> field : projectionFields.entrySet()) { + List includeFields = field.getValue(); + StringBuffer sb = new StringBuffer(); + for (String includeField : includeFields) { + sb.append(includeField).append(","); + } + sb.deleteCharAt(sb.length() - 1); + if (field.getKey().equalsIgnoreCase("include")) { + projection = Projections.include(sb.toString()); + } else if (field.getKey().equalsIgnoreCase("exclude")) { + projection = Projections.exclude(sb.toString()); + } else { + logger.error("Projection " + field + " not supported"); + } + } + } + return projection; + } + +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiUpdateManyOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiUpdateManyOpDispenser.java new file mode 100644 index 000000000..82269b156 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiUpdateManyOpDispenser.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; + +import java.util.function.LongFunction; + +public class DataApiUpdateManyOpDispenser extends DataApiOpDispenser { + public DataApiUpdateManyOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + } + + @Override + public DataApiBaseOp getOp(long value) { + return null; + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiUpdateOneOpDispenser.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiUpdateOneOpDispenser.java new file mode 100644 index 000000000..114c7945e --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/opdispensers/DataApiUpdateOneOpDispenser.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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.dataapi.opdispensers; + +import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter; +import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp; +import io.nosqlbench.adapters.api.templating.ParsedOp; + +import java.util.function.LongFunction; + +public class DataApiUpdateOneOpDispenser extends DataApiOpDispenser { + public DataApiUpdateOneOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction targetFunction) { + super(adapter, op, targetFunction); + } + + @Override + public DataApiBaseOp getOp(long value) { + return null; + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiBaseOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiBaseOp.java new file mode 100644 index 000000000..13181c5db --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiBaseOp.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Database; +import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.CycleOp; + +public abstract class DataApiBaseOp implements CycleOp { + protected final Database db; + + public DataApiBaseOp(Database db) { + this.db = db; + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiCreateCollectionOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiCreateCollectionOp.java new file mode 100644 index 000000000..625ca385a --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiCreateCollectionOp.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.CollectionOptions; + +public class DataApiCreateCollectionOp extends DataApiBaseOp { + private final String collectionName; + private final CollectionOptions options; + + public DataApiCreateCollectionOp(Database db, String collectionName, CollectionOptions options) { + super(db); + this.collectionName = collectionName; + this.options = options; + } + + @Override + public Object apply(long value) { + return db.createCollection(collectionName, options); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiDeleteManyOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiDeleteManyOp.java new file mode 100644 index 000000000..deabceca8 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiDeleteManyOp.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Collection; +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Filter; + +public class DataApiDeleteManyOp extends DataApiBaseOp { + private final Collection collection; + private final Filter filter; + + public DataApiDeleteManyOp(Database db, Collection collection, Filter filter) { + super(db); + this.collection = collection; + this.filter = filter; + } + + @Override + public Object apply(long value) { + return collection.deleteMany(filter); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiDeleteOneOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiDeleteOneOp.java new file mode 100644 index 000000000..0e4c874fc --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiDeleteOneOp.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Collection; +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.DeleteOneOptions; +import com.datastax.astra.client.model.Filter; + +public class DataApiDeleteOneOp extends DataApiBaseOp { + private final Collection collection; + private final Filter filter; + private final DeleteOneOptions options; + + public DataApiDeleteOneOp(Database db, Collection collection, Filter filter, DeleteOneOptions options) { + super(db); + this.collection = collection; + this.filter = filter; + this.options = options; + } + + @Override + public Object apply(long value) { + return collection.deleteOne(filter, options); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiDropCollectionOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiDropCollectionOp.java new file mode 100644 index 000000000..effd4236b --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiDropCollectionOp.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Database; + +public class DataApiDropCollectionOp extends DataApiBaseOp { + private final String collectionName; + public DataApiDropCollectionOp(Database db, String collectionName) { + super(db); + this.collectionName = collectionName; + } + + @Override + public Object apply(long value) { + Boolean exists = db.collectionExists(collectionName); + // TODO: we need to remove these from the ops when we can, because this hides additional ops which + // should be surfaced in the test definition. Condition operations should be provided with clear views + // at the workload template level + if (exists) { + db.dropCollection(collectionName); + } + return exists; + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindOneAndDeleteOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindOneAndDeleteOp.java new file mode 100644 index 000000000..e512d2865 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindOneAndDeleteOp.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Collection; +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Document; +import com.datastax.astra.client.model.Filter; +import com.datastax.astra.client.model.FindOneAndDeleteOptions; + +public class DataApiFindOneAndDeleteOp extends DataApiBaseOp { + private final Collection collection; + private final Filter filter; + private final FindOneAndDeleteOptions options; + + public DataApiFindOneAndDeleteOp(Database db, Collection collection, Filter filter, FindOneAndDeleteOptions options) { + super(db); + this.collection = collection; + this.filter = filter; + this.options = options; + } + + @Override + public Object apply(long value) { + return collection.findOneAndDelete(filter, options); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindOneAndUpdateOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindOneAndUpdateOp.java new file mode 100644 index 000000000..1ad55e00f --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindOneAndUpdateOp.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Collection; +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.*; + +public class DataApiFindOneAndUpdateOp extends DataApiBaseOp { + private final Collection collection; + private final Filter filter; + private final Update update; + + public DataApiFindOneAndUpdateOp(Database db, Collection collection, Filter filter, Update update) { + super(db); + this.collection = collection; + this.filter = filter; + this.update = update; + } + + @Override + public Object apply(long value) { + return collection.findOneAndUpdate(filter, update); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindOneOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindOneOp.java new file mode 100644 index 000000000..17d1089d6 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindOneOp.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Collection; +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Document; +import com.datastax.astra.client.model.Filter; +import com.datastax.astra.client.model.FindOneOptions; + +public class DataApiFindOneOp extends DataApiBaseOp { + private final Collection collection; + private final Filter filter; + private final FindOneOptions options; + + public DataApiFindOneOp(Database db, Collection collection, Filter filter, FindOneOptions options) { + super(db); + this.collection = collection; + this.filter = filter; + this.options = options; + } + + @Override + public Object apply(long value) { + return collection.findOne(filter, options); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindOp.java new file mode 100644 index 000000000..f0d9f054e --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindOp.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Collection; +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.*; + +import java.util.List; +import java.util.stream.StreamSupport; + +public class DataApiFindOp extends DataApiBaseOp { + private final Collection collection; + private final Filter filter; + private final FindOptions options; + + public DataApiFindOp(Database db, Collection collection, Filter filter, FindOptions options) { + super(db); + this.collection = collection; + this.filter = filter; + this.options = options; + } + + @Override + public List apply(long value) { + // TODO: make sure we're traversing result data + FindIterable documentStream = collection.find(filter, options); + List documents = StreamSupport.stream(documentStream.spliterator(), false).toList(); + return documents; + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindVectorFilterOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindVectorFilterOp.java new file mode 100644 index 000000000..5f7c21bd6 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindVectorFilterOp.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Collection; +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Document; +import com.datastax.astra.client.model.Filter; + +public class DataApiFindVectorFilterOp extends DataApiBaseOp { + private final Collection collection; + private final float[] vector; + private final int limit; + private final Filter filter; + + public DataApiFindVectorFilterOp(Database db, Collection collection, float[] vector, int limit, Filter filter) { + super(db); + this.collection = collection; + this.vector = vector; + this.limit = limit; + this.filter = filter; + } + + @Override + public Object apply(long value) { + return collection.find(filter, vector, limit); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindVectorOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindVectorOp.java new file mode 100644 index 000000000..7c08a35fe --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiFindVectorOp.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Collection; +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Document; +import com.datastax.astra.client.model.Filter; +import com.datastax.astra.client.model.FindOptions; + +public class DataApiFindVectorOp extends DataApiBaseOp { + private final Collection collection; + private final float[] vector; + private final int limit; + + public DataApiFindVectorOp(Database db, Collection collection, float[] vector, int limit) { + super(db); + this.collection = collection; + this.vector = vector; + this.limit = limit; + } + + @Override + public Object apply(long value) { + return collection.find(vector, limit); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiInsertManyOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiInsertManyOp.java new file mode 100644 index 000000000..a3ceb4ef2 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiInsertManyOp.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Document; +import com.datastax.astra.client.model.InsertManyOptions; + +import java.util.List; + +public class DataApiInsertManyOp extends DataApiBaseOp { + private final List documents; + private final String collectionName; + private final InsertManyOptions options; + + + public DataApiInsertManyOp(Database db, String collectionName, List documents, InsertManyOptions options) { + super(db); + this.collectionName = collectionName; + this.documents = documents; + this.options = options; + } + + @Override + public Object apply(long value) { + return db.getCollection(collectionName).insertMany(documents, options); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiInsertOneOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiInsertOneOp.java new file mode 100644 index 000000000..a1ab20ff4 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiInsertOneOp.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Document; + +public class DataApiInsertOneOp extends DataApiBaseOp { + private final Document doc; + private final String collectionName; + + public DataApiInsertOneOp(Database db, String collectionName, Document doc) { + super(db); + this.collectionName = collectionName; + this.doc = doc; + } + + @Override + public Object apply(long value) { + return db.getCollection(collectionName).insertOne(doc); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiInsertOneVectorOp.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiInsertOneVectorOp.java new file mode 100644 index 000000000..4d21dcc68 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiInsertOneVectorOp.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 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.dataapi.ops; + +import com.datastax.astra.client.Database; +import com.datastax.astra.client.model.Document; + +public class DataApiInsertOneVectorOp extends DataApiBaseOp { + private final Document doc; + private final String collectionName; + private float[] vector; + + public DataApiInsertOneVectorOp(Database db, String collectionName, Document doc, float[] vector) { + super(db); + this.collectionName = collectionName; + this.doc = doc; + this.vector = vector; + } + + @Override + public Object apply(long value) { + return db.getCollection(collectionName).insertOne(doc, vector); + } +} diff --git a/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiOpType.java b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiOpType.java new file mode 100644 index 000000000..4ddae3b83 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/java/io/nosqlbench/adapter/dataapi/ops/DataApiOpType.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 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.dataapi.ops; + +public enum DataApiOpType { + create_collection, + insert_many, + insert_one, + insert_one_vector, + find, + find_one, + find_one_and_delete, + find_one_and_update, + find_vector, + find_vector_filter, + update_one, + update_many, + delete_one, + delete_many, + delete_collection +} diff --git a/nb-adapters/adapter-dataapi/src/main/resources/activities/astra_kv_dapi.yaml b/nb-adapters/adapter-dataapi/src/main/resources/activities/astra_kv_dapi.yaml new file mode 100644 index 000000000..bc1d6798a --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/resources/activities/astra_kv_dapi.yaml @@ -0,0 +1,193 @@ +min_version: "5.21.0" + +description: | + A basic workload that uses the DataStax Data API Client in Java, emulating what + applications would do in the native stack. + TEMPLATE(cardinality,1000) + TEMPLATE(collection,keyvalue) + TEMPLATE(dimensions,1536) + TEMPLATE(similarity,COSINE) + TEMPLATE(keycount,TEMPLATE(cardinality)) + TEMPLATE(valuecount,TEMPLATE(cardinality)) + +scenarios: + dapi_novector: + schema: run driver=dataapi tags==block:schema threads==1 cycles==UNDEF + rampup: >- + run driver=dataapi tags==block:rampup + cycles===TEMPLATE(rampup-cycles,TEMPLATE(cardinality)) + threads=auto errors=count + find_key: >- + run driver=dataapi tags==block:find_key + cycles===TEMPLATE(main-cycles,1000) + threads=auto errors=count + + dapi_vector_d1536: + schema_vector: run driver=dataapi tags==block:schema_vector threads==1 cycles==UNDEF + rampup_vector: >- + run driver=dataapi tags==block:rampup_vector + cycles===TEMPLATE(rampup-cycles,TEMPLATE(cardinality)) + threads=auto errors=count + find_key_vector: >- + run driver=dataapi tags==block:find_key_vector + cycles===TEMPLATE(main-cycles,TEMPLATE(cardinality)) + threads=auto errors=count + + + +# kv_dapi: +# kv_dapi_schema: run driver=http tags==block:schema threads==1 cycles==UNDEF +# kv_dapi_rampup: run driver=http tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto +# kv_dapi_main: run driver=http tags==block:"main.*" cycles===TEMPLATE(main-cycles,10000000) threads=auto + +# basic_check: +# schema: run driver=http tags==block:schema threads==1 cycles==UNDEF +# rampup: run driver=http tags==block:rampup cycles===TEMPLATE(rampup-cycles,10) threads=auto +# main: run driver=http tags==block:"main.*" cycles===TEMPLATE(main-cycles,10) threads=auto + +bindings: + # To enable an optional weighted set of hosts in place of a load balancer + # Examples + # single host: jsonapi_host=host1 + # multiple hosts: jsonapi_host=host1,host2,host3 + # multiple weighted hosts: jsonapi_host=host1:3,host2:7 + weighted_hosts: WeightedStrings('TEMPLATE(jsonapi_host,TEMPLATE(stargate_host,localhost))') + + seq_key: Mod(TEMPLATE(keycount)); ToString() -> String +# seq_key: Mod(TEMPLATE(keycount,50000000000L)); + seq_value: Hash(); Mod(TEMPLATE(valuecount)); ToString() -> String +# rw_key: TEMPLATE(keydist,Uniform(0,50000000000L)); + rw_key: TEMPLATE(keydist,Uniform(0,TEMPLATE(keycount))); ToString() -> String + rw_key_num: TEMPLATE(keydist,Uniform(0,TEMPLATE(keycount))); + rw_value: Hash(); TEMPLATE(valdist,Uniform(0,TEMPLATE(valuecount))); ToString() -> String + vector_value: HashedFloatVectors(TEMPLATE(dimensions,1536)); + + request_id: ToHashedUUID(); ToString(); + + params: + cl: TEMPLATE(cl,LOCAL_QUORUM) + +blocks: + reset_schema: + ops: + drop_index: + raw: |- + DROP INDEX IF EXISTS TEMPLATE(keyspace, baselines).TEMPLATE(table,keyvalue)_value_idx; + drop-table: + raw: |- + DROP TABLE IF EXISTS TEMPLATE(keyspace, baselines).TEMPLATE(table,keyvalue); + + schema: + ops: + delete_collection_op: + delete_collection: "TEMPLATE(collection)" + create_collection_op: + create_collection: "TEMPLATE(collection)" + +# separate these cases later, when you can recreate the same collection name with/without vector support + schema_vector: + ops: + delete_collection_op_v: + delete_collection: "TEMPLATE(collection)_v" + create_collection_op_v: + create_collection: "TEMPLATE(collection)_v" + dimensions: TEMPLATE(dimensions) + similarity: TEMPLATE(similarity) + + rampup: + ops: + insert_one_op: + insert_one: "TEMPLATE(collection)" + document: + _id: "{seq_key}" + value: "{seq_value}" + + rampup_vector: + ops: + insert_one_op_v: + insert_one_vector: "TEMPLATE(collection)_v" + document: + _id: "{seq_key}" + value: "{seq_value}" + vector: "{vector_value}" + +# rampup-uuid: +# ops: +# insert_one_op: +# insert-one: "TEMPLATE(collection)" +# document: +# value: "{seq_value}" + find_key: + params: + ratio: 5 + ops: + find_op: + find: "TEMPLATE(collection)" + filters: + - conjunction: "and" + operator: "lt" + field: "_id" + value: "{rw_key_num}" + vector: "{vector_value}" + + find_key_vector: + params: + ratio: 5 + ops: + find_op_v: + find_vector_filter: "TEMPLATE(collection)" + filters: + - conjunction: "and" + operator: "lt" + field: "_id" + value: "{rw_key_num}" + vector: "{vector_value}" + + +# +# rampup_with_vector_uuid: +# ops: +# insert_one_op: +# insert_one: "TEMPLATE(collection)" +# document: +# value: "{seq_value}" +# vector: "{vector_value}" +# +# main_read_with_vector: +# ops: +# find_op: +# find: "TEMPLATE(collection)" +# filter: +# _id: "{rw_key}" +# +# main_ann_with_vector_limit_20: +# params: +# ratio: 5 +# ops: +# find_op: +# find: "TEMPLATE(collection)" +# sort: +# vector: "{vector_value}" +# options: +# limit: 20 +# schema_with_text_sai: +# ops: +# delete_collection_op: +# delete_collection: "TEMPLATE(collection)" +# create_collection_op: +# create_collection: "TEMPLATE(collection)" +# rampup_with_text_sai: +# ops: +# insert_one_op: +# insert_one: "TEMPLATE(collection)" +# document: +# _id: "{seq_key}" +# value: "{seq_value}" +# main_read_with_text_sai: +# params: +# ratio: 5 +# ops: +# find_op: +# find: "TEMPLATE(collection)" +# filter: +# value: "{rw_value}" diff --git a/nb-adapters/adapter-dataapi/src/main/resources/activities/create_collection.yaml b/nb-adapters/adapter-dataapi/src/main/resources/activities/create_collection.yaml new file mode 100644 index 000000000..66ebc5fdf --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/resources/activities/create_collection.yaml @@ -0,0 +1,11 @@ +scenarios: + default: + create_collection: run driver=dataapi tags==blocks:create_collection cycles=1 + +blocks: + create_collection: + ops: + op1: + create_collection: "collectionName" + dimensions: 10 + similarity: "COSINE" diff --git a/nb-adapters/adapter-dataapi/src/main/resources/activities/delete_many.yaml b/nb-adapters/adapter-dataapi/src/main/resources/activities/delete_many.yaml new file mode 100644 index 000000000..18f981631 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/resources/activities/delete_many.yaml @@ -0,0 +1,18 @@ +scenarios: + default: + delete_many: run driver=dataapi tags==blocks:delete_many cycles=1 + +blocks: + delete_many: + ops: + op1: + delete_many: "collectionName" + filters: + - conjunction: "and" + operator: "lt" + field: "field1" + value: 10 + - conjunction: "or" + operator: "eq" + field: "field2" + value: "value2" diff --git a/nb-adapters/adapter-dataapi/src/main/resources/activities/delete_one.yaml b/nb-adapters/adapter-dataapi/src/main/resources/activities/delete_one.yaml new file mode 100644 index 000000000..2b9b7a799 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/resources/activities/delete_one.yaml @@ -0,0 +1,13 @@ +scenarios: + default: + delete_one: run driver=dataapi tags==blocks:delete_one cycles=1 + +blocks: + delete_one: + ops: + op1: + delete_one: "collectionName" + sort: + type: "asc" + field: "field1" + vector: "1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0" diff --git a/nb-adapters/adapter-dataapi/src/main/resources/activities/drop_collection.yaml b/nb-adapters/adapter-dataapi/src/main/resources/activities/drop_collection.yaml new file mode 100644 index 000000000..434bc92a7 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/resources/activities/drop_collection.yaml @@ -0,0 +1,9 @@ +scenarios: + default: + drop_collection: run driver=dataapi tags==blocks:drop_collection cycles=1 + +blocks: + drop_collection: + ops: + op1: + drop_collection: "collectionName" diff --git a/nb-adapters/adapter-dataapi/src/main/resources/activities/find.yaml b/nb-adapters/adapter-dataapi/src/main/resources/activities/find.yaml new file mode 100644 index 000000000..72b406dcd --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/resources/activities/find.yaml @@ -0,0 +1,26 @@ +scenarios: + default: + find: run driver=dataapi tags==blocks:find cycles=10 + +blocks: + find: + ops: + op1: + find: "collectionName" + filters: + - conjunction: "and" + operator: "lt" + field: "field1" + value: 10 + - conjunction: "or" + operator: "eq" + field: "field2" + value: "value2" + sort: + type: "asc" + field: "field1" + vector: "1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0" + projection: + include: + - "field1" + - "field2" diff --git a/nb-adapters/adapter-dataapi/src/main/resources/activities/find_one.yaml b/nb-adapters/adapter-dataapi/src/main/resources/activities/find_one.yaml new file mode 100644 index 000000000..e86bb16a3 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/resources/activities/find_one.yaml @@ -0,0 +1,26 @@ +scenarios: + default: + find_one: run driver=dataapi tags==blocks:find_one cycles=10 + +blocks: + find_one: + ops: + op1: + find_one: "collectionName" + filters: + - conjunction: "and" + operator: "lt" + field: "field1" + value: 10 + - conjunction: "or" + operator: "eq" + field: "field2" + value: "value2" + sort: + type: "asc" + field: "field1" + vector: "1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0" + projection: + include: + - "field1" + - "field2" diff --git a/nb-adapters/adapter-dataapi/src/main/resources/activities/find_one_and_delete.yaml b/nb-adapters/adapter-dataapi/src/main/resources/activities/find_one_and_delete.yaml new file mode 100644 index 000000000..e28b27c3c --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/resources/activities/find_one_and_delete.yaml @@ -0,0 +1,25 @@ +scenarios: + default: + find_one_and_delete: run driver=dataapi tags==blocks:find_one_and_delete cycles=1 + +blocks: + find_one_and_delete: + ops: + op1: + find_one_and_delete: "collectionName" + filters: + - conjunction: "and" + operator: "lt" + field: "field1" + value: 10 + - conjunction: "or" + operator: "eq" + field: "field2" + value: "value2" + sort: + type: "asc" + field: "field1" + projection: + include: + - "field1" + - "field2" diff --git a/nb-adapters/adapter-dataapi/src/main/resources/activities/find_one_and_update.yaml b/nb-adapters/adapter-dataapi/src/main/resources/activities/find_one_and_update.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/nb-adapters/adapter-dataapi/src/main/resources/activities/insert_many.yaml b/nb-adapters/adapter-dataapi/src/main/resources/activities/insert_many.yaml new file mode 100644 index 000000000..81a818d6f --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/resources/activities/insert_many.yaml @@ -0,0 +1,17 @@ +scenarios: + default: + insert_many: run driver=dataapi tags==blocks:insert_many cycles=1 + +blocks: + insert_many: + ops: + op1: + insert_many: "collectionName" + options: + chunkSize: "1000" + concurrency: "10" + ordered: "false" + documents: + - "{valid json here}" + - "{valid json here}" + - "{valid json here}" diff --git a/nb-adapters/adapter-dataapi/src/main/resources/activities/insert_one.yaml b/nb-adapters/adapter-dataapi/src/main/resources/activities/insert_one.yaml new file mode 100644 index 000000000..567f06cd0 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/resources/activities/insert_one.yaml @@ -0,0 +1,10 @@ +scenarios: + default: + insert_one: run driver=dataapi tags==blocks:insert_one cycles=1 + +blocks: + insert_one: + ops: + op1: + insert_one: "collectionName" + document: "{valid json here}" diff --git a/nb-adapters/adapter-dataapi/src/main/resources/activities/insert_one_vector.yaml b/nb-adapters/adapter-dataapi/src/main/resources/activities/insert_one_vector.yaml new file mode 100644 index 000000000..a9bce8200 --- /dev/null +++ b/nb-adapters/adapter-dataapi/src/main/resources/activities/insert_one_vector.yaml @@ -0,0 +1,11 @@ +scenarios: + default: + insert_one: run driver=dataapi tags==blocks:insert_one cycles=1 + +blocks: + insert_one: + ops: + op1: + insert_one: "collectionName" + document: "{valid json here}" + vector: "1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0" diff --git a/nb-adapters/nb-adapters-included/pom.xml b/nb-adapters/nb-adapters-included/pom.xml index 182283b08..c05e8ca4e 100644 --- a/nb-adapters/nb-adapters-included/pom.xml +++ b/nb-adapters/nb-adapters-included/pom.xml @@ -141,6 +141,20 @@ + + adapter-dataapi-include + + true + + + + io.nosqlbench + adapter-dataapi + ${revision} + + + + adapter-dynamodb-include @@ -186,7 +200,7 @@ adapter-s4j-include - true + false @@ -252,6 +266,7 @@ + diff --git a/nb-adapters/pom.xml b/nb-adapters/pom.xml index 04d0bfcd2..83677a2bd 100644 --- a/nb-adapters/pom.xml +++ b/nb-adapters/pom.xml @@ -1,5 +1,5 @@