diff --git a/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceJsonWriter.cs b/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceJsonWriter.cs index b13a1e545b..9a3da7971b 100644 --- a/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceJsonWriter.cs +++ b/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceJsonWriter.cs @@ -394,7 +394,7 @@ public void Visit(StoreResult storeResult) this.jsonWriter.WriteStringValue(storeResult.StatusCode.ToString()); this.jsonWriter.WriteFieldName(nameof(storeResult.SubStatusCode)); - this.jsonWriter.WriteStringValue(storeResult.SubStatusCode.ToString()); + this.jsonWriter.WriteStringValue(this.GetSubStatusCodeString(storeResult.StatusCode, storeResult.SubStatusCode)); this.jsonWriter.WriteFieldName(nameof(storeResult.LSN)); this.jsonWriter.WriteNumberValue(storeResult.LSN); @@ -452,6 +452,116 @@ public void Visit(StoreResult storeResult) this.jsonWriter.WriteObjectEnd(); } + internal string GetSubStatusCodeString(StatusCodes statusCode, SubStatusCodes subStatusCode) + { + if ((int)subStatusCode == 1002) + { + return statusCode == StatusCodes.NotFound + ? "ReadSessionNotAvailable" + : SubStatusCodes.PartitionKeyRangeGone.ToString(); + } + + if ((int)subStatusCode == 2001) + { + return statusCode == StatusCodes.NoContent + ? "MissedTargetLsn" + : SubStatusCodes.SplitIsDisabled.ToString(); + } + + if ((int)subStatusCode == 2002) + { + return statusCode == StatusCodes.NoContent + ? "MissedTargetLsnOver100" + : SubStatusCodes.CollectionsInPartitionGotUpdated.ToString(); + } + + if ((int)subStatusCode == 2003) + { + return statusCode == StatusCodes.NoContent + ? "MissedTargetLsnOver1000" + : SubStatusCodes.CanNotAcquirePKRangesLock.ToString(); + } + + if ((int)subStatusCode == 2004) + { + return statusCode == StatusCodes.NoContent + ? "MissedTargetLsnOver10000" + : SubStatusCodes.ResourceNotFound.ToString(); + } + + if ((int)subStatusCode == 2011) + { + return statusCode == StatusCodes.NoContent + ? "MissedTargetGlobalCommittedLsn" + : SubStatusCodes.StorageSplitConflictingWithNWayThroughputSplit.ToString(); + } + + if ((int)subStatusCode == 2012) + { + return statusCode == StatusCodes.NoContent + ? "MissedTargetGlobalCommittedLsnOver100" + : SubStatusCodes.MergeIsDisabled.ToString(); + } + + if ((int)subStatusCode == 1004) + { + return statusCode == StatusCodes.BadRequest + ? "CrossPartitionQueryNotServable" + : SubStatusCodes.ConfigurationNameNotFound.ToString(); + } + + if ((int)subStatusCode == 1007) + { + return statusCode == StatusCodes.Gone + ? "CompletingSplit" + : SubStatusCodes.InsufficientBindablePartitions.ToString(); + } + + if ((int)subStatusCode == 1008) + { + return statusCode == StatusCodes.Gone + ? "CompletingPartitionMigration" + : SubStatusCodes.DatabaseAccountNotFound.ToString(); + } + + if ((int)subStatusCode == 1005) + { + return statusCode == StatusCodes.NotFound + ? "ConfigurationPropertyNotFound" + : SubStatusCodes.ProvisionLimitReached.ToString(); + } + + if ((int)subStatusCode == 3207) + { + return statusCode == StatusCodes.Conflict + ? "ConfigurationNameAlreadyExists" + : SubStatusCodes.PrepareTimeLimitExceeded.ToString(); + } + + if ((int)subStatusCode == 6001) + { + return statusCode == StatusCodes.ServiceUnavailable + ? "AggregatedHealthStateError" + : SubStatusCodes.PartitionMigrationWaitForFullSyncReceivedInternalServerErrorDuringCompleteMigrationFromBackend.ToString(); + } + + if ((int)subStatusCode == 6002) + { + return statusCode == StatusCodes.ServiceUnavailable + ? "ApplicationHealthStateError" + : SubStatusCodes.PartitionMigrationWaitForFullSyncReceivedInternalServerErrorDuringAbortMigrationFromBackend.ToString(); + } + + if ((int)subStatusCode == 6003) + { + return statusCode == StatusCodes.ServiceUnavailable + ? "HealthStateError" + : SubStatusCodes.PartitionMigrationFinalizeMigrationsDidNotCompleteInTenRetries.ToString(); + } + + return subStatusCode.ToString(); + } + public void Visit(PartitionKeyRangeCacheTraceDatum partitionKeyRangeCacheTraceDatum) { this.jsonWriter.WriteObjectStart(); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/EndToEndTraceWriterBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/EndToEndTraceWriterBaselineTests.cs index a9151ae136..641f557ed2 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/EndToEndTraceWriterBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/EndToEndTraceWriterBaselineTests.cs @@ -19,6 +19,7 @@ namespace Microsoft.Azure.Cosmos.EmulatorTests.Tracing using Microsoft.Azure.Cosmos.ChangeFeed; using Microsoft.Azure.Cosmos.CosmosElements; using Microsoft.Azure.Cosmos.Diagnostics; + using Microsoft.Azure.Cosmos.FaultInjection; using Microsoft.Azure.Cosmos.SDK.EmulatorTests; using Microsoft.Azure.Cosmos.Services.Management.Tests.BaselineTest; using Microsoft.Azure.Cosmos.Telemetry; @@ -716,6 +717,59 @@ public async Task QueryAsync() this.ExecuteTestSuite(inputs); } + [TestMethod] + public async Task ValidateCorrectSubStatusCodeTestAsync() + { + FaultInjectionCondition condition = new FaultInjectionConditionBuilder() + .WithConnectionType(FaultInjectionConnectionType.Direct) + .WithOperationType(FaultInjectionOperationType.ReadItem) + .Build(); + + FaultInjectionServerErrorResult result = new FaultInjectionServerErrorResultBuilder(FaultInjectionServerErrorType.ReadSessionNotAvailable) + .Build(); + + FaultInjectionRule rule = new FaultInjectionRuleBuilder("readSessionNotAvailable", condition, result) + .Build(); + + FaultInjector injector = new FaultInjector(new List { rule }); + + rule.Disable(); + + CosmosClientOptions clientOptions = new CosmosClientOptions() + { + ConnectionMode = ConnectionMode.Direct, + ConsistencyLevel = ConsistencyLevel.Eventual, + FaultInjector = injector, + }; + + (string endpoint, string authKey) = TestCommon.GetAccountInfo(); + + using (CosmosClient client = new CosmosClient(endpoint, authKey, clientOptions)) + { + + Database testDatabase = await client.CreateDatabaseAsync("testDatabase"); + Container testContainer = await testDatabase.CreateContainerAsync(new ContainerProperties("testContainer", "/pk")); + + ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity(); + await testContainer.CreateItemAsync(testItem, new PartitionKey(testItem.pk)); + + rule.Enable(); + + try + { + ItemResponse _ = await testContainer.ReadItemAsync(testItem.id, new PartitionKey(testItem.pk)); + } + catch (CosmosException ex) + { + Assert.IsTrue(ex.Diagnostics.ToString().Contains("ReadSessionNotAvailable")); + } + finally + { + await testDatabase.DeleteAsync(); + } + } + } + [TestMethod] public async Task ValidateInvalidCredentialsTraceAsync() {