Exemple #1
0
        public static async Task <HttpResponseMessage> RunProjectionRun(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequestMessage req,
            ILogger log)
        {
            #region Logging
            if (null != log)
            {
                log.LogDebug("Function triggered HTTP in RunProjection");
            }
            #endregion

            string parentRequestName;
            string projectionName;
            string domainName;
            string aggregateTypeName;
            string entityUniqueIdentifier;
            Nullable <DateTime> asOfDate = null;

            // Get the parameters from the query
            parentRequestName      = req.GetQueryNameValuePairsExt()[@"ParentRequestName"];
            projectionName         = req.GetQueryNameValuePairsExt()[@"ProjectionName"];
            domainName             = req.GetQueryNameValuePairsExt()[@"DomainName"];
            aggregateTypeName      = req.GetQueryNameValuePairsExt()[@"AggregateTypeName"];
            entityUniqueIdentifier = req.GetQueryNameValuePairsExt()[@"EntityUniqueIdentifier"];

            string   asOfDateString = req.GetQueryNameValuePairsExt()[@"AsOfDate"];
            DateTime asOfDateValue;
            if (DateTime.TryParse(asOfDateString, out asOfDateValue))
            {
                asOfDate = asOfDateValue;
            }


            ProjectionRequest request = new ProjectionRequest()
            {
                ParentRequestName = parentRequestName,
                ProjectionName    = projectionName,
                DomainName        = domainName,
                AggregateTypeName = aggregateTypeName,
                AggregateInstanceUniqueIdentifier = entityUniqueIdentifier,
                AsOfDate = asOfDate
            };

            ProjectionResultsRecord <object> response = await RunProjection(request, log);

            if (null != response)
            {
                return(req.CreateResponse(HttpStatusCode.OK, response,
                                          new System.Net.Http.Formatting.JsonMediaTypeFormatter()));
            }
            else
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest,
                                          $"No projection response for {request }"));
            }
        }
        public static async Task <IActionResult> RunLeagueSummaryInformationProjection(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
            ILogger log)
        {
            #region Logging
            if (null != log)
            {
                log.LogDebug("Function triggered HTTP in RunLeagueSummaryInformationProjectionRun");
            }
            #endregion

            // Get the query identifier
            string leagueName = req.Query["LeagueName"];

            if (string.IsNullOrWhiteSpace(leagueName))
            {
                string  requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                dynamic data        = JsonConvert.DeserializeObject(requestBody);
                leagueName = leagueName ?? data?.LeagueName;
            }


            ProjectionResultsRecord <Get_League_Summary_Definition_Return> ret = null;
            string message = $"Running projection for {leagueName}";

            ret = await ProcessLeagueSummaryInformationProjection("League_Summary_Information",
                                                                  leagueName,
                                                                  log);


            if (null != ret)
            {
                if (null != ret.Result)
                {
                    message = $"{leagueName} Location: {ret.Result.Location } incorporated {ret.Result.Date_Incorporated} (Twitter handle:{ret.Result.Twitter_Handle }) ";
                }
            }

            if (string.IsNullOrWhiteSpace(leagueName))
            {
                return(new BadRequestObjectResult($"Please pass a league name to run the projection over"));
            }
            else
            {
                return((ActionResult) new OkObjectResult(new { leagueName, message, ret }));
            }
        }
Exemple #3
0
        public static async Task <ActivityResponse> LogQueryProjectionResultActivity(
            [ActivityTrigger] DurableActivityContext context,
            ILogger log
            )
        {
            CQRSAzure.EventSourcing.IWriteContext writeContext = null; // TODO: Pass this as a parameter

            ActivityResponse resp = new ActivityResponse()
            {
                FunctionName = "LogQueryProjectionResultActivity"
            };

            // get the ProjectionResultsRecord
            ProjectionResultsRecord <object> data = context.GetInput <ProjectionResultsRecord <object> >();

            if (null != data)
            {
                await QueryLogRecord.LogProjectionResult(data.CorrelationIdentifier,
                                                         data.ParentRequestName,
                                                         data.ProjectionName,
                                                         data.DomainName,
                                                         data.AggregateTypeName,
                                                         data.EntityUniqueIdentifier,
                                                         data.CurrentAsOfDate,
                                                         data.Result,
                                                         data.CurrentSequenceNumber,
                                                         writeContext);

                resp.Message = $"Saved projection result to query {data.ParentRequestName} - {data.CorrelationIdentifier} ";
            }
            else
            {
                resp.Message    = "Unable to get projection result from context";
                resp.FatalError = true;
            }

            return(resp);
        }
Exemple #4
0
        public static async Task <ActivityResponse> QueryProjectionProcessorOrchestrator(
            [OrchestrationTrigger] DurableOrchestrationContext context,
            Microsoft.Extensions.Logging.ILogger log)
        {
            ActivityResponse response = new ActivityResponse()
            {
                FunctionName = "QueryProjectionProcessorOrchestrator"
            };

            Query_Projections_Projection_Request request = context.GetInput <Query_Projections_Projection_Request>();

            if (null != request)
            {
                Guid UniqueIdentifierGuid;
                if (!Guid.TryParse(request.UniqueIdentifier, out UniqueIdentifierGuid))
                {
                    if (!Guid.TryParse(request.CallbackOrchestrationIdentifier, out UniqueIdentifierGuid))
                    {
                        if (!Guid.TryParse(context.ParentInstanceId, out UniqueIdentifierGuid))
                        {
                            if (!Guid.TryParse(context.InstanceId, out UniqueIdentifierGuid))
                            {
                                UniqueIdentifierGuid = Guid.NewGuid();
                            }
                        }
                    }
                }



                // get all the projection requests for the query
                List <Query_Projections_Projection_Return> allProjections = await context.CallActivityWithRetryAsync <List <Query_Projections_Projection_Return> >("GetQueryProjectionsStatusProjectionActivity",
                                                                                                                                                                   DomainSettings.QueryRetryOptions(),
                                                                                                                                                                   request);

                if (null != allProjections)
                {
                    #region Logging
                    if (null != log)
                    {
                        log.LogInformation($"Query {request.QueryName}.{request.UniqueIdentifier} has {allProjections.Count} projections total ");
                    }
                    #endregion

                    // Run them - This should be done by fan-out/fan-in
                    List <Task <ProjectionResultsRecord <object> > > allProjectionTasks = new List <Task <ProjectionResultsRecord <object> > >();

                    // run all the outstanding projections in parallel
                    foreach (Query_Projections_Projection_Return projectionRequest in allProjections)
                    {
                        if (projectionRequest.ProjectionState == Query_Projections_Projection_Return.QueryProjectionState.Queued)
                        {
                            ProjectionRequest projRequest = new ProjectionRequest()
                            {
                                ParentRequestName                 = request.QueryName,
                                CorrelationIdentifier             = UniqueIdentifierGuid,
                                DomainName                        = projectionRequest.Projection.DomainName,
                                AggregateTypeName                 = projectionRequest.Projection.AggregateTypeName,
                                AggregateInstanceUniqueIdentifier = projectionRequest.Projection.InstanceKey,
                                AsOfDate       = request.AsOfDate,
                                ProjectionName = projectionRequest.Projection.ProjectionTypeName
                            };

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


                            // mark it as in-flight
                            response = await context.CallActivityWithRetryAsync <ActivityResponse>("LogQueryProjectionInFlightActivity",
                                                                                                   DomainSettings.QueryRetryOptions(),
                                                                                                   projRequest);

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

                    // Now start them running using a fan-out/fan in pattern
                    foreach (Query_Projections_Projection_Return projectionRequest in allProjections)
                    {
                        if (projectionRequest.ProjectionState == Query_Projections_Projection_Return.QueryProjectionState.Queued)
                        {
                            ProjectionRequest projRequest = new ProjectionRequest()
                            {
                                ParentRequestName                 = request.QueryName,
                                CorrelationIdentifier             = UniqueIdentifierGuid,
                                DomainName                        = projectionRequest.Projection.DomainName,
                                AggregateTypeName                 = projectionRequest.Projection.AggregateTypeName,
                                AggregateInstanceUniqueIdentifier = projectionRequest.Projection.InstanceKey,
                                AsOfDate       = request.AsOfDate,
                                ProjectionName = projectionRequest.Projection.ProjectionTypeName
                            };


                            // and start running it...
                            allProjectionTasks.Add(context.CallActivityWithRetryAsync <ProjectionResultsRecord <object> >("RunProjectionActivity",
                                                                                                                          DomainSettings.QueryRetryOptions(),
                                                                                                                          projRequest));
                        }
                    }

                    // Run the projections in parallel...
                    await Task.WhenAll(allProjectionTasks);

                    // and save their results to the query
                    foreach (var returnValue in allProjectionTasks)
                    {
                        ProjectionResultsRecord <object> result = returnValue.Result;

                        if (null != result)
                        {
                            if (!result.Error)
                            {
                                response = await context.CallActivityWithRetryAsync <ActivityResponse>("LogQueryProjectionResultActivity",
                                                                                                       DomainSettings.QueryRetryOptions(),
                                                                                                       result);
                            }
                            else
                            {
                                #region Logging
                                if (null != log)
                                {
                                    log.LogError($"Error running projection {result.ProjectionName} - {result.StatusMessage} ");
                                }
                                #endregion
                                response.Message = $"Error running projection {result.ProjectionName} - {result.StatusMessage} ";
                            }
                            if (null != response)
                            {
                                context.SetCustomStatus(response);
                            }
                        }
                        else
                        {
                            #region Logging
                            if (null != log)
                            {
                                log.LogError($"Projection {returnValue.Id} did not return any values : {returnValue.Exception}");
                            }
                            #endregion
                        }
                    }
                }


                // when all done - trigger the calling orchestration to come out of hibernation
                if (!string.IsNullOrWhiteSpace(request.CallbackOrchestrationIdentifier))
                {
                }
            }
            else
            {
                response.Message    = $"Unable to read projection request data from context {context.InstanceId}";
                response.FatalError = true;
            }

            return(response);
        }
Exemple #5
0
        public static async Task <ActivityResponse> GetLeagueSummaryQueryProjectionProcessOrchestrator
            ([OrchestrationTrigger] DurableOrchestrationContext context,
            Microsoft.Extensions.Logging.ILogger log)
        {
            ActivityResponse resp = new ActivityResponse()
            {
                FunctionName = "GetLeagueSummaryQueryProjectionProcessOrchestrator"
            };

            // Get the query definition form the context...
            QueryRequest <Get_League_Summary_Definition> queryRequest = context.GetInput <QueryRequest <Get_League_Summary_Definition> >();

            if (null != queryRequest)
            {
                // Get all the outstanding projection requests
                Query_Projections_Projection_Request projectionQueryRequest = new Query_Projections_Projection_Request()
                {
                    UniqueIdentifier = queryRequest.QueryUniqueIdentifier.ToString(),
                    QueryName        = queryRequest.QueryName
                };
                List <Query_Projections_Projection_Return> allProjections = await context.CallActivityAsync <List <Query_Projections_Projection_Return> >("GetQueryProjectionsStatusProjectionActivity", projectionQueryRequest);

                if (null != allProjections)
                {
                    // This should be done by fan-out/fan-in
                    List <Task <ProjectionResultsRecord <Get_League_Summary_Definition_Return> > > allProjectionTasks = new List <Task <ProjectionResultsRecord <Get_League_Summary_Definition_Return> > >();

                    // run all the outstanding projections in parallel
                    foreach (Query_Projections_Projection_Return projectionRequest in allProjections)
                    {
                        if (projectionRequest.ProjectionState == Query_Projections_Projection_Return.QueryProjectionState.Queued)
                        {
                            ProjectionRequest projRequest = new ProjectionRequest()
                            {
                                ParentRequestName                 = queryRequest.QueryName,
                                CorrelationIdentifier             = queryRequest.QueryUniqueIdentifier,
                                DomainName                        = "Leagues",
                                AggregateTypeName                 = "League",
                                AggregateInstanceUniqueIdentifier = projectionRequest.Projection.InstanceKey,
                                AsOfDate       = null,
                                ProjectionName = projectionRequest.Projection.ProjectionTypeName
                            };

                            // mark it as in-flight
                            resp = await context.CallActivityAsync <ActivityResponse>("LogQueryProjectionInFlightActivity", projRequest);

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

                            // and start running it...
                            allProjectionTasks.Add(context.CallActivityAsync <ProjectionResultsRecord <Get_League_Summary_Definition_Return> >("RunLeagueSummaryInformationProjectionActivity", projRequest));
                        }
                    }

                    #region Logging
                    if (null != log)
                    {
                        log.LogInformation($"Running {allProjectionTasks.Count } projections in parallel");
                    }
                    #endregion

                    // and persist their results to the query
                    context.SetCustomStatus($"Running {allProjectionTasks.Count } projections in parallel");

                    await Task.WhenAll(allProjectionTasks);

                    #region Logging
                    if (null != log)
                    {
                        log.LogInformation($"Completed running {allProjectionTasks.Count } projections in parallel");
                    }
                    #endregion

                    foreach (var returnValue in allProjectionTasks)
                    {
                        ProjectionResultsRecord <Get_League_Summary_Definition_Return> projectionResponse = returnValue.Result;
                        // add in the extra details
                        projectionResponse.CorrelationIdentifier = queryRequest.QueryUniqueIdentifier;
                        projectionResponse.ParentRequestName     = queryRequest.QueryName;
                        // log the result...
                        resp = await context.CallActivityAsync <ActivityResponse>("LogQueryProjectionResultActivity", projectionResponse);

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


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

            return(resp);
        }