diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/README.md b/sdk/cosmos/azure-cosmos-dotnet-benchmark/README.md index 3ac7e22eff4b..90a29a662ddd 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/README.md +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/README.md @@ -63,7 +63,9 @@ Copyright (C) 2019 CosmosBenchmark --partitionKeyPath Container partition key path - -pl Degree of parallism + -pl Degree of parallism + + -w Workload name --itemTemplateFile Item template diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/pom.xml b/sdk/cosmos/azure-cosmos-dotnet-benchmark/pom.xml index 9b0d1a8a322e..523cb31bb405 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/pom.xml +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/pom.xml @@ -80,6 +80,19 @@ Licensed under the MIT License. 4.13.1 test + + org.testng + testng + 6.14.3 + test + + + org.assertj + assertj-core + 3.16.1 + test + + diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/BenchmarkConfig.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/BenchmarkConfig.java index 5db6824fa2ea..559ff9255d53 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/BenchmarkConfig.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/BenchmarkConfig.java @@ -16,8 +16,8 @@ public class BenchmarkConfig { public final static String USER_AGENT_SUFFIX = "cosmosdbdotnetbenchmark"; @Parameter(names = "-w", description = "Type of Workload:\n" - + "\tReadTExists - run a READ workload that prints both throughput and latency *\n" + "\tInsert - run a Insert workload that prints both throughput and latency\n" + + "\tInsertWithoutExplicitPKAndId - same as Insert, but parsing PK and id from ObjectNode\n" , converter = Operation.OperationTypeConverter.class) private Operation operation = Operation.Insert; @@ -239,8 +239,8 @@ public boolean isHelp() { } public enum Operation { - ReadTExists, - Insert; + Insert, + InsertWithoutExplicitPKAndId; static Operation fromString(String code) { diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/IBenchmarkOperation.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/IBenchmarkOperation.java index d8a910e94ebe..b4b96cb9d45e 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/IBenchmarkOperation.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/IBenchmarkOperation.java @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.azure.cosmos.dotnet.benchmark; import reactor.core.publisher.Mono; diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/IExecutionStrategy.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/IExecutionStrategy.java index 085f7128319d..f45a0e080181 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/IExecutionStrategy.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/IExecutionStrategy.java @@ -1,6 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.azure.cosmos.dotnet.benchmark; -import com.azure.cosmos.implementation.guava25.base.Function; +import java.util.function.Supplier; interface IExecutionStrategy { RunSummary execute( @@ -11,7 +14,7 @@ RunSummary execute( static IExecutionStrategy startNew( BenchmarkConfig config, - Function benchmarkOperation) { + Supplier benchmarkOperation) { return new ParallelExecutionStrategy(config, benchmarkOperation); } diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/IExecutor.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/IExecutor.java index 4f4a4a4f4982..25dd39d1b9fb 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/IExecutor.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/IExecutor.java @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.azure.cosmos.dotnet.benchmark; import reactor.core.publisher.Mono; diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/JsonHelper.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/JsonHelper.java index e3368f42a520..790d3d7cef1d 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/JsonHelper.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/JsonHelper.java @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.azure.cosmos.dotnet.benchmark; import com.azure.cosmos.implementation.Utils; diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/Main.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/Main.java index ebb6bc1ae871..677aeed48bda 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/Main.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/Main.java @@ -8,7 +8,6 @@ import com.azure.cosmos.CosmosClientBuilder; import com.azure.cosmos.ThrottlingRetryOptions; import com.azure.cosmos.dotnet.benchmark.operations.InsertBenchmarkOperation; -import com.azure.cosmos.implementation.guava25.base.Function; import com.azure.cosmos.models.CosmosItemResponse; import com.azure.cosmos.models.PartitionKey; import com.azure.cosmos.models.PartitionKeyDefinition; @@ -25,6 +24,7 @@ import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.Objects; +import java.util.function.Supplier; public class Main { @@ -99,7 +99,7 @@ public static void main(String[] args) throws Exception { Utility.traceInformation(""); int opsPerTask = cfg.getItemCount() / taskCount; - Function benchmarkFactory = + Supplier benchmarkFactory = getBenchmarkFactory(cfg, partitionKeyPath, cosmosClient); IExecutionStrategy execution = IExecutionStrategy.startNew(cfg, benchmarkFactory); @@ -167,21 +167,35 @@ public static void main(String[] args) throws Exception { cosmosClient.close(); } } - } - private static Function getBenchmarkFactory( + private static Supplier getBenchmarkFactory( BenchmarkConfig cfg, String partitionKeyPath, CosmosAsyncClient cosmosClient) throws IOException { String sampleItem = new String(Files.readAllBytes(Paths.get(cfg.getItemTemplateFile()))); - return (dummy) -> new InsertBenchmarkOperation( - cosmosClient, - cfg.getDatabase(), - cfg.getContainer(), - partitionKeyPath, - sampleItem); + switch (cfg.getOperation()) + { + case InsertWithoutExplicitPKAndId: + return () -> new InsertBenchmarkOperation( + cosmosClient, + cfg.getDatabase(), + cfg.getContainer(), + partitionKeyPath, + sampleItem, + false); + default: + return () -> new InsertBenchmarkOperation( + cosmosClient, + cfg.getDatabase(), + cfg.getContainer(), + partitionKeyPath, + sampleItem, + true); + } + + } } diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/OperationResult.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/OperationResult.java index 72f0a50da16f..83ad6f0f3d18 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/OperationResult.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/OperationResult.java @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.azure.cosmos.dotnet.benchmark; import com.azure.cosmos.implementation.guava25.base.Function; diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/ParallelExecutionStrategy.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/ParallelExecutionStrategy.java index fd837572347b..76ff038d42b3 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/ParallelExecutionStrategy.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/ParallelExecutionStrategy.java @@ -1,6 +1,8 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.azure.cosmos.dotnet.benchmark; -import com.azure.cosmos.implementation.guava25.base.Function; import reactor.core.publisher.Flux; import reactor.core.scheduler.Schedulers; @@ -17,12 +19,12 @@ public class ParallelExecutionStrategy implements IExecutionStrategy { private static final long OUTPUT_LOOP_DELAY_IN_MS = 1000; - private final Function benchmarkOperation; + private final Supplier benchmarkOperation; private final BenchmarkConfig config; private final AtomicInteger pendingExecutorCount = new AtomicInteger(); public ParallelExecutionStrategy(BenchmarkConfig config, - Function benchmarkOperation) { + Supplier benchmarkOperation) { this.config = config; this.benchmarkOperation = benchmarkOperation; @@ -37,7 +39,7 @@ public RunSummary execute( IExecutor warmupExecutor = new SerialOperationExecutor( "Warmup", - this.benchmarkOperation.apply(null)); + this.benchmarkOperation.get()); // Block while warmup happens warmupExecutor.execute( @@ -62,7 +64,7 @@ public RunSummary execute( .flatMap((i) -> { executors[i] = new SerialOperationExecutor( String.valueOf(i), - this.benchmarkOperation.apply(null)); + this.benchmarkOperation.get()); return executors[i].execute( serialExecutorIterationCount, diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/RunSummary.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/RunSummary.java index 5ac1d3e1ad07..650c6aed5c25 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/RunSummary.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/RunSummary.java @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.azure.cosmos.dotnet.benchmark; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/SerialOperationExecutor.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/SerialOperationExecutor.java index e66ab7c83252..07e9110f6947 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/SerialOperationExecutor.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/SerialOperationExecutor.java @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.azure.cosmos.dotnet.benchmark; import reactor.core.publisher.Flux; diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/Summary.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/Summary.java index b0cd9fe541cc..9fb87b165b11 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/Summary.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/Summary.java @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.azure.cosmos.dotnet.benchmark; class Summary { diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/TelemetrySpan.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/TelemetrySpan.java index d32f3f15090a..439b4eb650a4 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/TelemetrySpan.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/TelemetrySpan.java @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.azure.cosmos.dotnet.benchmark; import java.util.Arrays; diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/operations/InsertBenchmarkOperation.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/operations/InsertBenchmarkOperation.java index 920b64f6db77..c29456feb4a1 100644 --- a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/operations/InsertBenchmarkOperation.java +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/main/java/com/azure/cosmos/dotnet/benchmark/operations/InsertBenchmarkOperation.java @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.azure.cosmos.dotnet.benchmark.operations; import com.azure.cosmos.CosmosAsyncClient; @@ -18,6 +21,7 @@ public class InsertBenchmarkOperation implements IBenchmarkOperation { private final String databaseName; private final String partitionKeyPath; private final ObjectNode sampleJsonNode; + private final boolean explicitlyProvidePKAndId; private PartitionKey partitionKey; public InsertBenchmarkOperation( @@ -25,13 +29,15 @@ public InsertBenchmarkOperation( String databaseName, String containerName, String partitionKeyPath, - String sampleJson) { + String sampleJson, + boolean explicitlyProvidePKAndId) { this.databaseName = databaseName; this.containerName = containerName; this.partitionKeyPath = partitionKeyPath.replace("/", ""); this.sampleJsonNode = (ObjectNode)JsonHelper.fromJsonString(sampleJson); this.container = cosmosClient.getDatabase(databaseName).getContainer(containerName); + this.explicitlyProvidePKAndId = explicitlyProvidePKAndId; } @Override @@ -52,10 +58,12 @@ public Mono prepare() { @Override public Mono executeOnce() { - Mono> createTask = this.container.createItem( - this.sampleJsonNode, - this.partitionKey, - null); + Mono> createTask = this.explicitlyProvidePKAndId ? + this.container.createItem( + this.sampleJsonNode, + this.partitionKey, + null) + : this.container.createItem(this.sampleJsonNode); return createTask .map((r) -> { diff --git a/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/test/java/BasicOperationTest.java b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/test/java/BasicOperationTest.java new file mode 100644 index 000000000000..d52e57ed075c --- /dev/null +++ b/sdk/cosmos/azure-cosmos-dotnet-benchmark/src/test/java/BasicOperationTest.java @@ -0,0 +1,154 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import com.azure.core.credential.AzureKeyCredential; +import com.azure.cosmos.CosmosClient; +import com.azure.cosmos.CosmosClientBuilder; +import com.azure.cosmos.CosmosContainer; +import com.azure.cosmos.CosmosDatabase; +import com.azure.cosmos.dotnet.benchmark.Main; +import com.azure.cosmos.implementation.TestConfigurations; +import com.azure.cosmos.models.ThroughputProperties; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +public class BasicOperationTest { + private static final Logger LOGGER = LoggerFactory.getLogger(BasicOperationTest.class.getSimpleName()); + private static final int TIMEOUT = 600000; + + private CosmosClient client; + private CosmosDatabase createdDatabase; + private CosmosContainer createdTestContainer; + private CosmosContainer createdResultsContainer; + + @BeforeClass(groups = {"emulator"}, timeOut = TIMEOUT) + public void before_BasicOperationTest() { + assertThat(this.client).isNull(); + CosmosClientBuilder clientBuilder = new CosmosClientBuilder() + .endpoint(TestConfigurations.HOST) + .credential(new AzureKeyCredential(TestConfigurations.MASTER_KEY)) + .directMode(); + + this.client = clientBuilder.buildClient(); + String suffix = "_" + UUID.randomUUID().toString(); + String testContainerName = "test" + suffix; + String resultsContainerName = "results" + suffix; + this.client.createDatabase("db" + suffix); + this.createdDatabase = this.client.getDatabase("db" + suffix); + this.createdDatabase.createContainer( + "test" + suffix, + "/pk", + ThroughputProperties.createManualThroughput(20000)); + this.createdTestContainer = this.createdDatabase.getContainer("test" + suffix); + this.createdDatabase.createContainer( + "results" + suffix, + "/pk", + ThroughputProperties.createManualThroughput(20000)); + this.createdResultsContainer = this.createdDatabase.getContainer("results" + suffix); + } + + @AfterClass(groups = {"emulator"}, timeOut = TIMEOUT, alwaysRun = true) + public void afterClass() { + assertThat(this.client).isNotNull(); + assertThat(this.createdDatabase).isNotNull(); + this.createdDatabase.delete(); + this.client.close(); + } + + @Test(groups = { "simple" }, timeOut = TIMEOUT) + public void Run_InsertWithoutExplicitPKAndId() throws Exception { + this.runTest( + "InsertWithoutExplicitPKAndId", + 2, 2000); + } + + @Test(groups = { "simple" }, timeOut = TIMEOUT) + public void Run_Insert() throws Exception { + this.runTest( + "Insert", + 2, 2000); + } + + private void runTest(String workload, int concurrency, int numberOfIterations) throws Exception { + String runId = workload + "_" + UUID.randomUUID().toString(); + + LocalDateTime now = LocalDateTime.ofInstant(Instant.now(), ZoneId.of("UTC")); + + String[] args = new String[] { + "-e", TestConfigurations.HOST, + "-k", TestConfigurations.MASTER_KEY, + "--database", this.createdDatabase.getId(), + "--container", this.createdTestContainer.getId(), + "-pl", String.valueOf(concurrency), + "-n", String.valueOf(2000), + "-w", "InsertWithoutExplicitPKAndId", + "--enableLatencyPercentiles", + "--traceFailures", + "--runId", runId, + "--commitId", runId, + "--commitDate", String.format( + "%d-%02d-%02d", + now.getYear(), + now.getMonthValue(), + now.getDayOfMonth()), + "--commitTime", String.format( + "%02d:%02d:%02d.%d", + now.getHour(), + now.getMinute(), + now.getSecond(), + now.getNano()), + "--resultsPartitionKeyValue", runId, + "--resultsContainer", createdResultsContainer.getId(), + "--publishResults" + }; + + Main.main(args); + + LOGGER.info("Finished test run '" + runId + "'"); + + List results = this + .createdResultsContainer + .queryItems( + "SELECT * FROM c WHERE c.pk = '" + runId + "'", + null, + ObjectNode.class) + .stream() + .collect(Collectors.toList()); + + assertThat(results) + .isNotNull() + .hasSize(1); + + ObjectNode result = results.get(0); + + assertThat(result) + .isNotNull(); + + assertThat(result.get("TotalOps")) + .isNotNull(); + assertThat(result.get("TotalOps").asInt(-1)) + .isPositive(); + + LOGGER.info("Results for test run '" + runId + "' ..."); + LOGGER.info(String.format("Total ops: %,.2f", result.get("TotalOps").asDouble())); + LOGGER.info(String.format("Top10 Rps: %,.2f", result.get("Top10PercentAverageRps").asDouble())); + LOGGER.info(String.format("Top20 Rps: %,.2f", result.get("Top20PercentAverageRps").asDouble())); + LOGGER.info(String.format("Top30 Rps: %,.2f", result.get("Top30PercentAverageRps").asDouble())); + LOGGER.info(String.format("P50 latency: %,.2f", result.get("Top50PercentLatencyInMs").asDouble())); + LOGGER.info(String.format("P75 latency: %,.2f", result.get("Top75PercentLatencyInMs").asDouble())); + LOGGER.info(String.format("P95 latency Rps: %,.2f", result.get("Top95PercentAverageRps").asDouble())); + } +} diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/InternalObjectNode.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/InternalObjectNode.java index bcebccd261ef..17891ff7c939 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/InternalObjectNode.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/InternalObjectNode.java @@ -72,6 +72,8 @@ public static InternalObjectNode fromObjectToInternalObjectNode(Object cosmosIte return (InternalObjectNode) cosmosItem; } else if (cosmosItem instanceof byte[]) { return new InternalObjectNode((byte[]) cosmosItem); + } else if (cosmosItem instanceof ObjectNode) { + return new InternalObjectNode((ObjectNode) cosmosItem); } else { try { return new InternalObjectNode(InternalObjectNode.MAPPER.writeValueAsString(cosmosItem)); @@ -87,9 +89,11 @@ public static InternalObjectNode fromObjectToInternalObjectNode(Object cosmosIte public static Document fromObject(Object cosmosItem) { Document typedItem; if (cosmosItem instanceof InternalObjectNode) { - typedItem = new Document(((InternalObjectNode) cosmosItem).toJson()); + return new Document(((InternalObjectNode) cosmosItem).toJson()); } else if (cosmosItem instanceof byte[]) { return new Document((byte[]) cosmosItem); + } else if (cosmosItem instanceof ObjectNode) { + return new Document((new InternalObjectNode((ObjectNode)cosmosItem)).toJson()); } else { try { return new Document(InternalObjectNode.MAPPER.writeValueAsString(cosmosItem)); @@ -97,8 +101,6 @@ public static Document fromObject(Object cosmosItem) { throw new IllegalArgumentException("Can't serialize the object into the json string", e); } } - - return typedItem; } public static ByteBuffer serializeJsonToByteBuffer(Object cosmosItem, ObjectMapper objectMapper) { @@ -106,6 +108,8 @@ public static ByteBuffer serializeJsonToByteBuffer(Object cosmosItem, ObjectMapp return ((InternalObjectNode) cosmosItem).serializeJsonToByteBuffer(); } else if (cosmosItem instanceof Document) { return ModelBridgeInternal.serializeJsonToByteBuffer((Document) cosmosItem); + } else if (cosmosItem instanceof ObjectNode) { + return (new InternalObjectNode((ObjectNode)cosmosItem).serializeJsonToByteBuffer()); } else if (cosmosItem instanceof byte[]) { return ByteBuffer.wrap((byte[]) cosmosItem); } else { @@ -115,7 +119,7 @@ public static ByteBuffer serializeJsonToByteBuffer(Object cosmosItem, ObjectMapp static List getTypedResultsFromV2Results(List results, Class klass) { return results.stream().map(document -> ModelBridgeInternal.toObjectFromJsonSerializable(document, klass)) - .collect(Collectors.toList()); + .collect(Collectors.toList()); } /** @@ -126,8 +130,13 @@ static List getTypedResultsFromV2Results(List results, Class * @return the object * @throws IOException the io exception */ + @SuppressWarnings("unchecked") public T getObject(Class klass) throws IOException { - return MAPPER.readValue(this.toJson(), klass); - } -} + if (klass == ObjectNode.class) { + return (T) this.getPropertyBag(); + } + + return MAPPER.treeToValue(this.getPropertyBag(), klass); + } +} \ No newline at end of file diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java index 5dfeff17b83a..0d41e6028cb2 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java @@ -1211,6 +1211,8 @@ private void addPartitionKeyInformation(RxDocumentServiceRequest request, InternalObjectNode internalObjectNode; if (objectDoc instanceof InternalObjectNode) { internalObjectNode = (InternalObjectNode) objectDoc; + } else if (objectDoc instanceof ObjectNode) { + internalObjectNode = new InternalObjectNode((ObjectNode)objectDoc); } else if (contentAsByteBuffer != null) { contentAsByteBuffer.rewind(); internalObjectNode = new InternalObjectNode(contentAsByteBuffer); diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosItemTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosItemTest.java index 27bd628431ac..51ae3be27421 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosItemTest.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosItemTest.java @@ -67,7 +67,6 @@ public void createItem() throws Exception { properties = getDocumentDefinition(UUID.randomUUID().toString()); CosmosItemResponse itemResponse1 = container.createItem(properties, new CosmosItemRequestOptions()); validateItemResponse(properties, itemResponse1); - } @Test(groups = {"simple"}, timeOut = TIMEOUT) diff --git a/sdk/cosmos/pom.xml b/sdk/cosmos/pom.xml index bb852964708f..c0a5f66ad25e 100644 --- a/sdk/cosmos/pom.xml +++ b/sdk/cosmos/pom.xml @@ -59,6 +59,7 @@ azure-cosmos azure-cosmos-benchmark + azure-cosmos-dotnet-benchmark azure-cosmos-encryption azure-spring-data-cosmos azure-spring-data-cosmos-test