Handling multiple return values in an Azure function

52 Views Asked by At

I've got an Azure function that currently consumes messages from an Azure Service Bus, does some transformation and posts a message to an Azure Event Hub. However, I also want to post a message to an Azure Service Bus, different from the one I'm consuming from. Can this be achieved by using multiple return values?

[FunctionName("IntegrationFunction")]
[return: EventHub("%Transactions:EVH:Transactions:Hub%", Connection = "Transactions:EVH:Transactions")]
public Transaction Run(
    [ServiceBusTrigger(
        "%Transactions:SB:Transactions:ReceiveTopic%",
        "%Transactions:SB:Transactions:AnalyticsTopicSubscription%",
        Connection = "Transactions:SB:Transactions")]
    string mySbMsg,
    ILogger log)
{
    if (string.IsNullOrWhiteSpace(mySbMsg))
    {
        throw new ArgumentNullException(nameof(mySbMsg));
    }

    log.LogInformation($"Service bus topic trigger function processing message: {mySbMsg}");
    
    var retailTransaction = JsonConvert.DeserializeObject<RetailTransaction>(
        mySbMsg,
        JsonSerialisationUtils.SerialiserSettings);
    
    if (retailTransaction == null)
    {
        throw new JsonException("Deserialized transaction was null");
    }

    try
    {
        var transaction = retailTransaction.ToDto();
        log.LogInformation($"Transaction {transaction.TransactionNumber} processed.");
        return transaction;
    }
    catch (Exception e)
    {
        log.LogError(e, "Error mapping transaction.");
    }

    return null;
}
1

There are 1 best solutions below

0
Ikhtesam Afrin On

It is not feasible to use multiple return in azure function as mentioned in this github issue instead you can use CloudQueue or IAsyncCollector<T> object.

  • I am using the below code to send the service bus message to Event hub as well as another service bus queue.
using System;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace _78237298
{
    public class IntegrationFunction
    {
        [FunctionName("IntegrationFunction")]
        public async Task Run(
            [ServiceBusTrigger(
            "%Transactions:SB:Transactions:ReceiveTopic%", 
            "%Transactions:SB:Transactions:AnalyticsTopicSubscription%", 
            Connection = "Transactions:SB:Transactions")]
            string mySbMsg,
            [EventHub("%Transactions:EVH:Transactions:Hub%", Connection = "Transactions:EVH:Transactions")] IAsyncCollector<Transaction> outputEventHubMessages,
            [ServiceBus("%OtherServiceBus:QueueName%", Connection = "OtherServiceBus:ConnectionString")] IAsyncCollector<string> outputQueueMessages,
            ILogger log)
        {
            if (string.IsNullOrWhiteSpace(mySbMsg))
            {
                throw new ArgumentNullException(nameof(mySbMsg));
            }

            log.LogInformation($"Service bus topic trigger function processing message: {mySbMsg}");

            var retailTransaction = JsonConvert.DeserializeObject<RetailTransaction>(
                mySbMsg);

            if (retailTransaction == null)
            {
                throw new JsonException("Deserialized transaction was null");
            }

            try
            {
                var transaction = retailTransaction.ToDto();
                log.LogInformation($"Transaction {transaction.TransactionNumber} processed.");
                
                // Send to Event Hub
                await outputEventHubMessages.AddAsync(transaction);

                // Send to another Service Bus queue
                var anotherSbMsg = JsonConvert.SerializeObject(transaction);
                await outputQueueMessages.AddAsync(anotherSbMsg);
            }
            catch (Exception e)
            {
                log.LogError(e, "Error mapping transaction.");
            }

        }
    }

    public class RetailTransaction
    {
        public string TransactionNumber { get; set; }
        public decimal Amount { get; set; }

        public Transaction ToDto()
        {
            return new Transaction
            {
                TransactionNumber = this.TransactionNumber,
                Amount = this.Amount
            };
        }
    }

    public class Transaction
    {
        public string TransactionNumber { get; set; }
        public decimal Amount { get; set; }
    }
}

.csproj-

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <RootNamespace>_78237298</RootNamespace>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Azure.Messaging.EventHubs" Version="5.11.1" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.EventHubs" Version="6.2.0" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.ServiceBus" Version="5.14.0" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.3.0" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

Output-

1st Service Bus Topic-

I am sending message from this Service Bus.

enter image description here

enter image description here

Event Hub-

enter image description here

2nd Service Bus Queue-

enter image description here