Beispiel #1
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));
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = "resolveroutingproperties")]
            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: {requestDetails.TrackingId}, 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(requestDetails.TrackingId) && req?.HttpContext?.Response?.Headers?.ContainsKey(HeaderConstants.AimTrackingId) == false)
                {
                    req?.HttpContext?.Response?.Headers?.Add(HeaderConstants.AimTrackingId, requestDetails.TrackingId);
                }
            }
            catch (Exception ex)
            {
                return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, $"An exception occurred trying to parse the received envelope message", ex, logPrefix, log));
            }

            // Check if we have a ScenarioName
            if (string.IsNullOrWhiteSpace(envelope.Scenario))
            {
                // Missing ScenarioName
                return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, "ScenarioName cannot be found in the request body", logPrefix, log));
            }

            // Get the RoutingProperties from config
            JObject routingProperties;

            try
            {
                log.LogDebug($"{logPrefix}Getting full RoutingSlip from config");
                routingProperties = await new ApimRestClient(requestDetails).GetRoutingPropertiesAsync(envelope.Scenario);
            }
            catch (AzureResponseException arex)
            {
                // Exception occurred
                AzureResponseHelper.SetCustomResponseHeaders(req, arex);
                return(AzureResponseHelper.CreateFaultObjectResult("An AzureResponseException error occurred calling APIM", arex, logPrefix, log));
            }
            catch (Exception ex)
            {
                // Exception occurred
                return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, "An error occurred calling APIM", ex, logPrefix, log));
            }

            try
            {
                RoutingPropertyHelper.CalculateRoutingProperties(routingProperties, envelope);
            }
            catch (Exception ex)
            {
                // Exception occurred
                return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, "An error occurred calculating routing properties", ex, logPrefix, log));
            }

            log.LogDebug($"{logPrefix}Finished calculating routing properties - returning response");

            return(new OkObjectResult(envelope.ToJObject()));
        }
Beispiel #3
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = "wrapxmlenvelope")]
            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: {requestDetails.TrackingId}, clearCache: {requestDetails.ClearCache}, enableTrace: {requestDetails.EnableTrace}");

            bool   emitXmlDeclaration = ((string)req.Query["emitXmlDeclaration"] ?? "false") == "true";
            string envelopeSpecNames  = req.Query["envelopeSpecNames"];

            // Validate the request
            IActionResult result = ValidateRequest(requestDetails, logPrefix, log);

            if (result != null)
            {
                return(await Task.FromResult <IActionResult>(result));
            }

            if (string.IsNullOrWhiteSpace(envelopeSpecNames))
            {
                return(await Task.FromResult <IActionResult>(AzureResponseHelper.CreateFaultObjectResult(requestDetails, $"The envelopeSpecNames query string parameter is blank - this needs to be supplied and populated with a least one envelope SpecName", logPrefix, log)));
            }

            log.LogDebug($"{logPrefix}Request parameters are valid");

            // Check that BodyContent is XML
            if ((string.Compare(requestDetails.RequestContentType, "text/xml", true) != 0) && (string.Compare(requestDetails.RequestContentType, "application/xml", true) != 0))
            {
                return(await Task.FromResult <IActionResult>(AzureResponseHelper.CreateFaultObjectResult(requestDetails, $"Expected an XML content type, but instead have been supplied a ContentType of {(string.IsNullOrWhiteSpace(requestDetails.RequestContentType) ? "text" : requestDetails.RequestContentType)}", logPrefix, log)));
            }

            // Attempt to load the content into an XDocument
            XDocument bodyDocument;

            try
            {
                log.LogDebug($"{logPrefix}Parsing the request body as an XDocument");
                bodyDocument = XDocument.Parse(requestDetails.RequestBody);

                // 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);
                }
            }
            catch (Exception ex)
            {
                return(await Task.FromResult <IActionResult>(AzureResponseHelper.CreateFaultObjectResult(requestDetails, $"An exception occurred trying to parse the received XML body into an XDocument", ex, logPrefix, log)));
            }

            // Attempt to get the first EnvelopeSchema
            string envelopeSchemaName = envelopeSpecNames.Split(",")[0];
            string envelopeSchemaContent;

            try
            {
                log.LogDebug($"{logPrefix}Getting schema content from IntegrationAccount");
                envelopeSchemaContent = await new ApimRestClient(requestDetails).GetSchemaContentByNameAsync(envelopeSchemaName);
            }
            catch (AzureResponseException arex)
            {
                // Exception occurred
                AzureResponseHelper.SetCustomResponseHeaders(req, arex);
                return(AzureResponseHelper.CreateFaultObjectResult("An AzureResponseException error occurred calling APIM", arex, logPrefix, log));
            }
            catch (Exception ex)
            {
                // Exception occurred
                return(AzureResponseHelper.CreateFaultObjectResult(requestDetails, "An error occurred calling APIM", ex, logPrefix, log));
            }

            // TODO: Load the XSD into an XmlSchema class
            // TODO: Check the BizTalk IsEnvelope property is set
            // TODO: Check the Body XPath value is set
            // TODO: Generate an instance of the envelope
            // TODO: Select the body node using the Body xPath
            // TODO: Support the emitXmlDeclarationProperty
            // TODO: Insert body content
            // TODO: Return this content

            XDocument xmlEnvelope = bodyDocument;

            log.LogDebug($"{logPrefix}Finished wrapping content - returning response");

            // Special hack for XML content - OkObjectResult doesn't support XmlDocument in Functions at this time
            // without adding the XmlSerializerFormmatter to the list of services
            // See here: https://github.com/Azure/azure-functions-host/issues/2896
            return(await Task.FromResult <IActionResult>(new ContentResult()
            {
                Content = xmlEnvelope.ToString(),
                ContentType = "application/xml",
                StatusCode = 200
            }));
        }