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

Refactor deferred binding attributes #1723

Merged
merged 9 commits into from
Jul 10, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Microsoft.Azure.Functions.Worker
{
[AllowConverterFallback(false)]
[ConverterFallbackBehavior(ConverterFallbackBehavior.Default)]
[InputConverter(typeof(CosmosDBConverter))]
public sealed class CosmosDBInputAttribute : InputBindingAttribute
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace Microsoft.Azure.Functions.Worker
{
[AllowConverterFallback(true)]
[ConverterFallbackBehavior(ConverterFallbackBehavior.Default)]
[InputConverter(typeof(EventGridCloudEventConverter))]
[InputConverter(typeof(EventGridEventConverter))]
[InputConverter(typeof(EventGridBinaryDataConverter))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ namespace Microsoft.Azure.Functions.Worker.Extensions.EventGrid.TypeConverters
/// <summary>
/// Converter to bind to <see cref="BinaryData" /> or <see cref="BinaryData[]" /> type parameters.
/// </summary>
[SupportedConverterType(typeof(BinaryData))]
[SupportedConverterType(typeof(BinaryData[]))]
[SupportedTargetType(typeof(BinaryData))]
[SupportedTargetType(typeof(BinaryData[]))]
internal class EventGridBinaryDataConverter : EventGridConverterBase
{
protected override ConversionResult ConvertCore(Type targetType, string json)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ namespace Microsoft.Azure.Functions.Worker.Extensions.EventGrid.TypeConverters
/// <summary>
/// Converter to bind to <see cref="CloudEvent" /> or <see cref="CloudEvent[]" /> type parameters.
/// </summary>
[SupportedConverterType(typeof(CloudEvent))]
[SupportedConverterType(typeof(CloudEvent[]))]
[SupportedTargetType(typeof(CloudEvent))]
[SupportedTargetType(typeof(CloudEvent[]))]
internal class EventGridCloudEventConverter: EventGridConverterBase
{
protected override ConversionResult ConvertCore(Type targetType, string json)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ namespace Microsoft.Azure.Functions.Worker.Extensions.EventGrid.TypeConverters
/// <summary>
/// Converter to bind to <see cref="EventGridEvent" /> or <see cref="EventGridEvent[]" /> type parameters.
/// </summary>
[SupportedConverterType(typeof(EventGridEvent))]
[SupportedConverterType(typeof(EventGridEvent[]))]
[SupportedTargetType(typeof(EventGridEvent))]
[SupportedTargetType(typeof(EventGridEvent[]))]
internal class EventGridEventConverter : EventGridConverterBase
{
protected override ConversionResult ConvertCore(Type targetType, string json)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Microsoft.Azure.Functions.Worker.Extensions.EventGrid.TypeConverters
/// <summary>
/// Converter to bind to <see cref="string[]" /> type parameters.
/// </summary>
[SupportedConverterType(typeof(string[]))]
[SupportedTargetType(typeof(string[]))]
internal class EventGridStringArrayConverter : EventGridConverterBase
{
protected override ConversionResult ConvertCore(Type targetType, string json)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
namespace Microsoft.Azure.Functions.Worker
{
/// <summary>
/// Converter to bind to <see cref="EventData" /> or <see cref="EventData[]" /> type parameters.
/// Converter to bind to <see cref="EventData" /> or <see cref="EventData[]" /> type parameters.
/// </summary>
[SupportsDeferredBinding]
[SupportedConverterType(typeof(EventData))]
[SupportedConverterType(typeof(EventData[]))]
[SupportedTargetType(typeof(EventData))]
[SupportedTargetType(typeof(EventData[]))]
internal class EventDataConverter : IInputConverter
{
public ValueTask<ConversionResult> ConvertAsync(ConverterContext context)
Expand All @@ -30,7 +30,7 @@ public ValueTask<ConversionResult> ConvertAsync(ConverterContext context)
{
ModelBindingData binding => ConversionResult.Success(ConvertToEventData(binding)),
// Only array collections are currently supported, which matches the behavior of the in-proc extension.
CollectionModelBindingData collection => ConversionResult.Success(collection.ModelBindingDataArray
CollectionModelBindingData collection => ConversionResult.Success(collection.ModelBindingData
.Select(ConvertToEventData).ToArray()),
_ => ConversionResult.Unhandled()
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Microsoft.Azure.Functions.Worker
/// Attribute used to mark a function that should be triggered by Event Hubs messages.
/// </summary>
[BindingCapabilities(KnownBindingCapabilities.FunctionLevelRetry)]
[AllowConverterFallback(true)]
[ConverterFallbackBehavior(ConverterFallbackBehavior.Default)]
[InputConverter(typeof(EventDataConverter))]
public sealed class EventHubTriggerAttribute : TriggerBindingAttribute, ISupportCardinality
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ namespace Microsoft.Azure.Functions.Worker
/// Converter to bind to <see cref="ServiceBusReceivedMessage" /> or <see cref="ServiceBusReceivedMessage[]" /> type parameters.
/// </summary>
[SupportsDeferredBinding]
[SupportedConverterType(typeof(ServiceBusReceivedMessage))]
[SupportedConverterType(typeof(ServiceBusReceivedMessage[]))]
[SupportedTargetType(typeof(ServiceBusReceivedMessage))]
[SupportedTargetType(typeof(ServiceBusReceivedMessage[]))]
internal class ServiceBusReceivedMessageConverter : IInputConverter
{
public ValueTask<ConversionResult> ConvertAsync(ConverterContext context)
Expand All @@ -30,7 +30,7 @@ public ValueTask<ConversionResult> ConvertAsync(ConverterContext context)
{
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
CollectionModelBindingData collection => ConversionResult.Success(collection.ModelBindingData
.Select(ConvertToServiceBusReceivedMessage).ToArray()),
_ => ConversionResult.Unhandled()
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Microsoft.Azure.Functions.Worker
{
[AllowConverterFallback(true)]
[ConverterFallbackBehavior(ConverterFallbackBehavior.Default)]
[InputConverter(typeof(ServiceBusReceivedMessageConverter))]
public sealed class ServiceBusTriggerAttribute : TriggerBindingAttribute, ISupportCardinality
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Microsoft.Azure.Functions.Worker
{
[AllowConverterFallback(true)]
[ConverterFallbackBehavior(ConverterFallbackBehavior.Default)]
[InputConverter(typeof(BlobStorageConverter))]
public sealed class BlobInputAttribute : InputBindingAttribute
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ private async ValueTask<ConversionResult> ConvertFromCollectionBindingDataAsync(
? context.TargetType.GetElementType()
: context.TargetType.GenericTypeArguments[0];

IList result = Array.CreateInstance(elementType, collectionModelBindingData.ModelBindingDataArray.Length);
IList result = Array.CreateInstance(elementType, collectionModelBindingData.ModelBindingData.Length);

try
{
for (var i = 0; i < collectionModelBindingData.ModelBindingDataArray.Length; i++)
for (var i = 0; i < collectionModelBindingData.ModelBindingData.Length; i++)
{
var modelBindingData = collectionModelBindingData.ModelBindingDataArray[i];
var modelBindingData = collectionModelBindingData.ModelBindingData[i];

if (modelBindingData.Source is not Constants.BlobExtensionName)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Microsoft.Azure.Functions.Worker
{
[AllowConverterFallback(true)]
[ConverterFallbackBehavior(ConverterFallbackBehavior.Default)]
[InputConverter(typeof(BlobStorageConverter))]
public sealed class BlobTriggerAttribute : TriggerBindingAttribute
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace Microsoft.Azure.Functions.Worker
{
[AllowConverterFallback(true)]
[ConverterFallbackBehavior(ConverterFallbackBehavior.Default)]
[InputConverter(typeof(QueueMessageConverter))]
[InputConverter(typeof(QueueMessageBinaryDataConverter))]
public sealed class QueueTriggerAttribute : TriggerBindingAttribute
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.Azure.Functions.Worker
/// Converter to bind to <see cref="BinaryData" /> type parameters.
/// </summary>
[SupportsDeferredBinding]
[SupportedConverterType(typeof(BinaryData))]
[SupportedTargetType(typeof(BinaryData))]
internal sealed class QueueMessageBinaryDataConverter : QueueConverterBase<BinaryData>
{
public QueueMessageBinaryDataConverter() : base()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.Azure.Functions.Worker
/// Converter to bind to <see cref="QueueMessage" /> type parameters.
/// </summary>
[SupportsDeferredBinding]
[SupportedConverterType(typeof(QueueMessage))]
[SupportedTargetType(typeof(QueueMessage))]
internal sealed class QueueMessageConverter : QueueConverterBase<QueueMessage>
{
private readonly JsonSerializerOptions _jsonOptions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Microsoft.Azure.Functions.Worker
/// <summary>
/// Attribute used to configure a parameter as the input target for the Azure Storage Tables binding.
/// </summary>
[AllowConverterFallback(true)]
[ConverterFallbackBehavior(ConverterFallbackBehavior.Default)]
[InputConverter(typeof(TableClientConverter))]
[InputConverter(typeof(TableEntityConverter))]
[InputConverter(typeof(TableEntityEnumerableConverter))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Microsoft.Azure.Functions.Worker.Extensions.Tables.TypeConverters
/// Converter to bind <see cref="TableClient" /> type parameters.
/// </summary>
[SupportsDeferredBinding]
[SupportedConverterType(typeof(TableClient))]
[SupportedTargetType(typeof(TableClient))]
internal class TableClientConverter: TableConverterBase<TableClient>
{
public TableClientConverter(IOptionsSnapshot<TablesBindingOptions> tableOptions, ILogger<TableClientConverter> logger)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Microsoft.Azure.Functions.Worker.Extensions.Tables.TypeConverters
/// Converter to bind <see cref="TableEntity" /> type parameters.
/// </summary>
[SupportsDeferredBinding]
[SupportedConverterType(typeof(TableEntity))]
[SupportedTargetType(typeof(TableEntity))]
internal class TableEntityConverter : TableConverterBase<TableEntity>
{
public TableEntityConverter(IOptionsSnapshot<TablesBindingOptions> tableOptions, ILogger<TableEntityConverter> logger)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Microsoft.Azure.Functions.Worker.Extensions.Tables.TypeConverters
/// Converter to bind <see cref="IEnumerable{T}" /> of type <see cref="TableEntity"/> parameters.
/// </summary>
[SupportsDeferredBinding]
[SupportedConverterType(typeof(IEnumerable<TableEntity>))]
[SupportedTargetType(typeof(IEnumerable<TableEntity>))]
internal class TableEntityEnumerableConverter : TableConverterBase<IEnumerable<TableEntity>>
{
public TableEntityEnumerableConverter(IOptionsSnapshot<TablesBindingOptions> tableOptions, ILogger<TableEntityEnumerableConverter> logger)
Expand Down
4 changes: 2 additions & 2 deletions sdk/Sdk.Analyzers/BindingTypeCodeRefactoringProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ private static List<ITypeSymbol> GetSupportedTypes(SemanticModel model, List<Att
var converter = model.Compilation.GetTypeByMetadataName(converterName);
var converterAttributes = converter.GetAttributes();

var supportedConverterTypeAttributeType = model.Compilation.GetTypeByMetadataName(Constants.Types.SupportedConverterTypeAttribute);
var supportedTargetTypeAttributeType = model.Compilation.GetTypeByMetadataName(Constants.Types.SupportedTargetTypeAttribute);

supportedTypes.AddRange(converterAttributes
.Where(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, supportedConverterTypeAttributeType))
.Where(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, supportedTargetTypeAttributeType))
.Select(a => (ITypeSymbol)a.ConstructorArguments.FirstOrDefault().Value)
.ToList());
}
Expand Down
22 changes: 11 additions & 11 deletions sdk/Sdk.Analyzers/BindingTypeNotSupported.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ private static void AnalyzeParameter(SymbolAnalysisContext context, IParameterSy
continue;
}

var allowConverterFallbackParameterValue = GetAllowConverterFallbackParameterValue(context, attributeType);
if (allowConverterFallbackParameterValue is bool allowFallback && allowFallback)
var converterFallbackBehaviorParameterValue = GetConverterFallbackBehaviorParameterValue(context, attributeType);
if (converterFallbackBehaviorParameterValue.ToString() is not "Disallow")
{
// If allowConverterFallback is true, we don't need to check for supported types
// If the ConverterFallbackBehavior is Allow or Default, we don't need to check for supported types
// because we don't know all of the types that are supported via the fallback
continue;
}
Expand All @@ -78,11 +78,11 @@ private static void AnalyzeParameter(SymbolAnalysisContext context, IParameterSy
}
}

private static object GetAllowConverterFallbackParameterValue(SymbolAnalysisContext context, ITypeSymbol attributeType)
private static object GetConverterFallbackBehaviorParameterValue(SymbolAnalysisContext context, ITypeSymbol attributeType)
{
var allowConverterFallbackAttributeType = context.Compilation.GetTypeByMetadataName(Constants.Types.AllowConverterFallbackAttribute);
var allowConverterFallbackAttribute = attributeType.GetAttributes().FirstOrDefault(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, allowConverterFallbackAttributeType));
return allowConverterFallbackAttribute.ConstructorArguments.FirstOrDefault().Value;
var converterFallbackBehaviorAttributeType = context.Compilation.GetTypeByMetadataName(Constants.Types.ConverterFallbackBehaviorAttribute);
var converterFallbackBehaviorAttribute = attributeType.GetAttributes().FirstOrDefault(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, converterFallbackBehaviorAttributeType));
return converterFallbackBehaviorAttribute.ConstructorArguments.FirstOrDefault().Value;
}

private static List<object> GetSupportedTypes(SymbolAnalysisContext context, List<AttributeData> inputConverterAttributes)
Expand All @@ -96,16 +96,16 @@ private static List<object> GetSupportedTypes(SymbolAnalysisContext context, Lis

var converterAttributes = converter.GetAttributes();

var supportedConverterTypeAttributeType = context.Compilation.GetTypeByMetadataName(Constants.Types.SupportedConverterTypeAttribute);
var converterHasSupportedTypeAttribute = converterAttributes.Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, supportedConverterTypeAttributeType));
var supportedTargetTypeAttributeType = context.Compilation.GetTypeByMetadataName(Constants.Types.SupportedTargetTypeAttribute);
var converterHasSupportedTypeAttribute = converterAttributes.Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, supportedTargetTypeAttributeType));
if (!converterHasSupportedTypeAttribute)
{
// If a converter does not have the `SupportedConverterTypeAttribute`, we don't need to check for supported types
// If a converter does not have the `SupportedTargetTypeAttribute`, we don't need to check for supported types
continue;
}

supportedTypes.AddRange(converterAttributes
.Where(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, supportedConverterTypeAttributeType))
.Where(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, supportedTargetTypeAttributeType))
.SelectMany(a => a.ConstructorArguments.Select(arg => arg.Value))
.ToList());
}
Expand Down
4 changes: 2 additions & 2 deletions sdk/Sdk.Analyzers/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ internal static class Types
public const string InputBindingAttribute = "Microsoft.Azure.Functions.Worker.Extensions.Abstractions.InputBindingAttribute";
public const string TriggerBindingAttribute = "Microsoft.Azure.Functions.Worker.Extensions.Abstractions.TriggerBindingAttribute";
public const string InputConverterAttribute = "Microsoft.Azure.Functions.Worker.Converters.InputConverterAttribute";
public const string AllowConverterFallbackAttribute = "Microsoft.Azure.Functions.Worker.Converters.AllowConverterFallbackAttribute";
public const string SupportedConverterTypeAttribute = "Microsoft.Azure.Functions.Worker.Converters.SupportedConverterTypeAttribute";
public const string ConverterFallbackBehaviorAttribute = "Microsoft.Azure.Functions.Worker.Converters.ConverterFallbackBehaviorAttribute";
public const string SupportedTargetTypeAttribute = "Microsoft.Azure.Functions.Worker.Converters.SupportedTargetTypeAttribute";

// System types
internal const string TaskType = "System.Threading.Tasks.Task";
Expand Down
2 changes: 1 addition & 1 deletion sdk/Sdk.Generators/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ internal static class Types
internal const string FixedDelayRetryAttribute = "Microsoft.Azure.Functions.Worker.FixedDelayRetryAttribute";
internal const string ExponentialBackoffRetryAttribute = "Microsoft.Azure.Functions.Worker.ExponentialBackoffRetryAttribute";
internal const string InputConverterAttributeType = "Microsoft.Azure.Functions.Worker.Converters.InputConverterAttribute";
internal const string SupportedConverterTypeAttributeType = "Microsoft.Azure.Functions.Worker.Converters.SupportedConverterTypeAttribute";
internal const string SupportedTargetTypeAttributeType = "Microsoft.Azure.Functions.Worker.Converters.SupportedTargetTypeAttribute";
internal const string SupportsDeferredBindingAttributeType = "Microsoft.Azure.Functions.Worker.Extensions.Abstractions.SupportsDeferredBindingAttribute";

// System types
Expand Down