-
Notifications
You must be signed in to change notification settings - Fork 178
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ability to bind to SBReceivedMessage (#1313)
- Loading branch information
1 parent
15204b1
commit 9043b7a
Showing
13 changed files
with
477 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
namespace Microsoft.Azure.Functions.Worker.Extensions.ServiceBus | ||
{ | ||
internal static class Constants | ||
{ | ||
internal const string BinaryContentType = "application/octet-stream"; | ||
|
||
internal const string BindingSource = "AzureServiceBusReceivedMessage"; | ||
} | ||
} |
4 changes: 3 additions & 1 deletion
4
extensions/Worker.Extensions.ServiceBus/src/Properties/AssemblyInfo.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions; | ||
using System.Runtime.CompilerServices; | ||
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions; | ||
|
||
[assembly: ExtensionInformation("Microsoft.Azure.WebJobs.Extensions.ServiceBus", "5.11.0")] | ||
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")] |
65 changes: 65 additions & 0 deletions
65
extensions/Worker.Extensions.ServiceBus/src/ServiceBusReceivedMessageConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Azure.Core.Amqp; | ||
using Azure.Messaging.ServiceBus; | ||
using Microsoft.Azure.Functions.Worker.Converters; | ||
using Microsoft.Azure.Functions.Worker.Core; | ||
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions; | ||
using Microsoft.Azure.Functions.Worker.Extensions.ServiceBus; | ||
|
||
namespace Microsoft.Azure.Functions.Worker | ||
{ | ||
[SupportsDeferredBinding] | ||
[SupportedConverterType(typeof(ServiceBusReceivedMessage))] | ||
[SupportedConverterType(typeof(ServiceBusReceivedMessage[]))] | ||
internal class ServiceBusReceivedMessageConverter : IInputConverter | ||
{ | ||
public ValueTask<ConversionResult> ConvertAsync(ConverterContext context) | ||
{ | ||
try | ||
{ | ||
ConversionResult result = context?.Source switch | ||
{ | ||
ModelBindingData binding => ConversionResult.Success(ConvertToServiceBusReceivedMessage(binding)), | ||
// Only array collections are currently supported, which matches the behavior of the in-proc extension. | ||
CollectionModelBindingData collection => ConversionResult.Success(collection.ModelBindingDataArray | ||
.Select(ConvertToServiceBusReceivedMessage).ToArray()), | ||
_ => ConversionResult.Unhandled() | ||
}; | ||
return new ValueTask<ConversionResult>(result); | ||
} | ||
catch (Exception exception) | ||
{ | ||
return new ValueTask<ConversionResult>(ConversionResult.Failed(exception)); | ||
} | ||
} | ||
|
||
private ServiceBusReceivedMessage ConvertToServiceBusReceivedMessage(ModelBindingData binding) | ||
{ | ||
if (binding?.Source is not Constants.BindingSource) | ||
{ | ||
throw new InvalidOperationException( | ||
$"Unexpected binding source. Only '{Constants.BindingSource}' is supported."); | ||
} | ||
|
||
if (binding.ContentType != Constants.BinaryContentType) | ||
{ | ||
throw new InvalidOperationException( | ||
$"Unexpected content-type. Only '{Constants.BinaryContentType}' is supported."); | ||
} | ||
|
||
// The lock token is a 16 byte GUID | ||
const int lockTokenLength = 16; | ||
|
||
ReadOnlyMemory<byte> bytes = binding.Content.ToMemory(); | ||
ReadOnlyMemory<byte> lockTokenBytes = bytes.Slice(0, lockTokenLength); | ||
ReadOnlyMemory<byte> messageBytes = bytes.Slice(lockTokenLength, bytes.Length - lockTokenLength); | ||
return ServiceBusReceivedMessage.FromAmqpMessage(AmqpAnnotatedMessage.FromBytes(BinaryData.FromBytes(messageBytes)), | ||
BinaryData.FromBytes(lockTokenBytes)); | ||
} | ||
} | ||
} |
7 changes: 6 additions & 1 deletion
7
extensions/Worker.Extensions.ServiceBus/src/ServiceBusTriggerAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
samples/WorkerBindingSamples/ServiceBus/ServiceBusReceivedMessageBindingSamples.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
using Azure.Messaging.ServiceBus; | ||
using Microsoft.Azure.Functions.Worker; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace SampleApp | ||
{ | ||
/// <summary> | ||
/// Samples demonstrating binding to the <see cref="ServiceBusReceivedMessage"/> type. | ||
/// </summary> | ||
public class ServiceBusReceivedMessageBindingSamples | ||
{ | ||
private readonly ILogger<ServiceBusReceivedMessageBindingSamples> _logger; | ||
|
||
public ServiceBusReceivedMessageBindingSamples(ILogger<ServiceBusReceivedMessageBindingSamples> logger) | ||
{ | ||
_logger = logger; | ||
} | ||
|
||
/// <summary> | ||
/// This function demonstrates binding to a single <see cref="ServiceBusReceivedMessage"/>. | ||
/// </summary> | ||
[Function(nameof(ServiceBusReceivedMessageFunction))] | ||
public void ServiceBusReceivedMessageFunction( | ||
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection")] ServiceBusReceivedMessage message) | ||
{ | ||
_logger.LogInformation("Message ID: {id}", message.MessageId); | ||
_logger.LogInformation("Message Body: {body}", message.Body); | ||
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType); | ||
} | ||
|
||
/// <summary> | ||
/// This function demonstrates binding to an array of <see cref="ServiceBusReceivedMessage"/>. | ||
/// Note that when doing so, you must also set the <see cref="ServiceBusTriggerAttribute.IsBatched"/> property | ||
/// to <value>true</value>. | ||
/// </summary> | ||
[Function(nameof(ServiceBusReceivedMessageBatchFunction))] | ||
public void ServiceBusReceivedMessageBatchFunction( | ||
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection", IsBatched = true)] ServiceBusReceivedMessage[] messages) | ||
{ | ||
foreach (ServiceBusReceivedMessage message in messages) | ||
{ | ||
_logger.LogInformation("Message ID: {id}", message.MessageId); | ||
_logger.LogInformation("Message Body: {body}", message.Body); | ||
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// This functions demonstrates that it is possible to bind to both the ServiceBusReceivedMessage and any of the supported binding contract | ||
/// properties at the same time. If attempting this, the ServiceBusReceivedMessage must be the first parameter. There is not | ||
/// much benefit to doing this as all of the binding contract properties are available as properties on the ServiceBusReceivedMessage. | ||
/// </summary> | ||
[Function(nameof(ServiceBusReceivedMessageWithStringProperties))] | ||
public void ServiceBusReceivedMessageWithStringProperties( | ||
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection")] | ||
ServiceBusReceivedMessage message, string messageId, int deliveryCount) | ||
{ | ||
// The MessageId property and the messageId parameter are the same. | ||
_logger.LogInformation("Message ID: {id}", message.MessageId); | ||
_logger.LogInformation("Message ID: {id}", messageId); | ||
|
||
// Similarly the DeliveryCount property and the deliveryCount parameter are the same. | ||
_logger.LogInformation("Delivery Count: {count}", message.DeliveryCount); | ||
_logger.LogInformation("Delivery Count: {count}", deliveryCount); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.