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())); }
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 })); }