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);
            }
        }
        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);
                }
            }
        }
예제 #3
0
 internal static void Start(IChannelProvider channelProvider, IComponentChannelIdentifierRepository componentChannelIdentifierRepository, IHubContext <IngestEventsHub> hubContext)
 {
     channelProvider.GetMessageSource <SerializedEvent>(componentChannelIdentifierRepository.GetChannelIdentifierFor(IngestEventConstants.ChannelIdentifierCode)).GetChannel().Subscribe(evt =>
     {
         hubContext.Clients.All.SendAsync("onNewEvent", evt.GetEventObject());
     });
 }
        public IDisposable RegisterCommandHandler <Command, CommandHandler>(string messageChannelIdentifierCode)
            where CommandHandler : ICommandHandler <Command>
        {
            ChannelIdentifier messageChannelIdentifier = _componentChannelIdentifierRepository.GetChannelIdentifierFor(messageChannelIdentifierCode);

            return(_channelProvider.RegisterCommandHandler <Command, CommandHandler>(messageChannelIdentifier, _iocLifetimeScope));
        }
        public async Task ExecuteNextComponentInPlan(Guid ingestId)
        {
            var eventStore = await GetCaPMEventStore(ingestId);

            var storedEvents = await eventStore.GetStoredEvents();

            var firstNonCompletedComponentInPlan = storedEvents.GetFirstNonCompletedComponentInCurrentPlan();

            if (firstNonCompletedComponentInPlan.HasValue)
            {
                if (firstNonCompletedComponentInPlan.Value.IsCompensatingComponent)
                {
                    await ExecuteComponentCompensation(ingestId, firstNonCompletedComponentInPlan.Value);
                }
                else
                {
                    await ExecuteComponentWork(ingestId, firstNonCompletedComponentInPlan.Value);
                }
            }
            else
            {
                await eventStore.StoreEvent(new IngestCompleted(), _messageSenderFactory.GetChannel <SerializedEvent>(_componentChannelIdentifierRepository.GetChannelIdentifierFor(IngestEventConstants.ChannelIdentifierCode)));
            }
        }
예제 #6
0
 public async Task Post([FromBody] StartIngestionModel model)
 {
     if (ModelState.IsValid)
     {
         var capmMessageChannelIdentifier = _componentChannelIdentifierRepository.GetChannelIdentifierFor(CaPMSystem.CaPMComponentIdentifier);
         var capmMessageChannel           = _messageSenderFactory.GetChannel <StartIngestCommand>(capmMessageChannelIdentifier);
         await capmMessageChannel.Send(new StartIngestCommand()
         {
             SubmissionAgreementId = model.SubmissionAgreementId,
             IngestParameters      = model.IngestParameters
         });
     }
     else
     {
         throw new ArgumentException("Invalid model posted. " + System.Text.Json.JsonSerializer.Serialize(ModelState));
     }
 }
예제 #7
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);
        }