diff --git a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionContainer.cs b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionContainer.cs index 40f4ad0694..fff1fb0a8b 100644 --- a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionContainer.cs +++ b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionContainer.cs @@ -12,6 +12,7 @@ namespace Microsoft.Azure.Cosmos.Encryption using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Cosmos; + using Microsoft.Data.Encryption.Cryptography; using Newtonsoft.Json.Linq; internal sealed class EncryptionContainer : Container @@ -604,24 +605,140 @@ public override FeedIterator GetChangeFeedIterator( this.ResponseFactory); } - public override Task> PatchItemAsync( + public async override Task> PatchItemAsync( string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions = null, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + ResponseMessage responseMessage = await this.PatchItemStreamAsync( + id, + partitionKey, + patchOperations, + requestOptions, + cancellationToken); + + return this.ResponseFactory.CreateItemResponse(responseMessage); } - public override Task PatchItemStreamAsync( + public async override Task PatchItemStreamAsync( string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions = null, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + if (string.IsNullOrWhiteSpace(id)) + { + throw new ArgumentNullException(nameof(id)); + } + + if (partitionKey == null) + { + throw new ArgumentNullException(nameof(partitionKey)); + } + + if (patchOperations == null || + !patchOperations.Any()) + { + throw new ArgumentNullException(nameof(patchOperations)); + } + + EncryptionSettings encryptionSettings = await this.GetOrUpdateEncryptionSettingsFromCacheAsync( + obsoleteEncryptionSettings: null, + cancellationToken: cancellationToken); + + CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); + using (diagnosticsContext.CreateScope("PatchItem")) + { + List encryptedPatchOperations = await this.PatchItemHelperAsync( + patchOperations, + encryptionSettings, + cancellationToken); + + ResponseMessage responseMessage = await this.container.PatchItemStreamAsync( + id, + partitionKey, + encryptedPatchOperations, + requestOptions, + cancellationToken); + + responseMessage.Content = await EncryptionProcessor.DecryptAsync( + responseMessage.Content, + encryptionSettings, + diagnosticsContext, + cancellationToken); + + return responseMessage; + } + } + + private async Task> PatchItemHelperAsync( + IReadOnlyList patchOperations, + EncryptionSettings encryptionSettings, + CancellationToken cancellationToken = default) + { + List encryptedPatchOperations = new List(patchOperations.Count); + + foreach (PatchOperation patchOperation in patchOperations) + { + if (patchOperation.OperationType == PatchOperationType.Remove) + { + encryptedPatchOperations.Add(patchOperation); + continue; + } + + if (string.IsNullOrWhiteSpace(patchOperation.Path) || patchOperation.Path[0] != '/') + { + throw new ArgumentException($"Invalid path '{patchOperation.Path}'."); + } + + // get the top level path's encryption setting. + EncryptionSettingForProperty settingforProperty = encryptionSettings.GetEncryptionSettingForProperty( + patchOperation.Path.Split('/')[1]); + + // non-encrypted path + if (settingforProperty == null) + { + encryptedPatchOperations.Add(patchOperation); + continue; + } + else if (patchOperation.OperationType == PatchOperationType.Increment) + { + throw new InvalidOperationException($"Increment patch operation is not allowed for encrypted path '{patchOperation.Path}'."); + } + + if (!patchOperation.TrySerializeValueParameter(this.CosmosSerializer, out Stream valueParam)) + { + throw new ArgumentException($"Cannot serialize value parameter for operation: {patchOperation.OperationType}, path: {patchOperation.Path}."); + } + + Stream encryptedPropertyValue = await EncryptionProcessor.EncryptValueStreamAsync( + valueParam, + settingforProperty, + cancellationToken); + + switch (patchOperation.OperationType) + { + case PatchOperationType.Add: + encryptedPatchOperations.Add(PatchOperation.Add(patchOperation.Path, encryptedPropertyValue)); + break; + + case PatchOperationType.Replace: + encryptedPatchOperations.Add(PatchOperation.Replace(patchOperation.Path, encryptedPropertyValue)); + break; + + case PatchOperationType.Set: + encryptedPatchOperations.Add(PatchOperation.Set(patchOperation.Path, encryptedPropertyValue)); + break; + + default: + throw new NotSupportedException(nameof(patchOperation.OperationType)); + } + } + + return encryptedPatchOperations; } public override ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder( diff --git a/Microsoft.Azure.Cosmos.Encryption/tests/EmulatorTests/MdeEncryptionTests.cs b/Microsoft.Azure.Cosmos.Encryption/tests/EmulatorTests/MdeEncryptionTests.cs index cfb5670639..9407d7ae40 100644 --- a/Microsoft.Azure.Cosmos.Encryption/tests/EmulatorTests/MdeEncryptionTests.cs +++ b/Microsoft.Azure.Cosmos.Encryption/tests/EmulatorTests/MdeEncryptionTests.cs @@ -511,7 +511,7 @@ await MdeEncryptionTests.ValidateQueryResultsAsync( await MdeEncryptionTests.ValidateQueryResultsAsync( MdeEncryptionTests.encryptionContainer, - "SELECT c.id, c.PK, c.NonSensitive FROM c", + "SELECT c.id, c.PK, c.NonSensitive, c.NonSensitiveInt FROM c", expectedDoc); } @@ -1571,6 +1571,122 @@ public async Task EncryptionRudItem() await MdeEncryptionTests.MdeDeleteItemAsync(MdeEncryptionTests.encryptionContainer, replacedDoc); } + [TestMethod] + public async Task EncryptionPatchItem() + { + TestDoc docPostPatching = await MdeEncryptionTests.MdeCreateItemAsync(MdeEncryptionTests.encryptionContainer); + docPostPatching.NonSensitive = Guid.NewGuid().ToString(); + docPostPatching.NonSensitiveInt++; + docPostPatching.Sensitive_StringFormat = Guid.NewGuid().ToString(); + docPostPatching.Sensitive_DateFormat = new DateTime(2020, 02, 02); + docPostPatching.Sensitive_DecimalFormat = 11.11m; + docPostPatching.Sensitive_IntArray[1] = 1; + docPostPatching.Sensitive_IntMultiDimArray[1, 0] = 7; + docPostPatching.Sensitive_IntFormat = 2020; + docPostPatching.Sensitive_BoolFormat = false; + docPostPatching.Sensitive_FloatFormat = 2020.20f; + + // Maximum 10 operations at a time (current limit) + List patchOperations = new List + { + PatchOperation.Increment("/NonSensitiveInt", 1), + PatchOperation.Replace("/NonSensitive", docPostPatching.NonSensitive), + PatchOperation.Replace("/Sensitive_StringFormat", docPostPatching.Sensitive_StringFormat), + PatchOperation.Replace("/Sensitive_DateFormat", docPostPatching.Sensitive_DateFormat), + PatchOperation.Replace("/Sensitive_DecimalFormat", docPostPatching.Sensitive_DecimalFormat), + PatchOperation.Set("/Sensitive_IntArray/1", docPostPatching.Sensitive_IntArray[1]), + PatchOperation.Set("/Sensitive_IntMultiDimArray/1/0", docPostPatching.Sensitive_IntMultiDimArray[1,0]), + PatchOperation.Replace("/Sensitive_IntFormat", docPostPatching.Sensitive_IntFormat), + PatchOperation.Replace("/Sensitive_BoolFormat", docPostPatching.Sensitive_BoolFormat), + PatchOperation.Replace("/Sensitive_FloatFormat", docPostPatching.Sensitive_FloatFormat), + }; + + await MdeEncryptionTests.MdePatchItemAsync( + MdeEncryptionTests.encryptionContainer, + patchOperations, + docPostPatching, + HttpStatusCode.OK); + + docPostPatching.Sensitive_ArrayFormat = new TestDoc.Sensitive_ArrayData[] + { + new TestDoc.Sensitive_ArrayData + { + Sensitive_ArrayIntFormat = 1111, + Sensitive_ArrayDecimalFormat = 1111.11m + }, + new TestDoc.Sensitive_ArrayData + { + Sensitive_ArrayIntFormat = 2222, + Sensitive_ArrayDecimalFormat = 2222.22m + } + }; + + docPostPatching.Sensitive_ArrayMultiTypes.SetValue( + new TestDoc.Sensitive_ArrayMultiType() + { + Sensitive_NestedObjectFormatL0 = new TestDoc.Sensitive_NestedObjectL0() + { + Sensitive_IntFormatL0 = 123, + Sensitive_DecimalFormatL0 = 123.1m, + }, + Sensitive_StringArrayMultiType = new string[1] { "sensitivedata" }, + Sensitive_ArrayMultiTypeDecimalFormat = 123.2m, + Sensitive_IntArrayMultiType = new int[2] { 1, 2 } + }, + 0, + 1); + + docPostPatching.Sensitive_NestedObjectFormatL1 = new TestDoc.Sensitive_NestedObjectL1() + { + Sensitive_IntArrayL1 = new int[2] { 999, 100 }, + Sensitive_IntFormatL1 = 1999, + Sensitive_DecimalFormatL1 = 1999.1m, + Sensitive_ArrayFormatL1 = new TestDoc.Sensitive_ArrayData[] + { + new TestDoc.Sensitive_ArrayData + { + Sensitive_ArrayIntFormat = 0, + Sensitive_ArrayDecimalFormat = 0.1m + }, + new TestDoc.Sensitive_ArrayData + { + Sensitive_ArrayIntFormat = 1, + Sensitive_ArrayDecimalFormat = 2.1m + }, + new TestDoc.Sensitive_ArrayData + { + Sensitive_ArrayIntFormat = 2, + Sensitive_ArrayDecimalFormat = 3.1m + } + } + }; + + patchOperations.Clear(); + patchOperations.Add(PatchOperation.Add("/Sensitive_ArrayFormat/1", docPostPatching.Sensitive_ArrayFormat[1])); + patchOperations.Add(PatchOperation.Replace("/Sensitive_ArrayMultiTypes/0/1", docPostPatching.Sensitive_ArrayMultiTypes[0, 1])); + patchOperations.Add(PatchOperation.Remove("/Sensitive_NestedObjectFormatL1/Sensitive_NestedObjectFormatL2")); + patchOperations.Add(PatchOperation.Set("/Sensitive_NestedObjectFormatL1/Sensitive_ArrayFormatL1/0", docPostPatching.Sensitive_NestedObjectFormatL1.Sensitive_ArrayFormatL1[0])); + + await MdeEncryptionTests.MdePatchItemAsync( + MdeEncryptionTests.encryptionContainer, + patchOperations, + docPostPatching, + HttpStatusCode.OK); + + patchOperations.Add(PatchOperation.Increment("/Sensitive_IntFormat", 1)); + try + { + await MdeEncryptionTests.encryptionContainer.PatchItemAsync( + docPostPatching.Id, + new PartitionKey(docPostPatching.PK), + patchOperations); + } + catch(InvalidOperationException ex) + { + Assert.AreEqual("Increment patch operation is not allowed for encrypted path '/Sensitive_IntFormat'.", ex.Message); + } + } + [TestMethod] public async Task EncryptionTransactionalBatchWithCustomSerializer() { @@ -2126,6 +2242,23 @@ private static async Task> MdeReplaceItemAsync( VerifyExpectedDocResponse(testDoc, replaceResponse.Resource); return replaceResponse; } + + private static async Task> MdePatchItemAsync( + Container container, + List patchOperations, + TestDoc expectedTestDoc, + HttpStatusCode expectedStatusCode) + { + ItemResponse patchResponse = await container.PatchItemAsync( + expectedTestDoc.Id, + new PartitionKey(expectedTestDoc.PK), + patchOperations); + + Assert.AreEqual(expectedStatusCode, patchResponse.StatusCode); + VerifyExpectedDocResponse(expectedTestDoc, patchResponse.Resource); + return patchResponse; + } + private static ItemRequestOptions MdeGetRequestOptions( string ifMatchEtag = null) { @@ -2221,8 +2354,8 @@ private static void VerifyExpectedDocResponse(TestDoc expectedDoc, TestDoc verif for (int k = 0; k < expectedDoc.Sensitive_ArrayMultiTypes[i,j].Sensitive_IntArrayMultiType.Length; k++) { - Assert.AreEqual(expectedDoc.Sensitive_ArrayMultiTypes[i,j].Sensitive_StringArrayMultiType[k], - verifyDoc.Sensitive_ArrayMultiTypes[i,j].Sensitive_StringArrayMultiType[k]); + Assert.AreEqual(expectedDoc.Sensitive_ArrayMultiTypes[i,j].Sensitive_IntArrayMultiType[k], + verifyDoc.Sensitive_ArrayMultiTypes[i,j].Sensitive_IntArrayMultiType[k]); } } } @@ -2231,41 +2364,49 @@ private static void VerifyExpectedDocResponse(TestDoc expectedDoc, TestDoc verif if (expectedDoc.Sensitive_NestedObjectFormatL1 != null) { Assert.AreEqual(expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_IntFormatL1, verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_IntFormatL1); - Assert.AreEqual( - expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_IntFormatL2, - verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_IntFormatL2); - Assert.AreEqual( - expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_IntFormatL3, - verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_IntFormatL3); + if (expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2 == null) + { + Assert.IsNull(verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2); + } + else + { + Assert.AreEqual( + expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_IntFormatL2, + verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_IntFormatL2); + + Assert.AreEqual( + expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_IntFormatL3, + verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_IntFormatL3); - Assert.AreEqual( - expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_DecimalFormatL3, - verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_DecimalFormatL3); + Assert.AreEqual( + expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_DecimalFormatL3, + verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_DecimalFormatL3); - Assert.AreEqual( - expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayFormatL3[0].Sensitive_ArrayIntFormat, - verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayFormatL3[0].Sensitive_ArrayIntFormat); + Assert.AreEqual( + expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayFormatL3[0].Sensitive_ArrayIntFormat, + verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayFormatL3[0].Sensitive_ArrayIntFormat); - Assert.AreEqual( - expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayFormatL3[0].Sensitive_ArrayDecimalFormat, - verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayFormatL3[0].Sensitive_ArrayDecimalFormat); + Assert.AreEqual( + expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayFormatL3[0].Sensitive_ArrayDecimalFormat, + verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayFormatL3[0].Sensitive_ArrayDecimalFormat); - Assert.AreEqual( - expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_ArrayDecimalFormat, - verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_ArrayDecimalFormat); + Assert.AreEqual( + expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_ArrayDecimalFormat, + verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_ArrayDecimalFormat); - Assert.AreEqual( - expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_ArrayIntFormat, - verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_ArrayIntFormat); + Assert.AreEqual( + expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_ArrayIntFormat, + verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_ArrayIntFormat); - Assert.AreEqual( - expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_NestedObjectFormatL0.Sensitive_IntFormatL0, - verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_NestedObjectFormatL0.Sensitive_IntFormatL0); + Assert.AreEqual( + expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_NestedObjectFormatL0.Sensitive_IntFormatL0, + verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_NestedObjectFormatL0.Sensitive_IntFormatL0); - Assert.AreEqual( - expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_NestedObjectFormatL0.Sensitive_DecimalFormatL0, - verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_NestedObjectFormatL0.Sensitive_DecimalFormatL0); + Assert.AreEqual( + expectedDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_NestedObjectFormatL0.Sensitive_DecimalFormatL0, + verifyDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_NestedObjectFormatL3.Sensitive_ArrayWithObjectFormat[0].Sensitive_NestedObjectFormatL0.Sensitive_DecimalFormatL0); + } } else { @@ -2278,6 +2419,7 @@ private static void VerifyExpectedDocResponse(TestDoc expectedDoc, TestDoc verif Assert.AreEqual(expectedDoc.Sensitive_FloatFormat, verifyDoc.Sensitive_FloatFormat); Assert.AreEqual(expectedDoc.Sensitive_BoolFormat, verifyDoc.Sensitive_BoolFormat); Assert.AreEqual(expectedDoc.NonSensitive, verifyDoc.NonSensitive); + Assert.AreEqual(expectedDoc.NonSensitiveInt, verifyDoc.NonSensitiveInt); } public class TestDoc @@ -2290,6 +2432,8 @@ public class TestDoc public string NonSensitive { get; set; } + public int NonSensitiveInt { get; set; } + public string Sensitive_StringFormat { get; set; } public DateTime Sensitive_DateFormat { get; set; } @@ -2375,6 +2519,7 @@ public TestDoc(TestDoc other) this.Id = other.Id; this.PK = other.PK; this.NonSensitive = other.NonSensitive; + this.NonSensitiveInt = other.NonSensitiveInt; this.Sensitive_StringFormat = other.Sensitive_StringFormat; this.Sensitive_DateFormat = other.Sensitive_DateFormat; this.Sensitive_DecimalFormat = other.Sensitive_DecimalFormat; @@ -2394,6 +2539,7 @@ public override bool Equals(object obj) && this.Id == doc.Id && this.PK == doc.PK && this.NonSensitive == doc.NonSensitive + && this.NonSensitiveInt == doc.NonSensitiveInt && this.Sensitive_StringFormat == doc.Sensitive_StringFormat && this.Sensitive_DateFormat == doc.Sensitive_DateFormat && this.Sensitive_DecimalFormat == doc.Sensitive_DecimalFormat @@ -2413,6 +2559,7 @@ public bool EqualsExceptEncryptedProperty(object obj) && this.Id == doc.Id && this.PK == doc.PK && this.NonSensitive == doc.NonSensitive + && this.NonSensitiveInt == doc.NonSensitiveInt && this.Sensitive_StringFormat != doc.Sensitive_StringFormat; } public override int GetHashCode() @@ -2421,6 +2568,7 @@ public override int GetHashCode() hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.Id); hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.PK); hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.NonSensitive); + hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.NonSensitiveInt); hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.Sensitive_StringFormat); hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.Sensitive_DateFormat); hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.Sensitive_DecimalFormat); @@ -2441,6 +2589,7 @@ public static TestDoc Create(string partitionKey = null) Id = Guid.NewGuid().ToString(), PK = partitionKey ?? Guid.NewGuid().ToString(), NonSensitive = Guid.NewGuid().ToString(), + NonSensitiveInt = 10, Sensitive_StringFormat = Guid.NewGuid().ToString(), Sensitive_DateFormat = new DateTime(1987, 12, 25), Sensitive_DecimalFormat = 472.3108m, @@ -2469,7 +2618,7 @@ public static TestDoc Create(string partitionKey = null) Sensitive_ArrayMultiTypes = new Sensitive_ArrayMultiType[,] { { - new Sensitive_ArrayMultiType() + new Sensitive_ArrayMultiType() { Sensitive_NestedObjectFormatL0 = new Sensitive_NestedObjectL0() { @@ -2480,7 +2629,7 @@ public static TestDoc Create(string partitionKey = null) Sensitive_ArrayMultiTypeDecimalFormat = 10.2m, Sensitive_IntArrayMultiType = new int[2] { 999, 1000 } }, - new Sensitive_ArrayMultiType() + new Sensitive_ArrayMultiType() { Sensitive_NestedObjectFormatL0 = new Sensitive_NestedObjectL0() { @@ -2493,7 +2642,7 @@ public static TestDoc Create(string partitionKey = null) } }, { - new Sensitive_ArrayMultiType() + new Sensitive_ArrayMultiType() { Sensitive_NestedObjectFormatL0 = new Sensitive_NestedObjectL0() { @@ -2504,7 +2653,7 @@ public static TestDoc Create(string partitionKey = null) Sensitive_ArrayMultiTypeDecimalFormat = 9876.2m, Sensitive_IntArrayMultiType = new int[2] { 1, 2 } }, - new Sensitive_ArrayMultiType() + new Sensitive_ArrayMultiType() { Sensitive_NestedObjectFormatL0 = new Sensitive_NestedObjectL0() { @@ -2523,55 +2672,55 @@ public static TestDoc Create(string partitionKey = null) Sensitive_IntFormatL1 = 1999, Sensitive_DecimalFormatL1 = 1999.1m, Sensitive_ArrayFormatL1 = new Sensitive_ArrayData[] - { - new Sensitive_ArrayData { - Sensitive_ArrayIntFormat = 1, - Sensitive_ArrayDecimalFormat = 2.1m + new Sensitive_ArrayData + { + Sensitive_ArrayIntFormat = 1, + Sensitive_ArrayDecimalFormat = 2.1m + }, + new Sensitive_ArrayData + { + Sensitive_ArrayIntFormat = 2, + Sensitive_ArrayDecimalFormat = 3.1m + } }, - new Sensitive_ArrayData - { - Sensitive_ArrayIntFormat = 2, - Sensitive_ArrayDecimalFormat = 3.1m - } - }, Sensitive_NestedObjectFormatL2 = new Sensitive_NestedObjectL2() { Sensitive_IntFormatL2 = 2000, Sensitive_DecimalFormatL2 = 2000.1m, Sensitive_ArrayFormatL2 = new Sensitive_ArrayData[] - { - new Sensitive_ArrayData - { - Sensitive_ArrayIntFormat = 2, - Sensitive_ArrayDecimalFormat = 3.1m - } - }, + { + new Sensitive_ArrayData + { + Sensitive_ArrayIntFormat = 2, + Sensitive_ArrayDecimalFormat = 3.1m + } + }, Sensitive_NestedObjectFormatL3 = new Sensitive_NestedObjectL3() { Sensitive_IntFormatL3 = 3000, Sensitive_DecimalFormatL3 = 3000.1m, Sensitive_ArrayFormatL3 = new Sensitive_ArrayData[] - { - new Sensitive_ArrayData - { - Sensitive_ArrayIntFormat = 3, - Sensitive_ArrayDecimalFormat = 4.1m, - } - }, + { + new Sensitive_ArrayData + { + Sensitive_ArrayIntFormat = 3, + Sensitive_ArrayDecimalFormat = 4.1m, + } + }, Sensitive_ArrayWithObjectFormat = new Sensitive_ArrayDataWithObject[] - { - new Sensitive_ArrayDataWithObject - { - Sensitive_ArrayIntFormat = 4, - Sensitive_ArrayDecimalFormat = 5.1m, - Sensitive_NestedObjectFormatL0 = new Sensitive_NestedObjectL0() - { - Sensitive_IntFormatL0 = 888, - Sensitive_DecimalFormatL0 = 888.1m, - } - } - } + { + new Sensitive_ArrayDataWithObject + { + Sensitive_ArrayIntFormat = 4, + Sensitive_ArrayDecimalFormat = 5.1m, + Sensitive_NestedObjectFormatL0 = new Sensitive_NestedObjectL0() + { + Sensitive_IntFormatL0 = 888, + Sensitive_DecimalFormatL0 = 888.1m, + } + } + } } } }