private async Task HandleEventReactionAsync(IServiceDefinition serviceDefinitionFilter, HttpContext context, CancellationToken ct) { if (context.Request.Method != "PUT" && context.Request.Method != "POST") { context.Response.StatusCode = 405; // Method Not Allowed context.Response.ContentType = "text/plain"; await context.Response.Body.WriteAsync(Encoding.UTF8.GetBytes("To invoke a reaction to an event, use one of these HTTP verbs: GET, POST, PUT")); return; } var eventName = (context.Request.Query.TryGetValue("event", out var eventValues) && eventValues.Count == 1) ? eventValues[0] : null; if (string.IsNullOrWhiteSpace(eventName)) { context.Response.StatusCode = 404; context.Response.ContentType = "text/plain"; await context.Response.Body.WriteAsync(Encoding.UTF8.GetBytes("Missing 'event=xxx' in the URL query.")); return; } var serviceName = (context.Request.Query.TryGetValue("service", out var serviceValues) && serviceValues.Count == 1) ? serviceValues[0] : null; if (string.IsNullOrWhiteSpace(serviceName)) { context.Response.StatusCode = 404; context.Response.ContentType = "text/plain"; await context.Response.Body.WriteAsync(Encoding.UTF8.GetBytes("Missing 'service=xxx' in the URL query.")); return; } var eventDesc = new EventDescriptor { EventId = new EventId { EventName = eventName }, ServiceId = new ServiceId { ServiceName = serviceName } }; var eventHandlers = _eventDispatcher.GetEventHandlers(eventDesc); if ((eventHandlers?.Count ?? 0) == 0) { context.Response.StatusCode = DasyncHttpCodes.Succeeded; return; } var contentType = context.Request.GetContentType(); var isJsonRequest = string.Equals(contentType.MediaType, "application/json", StringComparison.OrdinalIgnoreCase); var isDasyncJsonRequest = string.Equals(contentType.MediaType, "application/dasync+json", StringComparison.OrdinalIgnoreCase); if (!isJsonRequest && !isDasyncJsonRequest) { context.Response.StatusCode = 406; // Not Acceptable context.Response.ContentType = "text/plain"; await context.Response.Body.WriteAsync(Encoding.UTF8.GetBytes("The request content type is either not specified or not supported")); return; } string parametersJson = null; if (isJsonRequest) { parametersJson = await context.Request.ReadBodyAsStringAsync(contentType); } else if (isDasyncJsonRequest) { var envelopeJson = await context.Request.ReadBodyAsStringAsync(contentType); var envelope = JsonConvert.DeserializeObject <EventEnvelope>(envelopeJson, JsonSettings); parametersJson = envelope.Parameters; } var results = new List <RaiseEventResult>(); _transitionUserContext.Current = GetUserContext(context); foreach (var subscriber in eventHandlers) { if (serviceDefinitionFilter != null && !string.Equals(subscriber.ServiceId.ServiceName, serviceDefinitionFilter.Name, StringComparison.OrdinalIgnoreCase)) { continue; } var subscriberServiceDefinition = _communicationModelProvider.Model.FindServiceByName(subscriber.ServiceId.ServiceName); #warning Use model for method resolution instead var eventHandlerRoutineMethodId = new RoutineMethodId { MethodName = subscriber.MethodId.MethodName }; MethodInfo routineMethod = _routineMethodResolver.Resolve(subscriberServiceDefinition, eventHandlerRoutineMethodId); var methodInvoker = _methodInvokerFactory.Create(routineMethod); var parameterContainer = methodInvoker.CreateParametersContainer(); if (!string.IsNullOrWhiteSpace(parametersJson)) { if (isDasyncJsonRequest) { _dasyncJsonSerializer.Populate(parametersJson, parameterContainer); } else { JsonConvert.PopulateObject(parametersJson, parameterContainer, JsonSettings); } } var intentId = _idGenerator.NewId(); _intentPreprocessor.PrepareContext(context); if (await _intentPreprocessor.PreprocessAsync(context, subscriberServiceDefinition, subscriber.MethodId, parameterContainer).ConfigureAwait(false)) { return; } foreach (var postAction in _transitionActions) { await postAction.OnRoutineStartAsync(subscriberServiceDefinition, subscriber.ServiceId, subscriber.MethodId, intentId); } var serviceInstance = _domainServiceProvider.GetService(subscriberServiceDefinition.Implementation); Task task; try { task = methodInvoker.Invoke(serviceInstance, parameterContainer); if (routineMethod.ReturnType != typeof(void)) { try { await task; } catch { } } } catch (Exception ex) { if (ex is TargetInvocationException) { ex = ex.InnerException; } task = Task.FromException(ex); } var taskResult = task?.ToTaskResult() ?? new TaskResult(); foreach (var postAction in _transitionActions) { await postAction.OnRoutineCompleteAsync(subscriberServiceDefinition, subscriber.ServiceId, subscriber.MethodId, intentId, taskResult); } results.Add(new RaiseEventResult { ServiceName = subscriber.ServiceId.ServiceName, MethodName = subscriber.MethodId.MethodName, Result = taskResult }); } context.Response.StatusCode = DasyncHttpCodes.Succeeded; if (isJsonRequest) { context.Response.ContentType = "application/json"; await context.Response.Body.WriteAsync(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(results, JsonSettings))); } else if (isDasyncJsonRequest) { context.Response.ContentType = "application/dasync+json"; _dasyncJsonSerializer.Serialize(context.Response.Body, results); } }