Exemplo n.º 1
0
        public static async Task <ActivityResponse> QueryOutputProcessorOrchestrator(
            [OrchestrationTrigger] DurableOrchestrationContext context,
            Microsoft.Extensions.Logging.ILogger log)
        {
            ActivityResponse response = new ActivityResponse()
            {
                FunctionName = "QueryOutputProcessorOrchestrator"
            };

            // Get the Query_Outputs_Request from the context...
            Query_Outputs_Request request = context.GetInput <Query_Outputs_Request>();

            if (null != request)
            {
                // Read the outputs for the given query
                Guid queryGuid;

                if (Guid.TryParse(request.UniqueIdentifier, out queryGuid))
                {
                    // Get the current state of the query...
                    Projection getQueryState = new Projection(Constants.Domain_Query,
                                                              request.QueryName,
                                                              queryGuid.ToString(),
                                                              nameof(Query_Summary_Projection));


                    if (null != getQueryState)
                    {
                        // Get all the output targets
                        Query_Outputs_Projection qryOutputs = new Query_Outputs_Projection(log);
                        await getQueryState.Process(qryOutputs);

                        if ((qryOutputs.CurrentSequenceNumber > 0) || (qryOutputs.ProjectionValuesChanged()))
                        {
                            #region Logging
                            if (null != log)
                            {
                                log.LogDebug($"Sending results to output targets from {request.QueryName} : {request.UniqueIdentifier} ");
                            }
                            #endregion

                            List <Task <ActivityResponse> > allOutputTasks = new List <Task <ActivityResponse> >();

                            if (null != request.Results)
                            {
                                // Create a QueryOutputRecord<object>
                                QueryOutputRecord <object> outputRequest = QueryOutputRecord <object> .Create(request.Results,
                                                                                                              @"",
                                                                                                              request.QueryName,
                                                                                                              queryGuid);

                                foreach (string location in qryOutputs.WebhookTargets)
                                {
                                    #region Logging
                                    if (null != log)
                                    {
                                        log.LogDebug($"Target : { location} - being sent by webhook in OutputResultsGetLeagueSummaryQuery");
                                    }
                                    #endregion

                                    outputRequest.Target = location;

                                    // add a task to ouputit it via webhook....
                                    allOutputTasks.Add(context.CallActivityWithRetryAsync <ActivityResponse>("QueryOutputToWebhookActivity",
                                                                                                             DomainSettings.QueryRetryOptions(),
                                                                                                             outputRequest));
                                }

                                foreach (string location in qryOutputs.BlobTargets)
                                {
                                    #region Logging
                                    if (null != log)
                                    {
                                        log.LogDebug($"Target : { location} - being persisted to a Blob in {response.FunctionName}");
                                    }
                                    #endregion

                                    outputRequest.Target = location;

                                    // add a task to ouputit it via webhook....
                                    allOutputTasks.Add(context.CallActivityWithRetryAsync <ActivityResponse>("QueryOutputToBlobActivity",
                                                                                                             DomainSettings.QueryRetryOptions(),
                                                                                                             outputRequest));
                                }

                                foreach (string location in qryOutputs.ServiceBusTargets)
                                {
                                    #region Logging
                                    if (null != log)
                                    {
                                        log.LogDebug($"Target : { location} - being sent out via service bus in {response.FunctionName}");
                                    }
                                    #endregion

                                    outputRequest.Target = location;

                                    // add a task to ouputit it via service bus....
                                    allOutputTasks.Add(context.CallActivityWithRetryAsync <ActivityResponse>("QueryOutputToServiceBusActivity",
                                                                                                             DomainSettings.QueryRetryOptions(),
                                                                                                             outputRequest));
                                }


                                //EventGridTargets
                                foreach (string location in qryOutputs.EventGridTargets)
                                {
                                    #region Logging
                                    if (null != log)
                                    {
                                        log.LogDebug($"Target : { location} - being sent out via event grid in {response.FunctionName}");
                                    }
                                    #endregion

                                    outputRequest.Target = location;

                                    // add a task to ouputit it via event grid....
                                    allOutputTasks.Add(context.CallActivityWithRetryAsync <ActivityResponse>("QueryOutputToEventGridActivity",
                                                                                                             DomainSettings.QueryRetryOptions(),
                                                                                                             outputRequest));
                                }


                                foreach (string location in qryOutputs.SignalRTargets)
                                {
                                    #region Logging
                                    if (null != log)
                                    {
                                        log.LogDebug($"Target : { location} - being sent out via SignalR in {response.FunctionName}");
                                    }
                                    #endregion

                                    outputRequest.Target = location;

                                    // add a task to ouputit it via SignalR....
                                    allOutputTasks.Add(context.CallActivityWithRetryAsync <ActivityResponse>("QueryOutputToSignalRActivity",
                                                                                                             DomainSettings.QueryRetryOptions(),
                                                                                                             outputRequest));
                                }

                                // TODO: All the other output methods
                            }

                            // Await for all the outputs to have run in parallel...
                            await Task.WhenAll(allOutputTasks);

                            foreach (var returnedResponse in allOutputTasks)
                            {
                                if (returnedResponse.Result.FatalError)
                                {
                                    response.FatalError = true;
                                    response.Message    = returnedResponse.Result.Message;
                                }

                                #region Logging
                                if (null != log)
                                {
                                    log.LogDebug($"Sent results to output targets from {returnedResponse.Result.FunctionName} : {returnedResponse.Result.Message } ");
                                }
                                #endregion
                                context.SetCustomStatus(returnedResponse.Result);
                            }
                        }
                    }
                }
            }
            else
            {
                response.Message    = $"Unable to get outputs request details in sub orchestration {context.InstanceId} ";
                response.FatalError = true;
            }

            return(response);
        }
Exemplo n.º 2
0
        public static async Task <Get_League_Summary_Definition_Return> OnGetLeagueSummaryQueryHandlerOrchestrator
            ([OrchestrationTrigger] DurableOrchestrationContext context,
            Microsoft.Extensions.Logging.ILogger log)
        {
            // Get the query definition form the context...
            QueryRequest <Get_League_Summary_Definition> queryRequest = context.GetInput <QueryRequest <Get_League_Summary_Definition> >();



            try
            {
                if (null != queryRequest)
                {
                    if (string.IsNullOrWhiteSpace(queryRequest.QueryName))
                    {
                        queryRequest.QueryName = "Get League Summary";
                    }

                    // Log the query request in its own own query event stream
                    Guid queryId = await context.CallActivityWithRetryAsync <Guid>("GetLeagueSummaryCreateQueryRequestActivity",
                                                                                   DomainSettings.QueryRetryOptions(),
                                                                                   queryRequest);

                    if (queryId.Equals(Guid.Empty))
                    {
                        #region Logging
                        if (null != log)
                        {
                            // Unable to get the request details from the orchestration
                            log.LogError("OnGetLeagueSummaryQueryHandlerOrchestrator : Unable to create the query event stream");
                        }
                        #endregion

                        return(null);
                    }
                    else
                    {
                        queryRequest.QueryUniqueIdentifier = queryId;
                        // Save the parameters to the event stream
                        ActivityResponse resp = null;

                        // If there are outputs set, log them...
                        resp = await context.CallActivityWithRetryAsync <ActivityResponse>("QueryLogOutputTargetActivity",
                                                                                           DomainSettings.QueryRetryOptions(),
                                                                                           queryRequest);

                        #region Logging
                        if (null != log)
                        {
                            if (null != resp)
                            {
                                log.LogInformation($"{resp.FunctionName} complete: {resp.Message } ");
                            }
                        }
                        #endregion


                        if (null != resp)
                        {
                            context.SetCustomStatus(resp);
                        }


                        resp = await context.CallActivityWithRetryAsync <ActivityResponse>("GetLeagueSummaryLogParametersActivity",
                                                                                           DomainSettings.QueryRetryOptions(),
                                                                                           queryRequest);

                        #region Logging
                        if (null != log)
                        {
                            if (null != resp)
                            {
                                log.LogInformation($"{resp.FunctionName} complete: {resp.Message } ");
                            }
                        }
                        #endregion


                        if (null != resp)
                        {
                            context.SetCustomStatus(resp);
                        }

                        // next validate the query
                        bool valid = false;

                        try
                        {
                            valid = await context.CallActivityWithRetryAsync <bool>("GetLeagueSummaryValidateActivity",
                                                                                    DomainSettings.QueryRetryOptions(),
                                                                                    queryRequest);
                        }
                        catch (FunctionFailedException ffs)
                        {
                            if (null == resp)
                            {
                                resp = new ActivityResponse()
                                {
                                    FunctionName = "GetLeagueSummaryValidateActivity"
                                };
                            }
                            resp.Message    = ffs.Message;
                            resp.FatalError = true;
                        }

                        if (!valid)
                        {
                            #region Logging
                            if (null != log)
                            {
                                // Could not run the query as the parameters don't make sense
                                log.LogError($"OnGetLeagueSummaryQueryHandlerOrchestrator : Query parameters are invalid {queryId}");
                            }
                            #endregion
                            return(null);
                        }
                        else
                        {
                            try
                            {
                                // Request all the projections needed to answer this query
                                resp = await context.CallActivityWithRetryAsync <ActivityResponse>("GetLeagueSummaryQueryProjectionRequestActivity",
                                                                                                   DomainSettings.QueryRetryOptions(),
                                                                                                   queryRequest);
                            }
                            catch (FunctionFailedException ffs)
                            {
                                if (null == resp)
                                {
                                    resp = new ActivityResponse()
                                    {
                                        FunctionName = "GetLeagueSummaryQueryProjectionRequestActivity"
                                    };
                                }
                                resp.Message    = ffs.Message;
                                resp.FatalError = true;
                            }

                            if (null != resp)
                            {
                                #region Logging
                                if (null != log)
                                {
                                    if (null != resp)
                                    {
                                        log.LogInformation($"{resp.FunctionName} complete: {resp.Message } ");
                                    }
                                }
                                #endregion
                                context.SetCustomStatus(resp);
                                if (resp.FatalError)
                                {
                                    #region Logging
                                    if (null != log)
                                    {
                                        log.LogError($"Fatal error in {resp.FunctionName} - {resp.Message} ");
                                    }
                                    #endregion
                                    return(null);
                                }
                            }

                            // Get all the outstanding projection requests by calling a sub-orchestrator
                            Query_Projections_Projection_Request projectionQueryRequest = new Query_Projections_Projection_Request()
                            {
                                UniqueIdentifier = queryRequest.QueryUniqueIdentifier.ToString(), QueryName = queryRequest.QueryName
                            };

                            try
                            {
                                resp = await context.CallSubOrchestratorWithRetryAsync <ActivityResponse>("QueryProjectionProcessorOrchestrator",
                                                                                                          DomainSettings.QueryRetryOptions(),
                                                                                                          projectionQueryRequest);
                            }
                            catch (FunctionFailedException ffs)
                            {
                                if (null == resp)
                                {
                                    resp = new ActivityResponse()
                                    {
                                        FunctionName = "QueryProjectionProcessorOrchestrator"
                                    };
                                }
                                resp.Message    = ffs.Message;
                                resp.FatalError = true;
                            }

                            if (null != resp)
                            {
                                #region Logging
                                if (null != log)
                                {
                                    if (null != resp)
                                    {
                                        log.LogInformation($"{resp.FunctionName} complete: {resp.Message } ");
                                    }
                                }
                                #endregion
                                context.SetCustomStatus(resp);
                                if (resp.FatalError)
                                {
                                    #region Logging
                                    if (null != log)
                                    {
                                        log.LogError($"Fatal error in {resp.FunctionName} - {resp.Message} ");
                                    }
                                    #endregion
                                    return(null);
                                }
                            }

                            // Get the results for ourselves to return...to do this the query must be complete...
                            Get_League_Summary_Definition_Return ret = await context.CallActivityWithRetryAsync <Get_League_Summary_Definition_Return>("GetLeagueSummaryGetResultsActivity",
                                                                                                                                                       DomainSettings.QueryRetryOptions(),
                                                                                                                                                       queryRequest);

                            // Output them to every registered output destination
                            Query_Outputs_Request request = new Query_Outputs_Request()
                            {
                                Results          = JObject.FromObject(ret),
                                QueryName        = queryRequest.QueryName,
                                UniqueIdentifier = queryRequest.QueryUniqueIdentifier.ToString()
                            };

                            try
                            {
                                resp = await context.CallSubOrchestratorWithRetryAsync <ActivityResponse>("QueryOutputProcessorOrchestrator",
                                                                                                          DomainSettings.QueryRetryOptions(),
                                                                                                          request);
                            }
                            catch (FunctionFailedException ffs)
                            {
                                if (null == resp)
                                {
                                    resp = new ActivityResponse()
                                    {
                                        FunctionName = "QueryOutputProcessorOrchestrator"
                                    };
                                }
                                resp.Message    = ffs.Message;
                                resp.FatalError = true;
                            }

                            if (null != resp)
                            {
                                #region Logging
                                if (null != log)
                                {
                                    if (null != resp)
                                    {
                                        log.LogInformation($"{resp.FunctionName} complete: {resp.Message } ");
                                    }
                                }
                                #endregion
                                context.SetCustomStatus(resp);
                                if (resp.FatalError)
                                {
                                    #region Logging
                                    if (null != log)
                                    {
                                        log.LogError($"Fatal error in {resp.FunctionName} - {resp.Message} ");
                                    }
                                    #endregion
                                    return(null);
                                }
                            }


                            return(ret);
                        }
                    }
                }
                else
                {
                    if (null != log)
                    {
                        // Unable to get the request details from the orchestration
                        log.LogError("OnGetLeagueSummaryQueryHandlerOrchestrator : Unable to get the query request from the context");

                        string contextAsString = context.GetInput <string>();
                        if (!string.IsNullOrWhiteSpace(contextAsString))
                        {
                            log.LogError($"Context was {contextAsString} ");
                        }
                        else
                        {
                            log.LogError($"Context was blank ");
                        }
                    }

                    return(null);
                }
            }
            catch (Exception ex)
            {
                #region Logging
                if (null != log)
                {
                    // Error running thew orchestration
                    log.LogError($"OnGetLeagueSummaryQueryHandlerOrchestrator : Error {ex.Message}");
                }
                #endregion
                if (null != context)
                {
                    context.SetCustomStatus($"OnGetLeagueSummaryQueryHandlerOrchestrator : Error {ex.Message}");
                }
                throw;
            }
        }