Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Statistics not getting populated correctly on CosmosException #846

Merged
merged 11 commits into from
Sep 27, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,24 @@ namespace Microsoft.Azure.Cosmos

internal sealed class CosmosClientSideRequestStatistics : IClientSideRequestStatistics
{
private static JsonSerializerSettings SerializerSettings = new JsonSerializerSettings()
simplynaveen20 marked this conversation as resolved.
Show resolved Hide resolved
{
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.None
};
internal const int MaxSupplementalRequestsForToString = 10;

internal DateTime requestStartTime;
internal DateTime requestEndTime;

private object lockObject = new object();

internal List<StoreResponseStatistics> responseStatisticsList;
internal List<StoreResponseStatistics> supplementalResponseStatisticsList;
internal Dictionary<string, AddressResolutionStatistics> addressResolutionStatistics;
public List<StoreResponseStatistics> responseStatisticsList { get; private set; }
public List<StoreResponseStatistics> supplementalResponseStatisticsList { get; internal set; }
public Dictionary<string, AddressResolutionStatistics> addressResolutionStatistics { get; private set; }

[JsonIgnoreAttribute]
public List<Uri> ContactedReplicas { get; set; }
[JsonIgnoreAttribute]
public HashSet<Uri> FailedReplicas { get; private set; }
[JsonIgnoreAttribute]
public HashSet<Uri> RegionsContacted { get; private set; }

public CosmosClientSideRequestStatistics()
Expand Down Expand Up @@ -150,6 +152,20 @@ public void RecordAddressResolutionEnd(string identifier)
}
}

public override string ToString()
ealsur marked this conversation as resolved.
Show resolved Hide resolved
{
if (this.supplementalResponseStatisticsList != null)
{
int supplementalResponseStatisticsListCount = this.supplementalResponseStatisticsList.Count;
int countToRemove = Math.Max(supplementalResponseStatisticsListCount - CosmosClientSideRequestStatistics.MaxSupplementalRequestsForToString, 0);
if (countToRemove > 0)
{
this.supplementalResponseStatisticsList.RemoveRange(0, countToRemove);
}
}
return JsonConvert.SerializeObject(this, CosmosClientSideRequestStatistics.SerializerSettings);
}

internal struct StoreResponseStatistics
{
public DateTime RequestResponseTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1533,6 +1533,45 @@ public async Task VerifySessionTokenPassThrough()
Assert.AreEqual(sessionToken, readResponse.Headers.Session);
}

[TestMethod]
public async Task VerifySessionNotFoundStatistics()
{
CosmosClient cosmosClient = TestCommon.CreateCosmosClient(new CosmosClientOptions() { ConsistencyLevel = Cosmos.ConsistencyLevel.Session });
DatabaseResponse database = await cosmosClient.CreateDatabaseIfNotExistsAsync("NoSession");
Container container = await database.Database.CreateContainerIfNotExistsAsync("NoSession", "/status");

try
{
ToDoActivity temp = ToDoActivity.CreateRandomToDoActivity("TBD");

ItemResponse<ToDoActivity> responseAstype = await container.CreateItemAsync<ToDoActivity>(partitionKey: new Cosmos.PartitionKey(temp.status), item: temp);

string invalidSessionToken = this.GetDifferentLSNToken(responseAstype.Headers.Session, 2000);

try
{
ItemResponse<ToDoActivity> readResponse = await container.ReadItemAsync<ToDoActivity>(temp.id, new Cosmos.PartitionKey(temp.status), new ItemRequestOptions() { SessionToken = invalidSessionToken });
Assert.Fail("Should had thrown ReadSessionNotAvailable");
}
catch (CosmosException cosmosException)
{
Assert.IsTrue(cosmosException.Message.Contains("ContactedReplicas"), cosmosException.Message);
}
}
finally
{
await database.Database.DeleteAsync();
}
}

private string GetDifferentLSNToken(string token, long lsnDifferent)
{
string[] tokenParts = token.Split(':');
ISessionToken sessionToken = SessionTokenHelper.Parse(tokenParts[1]);
ISessionToken differentSessionToken = TestCommon.CreateSessionToken(sessionToken, sessionToken.LSN + lsnDifferent);
return string.Format(CultureInfo.InvariantCulture, "{0}:{1}", tokenParts[0], differentSessionToken.ConvertToString());
}

/// <summary>
/// Stateless container re-create test.
/// Create two client instances and do meta data operations through a single client
Expand Down
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- [#835](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/835) Fixed a bug that caused sortedRanges exceptions
- [#846](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/846) Statistics not getting populated correctly on CosmosException.

## <a name="3.2.0"/> [3.2.0](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.2.0) - 2019-09-17

Expand Down