Skip to content

Commit 0dc04c1

Browse files
authored
[Storage][Functions] Fix blob trigger message serialization (Azure#24032)
* fix zero length file download. * re-record. * make sure track 1 and track 2 use same format. * changelog. * ignore case.
1 parent f26ae80 commit 0dc04c1

File tree

3 files changed

+89
-4
lines changed

3 files changed

+89
-4
lines changed

sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Release History
22

33
## 5.0.0-beta.6 (Unreleased)
4-
4+
- Fixed bug where internal message format of blob trigger didn't interop with previous major versions of the extension.
55

66
## 5.0.0-beta.5 (2021-07-09)
77
- This release contains bug fixes to improve quality.

sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/src/Listeners/BlobTriggerMessage.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
using System;
45
using System.Diagnostics.CodeAnalysis;
56
using Azure.Storage.Blobs.Models;
67
using Newtonsoft.Json;
7-
using Newtonsoft.Json.Converters;
88

99
namespace Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.Listeners
1010
{
@@ -21,10 +21,25 @@ public string Type
2121

2222
public string FunctionId { get; set; }
2323

24-
// $$$ Ignored this?
25-
[JsonConverter(typeof(StringEnumConverter))]
24+
// See BlobTypeInternal for exact serialization.
25+
[JsonIgnore]
2626
public BlobType BlobType { get; set; }
2727

28+
// BlobType enum have different values in track 2 vs track 1, e.g. Block vs BlockBlob.
29+
// This internal property makes sure we serialize new type same way track 1 extension did.
30+
// This also makes sure we can read both formats since we already shipped few betas and don't want to disturb them.
31+
[JsonProperty("BlobType")]
32+
private string BlobTypeInternal {
33+
get
34+
{
35+
return BlobType.ToString() + "Blob";
36+
}
37+
set
38+
{
39+
BlobType = (BlobType)Enum.Parse(typeof(BlobType), value.Replace("Blob", ""), true);
40+
}
41+
}
42+
2843
public string ContainerName { get; set; }
2944

3045
public string BlobName { get; set; }
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
namespace Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.Tests
5+
{
6+
using global::Azure.Storage.Blobs.Models;
7+
using Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.Listeners;
8+
using Newtonsoft.Json;
9+
using NUnit.Framework;
10+
11+
public class BlobTriggerMessageTests
12+
{
13+
[TestCase("containerName", "blobName", BlobType.Block, "etag", "functionId",
14+
"{\"Type\":\"BlobTrigger\",\"FunctionId\":\"functionId\",\"BlobType\":\"BlockBlob\",\"ContainerName\":\"containerName\",\"BlobName\":\"blobName\",\"ETag\":\"etag\"}")]
15+
[TestCase("containerName", "blobName", BlobType.Append, "etag", "functionId",
16+
"{\"Type\":\"BlobTrigger\",\"FunctionId\":\"functionId\",\"BlobType\":\"AppendBlob\",\"ContainerName\":\"containerName\",\"BlobName\":\"blobName\",\"ETag\":\"etag\"}")]
17+
[TestCase("containerName", "blobName", BlobType.Page, "etag", "functionId",
18+
"{\"Type\":\"BlobTrigger\",\"FunctionId\":\"functionId\",\"BlobType\":\"PageBlob\",\"ContainerName\":\"containerName\",\"BlobName\":\"blobName\",\"ETag\":\"etag\"}")]
19+
public void CanSerializeBlobTriggerMessage(string containerName, string blobName, BlobType blobType, string etag, string functionId, string expectedMessage)
20+
{
21+
var message = new BlobTriggerMessage()
22+
{
23+
ContainerName = containerName,
24+
BlobName = blobName,
25+
BlobType = blobType,
26+
ETag = etag,
27+
FunctionId = functionId,
28+
};
29+
30+
var serializedMessage = JsonConvert.SerializeObject(message, Formatting.None);
31+
32+
Assert.AreEqual(expectedMessage, serializedMessage);
33+
}
34+
35+
[TestCase("containerName", "blobName", BlobType.Block, "etag", "functionId",
36+
"{\"Type\":\"BlobTrigger\",\"FunctionId\":\"functionId\",\"BlobType\":\"Block\",\"ContainerName\":\"containerName\",\"BlobName\":\"blobName\",\"ETag\":\"etag\"}")]
37+
[TestCase("containerName", "blobName", BlobType.Append, "etag", "functionId",
38+
"{\"Type\":\"BlobTrigger\",\"FunctionId\":\"functionId\",\"BlobType\":\"Append\",\"ContainerName\":\"containerName\",\"BlobName\":\"blobName\",\"ETag\":\"etag\"}")]
39+
[TestCase("containerName", "blobName", BlobType.Page, "etag", "functionId",
40+
"{\"Type\":\"BlobTrigger\",\"FunctionId\":\"functionId\",\"BlobType\":\"Page\",\"ContainerName\":\"containerName\",\"BlobName\":\"blobName\",\"ETag\":\"etag\"}")]
41+
public void CanDeserializeBlobTriggerMessage(string containerName, string blobName, BlobType blobType, string etag, string functionId, string incomingMessage)
42+
{
43+
var message = JsonConvert.DeserializeObject<BlobTriggerMessage>(incomingMessage);
44+
45+
Assert.AreEqual(containerName, message.ContainerName);
46+
Assert.AreEqual(blobName, message.BlobName);
47+
Assert.AreEqual(blobType, message.BlobType);
48+
Assert.AreEqual(etag, message.ETag);
49+
Assert.AreEqual(functionId, message.FunctionId);
50+
}
51+
52+
// In track 1 BlobType enum had different values.
53+
[TestCase("containerName", "blobName", BlobType.Block, "etag", "functionId",
54+
"{\"Type\":\"BlobTrigger\",\"FunctionId\":\"functionId\",\"BlobType\":\"BlockBlob\",\"ContainerName\":\"containerName\",\"BlobName\":\"blobName\",\"ETag\":\"etag\"}")]
55+
[TestCase("containerName", "blobName", BlobType.Append, "etag", "functionId",
56+
"{\"Type\":\"BlobTrigger\",\"FunctionId\":\"functionId\",\"BlobType\":\"AppendBlob\",\"ContainerName\":\"containerName\",\"BlobName\":\"blobName\",\"ETag\":\"etag\"}")]
57+
[TestCase("containerName", "blobName", BlobType.Page, "etag", "functionId",
58+
"{\"Type\":\"BlobTrigger\",\"FunctionId\":\"functionId\",\"BlobType\":\"PageBlob\",\"ContainerName\":\"containerName\",\"BlobName\":\"blobName\",\"ETag\":\"etag\"}")]
59+
public void CanDeserializeTrack1BlobTriggerMessage(string containerName, string blobName, BlobType blobType, string etag, string functionId, string incomingMessage)
60+
{
61+
var message = JsonConvert.DeserializeObject<BlobTriggerMessage>(incomingMessage);
62+
63+
Assert.AreEqual(containerName, message.ContainerName);
64+
Assert.AreEqual(blobName, message.BlobName);
65+
Assert.AreEqual(blobType, message.BlobType);
66+
Assert.AreEqual(etag, message.ETag);
67+
Assert.AreEqual(functionId, message.FunctionId);
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)