This repository has been archived by the owner on Jul 19, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 34
/
EventGridExtensionConfig.cs
110 lines (95 loc) · 4.61 KB
/
EventGridExtensionConfig.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Azure.WebJobs.Host.Config;
using Microsoft.Azure.WebJobs.Host.Executors;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
namespace Microsoft.Azure.WebJobs.Extensions.EventGrid
{
public class EventGridExtensionConfig : IExtensionConfigProvider,
IAsyncConverter<HttpRequestMessage, HttpResponseMessage>
{
private TraceWriter _tracer = null;
public void Initialize(ExtensionConfigContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
else if (context.Trace == null)
{
throw new ArgumentNullException("context.Trace");
}
_tracer = context.Trace;
Uri url = context.GetWebhookHandler();
// Register our extension binding providers
context.Config.RegisterBindingExtensions(new EventGridTriggerAttributeBindingProvider(this));
}
private Dictionary<string, EventGridListener> _listeners = new Dictionary<string, EventGridListener>();
internal void AddListener(string key, EventGridListener listener)
{
_listeners.Add(key, listener);
}
async Task<HttpResponseMessage> IAsyncConverter<HttpRequestMessage, HttpResponseMessage>.ConvertAsync(HttpRequestMessage input, CancellationToken cancellationToken)
{
var response = ProcessAsync(input);
return await response;
}
private async Task<HttpResponseMessage> ProcessAsync(HttpRequestMessage req)
{
// webjobs.script uses req.GetQueryNameValuePairs();
// which requires webapi.core...but this does not work for .netframework2.0
// TODO change this once webjobs.script is migrated
var functionName = HttpUtility.ParseQueryString(req.RequestUri.Query)["functionName"];
if (String.IsNullOrEmpty(functionName) || !_listeners.ContainsKey(functionName))
{
return new HttpResponseMessage(HttpStatusCode.NotFound);
}
IEnumerable<string> eventTypeHeaders = null;
string eventTypeHeader = null;
if (req.Headers.TryGetValues("aeg-event-type", out eventTypeHeaders))
{
eventTypeHeader = eventTypeHeaders.First();
}
if (String.Equals(eventTypeHeader, "SubscriptionValidation", StringComparison.OrdinalIgnoreCase))
{
string jsonArray = await req.Content.ReadAsStringAsync();
SubscriptionValidationEvent validationEvent = null;
List<EventGridEvent> events = JsonConvert.DeserializeObject<List<EventGridEvent>>(jsonArray);
validationEvent = events[0].Data.ToObject<SubscriptionValidationEvent>();
SubscriptionValidationResponse validationResponse = new SubscriptionValidationResponse { ValidationResponse = validationEvent.ValidationCode };
var returnMessage = new HttpResponseMessage(HttpStatusCode.OK);
returnMessage.Content = new StringContent(JsonConvert.SerializeObject(validationResponse));
_tracer.Trace(new TraceEvent(System.Diagnostics.TraceLevel.Info,
$"perform handshake with eventGrid for endpoint: {req.RequestUri}"));
return returnMessage;
}
else if (String.Equals(eventTypeHeader, "Notification", StringComparison.OrdinalIgnoreCase))
{
string jsonArray = await req.Content.ReadAsStringAsync();
List<EventGridEvent> events = JsonConvert.DeserializeObject<List<EventGridEvent>>(jsonArray);
foreach (var ev in events)
{
TriggeredFunctionData triggerData = new TriggeredFunctionData
{
TriggerValue = ev
};
await _listeners[functionName].Executor.TryExecuteAsync(triggerData, CancellationToken.None);
}
return new HttpResponseMessage(HttpStatusCode.Accepted);
}
else if (String.Equals(eventTypeHeader, "Unsubscribe", StringComparison.OrdinalIgnoreCase))
{
// TODO disable function?
return new HttpResponseMessage(HttpStatusCode.Accepted);
}
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
}
}