1

I hope you can help me.

I'm new to Azure and having lots of trouble understanding it. I'm trying to write an azure function, who is triggered with EventHubTrigger (when a new event is sent to eventHub), and will store the event in my table in cosmos db. (cosmos db as an output).

I'm writing in C# so that function.json is created automatically and I can't edit it. I can't seem to make it work, to set the trigger and output binding correctly.

this is my function code:

[FunctionName("InsertEvent")]
public static void Run(
    [EventHubTrigger("WaterlyNamespace", 
    Connection = "connectionStr")] string eventHubString,
    [CosmosDB(
    databaseName: "waterly_db",
    collectionName: "water_table", 
    Id = "device_id",
    ConnectionStringSetting = "conStr" )] out dynamic dbItem,
    ILogger log)

{
    log.LogInformation("C# trigger function processed an event from eventhub");

    EventItem dataJson = JsonConvert.DeserializeObject<EventItem>(eventHubString);

    //adding timestamp to event json
    dataJson.timestamp = DateTime.Now;

    dbItem = dataJson;
}

This is the function.json generated:

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-3.0.3",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "eventHubTrigger",
      "connection": "ConnectionStr",
      "eventHubName": "WaterlyNamespace",
      "name": "eventHubString"
    }
  ],
  "disabled": false,
  "scriptFile": "../bin/Waterly-iot-functions.dll",
  "entryPoint": "Waterly_iot_functions.InsertEvent.Run"
}

This is the host.json:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingExcludedTypes": "Request",
      "samplingSettings": {
        "isEnabled": true
      }
    }
  },
  "extensions": {
    "cosmosDB": {
      "connectionMode": "Gateway",
      "protocol": "Https",
      "leaseOptions": {
        "leasePrefix": "prefix1"
      }
    }
  }
}

and this is what I see in the Azure portal after publishing this code: See Image

Any ideas why the trigger is in the output area in the Azure portal, and what am I missing?

Any help would be very appreciated. Thanks,

Shahar Peleg
  • 13
  • 1
  • 4
  • 1
    If those are the actual keys you are using for Event Hubs and Storage, you may want to regenerate them since others have them now. – juunas May 25 '20 at 13:30
  • I have post an answer. You can have a look. By the way, there are some bugs of azure function UI, so maybe you can not see the input and trigger on portal. But actually it has deployed successfully. Please let me know whether you can use it well or not after trying the answers I posted.:) – Cindy Pau May 26 '20 at 06:48

1 Answers1

4

I think you have a problem with the usage of the connection string in the attribute.

Follow my steps, it can works fine:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.EventHubs;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

namespace FunctionApp54
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static void Run([EventHubTrigger("test", Connection = "str")] EventData[] events,
            [CosmosDB(
                databaseName: "testbowman",
                collectionName: "testbowman",
                ConnectionStringSetting = "CosmosDBConnection",
                PartitionKey = "111")]out dynamic item, 
            ILogger log)
        {
            item = new { id = Guid.NewGuid() , custom = "11111111111111111111"};
        }
    }
}

This is my local.settings.json:(On local, env vars are setted in local.settings.json)

{
    "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "str": "Endpoint=sb://testbowman.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxxxxx",
    "CosmosDBConnection": "AccountEndpoint=https://testbowman.documents.azure.com:443/;AccountKey=xxxxxx;"
  }
}

You should get the connection string from these places:

enter image description here

enter image description here

And then I create a console app to send event to event hub.

using System;
using System.Text;
using System.Threading.Tasks;
using Azure.Messaging.EventHubs;
using Azure.Messaging.EventHubs.Producer;

namespace SendEventToEventHub
{
    class Program
    {
        private const string connectionString = "Endpoint=sb://testbowman.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=pftXmTesAa894OWYGZyD5s8GynR9hXVJl7CdbMy45Nc=";
        private const string eventHubName = "test";
        static async Task Main(string[] args)
        {
            // Create a producer client that you can use to send events to an event hub
            await using (var producerClient = new EventHubProducerClient(connectionString, eventHubName))
            {
                // Create a batch of events 
                using EventDataBatch eventBatch = await producerClient.CreateBatchAsync();

                // Add events to the batch. An event is a represented by a collection of bytes and metadata. 
                eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes("First event")));
                eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes("Second event")));
                eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes("Third event")));

                // Use the producer client to send the batch of events to the event hub
                await producerClient.SendAsync(eventBatch);
                Console.WriteLine("A batch of 3 events has been published.");
            }
        }
    }
}

After that, I start my function, and I can see the output in cosmosdb:

enter image description here

By the way, if you deploy to azure, the settings should be set in below instead of local.settings.json:

enter image description here

Please let me know if you can do it successfully after trying as above. Good luck.:)

Cindy Pau
  • 13,085
  • 1
  • 15
  • 27
  • 1
    Thank you so much for this answer, Zhu Bowman! It's working! I can't thank you enough! THANKS!!! – Shahar Peleg May 26 '20 at 14:09
  • @ShaharPeleg Hello and welcome to stack overflow. We should do this when our question is solved by others: [mark the answer to end this question](https://i.stack.imgur.com/VsESi.png). The reason for this is that when others search for related questions, they can clearly know this There have a solution to the problem, otherwise the problem will appear as "no answer" like other problems. This is a good way to avoid duplicate problems and will also help other who face the similar problem.:) – Cindy Pau May 26 '20 at 15:02