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

Fixed query responses to return null Content if it is a failure. #1036

Merged
merged 6 commits into from
Nov 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Microsoft.Azure.Cosmos/src/Query/v3Query/QueryIterator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public static QueryIterator Create(
count: responseCore.CosmosElements.Count,
responseLengthBytes: responseCore.ResponseLengthBytes,
diagnostics: diagnostics,
serializationOptions: this.cosmosSerializationFormatOptions,
responseHeaders: new CosmosQueryResponseMessageHeaders(
responseCore.ContinuationToken,
responseCore.DisallowContinuationTokenMessage,
Expand Down Expand Up @@ -129,8 +130,6 @@ public static QueryIterator Create(
});
}

queryResponse.CosmosSerializationOptions = this.cosmosSerializationFormatOptions;

return queryResponse;
}

Expand Down
48 changes: 29 additions & 19 deletions Microsoft.Azure.Cosmos/src/Query/v3Query/QueryResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ private QueryResponse(
RequestMessage requestMessage,
CosmosDiagnostics diagnostics,
string errorMessage,
Error error)
Error error,
Lazy<MemoryStream> memoryStream,
CosmosSerializationFormatOptions serializationOptions)
: base(
statusCode: statusCode,
requestMessage: requestMessage,
Expand All @@ -47,11 +49,8 @@ private QueryResponse(
this.CosmosElements = result;
this.Count = count;
this.ResponseLengthBytes = responseLengthBytes;
this.memoryStream = new Lazy<MemoryStream>(() => CosmosElementSerializer.ToStream(
this.QueryHeaders.ContainerRid,
this.CosmosElements,
this.QueryHeaders.ResourceType,
this.CosmosSerializationOptions));
this.memoryStream = memoryStream;
this.CosmosSerializationOptions = serializationOptions;
}

public int Count { get; }
Expand All @@ -60,7 +59,7 @@ public override Stream Content
{
get
{
return this.memoryStream.Value;
return this.memoryStream?.Value;
}
}

Expand All @@ -76,7 +75,7 @@ public override Stream Content
/// </remarks>
internal long ResponseLengthBytes { get; }

internal virtual CosmosSerializationFormatOptions CosmosSerializationOptions { get; set; }
internal virtual CosmosSerializationFormatOptions CosmosSerializationOptions { get; }

internal bool GetHasMoreResults()
{
Expand All @@ -88,7 +87,8 @@ internal static QueryResponse CreateSuccess(
int count,
long responseLengthBytes,
CosmosQueryResponseMessageHeaders responseHeaders,
CosmosDiagnostics diagnostics)
CosmosDiagnostics diagnostics,
CosmosSerializationFormatOptions serializationOptions)
{
if (count < 0)
{
Expand All @@ -100,6 +100,12 @@ internal static QueryResponse CreateSuccess(
throw new ArgumentOutOfRangeException("responseLengthBytes must be positive");
}

Lazy<MemoryStream> memoryStream = new Lazy<MemoryStream>(() => CosmosElementSerializer.ToStream(
responseHeaders.ContainerRid,
result,
responseHeaders.ResourceType,
serializationOptions));

QueryResponse cosmosQueryResponse = new QueryResponse(
result: result,
count: count,
Expand All @@ -109,7 +115,9 @@ internal static QueryResponse CreateSuccess(
statusCode: HttpStatusCode.OK,
errorMessage: null,
error: null,
requestMessage: null);
requestMessage: null,
memoryStream: memoryStream,
serializationOptions: serializationOptions);

return cosmosQueryResponse;
}
Expand All @@ -123,15 +131,17 @@ internal static QueryResponse CreateFailure(
CosmosDiagnostics diagnostics)
{
QueryResponse cosmosQueryResponse = new QueryResponse(
result: Enumerable.Empty<CosmosElement>(),
count: 0,
responseLengthBytes: 0,
responseHeaders: responseHeaders,
diagnostics: diagnostics,
statusCode: statusCode,
errorMessage: errorMessage,
error: error,
requestMessage: requestMessage);
result: Enumerable.Empty<CosmosElement>(),
count: 0,
responseLengthBytes: 0,
responseHeaders: responseHeaders,
diagnostics: diagnostics,
statusCode: statusCode,
errorMessage: errorMessage,
error: error,
requestMessage: requestMessage,
memoryStream: null,
serializationOptions: null);

return cosmosQueryResponse;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ public async Task CreateDropItemTest()
Assert.IsNotNull(deleteResponse);
}

[TestMethod]
public async Task NegativeCreateDropItemTest()
{
ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity();
ResponseMessage response = await this.Container.CreateItemStreamAsync(streamPayload: TestCommon.Serializer.ToStream(testItem), new Cosmos.PartitionKey("BadKey"));
Assert.IsNotNull(response);
Assert.IsNull(response.Content);
Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode);
}

[TestMethod]
public async Task CustomSerilizerTest()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public async Task SimpleTestAsync()
}
}

bool completionStatus = Task.WaitAll(tasks.ToArray(), TimeSpan.FromSeconds(5));
bool completionStatus = Task.WaitAll(tasks.ToArray(), TimeSpan.FromSeconds(10));
Assert.IsTrue(completionStatus);

foreach (Task task in tasks)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,40 @@ namespace Microsoft.Azure.Cosmos.Tests
[TestClass]
public class CosmosQueryUnitTests
{
[TestMethod]
public void VerifyNegativeCosmosQueryResponseStream()
{
string contianerRid = "mockContainerRid";
string errorMessage = "TestErrorMessage";
string activityId = "TestActivityId";
double requestCharge = 42.42;

Mock<CosmosDiagnostics> mockDiagnostics = new Mock<CosmosDiagnostics>();
CosmosDiagnostics diagnostics = mockDiagnostics.Object;
QueryResponse queryResponse = QueryResponse.CreateFailure(
statusCode: HttpStatusCode.NotFound,
errorMessage: errorMessage,
requestMessage: null,
error: null,
responseHeaders: new CosmosQueryResponseMessageHeaders(
null,
null,
ResourceType.Document,
contianerRid)
{
RequestCharge = requestCharge,
ActivityId = activityId
},
diagnostics: diagnostics);

Assert.AreEqual(HttpStatusCode.NotFound, queryResponse.StatusCode);
Assert.AreEqual(errorMessage, queryResponse.ErrorMessage);
Assert.AreEqual(requestCharge, queryResponse.Headers.RequestCharge);
Assert.AreEqual(activityId, queryResponse.Headers.ActivityId);
Assert.AreEqual(diagnostics, queryResponse.Diagnostics);
Assert.IsNull(queryResponse.Content);
}

[TestMethod]
public void VerifyCosmosQueryResponseStream()
{
Expand All @@ -39,6 +73,7 @@ public void VerifyCosmosQueryResponseStream()
result: responseCore.CosmosElements,
count: responseCore.CosmosElements.Count,
responseLengthBytes: responseCore.ResponseLengthBytes,
serializationOptions: null,
responseHeaders: new CosmosQueryResponseMessageHeaders(
responseCore.ContinuationToken,
responseCore.DisallowContinuationTokenMessage,
Expand All @@ -52,7 +87,7 @@ public void VerifyCosmosQueryResponseStream()

using (Stream stream = queryResponse.Content)
{
using(Stream innerStream = queryResponse.Content)
using (Stream innerStream = queryResponse.Content)
{
Assert.IsTrue(object.ReferenceEquals(stream, innerStream), "Content should return the same stream");
}
Expand All @@ -76,6 +111,7 @@ public void VerifyItemQueryResponseResult()
result: cosmosElements,
count: cosmosElements.Count,
responseLengthBytes: responseCore.ResponseLengthBytes,
serializationOptions: null,
responseHeaders: new CosmosQueryResponseMessageHeaders(
responseCore.ContinuationToken,
responseCore.DisallowContinuationTokenMessage,
Expand Down Expand Up @@ -116,6 +152,7 @@ public void VerifyItemQueryResponseCosmosElements()
result: cosmosElements,
count: cosmosElements.Count,
responseLengthBytes: responseCore.ResponseLengthBytes,
serializationOptions: null,
responseHeaders: new CosmosQueryResponseMessageHeaders(
responseCore.ContinuationToken,
responseCore.DisallowContinuationTokenMessage,
Expand Down Expand Up @@ -323,7 +360,7 @@ public async Task TestCosmosQueryPartitionKeyDefinition()

Mock<IDocumentQueryExecutionComponent> baseContext = new Mock<IDocumentQueryExecutionComponent>();
baseContext.Setup(x => x.DrainAsync(It.IsAny<int>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult<QueryResponseCore>(failure));
Func<string, Task<TryCatch<IDocumentQueryExecutionComponent>>> callBack = x => Task.FromResult<TryCatch<IDocumentQueryExecutionComponent>>(TryCatch<IDocumentQueryExecutionComponent> .FromResult(baseContext.Object));
Func<string, Task<TryCatch<IDocumentQueryExecutionComponent>>> callBack = x => Task.FromResult<TryCatch<IDocumentQueryExecutionComponent>>(TryCatch<IDocumentQueryExecutionComponent>.FromResult(baseContext.Object));
return (callBack, failure);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,7 @@ internal void GetCosmosElementsFromQueryResponseTest(JsonSerializationFormat jso
vertexArray,
count: 2,
responseLengthBytes: vertex1JsonWriterResult.Length + vertex2JsonWriterResult.Length,
serializationOptions: null,
responseHeaders: CosmosQueryResponseMessageHeaders.ConvertToQueryHeaders(
sourceHeaders: null,
resourceType: ResourceType.Document,
Expand Down Expand Up @@ -723,6 +724,7 @@ internal void GetDeserializedObjectsFromQueryResponseTest(JsonSerializationForma
vertexArray,
count: 2,
responseLengthBytes: vertex1JsonWriterResult.Length + vertex2JsonWriterResult.Length,
serializationOptions: null,
responseHeaders: CosmosQueryResponseMessageHeaders.ConvertToQueryHeaders(
sourceHeaders: null,
resourceType: ResourceType.Document,
Expand Down
4 changes: 1 addition & 3 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#1013](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/1013) Gateway OperationCanceledException are now returned as request timeouts
- [#1020](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/1020) Direct package update removes debug statements
- [#1023](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/1023) Fixed ThroughputResponse.IsReplacePending header mapping
- [#1036](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/1036) Fixed query responses to return null Content if it is a failure

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

Expand All @@ -47,13 +48,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#918](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/918) Fixed serializer being used for Scripts, Permissions, and Conflict related iterators
- [#936](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/936) Fixed bulk requests with large resources to have natural exception


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

- [#837](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/837) Fixed group by bug for non-Windows platforms
- [#927](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/927) Fixed query returning partial results instead of error
flow.


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

Expand Down