Skip to content

Commit

Permalink
Output binding converter run through code
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesRandall committed Feb 14, 2020
1 parent 8f68b70 commit 766e676
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ public interface IFunctionOptions<out TParentBuilder, out TFunctionOptionsBuilde
{
TParentBuilder Options(Action<TFunctionOptionsBuilder> options);
IOutputBindingBuilder<TParentBuilder> OutputTo { get; }
TParentBuilder OutputBindingConverter<TConverter>() where TConverter : IOutputBindingConverter;
}
}
11 changes: 5 additions & 6 deletions Source/FunctionMonkey.Compiler.Core/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,18 +152,17 @@ private bool VerifyOutputBindings(IFunctionHostBuilder builder)
{
if (signalROutputBinding.SignalROutputTypeName == SignalROutputBinding.SignalROutputMessageType)
{
if (!typeof(SignalRMessage).IsAssignableFrom(functionDefinition.CommandResultItemType))
if (signalROutputBinding.OutputBindingConverterType == null && !typeof(SignalRMessage).IsAssignableFrom(functionDefinition.CommandResultItemType))
{
_compilerLog.Error("Commands that use SignalRMessage output bindings must return a FunctionMonkey.Abstractions.SignalR.SignalRMessage class or a derivative");
_compilerLog.Error("Commands that use SignalRMessage output bindings must return a FunctionMonkey.Abstractions.SignalR.SignalRMessage class, a derivative, or use an output converter");
foundErrors = true;
}
}
else if (signalROutputBinding.SignalROutputTypeName ==
SignalROutputBinding.SignalROutputGroupActionType)
else if (signalROutputBinding.SignalROutputTypeName == SignalROutputBinding.SignalROutputGroupActionType)
{
if (!typeof(SignalRGroupAction).IsAssignableFrom(functionDefinition.CommandResultItemType))
if (signalROutputBinding.OutputBindingConverterType == null && !typeof(SignalRGroupAction).IsAssignableFrom(functionDefinition.CommandResultItemType))
{
_compilerLog.Error("Commands that use SignalRGroupAction output bindings must return a FunctionMonkey.Abstractions.SignalR.SignalRGroupAction class or a derivative");
_compilerLog.Error("Commands that use SignalRGroupAction output bindings must return a FunctionMonkey.Abstractions.SignalR.SignalRGroupAction class, a derivative, or use an output converter");
foundErrors = true;
}
}
Expand Down
19 changes: 17 additions & 2 deletions Source/FunctionMonkey/Builders/CosmosDbFunctionOptionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class CosmosDbFunctionOptionBuilder<TCommandOuter> : ICosmosDbFunctionOpt
private readonly ConnectionStringSettingNames _connectionStringSettingNames;
private readonly ICosmosDbFunctionBuilder _underlyingBuilder;
private readonly CosmosDbFunctionDefinition _functionDefinition;

public CosmosDbFunctionOptionBuilder(
ConnectionStringSettingNames connectionStringSettingNames,
ICosmosDbFunctionBuilder underlyingBuilder,
Expand Down Expand Up @@ -67,6 +67,21 @@ public ICosmosDbFunctionOptionBuilder<TCommandOuter> Options(Action<IFunctionOpt
}

public IOutputBindingBuilder<ICosmosDbFunctionOptionBuilder<TCommandOuter>> OutputTo =>
new OutputBindingBuilder<ICosmosDbFunctionOptionBuilder<TCommandOuter>>(_connectionStringSettingNames, this, _functionDefinition);
new OutputBindingBuilder<ICosmosDbFunctionOptionBuilder<TCommandOuter>>(_connectionStringSettingNames, this, _functionDefinition, _pendingOutputConverterType);

private Type _pendingOutputConverterType = null;
public ICosmosDbFunctionOptionBuilder<TCommandOuter> OutputBindingConverter<TConverter>() where TConverter : IOutputBindingConverter
{
if (_functionDefinition.OutputBinding != null)
{
_functionDefinition.OutputBinding.OutputBindingConverterType = typeof(TConverter);
}
else
{
_pendingOutputConverterType = typeof(TConverter);
}

return this;
}
}
}
18 changes: 17 additions & 1 deletion Source/FunctionMonkey/Builders/EventHubFunctionOptionBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using AzureFromTheTrenches.Commanding.Abstractions;
using FunctionMonkey.Abstractions;
using FunctionMonkey.Abstractions.Builders;
using FunctionMonkey.Abstractions.Builders.Model;

Expand Down Expand Up @@ -34,6 +35,21 @@ public IEventHubFunctionOptionBuilder<TCommandOuter> Options(Action<IFunctionOpt
}

public IOutputBindingBuilder<IEventHubFunctionOptionBuilder<TCommandOuter>> OutputTo =>
new OutputBindingBuilder<IEventHubFunctionOptionBuilder<TCommandOuter>>(_connectionStringSettingNames, this, _functionDefinition);
new OutputBindingBuilder<IEventHubFunctionOptionBuilder<TCommandOuter>>(_connectionStringSettingNames, this, _functionDefinition, _pendingOutputConverterType);

private Type _pendingOutputConverterType = null;
public IEventHubFunctionOptionBuilder<TCommandOuter> OutputBindingConverter<TConverter>() where TConverter : IOutputBindingConverter
{
if (_functionDefinition.OutputBinding != null)
{
_functionDefinition.OutputBinding.OutputBindingConverterType = typeof(TConverter);
}
else
{
_pendingOutputConverterType = typeof(TConverter);
}

return this;
}
}
}
17 changes: 15 additions & 2 deletions Source/FunctionMonkey/Builders/HttpFunctionConfigurationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,21 @@ public IHttpFunctionConfigurationBuilder<TCommandOuter> Options(Action<IHttpFunc
}

public IOutputBindingBuilder<IHttpFunctionConfigurationBuilder<TCommandOuter>> OutputTo =>
new OutputBindingBuilder<IHttpFunctionConfigurationBuilder<TCommandOuter>>(_connectionStringSettingNames, this, _definition);
new OutputBindingBuilder<IHttpFunctionConfigurationBuilder<TCommandOuter>>(_connectionStringSettingNames, this, _definition, _pendingOutputConverterType);


private Type _pendingOutputConverterType = null;
public IHttpFunctionConfigurationBuilder<TCommandOuter> OutputBindingConverter<TConverter>() where TConverter : IOutputBindingConverter
{
if (_definition.OutputBinding != null)
{
_definition.OutputBinding.OutputBindingConverterType = typeof(TConverter);
}
else
{
_pendingOutputConverterType = typeof(TConverter);
}

return this;
}
}
}
44 changes: 31 additions & 13 deletions Source/FunctionMonkey/Builders/OutputBindingBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,19 @@ internal class OutputBindingBuilder<TParentBuilder> : IOutputBindingBuilder<TPar
private readonly ConnectionStringSettingNames _connectionStringSettingNames;
private readonly TParentBuilder _parentBuilder;
private readonly AbstractFunctionDefinition _functionDefinition;

public OutputBindingBuilder(ConnectionStringSettingNames connectionStringSettingNames, TParentBuilder parentBuilder, AbstractFunctionDefinition functionDefinition)
private readonly Type _pendingOutputConverterType;

public OutputBindingBuilder(
ConnectionStringSettingNames connectionStringSettingNames,
TParentBuilder parentBuilder,
AbstractFunctionDefinition functionDefinition,
Type pendingOutputConverterType
)
{
_connectionStringSettingNames = connectionStringSettingNames;
_parentBuilder = parentBuilder;
_functionDefinition = functionDefinition;
_pendingOutputConverterType = pendingOutputConverterType;
}

public TParentBuilder ServiceBusQueue(string connectionString, string queueName)
Expand All @@ -32,9 +39,10 @@ public TParentBuilder ServiceBusQueue(string connectionString, string queueName)

_functionDefinition.OutputBinding = new ServiceBusQueueOutputBinding(_functionDefinition, connectionString)
{
QueueName = queueName
QueueName = queueName,
OutputBindingConverterType = _pendingOutputConverterType
};

return _parentBuilder;
}

Expand All @@ -54,7 +62,8 @@ public TParentBuilder ServiceBusQueue<TResult>(string connectionString, string q
_functionDefinition.OutputBinding = new ServiceBusQueueOutputBinding(_functionDefinition, connectionString)
{
QueueName = queueName,
SessionIdPropertyName = sessionIdPropertyName
SessionIdPropertyName = sessionIdPropertyName,
OutputBindingConverterType = _pendingOutputConverterType
};

return _parentBuilder;
Expand All @@ -70,7 +79,8 @@ public TParentBuilder ServiceBusTopic(string connectionString, string topicName)
VerifyOutputBinding();
_functionDefinition.OutputBinding = new ServiceBusTopicOutputBinding(_functionDefinition, connectionString)
{
TopicName = topicName
TopicName = topicName,
OutputBindingConverterType = _pendingOutputConverterType
};

return _parentBuilder;
Expand All @@ -92,7 +102,8 @@ public TParentBuilder ServiceBusTopic<TResult>(string connectionString, string t
_functionDefinition.OutputBinding = new ServiceBusTopicOutputBinding(_functionDefinition, connectionString)
{
TopicName = topicName,
SessionIdPropertyName = sessionIdPropertyName
SessionIdPropertyName = sessionIdPropertyName,
OutputBindingConverterType = _pendingOutputConverterType
};

return _parentBuilder;
Expand All @@ -114,7 +125,8 @@ public TParentBuilder SignalRMessage(string connectionStringSettingName, string
_functionDefinition.OutputBinding = new SignalROutputBinding(_functionDefinition, connectionStringSettingName)
{
HubName = hubName,
SignalROutputTypeName = SignalROutputBinding.SignalROutputMessageType // can't use typeof() here as we don't want to bring the SignalR package into here
SignalROutputTypeName = SignalROutputBinding.SignalROutputMessageType, // can't use typeof() here as we don't want to bring the SignalR package into here
OutputBindingConverterType = _pendingOutputConverterType
};
return _parentBuilder;
}
Expand All @@ -127,7 +139,8 @@ public TParentBuilder SignalRGroupAction(string connectionStringSettingName, str
connectionStringSettingName)
{
HubName = hubName,
SignalROutputTypeName = SignalROutputBinding.SignalROutputGroupActionType // can't use typeof() here as we don't want to bring the SignalR package into here
SignalROutputTypeName = SignalROutputBinding.SignalROutputGroupActionType, // can't use typeof() here as we don't want to bring the SignalR package into here
OutputBindingConverterType = _pendingOutputConverterType
};
return _parentBuilder;
}
Expand All @@ -142,6 +155,7 @@ public TParentBuilder StorageBlob(string connectionStringSettingName, string nam
if (_functionDefinition.OutputBinding is null)
{
_functionDefinition.OutputBinding = new StorageBlobOutputBinding(_functionDefinition);
_functionDefinition.OutputBinding.OutputBindingConverterType = _pendingOutputConverterType;
}

if (_functionDefinition.OutputBinding is StorageBlobOutputBinding blobBinding)
Expand Down Expand Up @@ -170,7 +184,8 @@ public TParentBuilder StorageQueue(string connectionStringSettingName, string qu
VerifyOutputBinding();
_functionDefinition.OutputBinding = new StorageQueueOutputBinding(_functionDefinition, connectionStringSettingName)
{
QueueName = queueName
QueueName = queueName,
OutputBindingConverterType = _pendingOutputConverterType
};
return _parentBuilder;
}
Expand All @@ -185,7 +200,8 @@ public TParentBuilder StorageTable(string connectionStringSettingName, string ta
VerifyOutputBinding();
_functionDefinition.OutputBinding = new StorageTableOutputBinding(_functionDefinition, connectionStringSettingName)
{
TableName = tableName
TableName = tableName,
OutputBindingConverterType = _pendingOutputConverterType
};
return _parentBuilder;
}
Expand All @@ -207,7 +223,8 @@ public TParentBuilder CosmosDb(string connectionStringSettingName, string collec
{
CollectionName = collectionName,
DatabaseName = databaseName,
IsCollection = isCollection
IsCollection = isCollection,
OutputBindingConverterType = _pendingOutputConverterType
};

return _parentBuilder;
Expand All @@ -223,7 +240,8 @@ public TParentBuilder EventHub(string connectionStringSettingName, string hubNam
VerifyOutputBinding();
_functionDefinition.OutputBinding = new EventHubOutputBinding(_functionDefinition, connectionStringSettingName)
{
EventHub = hubName
EventHub = hubName,
OutputBindingConverterType = _pendingOutputConverterType
};

return _parentBuilder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,24 @@ public IServiceBusFunctionOptionBuilder<TCommandOuter> Options(Action<IFunctionO
return this;
}



public IOutputBindingBuilder<IServiceBusFunctionOptionBuilder<TCommandOuter>> OutputTo =>
new OutputBindingBuilder<IServiceBusFunctionOptionBuilder<TCommandOuter>>(_connectionStringSettingNames, this, _functionDefinition);
new OutputBindingBuilder<IServiceBusFunctionOptionBuilder<TCommandOuter>>(_connectionStringSettingNames, this, _functionDefinition, _pendingOutputConverterType);

private Type _pendingOutputConverterType = null;
public IServiceBusFunctionOptionBuilder<TCommandOuter> OutputBindingConverter<TConverter>() where TConverter : IOutputBindingConverter
{
if (_functionDefinition.OutputBinding != null)
{
_functionDefinition.OutputBinding.OutputBindingConverterType = typeof(TConverter);
}
else
{
_pendingOutputConverterType = typeof(TConverter);
}

return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Net.Http;
using AzureFromTheTrenches.Commanding.Abstractions;
using FunctionMonkey.Abstractions;
using FunctionMonkey.Abstractions.Builders;
using FunctionMonkey.Abstractions.Builders.Model;
using FunctionMonkey.Commanding.Abstractions;
Expand Down Expand Up @@ -49,7 +50,22 @@ public ISignalRFunctionConfigurationBuilder<TCommandOuter> Options(Action<IHttpF
}

public IOutputBindingBuilder<ISignalRFunctionConfigurationBuilder<TCommandOuter>> OutputTo =>
new OutputBindingBuilder<ISignalRFunctionConfigurationBuilder<TCommandOuter>>(_connectionStringSettingNames, this, _definition);
new OutputBindingBuilder<ISignalRFunctionConfigurationBuilder<TCommandOuter>>(_connectionStringSettingNames, this, _definition, _pendingOutputConverterType);

private Type _pendingOutputConverterType = null;
public ISignalRFunctionConfigurationBuilder<TCommandOuter> OutputBindingConverter<TConverter>() where TConverter : IOutputBindingConverter
{
if (_definition.OutputBinding != null)
{
_definition.OutputBinding.OutputBindingConverterType = typeof(TConverter);
}
else
{
_pendingOutputConverterType = typeof(TConverter);
}

return this;
}

public ISignalRFunctionConfigurationBuilder<TCommand> Negotiate<TCommand>(string route, AuthorizationTypeEnum? authorizationType = null,
params HttpMethod[] method)
Expand Down
17 changes: 16 additions & 1 deletion Source/FunctionMonkey/Builders/StorageFunctionOptionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ public IStorageFunctionOptionBuilder<TCommandOuter> Options(Action<IFunctionOpti
}

public IOutputBindingBuilder<IStorageFunctionOptionBuilder<TCommandOuter>> OutputTo =>
new OutputBindingBuilder<IStorageFunctionOptionBuilder<TCommandOuter>>(_connectionStringSettingNames, this, _definition);
new OutputBindingBuilder<IStorageFunctionOptionBuilder<TCommandOuter>>(_connectionStringSettingNames, this, _definition, _pendingOutputConverterType);

private Type _pendingOutputConverterType = null;
public IStorageFunctionOptionBuilder<TCommandOuter> OutputBindingConverter<TConverter>() where TConverter : IOutputBindingConverter
{
if (_definition.OutputBinding != null)
{
_definition.OutputBinding.OutputBindingConverterType = typeof(TConverter);
}
else
{
_pendingOutputConverterType = typeof(TConverter);
}

return this;
}
}
}
17 changes: 16 additions & 1 deletion Source/FunctionMonkey/Builders/TimerFunctionOptionsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,21 @@ public IFunctionBuilder SignalR(Action<ISignalRFunctionBuilder> signalRFunctionB
return _functionBuilder.SignalR(signalRFunctionBuilder);
}

public IOutputBindingBuilder<IFunctionBuilder> OutputTo => new OutputBindingBuilder<IFunctionBuilder>(_connectionStringSettingNames, _functionBuilder, _functionDefinition);
public IOutputBindingBuilder<IFunctionBuilder> OutputTo => new OutputBindingBuilder<IFunctionBuilder>(_connectionStringSettingNames, _functionBuilder, _functionDefinition, _pendingOutputConverterType);

private Type _pendingOutputConverterType = null;
public IFunctionBuilder OutputBindingConverter<TConverter>() where TConverter : IOutputBindingConverter
{
if (_functionDefinition.OutputBinding != null)
{
_functionDefinition.OutputBinding.OutputBindingConverterType = typeof(TConverter);
}
else
{
_pendingOutputConverterType = typeof(TConverter);
}

return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ protected override IFunctionBuilder CreateAdditionalFunctions(IFunctionBuilder b

.HttpFunction<HttpTriggerServiceBusQueueOutputWithConverterCommand>("/toServiceBusQueueWithConverter")
.OutputTo.ServiceBusQueue(Constants.ServiceBus.MarkerQueue)
.OutputBindingConverter<OptionalValueCommandOutputBindingConverter>()

.HttpFunction<HttpTriggerServiceBusQueueCollectionOutputCommand>("/collectionToServiceBusQueue")
.OutputTo.ServiceBusQueue(Constants.ServiceBus.MarkerQueue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ public void Build(IFunctionHostBuilder builder)
{"DefaultHeaderStringValue", "x-default-string"}
}
})
.DefaultOutputConverter<OptionalValueCommandConverter>()
.Functions(functions =>
{
CreateCommonFunctions(functions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace FunctionMonkey.Tests.Integration.Common
{
public class OptionalValueCommandConverter : IOutputBindingConverter
public class OptionalValueCommandOutputBindingConverter : IOutputBindingConverter
{
public object Convert(object input)
{
Expand Down

0 comments on commit 766e676

Please sign in to comment.