public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = "sendtonextroute")] HttpRequest req, ILogger log) { // Get Request Details RequestDetails requestDetails = new RequestDetails(req, LogId); string logPrefix = $"{LogId}:{requestDetails.TrackingId}: "; // Add the tracking ID to the Response Headers if (!string.IsNullOrWhiteSpace(requestDetails.TrackingId)) { req.HttpContext.Response.Headers[HeaderConstants.AimTrackingId] = requestDetails.TrackingId; } log.LogDebug($"{logPrefix}Called with parameters messageContentType: {requestDetails.RequestContentType}, messageContentEncoding: {requestDetails.RequestContentEncoding}, messageTransferEncoding: {requestDetails.RequestTransferEncoding}, headerTrackingId: {logPrefix}, clearCache: {requestDetails.ClearCache}, enableTrace: {requestDetails.EnableTrace}"); // Validate the request IActionResult result = ValidateRequest(requestDetails, logPrefix, log); if (result != null) { return(result); } log.LogDebug($"{logPrefix}Request parameters are valid"); // Attempt to load the envelope Envelope envelope; try { log.LogDebug($"{logPrefix}Parsing the request body as an envelope"); envelope = new Envelope(requestDetails); requestDetails.UpdateTrackingId(envelope.TrackingId); // Add TrackingId header if (!string.IsNullOrEmpty(logPrefix) && req?.HttpContext?.Response?.Headers?.ContainsKey(HeaderConstants.AimTrackingId) == false) { req?.HttpContext?.Response?.Headers?.Add(HeaderConstants.AimTrackingId, logPrefix); } } catch (Exception ex) { return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, $"An exception occurred trying to parse the received envelope message", ex, logPrefix, log)); } // We need a ScenarioName if (string.IsNullOrWhiteSpace(envelope.Scenario)) { // Missing ScenarioName return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, "ScenarioName cannot be found in the request body", logPrefix, log)); } // Check we have a routeIndex if (envelope.RouteIndex == null) { // Invalid RouteIndex return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, "RouteIndex is blank or not a number", logPrefix, log)); } // RouteIndex must not be a negative number if (envelope.RouteIndex < 0) { // Invalid RouteIndex return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, "RouteIndex must be 0 or greater", logPrefix, log)); } // Check if we have any routes if (envelope.Routes == null) { // No routes to process - return an ACK log.LogDebug($"{logPrefix}No routes to process - returning an ACK"); return(new OkObjectResult(EnvelopeBuilder.BuildAckEnvelope("No routes to process", null, logPrefix))); } // Check if we're past the last route if (envelope.NextRoute == null) { // No more routes - return an ACK log.LogDebug($"{logPrefix}Have processed all routes - returning an ACK"); return(new OkObjectResult(EnvelopeBuilder.BuildAckEnvelope("Finished processing all routes", null, logPrefix))); } // Get the full RoutingSlip (including the routing parameters) from App Configuration JObject routingSlip; try { log.LogDebug($"{logPrefix}Getting the full RoutingSlip from config"); routingSlip = await new ApimRestClient(requestDetails).GetRoutingSlipAsync(envelope.Scenario); } catch (AzureResponseException arex) { // Exception occurred return(AzureResponseHelper.CreateFaultObjectResult($"An AzureResponseException occurred calling APIM to get a RoutingSlip for scenario {envelope.Scenario}", arex, logPrefix, log)); } catch (Exception ex) { // Exception occurred return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, $"An exception occurred calling APIM to get a RoutingSlip for scenario {envelope.Scenario}", ex, logPrefix, log)); } // Get the array of routes JArray routes = (JArray)routingSlip?.First?.First; // Get the current route JObject currentRoute = routes[envelope.RouteIndex] as JObject; if (currentRoute == null) { return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, $"Unable to find the current route, with routeIndex {envelope.RouteIndex}", logPrefix, log)); } // Get the route parameters JObject routingParameters = currentRoute["routingParameters"] as JObject; if (routingParameters == null) { return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, $"Unable to find any parameters for the route with index {envelope.RouteIndex}", logPrefix, log)); } // Get the message receiver type string messageReceiverType = routingParameters?["messageReceiverType"]?.ToString(); if (string.IsNullOrWhiteSpace(messageReceiverType)) { return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, $"No MessageReceiverType is set for the route with index {envelope.RouteIndex}", logPrefix, log)); } log.LogDebug($"{logPrefix}Next route MessageReceiverType is {messageReceiverType}"); JObject routeParameters = routingParameters?["parameters"] as JObject; // Increment the routeIndex envelope.IncrementRouteIndex(); // Switch by messageReceiverType switch (messageReceiverType.ToLower()) { case "microsoft.workflows.azurelogicapp": { log.LogDebug($"{logPrefix}Calling the next route LogicApp"); return(await RouteToLogicApp(envelope, routeParameters, requestDetails, logPrefix, log)); } default: { return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, $"Unsupported MessageReceiverType value of {messageReceiverType}", logPrefix, log)); } } }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = "buildenvelope/{envelopeType}/{scenario}")] HttpRequest req, string envelopeType, string scenario, ILogger log) { // Get Request Details RequestDetails requestDetails = new RequestDetails(req, LogId); string logPrefix = $"{LogId}:{requestDetails.TrackingId}: "; // Add the tracking ID to the Response Headers if (!string.IsNullOrWhiteSpace(requestDetails.TrackingId)) { req.HttpContext.Response.Headers[HeaderConstants.AimTrackingId] = requestDetails.TrackingId; } log.LogDebug($"{logPrefix}Called with parameters envelopeType: {envelopeType}, scenario: {scenario}, messageContentType: {requestDetails.RequestContentType}, messageContentEncoding: {requestDetails.RequestContentEncoding}, messageTransferEncoding: {requestDetails.RequestTransferEncoding}, headerTrackingId: {requestDetails.TrackingId}, clearCache: {requestDetails.ClearCache}, enableTrace: {requestDetails.EnableTrace}"); envelopeType = envelopeType.ToLower(); // Validate the request IActionResult result = ValidateRequest(envelopeType, scenario, requestDetails, logPrefix, log); if (result != null) { return(result); } log.LogDebug($"{logPrefix}Request parameters are valid"); JObject envelope; // Switch by envelopeType switch (envelopeType) { case EnvelopeTypeAck: { log.LogDebug($"{logPrefix}Building an ACK envelope"); envelope = EnvelopeBuilder.BuildAckEnvelope(requestDetails); break; } case EnvelopeTypeNack: { log.LogDebug($"{logPrefix}Building a NACK envelope"); envelope = EnvelopeBuilder.BuildNackEnvelope(requestDetails); break; } case EnvelopeTypeDocument: { try { log.LogDebug($"{logPrefix}Building a Content envelope"); envelope = await BuildDocumentEnvelopeAsync(scenario, requestDetails, logPrefix, log); // Update the request TrackingId if need be requestDetails.UpdateTrackingId(envelope?["header"]?["properties"]?["trackingId"]?.Value <string>()); } catch (AzureResponseException arex) { // Exception occurred AzureResponseHelper.SetCustomResponseHeaders(req, arex); return(AzureResponseHelper.CreateFaultObjectResult("An AzureResponseException error occurred building a Document envelope", arex, logPrefix, log)); } catch (Exception ex) { // Exception occurred return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, "An error occurred building a Document envelope", ex, logPrefix, log)); } break; } default: { // Invalid EnvelopeType return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, $"Invalid envelopeType parameter supplied - must be one of {string.Join(", ", s_allowedEnvelopeTypes)}", logPrefix, log)); } } // Add TrackingId header if (!string.IsNullOrEmpty(requestDetails.TrackingId) && req?.HttpContext?.Response?.Headers?.ContainsKey(HeaderConstants.AimTrackingId) == false) { req?.HttpContext?.Response?.Headers?.Add(HeaderConstants.AimTrackingId, requestDetails.TrackingId); } log.LogDebug($"{logPrefix}Finished building envelope - returning response"); return(new OkObjectResult(envelope)); }