Skip to content
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
1 change: 1 addition & 0 deletions extensions/Worker.Extensions.CosmosDB/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
### Microsoft.Azure.Functions.Worker.Extensions.CosmosDB 4.12.0

- Updated `Microsoft.Azure.WebJobs.Extensions.CosmosDB` reference to 4.9.0
- Return a successful result with a null value when a Cosmos document cannot be found (#2942/#2545)
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ private async ValueTask<ConversionResult> ConvertFromBindingDataAsync(ConverterC

return ConversionResult.Success(result);
}
catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return ConversionResult.Success(null);
}
catch (Exception ex)
{
return ConversionResult.Failed(ex);
Expand Down
5 changes: 5 additions & 0 deletions test/E2ETests/E2EApps/E2EApp/Cosmos/CosmosFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ public async Task<HttpResponseData> DocByIdFromRouteData(
Id = "{id}",
PartitionKey = "{partitionKey}")] MyDocument doc)
{
if (doc == null)
{
return req.CreateResponse(HttpStatusCode.NotFound);
}

var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync(doc.Text);
return response;
Expand Down
22 changes: 22 additions & 0 deletions test/E2ETests/E2ETests/Cosmos/CosmosDBEndToEndTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,28 @@ public async Task CosmosInput_DocByIdFromRouteData_Succeeds()
}
}

[Fact]
public async Task CosmosInput_DocByIdFromRouteDataNotFound_Succeeds()
{
string expectedDocId = Guid.NewGuid().ToString();
string functionPath = $"docsbyroute/{expectedDocId}/{expectedDocId}";
try
{
//Trigger
HttpResponseMessage response = await HttpHelpers.InvokeHttpTrigger(functionPath);

//Verify
HttpStatusCode expectedStatusCode = HttpStatusCode.NotFound;

Assert.Equal(expectedStatusCode, response.StatusCode);
}
finally
{
//Clean up
await CosmosDBHelpers.DeleteTestDocuments(expectedDocId);
}
}

[Fact]
public async Task CosmosInput_DocByIdFromRouteDataUsingSqlQuery_Succeeds()
{
Expand Down
37 changes: 34 additions & 3 deletions test/Worker.Extensions.Tests/Cosmos/CosmosDBConverterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -359,14 +360,18 @@ public async Task ConvertAsync_CosmosContainerIsNull_ThrowsException_ReturnsFail
Assert.Equal($"Unable to create Cosmos container client for 'myContainer'.", conversionResult.Error.Message);
}

[Fact]
public async Task ConvertAsync_POCO_IdProvided_StatusNot200_ThrowsException_ReturnsFailure()
[Theory]
Comment thread
florianlenz96 marked this conversation as resolved.
[InlineData(HttpStatusCode.Conflict)]
[InlineData(HttpStatusCode.Forbidden)]
[InlineData(HttpStatusCode.InternalServerError)]
[InlineData(HttpStatusCode.BadRequest)]
public async Task ConvertAsync_POCO_IdProvided_NotSuccessStatus_ThrowsException_ReturnsFailure(HttpStatusCode httpStatusCode)
{
object grpcModelBindingData = GrpcTestHelper.GetTestGrpcModelBindingData(GetTestBinaryData(id: "1", partitionKey: "1"), "CosmosDB");
var context = new TestConverterContext(typeof(ToDoItem), grpcModelBindingData);

var mockResponse = new Mock<ResponseMessage>();
var cosmosException = new CosmosException("test failure", System.Net.HttpStatusCode.NotFound, 0, "test", 0);
var cosmosException = new CosmosException("test failure", httpStatusCode, 0, "test", 0);
mockResponse.Setup(x => x.EnsureSuccessStatusCode()).Throws(cosmosException);

var mockContainer = new Mock<Container>();
Expand All @@ -384,6 +389,32 @@ public async Task ConvertAsync_POCO_IdProvided_StatusNot200_ThrowsException_Retu
Assert.Equal("test failure", conversionResult.Error.Message);
}

[Fact]
public async Task ConvertAsync_POCO_IdProvided_Status404_ReturnsSuccess()
{
object grpcModelBindingData = GrpcTestHelper.GetTestGrpcModelBindingData(GetTestBinaryData(id: "1", partitionKey: "1"), "CosmosDB");
var context = new TestConverterContext(typeof(ToDoItem), grpcModelBindingData);

var mockResponse = new Mock<ResponseMessage>();
mockResponse.Setup(x => x.IsSuccessStatusCode).Returns(false);
var cosmosException = new CosmosException("test failure", HttpStatusCode.NotFound, 0, "test", 0);
mockResponse.Setup(x => x.EnsureSuccessStatusCode()).Throws(cosmosException);

var mockContainer = new Mock<Container>();
mockContainer
.Setup(m => m.ReadItemStreamAsync(It.IsAny<string>(), It.IsAny<PartitionKey>(), null, default))
.ReturnsAsync(mockResponse.Object);

_mockCosmosClient
.Setup(m => m.GetContainer(It.IsAny<string>(), It.IsAny<string>()))
.Returns(mockContainer.Object);

var conversionResult = await _cosmosDBConverter.ConvertAsync(context);

Assert.Equal(ConversionStatus.Succeeded, conversionResult.Status);
Assert.Null(conversionResult.Value);
}

private BinaryData GetTestBinaryData(string db = "testDb", string container = "testContainer", string connection = "cosmosConnection", string id = "", string partitionKey = "", string query = "", string location = "", string queryParams = "{}")
{
string jsonData = $@"{{
Expand Down