Issues with creating new Cosmos DB documents with Logic App

Recently I had to build a solution for a customer. One part was to create order documents in a Cosmos DB using a Logic App. Sounds easy, however, I struggled a bit because of a simple thing and thought that this could help others. So here we go.

The Logic App will be HTTP-triggered. The request body will contain the order details. For this blog post I simplified the procedure (less order details, no schema validation etc.). After the trigger I use a “Create or update document” step, connect to the Cosmos DB and use the body to create the document

image

Once prepared, I use a simple PowerShell script to test the Logic App. Here you can also see how the body is constructed.

$uri = https://prod-35.westeurope.logic.azure.com:443/workflows/58a………”
$id = [guid]::NewGuid()
$product = “Office 2003 Professional”
$orderdate = get-date -format s
$person = “Marcel Zehner”
$country = “Switzerland”
$Status = “Ordered”

$body = @{
“id” = $id;
“product” = $product;
“orderdate” = $orderdate;
“person” = $person;
“country” = $country;
“status” = $status
} | ConvertTo-Json

Invoke-WebRequest -Uri $uri -Body $body -Method POST -ContentType application/json

The Logic App triggers, but later fails. The request body looks OK, but the document has not been created. Let’s have a look at the error message.

image

image

{

“code”: “BadRequest”,

“message”: “Message: {\”Errors\”:[\”The partition key supplied in x-ms-partitionkey header has fewer components than defined in the the collection.\”]}\r\nActivityId: 397f8bfc-b4d6-461d-934b-ef834182eb3a, Request URI: /apps/36834417-c2b8-4524-871e-e3247817af32/services/cad59f1d-0db5-448a-b8ce-ab8e45f2f3d9/partitions/2e968e2a-42b1-40fe-9b91-1c294c301efc/replicas/131934563705646138p/, RequestStats: \r\nRequestStartTime: 2019-02-05T17:25:00.7030395Z, Number of regions attempted: 1\r\n, SDK: Microsoft.Azure.Documents.Common/2.1.0.0″

}

So there seems to be an issue with the Cosmos DB partition key. This key is used for scaling, so let’s have a look at the collection configuration. The “orders” collection uses a partition key “country”.

image

Now back in the Logic App designer you will discover that you can add a partition key value to the step. Let’s do that. For now I just hardcode the value to see if this works. But nope, after firing the PowerShell script the Logic App fails again. But this time with a different error message.

image

image

{

“code”: “BadRequest”,

“message”: “Partition key [Switzerland] is invalid.\r\nActivityId: 31c27f0b-e75a-4fa7-9aac-9a4d777e0529, \r\nRequestStartTime: 2019-02-05T16:07:12.1086065Z, Number of regions attempted: 1\r\n, Microsoft.Azure.Documents.Common/2.1.0.0″

}

One interesting thing is, that the value is shown in brackets which means that it is interpreted as an array. Back at the drawing board I changed the hardcoded value to something different and added quotation marks. Again, another error message. This time it’s a bit clearer. The partition key value obviously MUST be in quotation marks and it MUST match the value for the same key in the payload.

{

“code”: “BadRequest”,

“message”: “Message: {\”Errors\”:[\”PartitionKey extracted from document doesn’t match the one specified in the header\”]}\r\nActivityId: 3c500c0c-c2ed-4587-b16f-4565877d87b6, Request URI: /apps/36834417-c2b8-4524-871e-e3247817af32/services/cad59f1d-0db5-448a-b8ce-ab8e45f2f3d9/partitions/2e968e2a-42b1-40fe-9b91-1c294c301efc/replicas/131934563705646138p/, RequestStats: \r\nRequestStartTime: 2019-02-05T16:10:24.7924046Z, Number of regions attempted: 1\r\n, SDK: Microsoft.Azure.Documents.Common/2.1.0.0″

}

After changing everything properly, it worked like a charm.

– Partition key in quotation mark
– “Country” value identical to the one submitted in the request body

image

image

The last step was bringing the value for the partition key dynamically to the field. I use a “Parse JSON” step for that. In this step, the request body is parsed, so that afterwards all individual key-value pairs can easily be accessed.

image

{
“type”: “object”,
“properties”: {
“id”: {
“type”: “string”
},
“person”: {
“type”: “string”
},
“status”: {
“type”: “string”
},
“product”: {
“type”: “string”
},
“orderdate”: {
“type”: “string”
},
“country”: {
“type”: “string”
}
}
}

Finally, I use the dynamic “country” value from the Parse JSON output in the partition key property. And don’t miss the quotation marks!

image

Firing the script again now does exactly what I need.

image

I found this a bit confusing and also discovered that this is/was an issue for many folks out there – not only for the ones using Logic App but trying to create new Cosmos DB documents in general. I hope this blog post can help out a bit …

Cheers
Marcel

This entry was posted in Azure and tagged , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s