Beispiel #1
0
        public async Task Handle(StartIngestCommand command)
        {
            // We currently assume that the service that have sent the StartIngestCommand has already verified that the caller has authority
            // to invoke the specified submission agreement, so we just use the agreement specified.
            SubmissionAgreement submissionAgreement;

            try
            {
                submissionAgreement = _submissionAgreementStore.Get(command.SubmissionAgreementId);
            }
            catch (KeyNotFoundException)
            {
                Debug.WriteLine($"There is no submission agreement with the ID '{command.SubmissionAgreementId}'. Aborting!");
                return;
            }

            var newIngestId        = Guid.NewGuid();
            var ingestStartedEvent = new IngestStarted()
            {
                IngestParameters  = command.IngestParameters,
                ExternalContextId = command.ExternalContextId
            };
            var eventStore = await CaPMIngestEventStore.CreateCaPMEventStore(_stagingStoreContainer, newIngestId).ConfigureAwait(false);

            await eventStore.StoreEvent(ingestStartedEvent, _messageSenderFactory.GetChannel <SerializedEvent>(_componentChannelIdentifierRepository.GetChannelIdentifierFor(IngestEventConstants.ChannelIdentifierCode))).ConfigureAwait(false);

            await CreateIngestPlanBasedOnSubmissionAgreement(eventStore, submissionAgreement).ConfigureAwait(false);

            await _componentPlanExecutor.ExecuteNextComponentInPlan(newIngestId).ConfigureAwait(false);
        }
        public async Task Handle(CompleteComponentWorkCommand command)
        {
            var eventStore = await CaPMIngestEventStore.GetCaPMEventStore(_stagingStoreContainer, command.IngestId);

            var allPreviousEvents = await eventStore.GetStoredEvents();

            //In case the component has already been considered timeout out (or, for some erraneous reason
            //has already reported that it has errored or completed) we want to ignore this message.
            var currentlyExecutingComponent = allPreviousEvents.GetFirstNonCompletedComponentInCurrentPlan();

            if (currentlyExecutingComponent.HasValue && currentlyExecutingComponent.Value.ComponentExecutionId == command.ComponentExecutionId)
            {
                if (currentlyExecutingComponent.Value.IsCompensatingComponent)
                {
                    await eventStore.StoreEvent(new IngestComponentCompensationCompleted
                    {
                        ComponentExecutionId = command.ComponentExecutionId
                    }, _messageSenderFactory.GetChannel <SerializedEvent>(_componentChannelIdentifierRepository.GetChannelIdentifierFor(IngestEventConstants.ChannelIdentifierCode)));
                }
                else
                {
                    await eventStore.StoreEvent(new IngestComponentWorkCompleted()
                    {
                        ComponentExecutionId = command.ComponentExecutionId
                    }, _messageSenderFactory.GetChannel <SerializedEvent>(_componentChannelIdentifierRepository.GetChannelIdentifierFor(IngestEventConstants.ChannelIdentifierCode)));
                }
                await _componentPlanExecutor.ExecuteNextComponentInPlan(command.IngestId);
            }
        }
Beispiel #3
0
        public async Task <IIngestEvent[]> GetAllIngestEvents()
        {
            List <IIngestEvent> results = new List <IngestSaga.Events.IIngestEvent>();

            foreach (var ingestId in await _stagingStoreContainer.GetStoredContextIds())
            {
                var ingestEventStore = await CaPMIngestEventStore.GetCaPMEventStore(_stagingStoreContainer, ingestId);

                results.AddRange(await ingestEventStore.GetStoredEvents().ConfigureAwait(false));
            }
            return(results.ToArray());
        }
        public async Task Handle(FailComponentWorkCommand command)
        {
            var eventStore = await CaPMIngestEventStore.GetCaPMEventStore(_stagingStoreContainer, command.IngestId);

            var allPreviousEvents = await eventStore.GetStoredEvents();

            //In case the component has already been considered timeout out (or, for some erraneous reason
            //has already reported that it has errored or completed) we want to ignore this message.
            var currentlyExecutingComponent = allPreviousEvents.GetFirstNonCompletedComponentInCurrentPlan();

            if (currentlyExecutingComponent.HasValue && currentlyExecutingComponent.Value.ComponentExecutionId == command.ComponentExecutionId)
            {
                var previousPlan = allPreviousEvents.OfType <IngestPlanSet>().Last();
                if (currentlyExecutingComponent.Value.IsCompensatingComponent)
                {
                    await eventStore.StoreEvent(new IngestComponentCompensationFailed()
                    {
                        ComponentExecutionId = command.ComponentExecutionId,
                        Reason = command.Reason
                    }, _messageSenderFactory.GetChannel <SerializedEvent>(_componentChannelIdentifierRepository.GetChannelIdentifierFor(IngestEventConstants.ChannelIdentifierCode)));

                    await _componentPlanExecutor.ExecuteNextComponentInPlan(command.IngestId);
                }
                else
                {
                    await eventStore.StoreEvent(new IngestComponentWorkFailed()
                    {
                        ComponentExecutionId = command.ComponentExecutionId,
                        Reason = command.Reason
                    }, _messageSenderFactory.GetChannel <SerializedEvent>(_componentChannelIdentifierRepository.GetChannelIdentifierFor(IngestEventConstants.ChannelIdentifierCode)));

                    var ingestPlan = new IngestPlanSet()
                    {
                        IngestPlan = previousPlan.IngestPlan
                                     .Reverse()
                                     //Only compensate actions which have finished successfully
                                     .Where(p => p.ComponentExecutionId == command.ComponentExecutionId || allPreviousEvents.OfType <IngestComponentWorkCompleted>().Select(e => e.ComponentExecutionId).Contains(p.ComponentExecutionId))
                                     .Select((eventToCompensate, index) => new IngestPlanSet.IngestPlanEntry()
                        {
                            ComponentCode           = eventToCompensate.ComponentCode,
                            ComponentSettings       = eventToCompensate.ComponentSettings,
                            ComponentExecutionId    = Guid.NewGuid(),
                            IsCompensatingComponent = true,
                            Order = (uint)index
                        }).ToArray()
                    };
                    await eventStore.StoreEvent(ingestPlan, _messageSenderFactory.GetChannel <SerializedEvent>(_componentChannelIdentifierRepository.GetChannelIdentifierFor(IngestEventConstants.ChannelIdentifierCode)));

                    await _componentPlanExecutor.ExecuteNextComponentInPlan(command.IngestId);
                }
            }
        }
Beispiel #5
0
 private async Task CreateIngestPlanBasedOnSubmissionAgreement(CaPMIngestEventStore eventStore, SubmissionAgreement submissionAgreement)
 {
     var ingestPlan = new IngestPlanSet()
     {
         IngestPlan = submissionAgreement.ProcessComponents.Select((processComponent, index) => new IngestPlanSet.IngestPlanEntry()
         {
             ComponentCode             = processComponent.ComponentCode,
             ComponentExecutionId      = Guid.NewGuid(),
             ExecutionTimeoutInSeconds = processComponent.ExecutionTimeoutInSeconds,
             ComponentSettings         = processComponent.ComponentSettings,
             IsCompensatingComponent   = false,
             Order = (uint)index
         }).ToArray()
     };
     await eventStore.StoreEvent(ingestPlan, _messageSenderFactory.GetChannel <SerializedEvent>(_componentChannelIdentifierRepository.GetChannelIdentifierFor(IngestEventConstants.ChannelIdentifierCode)));
 }
Beispiel #6
0
        public async Task Handle(TimeoutComponentWorkCommand command)
        {
            var capmEventStore = await CaPMIngestEventStore.GetCaPMEventStore(_stagingStoreContainer, command.IngestId);

            var storedEvents = await capmEventStore.GetStoredEvents();

            //If the currently executing component is the one that is supposed to time out, we'll send
            //a message that the component failed due to timeout. Otherwise, the component this timeout
            //message is about a component which has already completed its work, in which case we just
            //ignore this message
            if (command.ComponentExecutionId.MatchesCurrentlyExecutingComponentExecutionId(storedEvents))
            {
                await _messageSenderFactory.GetChannel <FailComponentWorkCommand>(command.ComponentTimeoutMessageChannel).Send(new FailComponentWorkCommand()
                {
                    ComponentExecutionId = command.ComponentExecutionId,
                    IngestId             = command.IngestId,
                    Reason = "The component work processing timed out."
                });
            }
        }
 private Task <CaPMIngestEventStore> GetCaPMEventStore(Guid ingestId)
 {
     return(CaPMIngestEventStore.GetCaPMEventStore(_stagingStoreContainer, ingestId));
 }