Ejemplo n.º 1
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "put", Route = "{documentId:guid}/{serviceName}")] HttpRequest req,
            [CosmosDB(databaseName: "IntermediaryServiceDb", collectionName: "IntermediaryService",
                      ConnectionStringSetting = "CosmosDBConnection", Id = "{documentId}", PartitionKey = "{serviceName}")]
            IntermediaryServiceDocument intermediaryServiceDocument,
            ILogger log)
        {
            try
            {
                log.LogInformation($"Function 3 processed a request");

                //validate that a document was actually retrieved from CosmosDb
                if (intermediaryServiceDocument == null)
                {
                    log.LogWarning(UserFriendlyMessages.DocumentNotFound, req);
                    return(new NotFoundObjectResult(UserFriendlyMessages.DocumentNotFound));
                }

                string           requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                ThirdPartyStatus thirdPartyStatus;
                try
                {
                    thirdPartyStatus = JsonConvert.DeserializeObject <ThirdPartyStatus>(requestBody);
                    //Check that the clientDocument object and it's Body property are NOT null
                    if (thirdPartyStatus?.Status == null)
                    {
                        throw new JsonException("Object was deserialized to null");
                    }
                }
                catch (JsonException ex)
                {
                    log.LogInformation(ex, UserFriendlyMessages.ErrorProcessingBody, requestBody);
                    return(new BadRequestObjectResult(UserFriendlyMessages.ErrorProcessingBody));
                }

                //Check that the status is one of the three
                var statusOptions = new List <string>()
                {
                    "PROCESSED", "COMPLETED", "ERROR"
                };
                if (!statusOptions.Any(s => String.Equals(s, thirdPartyStatus.Status)))
                {
                    var logMessage = $"Expected PROCESSED, COMPLETED, ERROR but received {thirdPartyStatus.Status}";
                    log.LogWarning(logMessage, requestBody);
                    return(new BadRequestObjectResult(UserFriendlyMessages.UnexpectedBodyContent));
                }

                //Update the document
                intermediaryServiceDocument.Status = new Status(thirdPartyStatus);

                return(new NoContentResult());
            }

            catch (Exception ex) //gracefully deal with an unhandled exception
            {
                log.LogError(ex, UserFriendlyMessages.UnhandledException);
                return(new StatusCodeResult(500));
            }
        }
Ejemplo n.º 2
0
        public IActionResult Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = "request")] HttpRequest req,
            [CosmosDB(databaseName: "IntermediaryServiceDb", collectionName: "IntermediaryService", ConnectionStringSetting = "CosmosDBConnection")] out dynamic intermediaryDocument,
            ILogger log)
        {
            try
            {
                log.LogInformation("Function1 processed a request.");

                //retrieve the body of the request which should be of type Document
                Document document;
                string   requestBody = new StreamReader(req.Body).ReadToEndAsync().Result;
                //Note: I initially used "await" - however adding CosmosDB out binding in signature meant I can't have an async method anymore.
                //I may consider using a static cosmosDb client instead of the output binding if I need/want async
                try
                {
                    document = JsonConvert.DeserializeObject <Document>(requestBody);
                    //Check that the clientDocument object and it's Body property are NOT null
                    if (document?.Body == null)
                    {
                        throw new JsonException("Object was deserialized to null");
                    }
                }
                catch (JsonException ex)
                {
                    log.LogInformation(ex, UserFriendlyMessages.ErrorProcessingBody, requestBody);
                    intermediaryDocument = null;
                    return(new BadRequestObjectResult(UserFriendlyMessages.ErrorProcessingBody));
                }

                var uniqueId    = Guid.NewGuid().ToString();
                var serviceName = "ThirdParty"; //partition key for the cosmos container
                var callBack    = $"/{uniqueId}/{serviceName}";
                //send to third party using the injected httpClient.
                //Note: I initually used "await" - however when I added the Cosmos output binding the method could no longer be "async"
                //Perhaps use static CosmosDb client instead if "async" is necessary.
                var success = _thirdPartyServiceHttpClient.PostAsyncSuccessful(document, callBack, log).Result;

                //Now Generate an "Intermediary Service Document" to be stored in CosmosDB
                //It will keep status information and the document body
                intermediaryDocument = new IntermediaryServiceDocument
                {
                    id          = uniqueId,
                    Document    = document,
                    ServiceName = "ThirdParty", //partition key
                    CreateDate  = DateTime.UtcNow.ToString()
                };

                return(new OkObjectResult(intermediaryDocument.id));
            }
            catch (Exception ex) //gracefully deal with an unhandled exception
            {
                intermediaryDocument = null;
                log.LogError(ex, UserFriendlyMessages.UnhandledException);
                return(new StatusCodeResult(500));
            }
        }
Ejemplo n.º 3
0
        public async Task Run_StatusCompleted_CosmosDbDocumentUpdated_Return204Success(string status)
        {
            //arrange
            var thirdPartyStatus = new ThirdPartyStatus()
            {
                Detail = "",
                Status = status
            };
            string json                 = JsonConvert.SerializeObject(thirdPartyStatus);
            var    mockHttpRequest      = MockHttpRequestGenerator.CreateWithBodyString(json);
            var    intermediaryDocument = new IntermediaryServiceDocument();

            //act
            var actionResult = await Function3.Run(mockHttpRequest.Object, intermediaryDocument, _mockLogger);

            //assert
            Assert.IsInstanceOfType(actionResult, typeof(NoContentResult));
            Assert.IsTrue(string.Equals(status, intermediaryDocument.Status.StatusCode));
        }
Ejemplo n.º 4
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = "{documentId:guid}/{serviceName}")] HttpRequest req,
            [CosmosDB(databaseName: "IntermediaryServiceDb", collectionName: "IntermediaryService",
                      ConnectionStringSetting = "CosmosDBConnection", Id = "{documentId}", PartitionKey = "{serviceName}")]
            IntermediaryServiceDocument intermediaryServiceDocument,
            ILogger log)
        {
            try
            {
                log.LogInformation($"Function 2 processed a request");

                //validate that a document was actually retrieved from CosmosDb
                if (intermediaryServiceDocument == null)
                {
                    log.LogWarning(UserFriendlyMessages.DocumentNotFound, req);
                    return(new NotFoundObjectResult(UserFriendlyMessages.DocumentNotFound));
                }

                //validate the string is "STARTED"
                string requestBody = new StreamReader(req.Body).ReadToEndAsync().Result;
                if (!String.Equals(requestBody, "STARTED"))
                {
                    log.LogWarning(UserFriendlyMessages.UnexpectedBodyContent, req);
                    return(new BadRequestObjectResult(UserFriendlyMessages.UnexpectedBodyContent));
                }

                //Update the document
                intermediaryServiceDocument.HasStarted = true;
                //TODO: the thirdparty service could send another "START" post for this same document
                //we may want to intercept such a request and log it and handle accordingly

                return(new NoContentResult());
            }

            catch (Exception ex) //gracefully deal with an unhandled exception
            {
                log.LogError(ex, UserFriendlyMessages.UnhandledException);
                return(new StatusCodeResult(500));
            }
        }