diff --git a/sdk/cosmos/azure-cosmos-examples/src/main/java/com/azure/cosmos/rx/examples/multimaster/samples/ConflictWorker.java b/sdk/cosmos/azure-cosmos-examples/src/main/java/com/azure/cosmos/rx/examples/multimaster/samples/ConflictWorker.java index 7a896476392f..a9cff24b35d0 100644 --- a/sdk/cosmos/azure-cosmos-examples/src/main/java/com/azure/cosmos/rx/examples/multimaster/samples/ConflictWorker.java +++ b/sdk/cosmos/azure-cosmos-examples/src/main/java/com/azure/cosmos/rx/examples/multimaster/samples/ConflictWorker.java @@ -4,6 +4,7 @@ package com.azure.cosmos.rx.examples.multimaster.samples; import com.azure.cosmos.BridgeInternal; +import com.azure.cosmos.implementation.OperationKind; import com.azure.cosmos.models.ConflictResolutionPolicy; import com.azure.cosmos.CosmosException; import com.azure.cosmos.models.FeedResponse; @@ -575,7 +576,7 @@ private void validateManualConflict(List clients, Document } private boolean isDelete(Conflict conflict) { - return StringUtils.equalsIgnoreCase(conflict.getOperationKind(), "delete"); + return OperationKind.DELETE == conflict.getOperationKind(); } diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/Conflict.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/Conflict.java index 52627f3934b5..8f332e06a85b 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/Conflict.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/Conflict.java @@ -33,8 +33,8 @@ public Conflict(String jsonString) { * * @return the operation kind. */ - public String getOperationKind() { - return super.getString(Constants.Properties.OPERATION_TYPE); + public OperationKind getOperationKind() { + return OperationKind.fromServiceSerializedFormat(super.getString(Constants.Properties.OPERATION_TYPE)); } /** diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/OperationKind.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/OperationKind.java new file mode 100644 index 000000000000..3b159700ba0a --- /dev/null +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/OperationKind.java @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.cosmos.implementation; + +import java.util.HashMap; +import java.util.Map; + +/** + * Types of operation in Azure Cosmos DB result in conflict + */ +public enum OperationKind { + CREATE("create"), + DELETE("delete"), + REPLACE("replace"), + UPDATE("update"), + UNKNOWN("unknown"); + + private final String stringValue; + private static Map operationKindHashMap = new HashMap<>(); + static { + for (OperationKind cl : OperationKind.values()) { + operationKindHashMap.put(cl.toString(), cl); + } + } + OperationKind(String stringValue) { + this.stringValue = stringValue; + } + + /** + * Given the over wire version of OperationKind gives the corresponding enum or return UNKNOWN + * + * @param operationKind String value of OperationKind + * @return OperationKind Enum operation kind + */ + static OperationKind fromServiceSerializedFormat(String operationKind) { + + OperationKind operationKindEnum = operationKindHashMap.get(operationKind); + if (operationKindEnum == null) { + operationKindEnum = OperationKind.UNKNOWN; + } + + return operationKindEnum; + } + + @Override + public String toString() { + return this.stringValue; + } +} diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosConflictProperties.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosConflictProperties.java index 4a2bb02683dc..f347343cb1fe 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosConflictProperties.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosConflictProperties.java @@ -3,6 +3,7 @@ package com.azure.cosmos.models; import com.azure.cosmos.implementation.Conflict; +import com.azure.cosmos.implementation.OperationKind; import com.azure.cosmos.implementation.Resource; import java.time.OffsetDateTime; @@ -37,7 +38,7 @@ public final class CosmosConflictProperties { * * @return the operation kind. */ - public String getOperationKind() { + public OperationKind getOperationKind() { return this.conflict.getOperationKind(); } diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/ConflictTests.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/ConflictTests.java index b317740fef14..bc5a891abd51 100644 --- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/ConflictTests.java +++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/ConflictTests.java @@ -5,44 +5,62 @@ import com.azure.cosmos.implementation.Conflict; import com.azure.cosmos.implementation.Document; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.io.IOUtils; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import java.util.ArrayList; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; public class ConflictTests { - private String conflictAsString; + private List confList = new ArrayList(); @BeforeClass(groups = { "unit" }) public void before_ConflictTests() throws Exception { - conflictAsString = IOUtils.toString( + String conflictAsString = IOUtils.toString( getClass().getClassLoader().getResourceAsStream("sampleConflict.json"), "UTF-8"); + ObjectMapper mapper = new ObjectMapper(); + JsonNode valuesNode = mapper.readTree(conflictAsString).get("conflictList"); + for (JsonNode node : valuesNode) { + confList.add(node.toString()); + } } @Test(groups = { "unit" }) public void getSourceResourceId() { - Conflict conf = new Conflict(conflictAsString); + Conflict conf = new Conflict(confList.get(0)); assertThat(conf.getSourceResourceId()).isEqualTo("k6d9ALgBmD+ChB4AAAAAAA=="); } @Test(groups = { "unit" }) public void getOperationKind() { - Conflict conf = new Conflict(conflictAsString); - assertThat(conf.getOperationKind()).isEqualTo("create"); + Conflict conf = new Conflict(confList.get(0)); + assertThat(conf.getOperationKind().toString()).isEqualTo("create"); + conf = new Conflict(confList.get(1)); + assertThat(conf.getOperationKind().toString()).isEqualTo("update"); + conf = new Conflict(confList.get(2)); + assertThat(conf.getOperationKind().toString()).isEqualTo("delete"); + conf = new Conflict(confList.get(3)); + assertThat(conf.getOperationKind().toString()).isEqualTo("replace"); + conf = new Conflict(confList.get(4)); + assertThat(conf.getOperationKind().toString()).isEqualTo("unknown"); conf.getSourceResourceId(); } @Test(groups = { "unit" }) public void getResourceType() { - Conflict conf = new Conflict(conflictAsString); + Conflict conf = new Conflict(confList.get(0)); assertThat(conf.getResourceType()).isEqualTo("document"); conf.getSourceResourceId(); } @Test(groups = { "unit" }) public void getResource() { - Conflict conf = new Conflict(conflictAsString); + Conflict conf = new Conflict(confList.get(0)); Document doc = conf.getResource(Document.class); assertThat(doc.getId()).isEqualTo("0007312a-a1c5-4b54-9e39-35de2367fa33"); assertThat(doc.getInt("regionId")).isEqualTo(2); diff --git a/sdk/cosmos/azure-cosmos/src/test/resources/sampleConflict.json b/sdk/cosmos/azure-cosmos/src/test/resources/sampleConflict.json index 12f2a507b7a3..081ee6fc4b2b 100644 --- a/sdk/cosmos/azure-cosmos/src/test/resources/sampleConflict.json +++ b/sdk/cosmos/azure-cosmos/src/test/resources/sampleConflict.json @@ -1,11 +1,59 @@ { - "id": "k6d9ALgBmD8BAAAAAAAAQA==", - "_rid": "k6d9ALgBmD8BAAAAAAAAQA==", - "_self": "dbs/k6d9AA==/colls/k6d9ALgBmD8=/conflicts/k6d9ALgBmD8BAAAAAAAAQA==/", - "_etag": "\"00004a0f-0000-0000-0000-5b6e214b0000\"", - "resourceType": "document", - "operationType": "create", - "resourceId": "k6d9ALgBmD+ChB4AAAAAAA==", - "content": "{\"id\":\"0007312a-a1c5-4b54-9e39-35de2367fa33\",\"regionId\":2,\"regionEndpoint\":\"https://test-southeastasia.documents.azure.com:443/\",\"_rid\":\"k6d9ALgBmD+ChB4AAAAAAA==\",\"_self\":\"dbs\\/k6d9AA==\\/colls\\/k6d9ALgBmD8=\\/docs\\/k6d9ALgBmD+ChB4AAAAAAA==\\/\",\"_etag\":\"\\\"00000200-0000-0000-0000-5b6e214b0000\\\"\",\"_attachments\":\"attachments\\/\",\"_ts\":1533944139}", - "_ts": 1533944139 + "conflictList": [ + { + "id": "k6d9ALgBmD8BAAAAAAAAQA==", + "_rid": "k6d9ALgBmD8BAAAAAAAAQA==", + "_self": "dbs/k6d9AA==/colls/k6d9ALgBmD8=/conflicts/k6d9ALgBmD8BAAAAAAAAQA==/", + "_etag": "\"00004a0f-0000-0000-0000-5b6e214b0000\"", + "resourceType": "document", + "operationType": "create", + "resourceId": "k6d9ALgBmD+ChB4AAAAAAA==", + "content": "{\"id\":\"0007312a-a1c5-4b54-9e39-35de2367fa33\",\"regionId\":2,\"regionEndpoint\":\"https://test-southeastasia.documents.azure.com:443/\",\"_rid\":\"k6d9ALgBmD+ChB4AAAAAAA==\",\"_self\":\"dbs\\/k6d9AA==\\/colls\\/k6d9ALgBmD8=\\/docs\\/k6d9ALgBmD+ChB4AAAAAAA==\\/\",\"_etag\":\"\\\"00000200-0000-0000-0000-5b6e214b0000\\\"\",\"_attachments\":\"attachments\\/\",\"_ts\":1533944139}", + "_ts": 1533944139 + }, + { + "id": "k6d9ALgBmD8BAAAAAAAAQA==", + "_rid": "k6d9ALgBmD8BAAAAAAAAQA==", + "_self": "dbs/k6d9AA==/colls/k6d9ALgBmD8=/conflicts/k6d9ALgBmD8BAAAAAAAAQA==/", + "_etag": "\"00004a0f-0000-0000-0000-5b6e214b0000\"", + "resourceType": "document", + "operationType": "update", + "resourceId": "k6d9ALgBmD+ChB4AAAAAAA==", + "content": "{\"id\":\"0007312a-a1c5-4b54-9e39-35de2367fa33\",\"regionId\":2,\"regionEndpoint\":\"https://test-southeastasia.documents.azure.com:443/\",\"_rid\":\"k6d9ALgBmD+ChB4AAAAAAA==\",\"_self\":\"dbs\\/k6d9AA==\\/colls\\/k6d9ALgBmD8=\\/docs\\/k6d9ALgBmD+ChB4AAAAAAA==\\/\",\"_etag\":\"\\\"00000200-0000-0000-0000-5b6e214b0000\\\"\",\"_attachments\":\"attachments\\/\",\"_ts\":1533944139}", + "_ts": 1533944139 + }, + { + "id": "k6d9ALgBmD8BAAAAAAAAQA==", + "_rid": "k6d9ALgBmD8BAAAAAAAAQA==", + "_self": "dbs/k6d9AA==/colls/k6d9ALgBmD8=/conflicts/k6d9ALgBmD8BAAAAAAAAQA==/", + "_etag": "\"00004a0f-0000-0000-0000-5b6e214b0000\"", + "resourceType": "document", + "operationType": "delete", + "resourceId": "k6d9ALgBmD+ChB4AAAAAAA==", + "content": "{\"id\":\"0007312a-a1c5-4b54-9e39-35de2367fa33\",\"regionId\":2,\"regionEndpoint\":\"https://test-southeastasia.documents.azure.com:443/\",\"_rid\":\"k6d9ALgBmD+ChB4AAAAAAA==\",\"_self\":\"dbs\\/k6d9AA==\\/colls\\/k6d9ALgBmD8=\\/docs\\/k6d9ALgBmD+ChB4AAAAAAA==\\/\",\"_etag\":\"\\\"00000200-0000-0000-0000-5b6e214b0000\\\"\",\"_attachments\":\"attachments\\/\",\"_ts\":1533944139}", + "_ts": 1533944139 + }, + { + "id": "k6d9ALgBmD8BAAAAAAAAQA==", + "_rid": "k6d9ALgBmD8BAAAAAAAAQA==", + "_self": "dbs/k6d9AA==/colls/k6d9ALgBmD8=/conflicts/k6d9ALgBmD8BAAAAAAAAQA==/", + "_etag": "\"00004a0f-0000-0000-0000-5b6e214b0000\"", + "resourceType": "document", + "operationType": "replace", + "resourceId": "k6d9ALgBmD+ChB4AAAAAAA==", + "content": "{\"id\":\"0007312a-a1c5-4b54-9e39-35de2367fa33\",\"regionId\":2,\"regionEndpoint\":\"https://test-southeastasia.documents.azure.com:443/\",\"_rid\":\"k6d9ALgBmD+ChB4AAAAAAA==\",\"_self\":\"dbs\\/k6d9AA==\\/colls\\/k6d9ALgBmD8=\\/docs\\/k6d9ALgBmD+ChB4AAAAAAA==\\/\",\"_etag\":\"\\\"00000200-0000-0000-0000-5b6e214b0000\\\"\",\"_attachments\":\"attachments\\/\",\"_ts\":1533944139}", + "_ts": 1533944139 + }, + { + "id": "k6d9ALgBmD8BAAAAAAAAQA==", + "_rid": "k6d9ALgBmD8BAAAAAAAAQA==", + "_self": "dbs/k6d9AA==/colls/k6d9ALgBmD8=/conflicts/k6d9ALgBmD8BAAAAAAAAQA==/", + "_etag": "\"00004a0f-0000-0000-0000-5b6e214b0000\"", + "resourceType": "document", + "operationType": "wrongType", + "resourceId": "k6d9ALgBmD+ChB4AAAAAAA==", + "content": "{\"id\":\"0007312a-a1c5-4b54-9e39-35de2367fa33\",\"regionId\":2,\"regionEndpoint\":\"https://test-southeastasia.documents.azure.com:443/\",\"_rid\":\"k6d9ALgBmD+ChB4AAAAAAA==\",\"_self\":\"dbs\\/k6d9AA==\\/colls\\/k6d9ALgBmD8=\\/docs\\/k6d9ALgBmD+ChB4AAAAAAA==\\/\",\"_etag\":\"\\\"00000200-0000-0000-0000-5b6e214b0000\\\"\",\"_attachments\":\"attachments\\/\",\"_ts\":1533944139}", + "_ts": 1533944139 + } + ] }