private async Task SendAsync(IList <object> events, Func <object, BinaryData> binaryDataFactory, CancellationToken cancellationToken) { bool isEventGridEvent = false; try { // test the first event to determine CloudEvent vs EventGridEvent // both event types are NOT supported in same list EventGridEvent.Parse(binaryDataFactory(events.First())); isEventGridEvent = true; } catch (ArgumentException) { } if (isEventGridEvent) { List <EventGridEvent> egEvents = new(events.Count); foreach (object evt in events) { egEvents.Add(EventGridEvent.Parse(binaryDataFactory(evt))); } await _client.SendEventsAsync(egEvents, cancellationToken).ConfigureAwait(false); } else { List <CloudEvent> cloudEvents = new(events.Count); foreach (object evt in events) { cloudEvents.Add(CloudEvent.Parse(binaryDataFactory(evt))); } await _client.SendEventsAsync(cloudEvents, cancellationToken).ConfigureAwait(false); } }
public void Initialize(ExtensionConfigContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } _logger = _loggerFactory.CreateLogger <EventGridExtensionConfigProvider>(); #pragma warning disable 618 Uri url = context.GetWebhookHandler(); #pragma warning restore 618 _logger.LogInformation($"registered EventGrid Endpoint = {url?.GetLeftPart(UriPartial.Path)}"); // Register our extension binding providers // use converterManager as a hashTable // also take benefit of identity converter context .AddBindingRule <EventGridTriggerAttribute>() // following converters are for EventGridTriggerAttribute only .AddConverter <JToken, string>(jtoken => jtoken.ToString(Formatting.Indented)) .AddConverter <JToken, string[]>(jarray => jarray.Select(ar => ar.ToString(Formatting.Indented)).ToArray()) .AddConverter <JToken, DirectInvokeString>(jtoken => new DirectInvokeString(null)) .AddConverter <JToken, EventGridEvent>(jobject => EventGridEvent.Parse(new BinaryData(jobject.ToString()))) // surface the type to function runtime .AddConverter <JToken, EventGridEvent[]>(jobject => EventGridEvent.ParseMany(new BinaryData(jobject.ToString()))) .AddConverter <JToken, CloudEvent>(jobject => CloudEvent.Parse(new BinaryData(jobject.ToString()))) .AddConverter <JToken, CloudEvent[]>(jobject => CloudEvent.ParseMany(new BinaryData(jobject.ToString()))) .AddConverter <JToken, BinaryData>(jobject => new BinaryData(jobject.ToString())) .AddConverter <JToken, BinaryData[]>(jobject => jobject.Select(obj => new BinaryData(obj.ToString())).ToArray()) .AddOpenConverter <JToken, OpenType.Poco>(typeof(JTokenToPocoConverter <>)) .AddOpenConverter <JToken, OpenType.Poco[]>(typeof(JTokenToPocoConverter <>)) .BindToTrigger <JToken>(new EventGridTriggerAttributeBindingProvider(this)); // Register the output binding var rule = context.AddBindingRule <EventGridAttribute>(); rule.BindToCollector(_converter); rule.AddValidator((a, t) => { // if app setting is missing, it will be caught by runtime // this logic tries to validate the practicality of attribute properties if (string.IsNullOrWhiteSpace(a.TopicKeySetting)) { throw new InvalidOperationException($"The '{nameof(EventGridAttribute.TopicKeySetting)}' property must be the name of an application setting containing the Topic Key"); } if (!Uri.IsWellFormedUriString(a.TopicEndpointUri, UriKind.Absolute)) { throw new InvalidOperationException($"The '{nameof(EventGridAttribute.TopicEndpointUri)}' property must be a valid absolute Uri"); } }); }
public async Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken)) { IList <object> events; var newEventList = new List <object>(); lock (_syncroot) { // swap the events to send out with a new list; locking so 'AddAsync' doesn't take place while we do this events = _eventsToSend; _eventsToSend = newEventList; } if (events.Any()) { // determine the schema by inspecting the first event (a topic can only support a single schema) var firstEvent = events.First(); if (firstEvent is string str) { bool isEventGridEvent = false; try { var ev = EventGridEvent.Parse(new BinaryData(str)); isEventGridEvent = true; } catch (ArgumentException) { } if (isEventGridEvent) { List <EventGridEvent> egEvents = new(events.Count); foreach (string evt in events) { egEvents.Add(EventGridEvent.Parse(new BinaryData(evt))); } await _client.SendEventsAsync(egEvents, cancellationToken).ConfigureAwait(false); } else { List <CloudEvent> cloudEvents = new(events.Count); foreach (string evt in events) { cloudEvents.Add(CloudEvent.Parse(new BinaryData(evt))); } await _client.SendEventsAsync(cloudEvents, cancellationToken).ConfigureAwait(false); } } else if (firstEvent is BinaryData data) { bool isEventGridEvent = false; try { var ev = EventGridEvent.Parse(data); isEventGridEvent = true; } catch (ArgumentException) { } if (isEventGridEvent) { List <EventGridEvent> egEvents = new(events.Count); foreach (BinaryData evt in events) { egEvents.Add(EventGridEvent.Parse(evt)); } await _client.SendEventsAsync(egEvents, cancellationToken).ConfigureAwait(false); } else { List <CloudEvent> cloudEvents = new(events.Count); foreach (BinaryData evt in events) { cloudEvents.Add(CloudEvent.Parse(evt)); } await _client.SendEventsAsync(cloudEvents, cancellationToken).ConfigureAwait(false); } } else if (firstEvent is JObject jObject) { bool isEventGridEvent = false; try { var ev = EventGridEvent.Parse(new BinaryData(jObject.ToString())); isEventGridEvent = true; } catch (ArgumentException) { } if (isEventGridEvent) { List <EventGridEvent> egEvents = new(events.Count); foreach (JObject evt in events) { egEvents.Add(EventGridEvent.Parse(new BinaryData(evt.ToString()))); } await _client.SendEventsAsync(egEvents, cancellationToken).ConfigureAwait(false); } else { List <CloudEvent> cloudEvents = new(events.Count); foreach (JObject evt in events) { cloudEvents.Add(CloudEvent.Parse(new BinaryData(evt.ToString()))); } await _client.SendEventsAsync(cloudEvents, cancellationToken).ConfigureAwait(false); } } else if (firstEvent is EventGridEvent) { List <EventGridEvent> egEvents = new(events.Count); foreach (object evt in events) { egEvents.Add((EventGridEvent)evt); } await _client.SendEventsAsync(egEvents, cancellationToken).ConfigureAwait(false); } else if (firstEvent is CloudEvent) { List <CloudEvent> cloudEvents = new(events.Count); foreach (object evt in events) { cloudEvents.Add((CloudEvent)evt); } await _client.SendEventsAsync(cloudEvents, cancellationToken).ConfigureAwait(false); } else { throw new InvalidOperationException( $"{firstEvent?.GetType().ToString()} is not a valid event type."); } } }