Coder Social home page Coder Social logo

pmcilreavy / azureeventgridsimulator Goto Github PK

View Code? Open in Web Editor NEW
82.0 5.0 40.0 293 KB

A simulator that provides endpoints to mimic the functionality of Azure Event Grid topics and subscribers and is compatible with the Azure.Messaging.EventGrid client library.

License: MIT License

C# 95.79% Batchfile 1.64% PowerShell 1.72% Dockerfile 0.85%
azure eventgrid simulator event-grid-topic event-grid-simulator

azureeventgridsimulator's Introduction

Azure Event Grid Simulator

GitHub Workflow Status GitHub contributors GitHub tag (latest SemVer) GitHub all releases Docker Pulls

A simulator that provides endpoints to mimic the functionality of Azure Event Grid topics and subscribers and is compatible with the Microsoft.Azure.EventGrid client library. NOTE: Currently only the EventGrid event schema is supported. Support for the CloudEvent schema may be added at a future date.

Configuration

Topics and their subscribers are configured in the appsettings.json file.

You can add multiple topics. Each topic must have a unique port. Each topic can have multiple subscribers. An example of one topic with one subscriber is shown below.

{
  "topics": [
    {
      "name": "MyAwesomeTopic",
      "port": 60101,
      "key": "TheLocal+DevelopmentKey=",
      "subscribers": [
        {
          "name": "LocalAzureFunctionSubscription",
          "endpoint": "http://localhost:7071/runtime/webhooks/EventGrid?functionName=PersistEventToDb",
          "disableValidation": true
        }
      ]
    }
  ]
}

Topic Settings

  • name: The name of the topic. It can only contain letters, numbers, and dashes.
  • port: The port to use for the topic endpoint. The topic will listen on https://0.0.0.0:{port}/.
  • key: The key that will be used to validate the aeg-sas-key or aeg-sas-token header in each request. If this is not supplied then no key validation will take place.
  • subscribers: The subscriptions for this topic.

Subscriber Settings

  • name: The name of the subscriber. It can only contain letters, numbers, and dashes.
  • endpoint: The subscription endpoint url. Events received by topic will be sent to this address.
  • disableValidation:
    • false (the default) subscription validation will be attempted each time the simulator starts.
    • true to disable subscription validation.

App Settings

  • dangerousAcceptAnyServerCertificateValidator: Set to true to accept any server certificate. This is useful when testing with self signed certificates.

Subscription Validation

When a subscription is added to Azure Event Grid it first sends a validation event to the subscription endpoint. The validation event contains a validationCode which the subscription endpoint must echo back. If this does not occur then Azure Event Grid will not enable the subscription.

More information about subscription validation can be found at https://docs.microsoft.com/en-us/azure/event-grid/webhook-event-delivery.

The Azure Event Grid Simualator will mimick this validation behaviour at start up but it can be disabled using the disableValidation setting (above).

Filtering Events

Event filtering is configurable on each subscriber using the filter model defined here: https://docs.microsoft.com/en-us/azure/event-grid/event-filtering. This page provides a full guide to the configuration options available and all parts of this guide are currently supported. For ease of transition, explicit limitations have also been adhered to. The restrictions mentioned have been further modified (https://azure.microsoft.com/en-us/updates/advanced-filtering-generally-available-in-event-grid/) and these new less restrictive filtering limits have been observed.

Extending the example above to include a basic filter which will only deliver events to the subscription if they are of a specific type is illustrated below.

{
  "topics": [
    {
      "name": "MyAwesomeTopic",
      "port": 60101,
      "key": "TheLocal+DevelopmentKey=",
      "subscribers": [
        {
          "name": "LocalAzureFunctionSubscription",
          "endpoint": "http://localhost:7071/runtime/webhooks/EventGrid?functionName=PersistEventToDb",
          "filter": {
            "includedEventTypes": ["my.eventType"]
          }
        }
      ]
    }
  ]
}

This can be extended to allow subject filtering:

"filter": {
  "subjectBeginsWith": "/blobServices/default/containers/mycontainer/log",
  "subjectEndsWith": ".jpg",
  "isSubjectCaseSensitive": true
}

or advanced filtering:

"filter": {
  "advancedFilters": [
    {
      "operatorType": "NumberGreaterThanOrEquals",
      "key": "Data.Key1",
      "value": 5
    },
    {
      "operatorType": "StringContains",
      "key": "Subject",
      "values": ["container1", "container2"]
    }
  ]
}

Note: you can also specify the configuration file to use by setting the ConfigFile command line argument, e.g.

AzureEventGridSimulator.exe --ConfigFile=/path/to/config.json

Docker

There's a published image available on the โ†— Docker hub called pmcilreavy/azureeventgridsimulator:latest. The image is not configured with any topics or subscribers. The configuration can be passed in via command line environment variables (as below) or via a json file.

Docker Run

Here's an example of running a container based on that image and passing in the configuration via environment variables to create 1 topic with 2 subscribers. In this example the folder C:\src\AzureEventGridSimulator\docker on the host is being shared with the container. Note: see the notes section further below on how to create a certificate file.

docker run `
        --detach `
        --publish 60101:60101 `
        -v C:\src\AzureEventGridSimulator\docker:/aegs `
        -e ASPNETCORE_ENVIRONMENT=Development `
        -e ASPNETCORE_Kestrel__Certificates__Default__Path=/aegs/azureEventGridSimulator.pfx `
        -e ASPNETCORE_Kestrel__Certificates__Default__Password=Y0urSup3rCrypt1cPa55w0rd! `
        -e TZ=Australia/Brisbane `
        -e AEGS_Topics__0__name=ExampleTopic `
        -e AEGS_Topics__0__port=60101 `
        -e AEGS_Topics__0__key=TheLocal+DevelopmentKey= `
        -e AEGS_Topics__0__subscribers__0__name=RequestCatcherSubscription `
        -e AEGS_Topics__0__subscribers__0__endpoint=https://azureeventgridsimulator.requestcatcher.com/ `
        -e AEGS_Topics__0__subscribers__0__disableValidation=true `
        -e AEGS_Topics__0__subscribers__1__name=AzureFunctionSubscription `
        -e AEGS_Topics__0__subscribers__1__endpoint=http://host.docker.internal:7071/runtime/webhooks/EventGrid?functionName=ExampleFunction `
        -e AEGS_Topics__0__subscribers__1__disableValidation=true `
        -e AEGS_Serilog__MinimumLevel__Default=Verbose `
        pmcilreavy/azureeventgridsimulator:latest

Docker Compose

There is a docker-compose.yml file in the src folder that you can use (or modify) to build your own Docker image.

docker-compose up   --build `
                    --force-recreate `
                    --remove-orphans `
                    --detach

Using the Simulator

Once configured and running, requests are posted to a topic endpoint. The endpoint of a topic will be in the form: https://localhost:<configured-port>/api/events?api-version=2018-01-01.

cURL Example

curl -k -H "Content-Type: application/json" -H "aeg-sas-key: TheLocal+DevelopmentKey=" -X POST "https://localhost:60101/api/events?api-version=2018-01-01" -d @Data.json

Data.json

[
  {
    "id": "8727823",
    "subject": "/example/subject",
    "data": {
      "MyProperty": "This is my awesome data!"
    },
    "eventType": "Example.DataType",
    "eventTime": "2019-01-01T00:00:00.000Z",
    "dataVersion": "1"
  }
]

Postman

An example request that you can import into Postman can be found in the AzureEventGridSimulator repo here https://github.com/pmcilreavy/AzureEventGridSimulator/blob/master/src/Azure%20Event%20Grid%20Simulator.postman_collection.json.

EventGridClient

var client = new EventGridClient(new TopicCredentials("TheLocal+DevelopmentKey="));
await client.PublishEventsWithHttpMessagesAsync(
    topicHostname: "localhost:60101",
    events: new List<EventGridEvent> { <your event> });

Notes

HTTPs

Azure Event Grid only accepts connections over https and so the simulator only supports https too.

The simulator will attempt to use the dotnet development certificate to secure each topic port. You can ensure that this certificate is installed and trusted by running the following command.

dotnet dev-certs https --trust

You can also generate a certificate file (suitable for using with a Docker container) like so.

dotnet dev-certs https --export-path ./docker/azureEventGridSimulator.pfx --password Y0urSup3rCrypt1cPa55w0rd!

Subscribers

A topic can have 0 to n subscribers. When a request is received for a topic, the events will be forwarded to each of the subscribers with the addition of an aeg-event-type: Notification header. If the message contains multiple events, they will be sent to each subscriber one at a time inline with the Azure Event Grid behaviour. "Event Grid sends the events to subscribers in an array that has a single event. This behavior may change in the future." https://docs.microsoft.com/en-us/azure/event-grid/event-schema

Key Validation

The simulator supports both: aeg-sas-key or aeg-sas-token request headers. Using aeg-sas-key is the simplest way. Just set the value of the aeg-sas-key to the same key value configured for the topic. Using an aeg-sas-token is more secure as the key is hashed but it's a bit trickier to set up. More information on sas token can be found here https://docs.microsoft.com/en-us/azure/event-grid/security-authentication#sas-tokens.

If the incoming request contains either an aeg-sas-token or an aeg-sas-key header and there is a Key configured for the topic then the simulator will validate the key and reject the request if the value in the header is not valid. If you want to skip the validation then set the Key to null in appsettings.json.

Size Validation

Azure Event Grid imposes certain size limits to the overall message body and to the each individual event. The overall message body must be <= 1Mb and each individual event must be <= 64Kb. These are the advertised size limits. My testing has shown that the actual limits are 1.5Mb and 65Kb.

Message Validation

Ensures that the properties of each event meets the minimum requirements.

Field Description
Id Must be a string. Not null or whitespace.
Subject Must be a string. Not null or whitespace.
EventType Must be a string. Not null or whitespace.
EventTime Must be a valid date/time.
MetadataVersion Must be null or 1.
Topic Leave null or empty. Event Grid will populate this field.
DataVersion Optional. e.g. 1.
Data Optional. Any custom object.

Why?

There are a couple of similar projects out there. What I found though is that they don't adequately simulate an actual Event Grid Topic endpoint.

Azure Event Grid only excepts connections over https and the Microsoft.Azure.EventGrid client only sends requests over https. If you're posting events to an Event Grid topic using custom code then maybe this isn't an issue. If you are using the client library though then any test endpoint must be https.

Typically an event grid topic endpoint url is like so: https://topic-name.location-name.eventgrid.azure.net/api/events. Note that all the information needed to post to a topic is contained in the host part. The Microsoft.Azure.EventGrid client will essentially reduce the url you give it down to just the host part and prefix it with https (regardless of the original scheme).

It posts the payload to https://host:port and drops the query uri. All of the existing simulator/ emulator projects I found don't support https and use a the query uri to distinguish between the topics. This isn't compatible with the Microsoft.Azure.EventGrid client.

Future Development

Some features that could be added if there was a need for them: -

azureeventgridsimulator's People

Contributors

andreybespamyatnov avatar dependabot[bot] avatar etherza avatar gsingh01 avatar jamesfoster avatar jumpingfool avatar m0ns1gn0r avatar pm7y avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

azureeventgridsimulator's Issues

Azure.RequestFailedException : Request not supported.

Hello!

I'm an Azure Event Grid newbie and I'm trying out the AzureEventGridSimulator on my local machine. I've followed the instructions but I still cannot get passed the following error message:

[16:57:36 DBG] HTTP POST /?api-version=2018-01-01 responded 400 in 0.3247 ms

which then results in a Azure.RequestFailedException : Request not supported. thrown from the EventGridPublisherClient. The subscriber is never being called at the specified endpoint.

Here's what I'm doing:

  1. I'm successfully starting the simulator from its docker image:

[16:36:59 VRB] AEGS_Serilog__Using__0=Serilog.Sinks.Console (MemoryConfigurationProvider)
AEGS_Serilog__Using__1=Serilog.Sinks.File (MemoryConfigurationProvider)
AEGS_Serilog__Using__2=Serilog.Sinks.Seq (MemoryConfigurationProvider)
ENVIRONMENT=Development (EnvironmentVariablesConfigurationProvider)
Kestrel:
Certificates:
Default:
Password=Y0urSup3rCrypt1cPa55w0rd! (EnvironmentVariablesConfigurationProvider)
Path=/aegs/azureEventGridSimulator.pfx (EnvironmentVariablesConfigurationProvider)
Serilog:
MinimumLevel:
Default=Verbose (EnvironmentVariablesConfigurationProvider)
Topics:
0:
key=TheLocal+DevelopmentKey= (EnvironmentVariablesConfigurationProvider)
name=geeks (EnvironmentVariablesConfigurationProvider)
port=60101 (EnvironmentVariablesConfigurationProvider)
subscribers:
0:
endpoint=https://localhost:5000/api/event-grid (EnvironmentVariablesConfigurationProvider)
name=geeks-backend (EnvironmentVariablesConfigurationProvider)
URLS= (EnvironmentVariablesConfigurationProvider)
Hosting environment: Development
Content root path: /app
Now listening on: https://0.0.0.0:60101
Application started. Press Ctrl+C to shut down.
[16:37:00 INF] It's Alive !

  1. I start the subscriber at https://localhost:5000

  2. I initialize the client and try to publish an event like this:

         var client = new EventGridPublisherClient(
             new Uri("https://localhost:60101"),
             new AzureKeyCredential("TheLocal+DevelopmentKey="));
    
         var cloudEvent = new CloudEvent("geeks", type, data);
         await client.SendEventAsync(cloudEvent);
         //var gridEvent = new EventGridEvent("geeks", type, "2018-01-01", data);
         //await client.SendEventAsync(gridEvent); // using EventGridEvent results in the same issue
    

but this just results in something like

[16:57:36 DBG] HTTP POST /?api-version=2018-01-01 responded 400 in 0.3247 ms

I would be very happy if somebody could give me a hint to what I'm doing wrong here.

BTW, I'm on .NET 5.0.402, and Azure.Messaging.EventGrid 4.7.0.

Too high log level for filtered out events

https://github.com/pmcilreavy/AzureEventGridSimulator/blob/ac2ce052c96c3b6a6ac636ce0c90e3659351d6e3/src/AzureEventGridSimulator/Domain/Commands/SendNotificationEventsToSubscriberCommandHandler.cs#L76-L79

I have two questions regarding this line:

  1. On our project we quite heavily use the filtering functionality based on event type. This means, we have tens on subscriptions different only in includedEventTypes. So a filtered out event is not an abnormal situation at all, it's probably even not worth the Information level. I would suggest to reduce the logging level to Debug, what do you think?
  2. But there are situation when we forget to create a subscription and an event really gets ignored. Would it be possible to emit a Warning when an event was filtered out of all subscriptions?

Getting "a Task was cancelled" error when publishing event with Azure.Messaging.EventGrid client

In my context, I'm using EventGridPublisherClient from Azure.Messaging.EventGrid package to publish events to the simulator.
It works fine, except that I got a "A task was cancelled" error. Considering the retry logic I configured on that client, I end up having each one of my events being handled 3 times in a row.

It seems to come from this line:
https://github.com/pmcilreavy/AzureEventGridSimulator/blob/5325b4b2b0c33719234851c5264f6c94c90d83a4/src/AzureEventGridSimulator/Domain/Commands/SendNotificationEventsToSubscriberCommandHandler.cs#L66

Why not waiting for the SendToSubscriber call to be completed with await?

As a temporary fix, here is what I did:

var sendToSubscriberTasks = request.Topic.Subscribers
             Select(x => SendToSubscriber(x, request.Events, request.Topic.Name));
await Task.WhenAll(sendToSubscriberTasks);

Local Storage Emulator: Blob upload-to-Event Grid Message-to-Storage Queue possible?

Hello,

Is there a way to use AzureEventGridSimulator to simulate an EventGrid message upon blob upload to a local Azure Storage Emulator? Then have this EG message write to the Queue Storage running on the same emulator?

Example:

  • Upload blob to container in local Azure Storage Emulator
  • AzureEventGridSimulator simulates an EventGrid message
  • AzureEventGridSimulator writes message to local Azure Storage Emulator Queue Storage

If so, could you provide a sample of the settings.json for such a setup?

Thank you

New Release

The latest release (1.0.10) is from January and is out of date the current readme. e.g. the "filter" option is not available in 1.0.10

Would it be possible to create an up to date release? Thanks

Docker - There are no configured topics. The application will now exit

When running the Azure Event Grid Simulator on docker, with the ConfigFile environment variable defined, it exits with this error:
"There are no configured topics. The application will now exit"

docker-compose.yml

version: "3.9"
services:
  eventgrid:
    image: pmcilreavy/azureeventgridsimulator:latest
    restart: unless-stopped
    ports:
      - 60101:60101
    volumes:
      - S:\Development\AzureEventGridSimulator\docker:/aegs:ro
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/aegs/azureEventGridSimulator.pfx
      - ASPNETCORE_Kestrel__Certificates__Default__Password=123456
      - TZ=Europe/London
      - AEGS_Serilog__MinimumLevel__Default=Verbose
      - ConfigFile=/aegs/config.json

config.json

{
  "topics": [
    {
      "name": "MyAwesomeTopic",
      "port": 60101,
      "key": "TheLocal+DevelopmentKey=",
      "subscribers": [
        {
          "name": "LocalAzureFunctionSubscription",
          "endpoint": "http://localhost:7071/runtime/webhooks/EventGrid?functionName=PersistEventToDb",
          "filter": {
            "includedEventTypes": ["my.eventType"]
          }
        }
      ]
    }
  ]
}

Directory Files

image

Error

image

Align OperatorTypes for advanced filtering

The currently available OperatorTypes for advanced filtering are the following:

public enum OperatorTypeEnum
{
    NumberGreaterThan,
    NumberGreaterThanOrEquals,
    NumberLessThan,
    NumberLessThanOrEquals,
    NumberIn,
    NumberNotIn,
    BoolEquals,
    StringContains,
    StringBeginsWith,
    StringEndsWith,
    StringIn,
    StringNotIn
}

In the meantime, Azure Event Grid provides the following additional ones:

NumberInRange
NumberNotInRange
StringNotContains
StringNotBeginsWith
StringNotEndsWith
IsNullOrUndefined
IsNotNull

I was wondering whether you plan on aligning the Operator Types?
Obviously it would be highly appreciated, as we like your tool and use it regularly for local testing.

Question: Azurite + AzureEventGridSimulator

Hello this is not an issue but a question:

I saw this article: https://docs.microsoft.com/en-us/azure/event-grid/blob-event-quickstart-portal#subscribe-to-the-blob-storage

and I have this running in the cloud. But I want to simulate it locally.

Azure Blob Storage Emulator (on file upload) ---> Event Grid Simulator ---> run local cloud function

I emulate Azure Blob Storage via Azurite, I know there is also Azure Blob Storage Emulator

as far as I understand, I need to call some localhost:port endpoint in your AzureEventGridSimulator manually and supply my pre-recorded event. Is there some easy way how to send events from Azure Blobl Storage emulator to AzureEventGridSimulator?

Did you ever had similar use cases or this is not a good approach?

Running the emulator on Docker

Hi all,

I am wondering if anyone has had luck running the emulator on docker? I am running docker on WSL2 am have been facing issues connecting to the endpoints.

Using the postman collection provided, I receive Error: connect ECONNREFUSED 127.0.0.1:60101. I have run the command to generate the certificates but am still facing issues.

Is there a more detailed example anywhere?

Unit test project currently not compiling

  • Error The call is ambiguous between the following methods or properties: 'Assert.Throws(Action)' and 'Assert.Throws(Func)' UnitTests C:\repos\pmcilreavy\AzureEventGridSimulator\src\UnitTests\Filtering\AdvancedFilterValidationTests.cs
  • Error The call is ambiguous between the following methods or properties: 'Assert.Throws(Action)' and 'Assert.Throws(Func)' UnitTests C:\repos\pmcilreavy\AzureEventGridSimulator\src\UnitTests\Filtering\AdvancedFilterValidationTests.cs
  • Error The call is ambiguous between the following methods or properties: 'Assert.Throws(Action)' and 'Assert.Throws(Func)' UnitTests C:\repos\pmcilreavy\AzureEventGridSimulator\src\UnitTests\Filtering\AdvancedFilterValidationTests.cs
  • Error The call is ambiguous between the following methods or properties: 'Assert.Throws(Action)' and 'Assert.Throws(Func)' UnitTests C:\repos\pmcilreavy\AzureEventGridSimulator\src\UnitTests\Filtering\AdvancedFilterValidationTests.cs
  • Error The call is ambiguous between the following methods or properties: 'Assert.Throws(Action)' and 'Assert.Throws(Func)' UnitTests C:\repos\pmcilreavy\AzureEventGridSimulator\src\UnitTests\Filtering\AdvancedFilterValidationTests.cs
  • Error The call is ambiguous between the following methods or properties: 'Assert.Throws(Action)' and 'Assert.Throws(Func)' UnitTests C:\repos\pmcilreavy\AzureEventGridSimulator\src\UnitTests\Filtering\AdvancedFilterValidationTests.cs
  • Error The call is ambiguous between the following methods or properties: 'Assert.Throws(Action)' and 'Assert.Throws(Func)' UnitTests C:\repos\pmcilreavy\AzureEventGridSimulator\src\UnitTests\Filtering\AdvancedFilterValidationTests.cs
  • Error The call is ambiguous between the following methods or properties: 'Assert.Throws(Action)' and 'Assert.Throws(Func)' UnitTests C:\repos\pmcilreavy\AzureEventGridSimulator\src\UnitTests\Filtering\AdvancedFilterValidationTests.cs
  • Error The call is ambiguous between the following methods or properties: 'Assert.ThrowsAny(Action)' and 'Assert.ThrowsAny(Func)' UnitTests C:\repos\pmcilreavy\AzureEventGridSimulator\src\UnitTests\Filtering\FilterSettingsValidationTests.cs

Add docker image

Would be useful if there was a docker image for this. In my case iam running a complex application consisting of multiple containers and I also need to test functionality that depends on eventgrid.

If you like I could setup the stuff needed to build a docker image.

Improve documentation

I think my struggles with the advanced filtering implementation are worth sharing here to maybe consider improving the documentation. Still, this is not supposed to be any blame regarding the general implementation, because we really appreciate this neat little simulator!

Here's a draft:

Advanced Filtering

Every advanced filter config consists of three properties.

operatorType: any in [NumberGreaterThan, NumberGreaterThanOrEquals, NumberLessThan, NumberLessThanOrEquals, NumberIn, NumberNotIn, BoolEquals, StringContains, StringBeginsWith, StringEndsWith, StringIn, StringNotIn]

key: name of a property of the event to filter for. Important: the property name must start with a capital letter, even if the "real" property in the event (i.e. the JSON object) might not.

The third property depends on the operatorType.
For the following operator types (StringIn, StringNotIn, NumberIn and NumberNotIn), use the values property with an array of at most 5 values:

"filter": {
  "advancedFilters": [
    {
      "operatorType": "StringIn",
      "key": "Data.Key1",
      "values": ["value1", "value2" ]
    }
  ]
}

For all the other operator types, use the value property with a single value:

"filter": {
  "advancedFilters": [
    {
      "operatorType": "NumberGreaterThanOrEquals",
      "key": "Data.Key1",
      "value": 5
    }
  ]
}

The example given in the current README on the other hand is - if I'm not mistaken - wrong.
The operatorType StringContains does not work with an array of values but only with a value.

"filter": {
  "advancedFilters": [
    {
      "operatorType": "NumberGreaterThanOrEquals",
      "key": "Data.Key1",
      "value": 5
    },
    {
      "operatorType": "StringContains",
      "key": "Subject",
      "values": ["container1", "container2"]
    }
  ]
}

Docker image azureeventgridsimulator:3.0.3 does not start on Apple M1 Pro

Hello.

Issue

The Docker image azureeventgridsimulator:3.0.3 / azureeventgridsimulator:latest does not start on a Apple M1 Pro, the server inside the container does not start.

I can deduce that because the logs Started and It's alive ! are not present.

I don't know if it is specific to all Mac or only Mac M1 Pro.

Do you have an idea why it does not work?

Everything was OK with the old latest Docker image which was published several months ago.

Configuration

  • Mac model: Apple M1 Pro
  • OS: Ventura 13.2
  • Docker version: 20.10.21-rd, build ac29474

Investigation

I ran the following command:

docker run pmcilreavy/azureeventgridsimulator:3.0.3 ... # ... = all extra arguments

Then, I tried to check if the service was running:

curl https://localhost:60101

But I got the following error:

curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:60101

Instead of:

{
  "error": {
    "code": "BadRequest",
    "message": "Request not supported."
  }
}

Then, I checked the Docker logs:

[15:28:02 VRB] AEGS_Serilog__Using__0=Serilog.Sinks.Console (MemoryConfigurationProvider)
AEGS_Serilog__Using__1=Serilog.Sinks.File (MemoryConfigurationProvider)
AEGS_Serilog__Using__2=Serilog.Sinks.Seq (MemoryConfigurationProvider)
ENVIRONMENT=Development (EnvironmentVariablesConfigurationProvider Prefix: 'ASPNETCORE_')
Kestrel:
  Certificates:
    Default:
      Password=Y0urSup3rCrypt1cPa55w0rd! (EnvironmentVariablesConfigurationProvider Prefix: 'ASPNETCORE_')
      Path=/aegs/dotnet-devcert.pfx (EnvironmentVariablesConfigurationProvider Prefix: 'ASPNETCORE_')
Serilog:
  MinimumLevel:
    Default=Verbose (EnvironmentVariablesConfigurationProvider Prefix: 'AEGS_')
Topics:
  0:
    key=TheLocal+DevelopmentKey= (EnvironmentVariablesConfigurationProvider Prefix: 'AEGS_')
    name=ExampleTopic (EnvironmentVariablesConfigurationProvider Prefix: 'AEGS_')
    port=60101 (EnvironmentVariablesConfigurationProvider Prefix: 'AEGS_')
    subscribers:
      0:
        disableValidation=true (EnvironmentVariablesConfigurationProvider Prefix: 'AEGS_')
        endpoint=http://host.docker.internal:7071/runtime/webhooks/EventGrid?functionName=Test (EnvironmentVariablesConfigurationProvider Prefix: 'AEGS_')
        filter:
          subjectBeginsWith=/events (EnvironmentVariablesConfigurationProvider Prefix: 'AEGS_')
        name=Test (EnvironmentVariablesConfigurationProvider Prefix: 'AEGS_')
URLS= (EnvironmentVariablesConfigurationProvider Prefix: 'ASPNETCORE_')

I did the same steps on Linux computer and everything worked. The only difference I had was that when I checked the Docker logs on the Linux computer, I could see the following extra logs at the end saying that the server was correctly started:

...
        name=Test (EnvironmentVariablesConfigurationProvider Prefix: 'AEGS_')
URLS= (EnvironmentVariablesConfigurationProvider Prefix: 'ASPNETCORE_')

[16:28:06 VRB] Started    <--- extra log
[16:28:06 INF] It's alive ! <--- extra log

Temporary fix

From the Apple M1 Pro, I cloned this project and from master (= the commit is 7d9e4be - (HEAD -> master, origin/master, origin/HEAD) Update README.md (8 days ago) <Paul Mcilreavy>), I locally built a Docker image.

Then I tried this locally build image: everything worked:

  • I had the extra logs.
  • The curl gave me the "bad request" response.

Pending Validation

When I run the simulator with the disableValidation flag set to true, everything works as expected.

However, when I enable validation, I never receive a POST request on the subscriber endpoint although the documentation says:

The Azure Event Grid Simualator will mimick this validation behaviour at start up [...]

And when an event is being published, the simulator log says:

[09:45:22 WRN] Subscription '...' on topic '...' can't receive events. It's still pending validation

Is there something I'm missing here?

Thanks for providing this wonderful simulator.

Add support for CloudEvent schema

Like the title says, Azure supports CloudEvent schema and as such it'd be great to add support for CloudEvent schema to the simulator.

I'm obviously happy to contribute ๐Ÿ˜„

Topic with no subscribers not actually working

Thanks for this project - it's really gonna save me some headaches!

A problem I've run into: topics with no subscribers cause exceptions. If you leave subscribers out altogether you get this:

System.NullReferenceException: Object reference not set to an instance of an object.
   at AzureEventGridSimulator.Controllers.ApiController.Post() in C:\projects\azureeventgridsimulator\src\AzureEventGridSimulator\Controllers\ApiController.cs:line 35
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
<snip>

But even if you define subscribers as an empty array you get the same problem. The only recourse right now seems to be defining a subscriber, even if that subscriber ends up erroring.

Property 'Topic' was expected to either be null/empty.

When sending an event with a specified topic, I get the following error.

System.InvalidOperationException: Property 'Topic' was found to be set to 'Test', but was expected to either be null/empty.
    at AzureEventGridSimulator.Domain.Entities.EventGridEvent.Validate()
    at AzureEventGridSimulator.Infrastructure.Middleware.EventGridMiddleware.ValidateNotificationRequest(HttpContext context, SimulatorSettings simulatorSettings, SasKeyValidator sasHeaderValidator, ILogger logger)

Looking into the code I can't really understand why Topic has to be null. Looking at the docs of microsoft it is totally fine to specify a topic in the event. I would understand that Event Grid Domains are not supported (which would be fine for me) but this validation seems incorrect.
Before the event is being forwarded, the topic is being overriden in SendNotificationEventsToSubscriberCommandHandler.Handle anyways, so why is the validation there in the first place?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.