Exemple #1
0
        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));
            }
            }
        }
Exemple #2
0
        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));
        }