/// <summary>
        /// Send out the results for a completed "Get-League-Summary" query
        /// </summary>
        /// <param name="queryId">
        /// Unique identifier of the query for which we want to send out the results
        /// </param>
        /// <param name="log">
        /// Trace target for logging the outcomes of this operation
        /// </param>
        private static async Task <ActivityResponse> OutputResultsGetLeagueSummaryQuery(
            string queryName,
            string queryId,
            ILogger log)
        {
            ActivityResponse ret = new ActivityResponse()
            {
                FunctionName = "OutputResultsGetLeagueSummaryQuery"
            };

            Guid queryGuid;

            if (Guid.TryParse(queryId, out queryGuid))
            {
                // Get the current state of the query...
                Projection getQueryState = new Projection(@"Query",
                                                          queryName,
                                                          queryGuid.ToString(),
                                                          nameof(Query_Summary_Projection));

                if (null != getQueryState)
                {
                    #region Logging
                    if (null != log)
                    {
                        log.LogDebug($"Projection processor created in OutputResultsGetLeagueSummaryQuery");
                    }
                    #endregion

                    // Run the query summary projection
                    Query_Summary_Projection qryProjection =
                        new Query_Summary_Projection(log);

                    await getQueryState.Process(qryProjection);

                    if ((qryProjection.CurrentSequenceNumber > 0) || (qryProjection.ProjectionValuesChanged()))
                    {
                        // Process the query state as is now...
                        #region Logging
                        if (null != log)
                        {
                            log.LogDebug($"Query { qryProjection.QueryName } projection run for {queryGuid } in OutputResultsGetLeagueSummaryQuery");
                        }
                        #endregion

                        // Ignore queries in an invalid state or not yet validated...
                        if (qryProjection.CurrentState == Query_Summary_Projection.QueryState.Invalid)
                        {
                            // No need to run projections on an invalid query
                            #region Logging
                            if (null != log)
                            {
                                log.LogWarning($"Query {queryGuid} state is {qryProjection.CurrentState} so no output processed in OutputResultsGetLeagueSummaryQuery");
                            }
                            #endregion

                            ret.Message    = $"Query {queryGuid} state is {qryProjection.CurrentState} so no output processed in OutputResultsGetLeagueSummaryQuery";
                            ret.FatalError = true;

                            return(ret);
                        }

                        // Check all the projections have been run..
                        Query_Projections_Projection qryProjectionState = new Query_Projections_Projection(log);
                        await getQueryState.Process(qryProjectionState);

                        if ((qryProjectionState.CurrentSequenceNumber > 0) || (qryProjectionState.ProjectionValuesChanged()))
                        {
                            if (qryProjectionState.UnprocessedRequests.Count == 0)
                            {
                                if (qryProjectionState.ProcessedRequests.Count > 0)
                                {
                                    // Turn the projections into a query return (This could include a collate step)
                                    Get_League_Summary_Definition_Return projectionReturn = new Get_League_Summary_Definition_Return(queryGuid,
                                                                                                                                     qryProjectionState.ProcessedRequests[0].AggregateInstanceKey);

                                    if (qryProjectionState.ProcessedRequests[0].ProjectionTypeName == typeof(Leagues.League.projection.League_Summary_Information).Name)
                                    {
                                        Leagues.League.projection.League_Summary_Information projectionResult = ((Newtonsoft.Json.Linq.JObject)qryProjectionState.ProcessedRequests[0].ReturnedValue).ToObject <Leagues.League.projection.League_Summary_Information>();
                                        if (null != projectionResult)
                                        {
                                            projectionReturn.Location          = projectionResult.Location;
                                            projectionReturn.Date_Incorporated = projectionResult.Date_Incorporated;
                                            projectionReturn.Twitter_Handle    = projectionResult.Twitter_Handle;
                                        }
                                        else
                                        {
                                            #region Logging
                                            if (null != log)
                                            {
                                                log.LogError($"Unable to convert {qryProjectionState.ProcessedRequests[0].ReturnedValue} to {nameof(Leagues.League.projection.League_Summary_Information)} in OutputResultsGetLeagueSummaryQuery");
                                            }
                                            #endregion
                                        }
                                    }

                                    // 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 in OutputResultsGetLeagueSummaryQuery");
                                        }
                                        #endregion
                                        foreach (string location in qryOutputs.Targets.Keys)
                                        {
                                            #region Logging
                                            if (null != log)
                                            {
                                                log.LogDebug($"Target : { location} - type {qryOutputs.Targets[location]} in OutputResultsGetLeagueSummaryQuery");
                                            }
                                            #endregion
                                            // Send the output to the location...
                                            QueryLogRecord.SendOutput(location, qryOutputs.Targets[location], ret);
                                        }

                                        ret.Message = $"Sent results to output targets ({qryOutputs.Targets.Keys.Count}) in OutputResultsGetLeagueSummaryQuery";
                                        return(ret);
                                    }
                                    else
                                    {
                                        // No outputs set
                                        #region Logging
                                        if (null != log)
                                        {
                                            log.LogWarning($"No output targets found in OutputResultsGetLeagueSummaryQuery");
                                        }
                                        #endregion
                                        ret.Message = $"No output targets found in OutputResultsGetLeagueSummaryQuery";
                                        return(ret);
                                    }
                                }
                                else
                                {
                                    // No processed projections found
                                    #region Logging
                                    if (null != log)
                                    {
                                        log.LogWarning($"Query {queryGuid} state is has no processed projections so no output processed in OutputResultsGetLeagueSummaryQuery");
                                    }
                                    #endregion
                                    ret.Message = $"Query {queryGuid} state is has no processed projections so no output processed in OutputResultsGetLeagueSummaryQuery";
                                    return(ret);
                                }
                            }
                            else
                            {
                                #region Logging
                                if (null != log)
                                {
                                    log.LogWarning($"Query {queryGuid} still has unprocessed projections so no output processed in OutputResultsGetLeagueSummaryQuery");
                                }
                                #endregion
                                ret.Message = $"Query {queryGuid} still has unprocessed projections so no output processed in OutputResultsGetLeagueSummaryQuery";
                                return(ret);
                            }
                        }
                        else
                        {
                            ret.Message    = $"Projection run but has no results";
                            ret.FatalError = true;
                            return(ret);
                        }
                    }
                }
            }


            ret.Message    = $"Query identifier blank or not set when running OutputResultsGetLeagueSummaryQuery";
            ret.FatalError = true;
            return(ret);
        }
Exemple #2
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);
        }
Exemple #3
0
        /// <summary>
        /// Send out the results for a completed "Get-League-Summary" query
        /// </summary>
        /// <param name="queryId">
        /// Unique identifier of the query for which we want to send out the results
        /// </param>
        /// <param name="log">
        /// Trace target for logging the outcomes of this operation
        /// </param>
        private static async Task <ActivityResponse> OutputResultsGetLeagueSummaryQuery(
            string queryName,
            string queryId,
            ILogger log)
        {
            ActivityResponse ret = new ActivityResponse()
            {
                FunctionName = "OutputResultsGetLeagueSummaryQuery"
            };

            Guid queryGuid;

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

                if (null != getQueryState)
                {
                    #region Logging
                    if (null != log)
                    {
                        log.LogDebug($"Projection processor created in OutputResultsGetLeagueSummaryQuery");
                    }
                    #endregion

                    // Run the query summary projection
                    Query_Summary_Projection qryProjection =
                        new Query_Summary_Projection(log);

                    await getQueryState.Process(qryProjection);

                    if ((qryProjection.CurrentSequenceNumber > 0) || (qryProjection.ProjectionValuesChanged()))
                    {
                        // Process the query state as is now...
                        #region Logging
                        if (null != log)
                        {
                            log.LogDebug($"Query { qryProjection.QueryName } projection run for {queryGuid } in OutputResultsGetLeagueSummaryQuery");
                        }
                        #endregion

                        // Ignore queries in an invalid state or not yet validated...
                        if (qryProjection.CurrentState == Query_Summary_Projection.QueryState.Invalid)
                        {
                            // No need to run projections on an invalid query
                            #region Logging
                            if (null != log)
                            {
                                log.LogWarning($"Query {queryGuid} state is {qryProjection.CurrentState} so no output processed in OutputResultsGetLeagueSummaryQuery");
                            }
                            #endregion

                            ret.Message    = $"Query {queryGuid} state is {qryProjection.CurrentState} so no output processed in OutputResultsGetLeagueSummaryQuery";
                            ret.FatalError = true;

                            return(ret);
                        }

                        // Check all the projections have been run..
                        Query_Projections_Projection qryProjectionState = new Query_Projections_Projection(log);
                        await getQueryState.Process(qryProjectionState);

                        if ((qryProjectionState.CurrentSequenceNumber > 0) || (qryProjectionState.ProjectionValuesChanged()))
                        {
                            if (qryProjectionState.UnprocessedRequests.Count == 0)
                            {
                                if (qryProjectionState.ProcessedRequests.Count > 0)
                                {
                                    // Turn the projections into a query return (This could include a collate step)
                                    Get_League_Summary_Definition_Return projectionReturn = new Get_League_Summary_Definition_Return(queryGuid,
                                                                                                                                     qryProjectionState.ProcessedRequests[0].AggregateInstanceKey);


                                    if (qryProjectionState.ProcessedRequests[0].ProjectionTypeName == typeof(Leagues.League.projection.League_Summary_Information).Name)
                                    {
                                        dynamic projectionResult = (qryProjectionState.ProcessedRequests[0].ReturnedValue);
                                        if (null != projectionResult)
                                        {
                                            projectionReturn.Location          = projectionResult.Location;
                                            projectionReturn.Date_Incorporated = projectionResult.Date_Incorporated;
                                            projectionReturn.Twitter_Handle    = projectionResult.Twitter_Handle;
                                        }
                                        else
                                        {
                                            #region Logging
                                            if (null != log)
                                            {
                                                log.LogError($"Unable to convert {qryProjectionState.ProcessedRequests[0].ReturnedValue} to {nameof(Leagues.League.projection.League_Summary_Information)} in OutputResultsGetLeagueSummaryQuery");
                                            }
                                            #endregion
                                        }
                                    }


                                    // Call the outputs processing sub-orchestration


                                    // 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 in OutputResultsGetLeagueSummaryQuery");
                                        }
                                        #endregion


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

                                            if (null != projectionReturn)
                                            {
                                                var payloadAsJSON = new StringContent(JsonConvert.SerializeObject(projectionReturn));
                                                using (var client = new HttpClient())
                                                {
                                                    var response = await client.PostAsync(location, payloadAsJSON);

                                                    if (!response.IsSuccessStatusCode)
                                                    {
                                                        ret.Message = $"Failed to send output to {location} webhook - {response.StatusCode} : {response.ReasonPhrase} ";
                                                        #region Logging
                                                        if (null != log)
                                                        {
                                                            log.LogError($"{ret.FunctionName } : {ret.Message}");
                                                        }
                                                        #endregion
                                                    }
                                                }
                                            }
                                        }

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

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

                                        foreach (string location in qryOutputs.DurableFunctionOrchestrationTargets)
                                        {
                                            #region Logging
                                            if (null != log)
                                            {
                                                log.LogDebug($"Target : { location} - being used to trigger a durable function to wake up in OutputResultsGetLeagueSummaryQuery");
                                            }
                                            #endregion
                                        }

                                        ret.Message = $"Sent results to output targets ({qryOutputs.Targets.Keys.Count}) in OutputResultsGetLeagueSummaryQuery";
                                        return(ret);
                                    }
                                    else
                                    {
                                        // No outputs set
                                        #region Logging
                                        if (null != log)
                                        {
                                            log.LogWarning($"No output targets found in OutputResultsGetLeagueSummaryQuery");
                                        }
                                        #endregion
                                        ret.Message = $"No output targets found in OutputResultsGetLeagueSummaryQuery";
                                        return(ret);
                                    }
                                }
                                else
                                {
                                    // No processed projections found
                                    #region Logging
                                    if (null != log)
                                    {
                                        log.LogWarning($"Query {queryGuid} state is has no processed projections so no output processed in OutputResultsGetLeagueSummaryQuery");
                                    }
                                    #endregion
                                    ret.Message = $"Query {queryGuid} state is has no processed projections so no output processed in OutputResultsGetLeagueSummaryQuery";
                                    return(ret);
                                }
                            }
                            else
                            {
                                #region Logging
                                if (null != log)
                                {
                                    log.LogWarning($"Query {queryGuid} still has unprocessed projections so no output processed in OutputResultsGetLeagueSummaryQuery");
                                }
                                #endregion
                                ret.Message = $"Query {queryGuid} still has unprocessed projections so no output processed in OutputResultsGetLeagueSummaryQuery";
                                return(ret);
                            }
                        }
                        else
                        {
                            ret.Message    = $"Projection run but has no results";
                            ret.FatalError = true;
                            return(ret);
                        }
                    }
                }
            }


            ret.Message    = $"Query identifier blank or not set when running OutputResultsGetLeagueSummaryQuery";
            ret.FatalError = true;
            return(ret);
        }