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