private Result MergeSpanEquipment(CommandContext cmdContext, Guid routeNodeId, SpanEquipmentWithConnectsHolder firstSpanEquipment, SpanEquipmentWithConnectsHolder secondSpanEquipment)
        {
            // Merge the first span equipment with the second one
            var firstSpanEquipmentAR = _eventStore.Aggregates.Load <SpanEquipmentAR>(firstSpanEquipment.SpanEquipment.Id);

            var firstSpanEquipmentConnectResult = firstSpanEquipmentAR.Merge(
                cmdContext: cmdContext,
                routeNodeId: routeNodeId,
                secondSpanEquipment.SpanEquipment
                );

            if (firstSpanEquipmentConnectResult.IsFailed)
            {
                return(firstSpanEquipmentConnectResult);
            }

            var firstSpanEquipmentWalk  = GetInterestInformation(firstSpanEquipment.SpanEquipment);
            var secondSpanEquipmentWalk = GetInterestInformation(secondSpanEquipment.SpanEquipment);

            // Update interest of the first span equipment to cover both span equipments
            var newSegmentIds = MergeWalks(firstSpanEquipmentWalk, secondSpanEquipmentWalk);

            var updateWalkOfInterestCommand       = new UpdateWalkOfInterest(firstSpanEquipment.SpanEquipment.WalkOfInterestId, newSegmentIds);
            var updateWalkOfInterestCommandResult = _commandDispatcher.HandleAsync <UpdateWalkOfInterest, Result <RouteNetworkInterest> >(updateWalkOfInterestCommand).Result;

            if (updateWalkOfInterestCommandResult.IsFailed)
            {
                return(updateWalkOfInterestCommandResult);
            }

            // Remove the second span equipment
            var secondSpanEquipmentAR = _eventStore.Aggregates.Load <SpanEquipmentAR>(secondSpanEquipment.SpanEquipment.Id);
            var removeSpanEquipment   = secondSpanEquipmentAR.Remove(cmdContext);

            if (removeSpanEquipment.IsSuccess)
            {
                // Remember to remove the walk of interest as well
                var unregisterInterestCmd       = new UnregisterInterest(secondSpanEquipment.SpanEquipment.WalkOfInterestId);
                var unregisterInterestCmdResult = _commandDispatcher.HandleAsync <UnregisterInterest, Result>(unregisterInterestCmd).Result;

                if (unregisterInterestCmdResult.IsFailed)
                {
                    throw new ApplicationException($"Failed to unregister interest: {secondSpanEquipment.SpanEquipment.WalkOfInterestId} of span equipment: {secondSpanEquipment.SpanEquipment.Id} in RemoveSpanStructureFromSpanEquipmentCommandHandler Error: {unregisterInterestCmdResult.Errors.First().Message}");
                }
            }

            _eventStore.Aggregates.Store(firstSpanEquipmentAR);
            _eventStore.Aggregates.Store(secondSpanEquipmentAR);

            NotifyExternalServicesAboutMerge(firstSpanEquipment.SpanEquipment.Id, updateWalkOfInterestCommandResult.Value.RouteNetworkElementRefs.ToArray());

            return(Result.Ok());
        }
Пример #2
0
        public async void CreateAndRemoveWalkOfInterest_ShouldReturnSuccess()
        {
            // Route network subset used in this test:
            // (CO_1) <- (S1) -> (HH_1)
            var interestId = Guid.NewGuid();

            var walk = new RouteNetworkElementIdList()
            {
                TestRouteNetwork.S1
            };

            var routeNetworkQuery = new GetRouteNetworkDetails(new RouteNetworkElementIdList()
            {
                TestRouteNetwork.CO_1
            })
            {
                RelatedInterestFilter = RelatedInterestFilterOptions.ReferencesFromRouteElementAndInterestObjects
            };

            // Act
            var registerWalkOfInterestCommand       = new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interestId, walk);
            var registerWalkOfInterestCommandResult = await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> > (registerWalkOfInterestCommand);

            Result <GetRouteNetworkDetailsResult> routeNetworkQueryResultBefore = await _queryDispatcher.HandleAsync <GetRouteNetworkDetails, Result <GetRouteNetworkDetailsResult> >(routeNetworkQuery);

            var unregisterWalkOfInterestCommand       = new UnregisterInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interestId);
            var unregisterWalkOfInterestCommandResult = await _commandDispatcher.HandleAsync <UnregisterInterest, Result>(unregisterWalkOfInterestCommand);

            Result <GetRouteNetworkDetailsResult> routeNetworkQueryResultAfter = await _queryDispatcher.HandleAsync <GetRouteNetworkDetails, Result <GetRouteNetworkDetailsResult> >(routeNetworkQuery);

            // Assert command result
            registerWalkOfInterestCommandResult.IsSuccess.Should().BeTrue();
            unregisterWalkOfInterestCommandResult.IsSuccess.Should().BeTrue();

            // Assert query result
            routeNetworkQueryResultBefore.IsSuccess.Should().BeTrue();
            routeNetworkQueryResultBefore.Value.Interests.ContainsKey(interestId).Should().BeTrue();

            routeNetworkQueryResultAfter.IsSuccess.Should().BeTrue();
            routeNetworkQueryResultAfter.Value.Interests.ContainsKey(interestId).Should().BeFalse();
        }
Пример #3
0
        public Task <Result> HandleAsync(RemoveSpanStructureFromSpanEquipment command)
        {
            var utilityNetwork = _eventStore.Projections.Get <UtilityNetworkProjection>();

            // Because the client is not required to provide the span equipment id (that we need to lookup the
            // aggregate root), we look it up via the utility network graph.
            if (!utilityNetwork.Graph.TryGetGraphElement <IUtilityGraphSegmentRef>(command.SpanSegmentId, out var spanSegmentGraphElement))
            {
                return(Task.FromResult(Result.Fail(new RemoveSpanStructureFromSpanEquipmentError(RemoveSpanStructureFromSpanEquipmentErrorCodes.SPAN_SEGMENT_NOT_FOUND, $"Cannot find any span segment in the utility graph with id: {command.SpanSegmentId}"))));
            }

            var spanEquipment = spanSegmentGraphElement.SpanEquipment(utilityNetwork);

            // Get specification
            var specification = _eventStore.Projections.Get <SpanEquipmentSpecificationsProjection>().Specifications[spanEquipment.SpecificationId];

            // Get interest information for span equipment
            var interestQueryResult = _queryDispatcher.HandleAsync <GetRouteNetworkDetails, Result <GetRouteNetworkDetailsResult> >(new GetRouteNetworkDetails(new InterestIdList()
            {
                spanEquipment.WalkOfInterestId
            })).Result;

            if (interestQueryResult.IsFailed)
            {
                throw new ApplicationException($"Got unexpected error result: {interestQueryResult.Errors.First().Message} trying to query interest information for span equipment while processing the RemoveSpanStructureFromSpanEquipment command: " + JsonConvert.SerializeObject(command));
            }

            if (interestQueryResult.Value.Interests == null)
            {
                throw new ApplicationException($"Got null interest result processing RemoveSpanStructureFromSpanEquipment command: " + JsonConvert.SerializeObject(command));
            }

            var commandContext = new CommandContext(command.CorrelationId, command.CmdId, command.UserContext);

            // If outer conduit, that remove entire span equipment
            if (spanSegmentGraphElement.StructureIndex == 0)
            {
                var spanEquipmentAR     = _eventStore.Aggregates.Load <SpanEquipmentAR>(spanEquipment.Id);
                var removeSpanEquipment = spanEquipmentAR.Remove(commandContext);

                if (removeSpanEquipment.IsSuccess)
                {
                    // Remember to remove the walk of interest as well
                    var unregisterInterestCmd       = new UnregisterInterest(spanEquipment.WalkOfInterestId);
                    var unregisterInterestCmdResult = _commandDispatcher.HandleAsync <UnregisterInterest, Result>(unregisterInterestCmd).Result;

                    if (unregisterInterestCmdResult.IsFailed)
                    {
                        throw new ApplicationException($"Failed to unregister interest: {spanEquipment.WalkOfInterestId} of span equipment: {spanEquipment.Id} in RemoveSpanStructureFromSpanEquipmentCommandHandler Error: {unregisterInterestCmdResult.Errors.First().Message}");
                    }

                    _eventStore.Aggregates.Store(spanEquipmentAR);

                    NotifyExternalServicesAboutSpanEquipmentDeletion(spanEquipment.Id, interestQueryResult.Value.Interests[spanEquipment.WalkOfInterestId].RouteNetworkElementRefs);
                }

                return(Task.FromResult(removeSpanEquipment));
            }
            else
            {
                var spanEquipmentAR = _eventStore.Aggregates.Load <SpanEquipmentAR>(spanEquipment.Id);

                var removeSpanStructure = spanEquipmentAR.RemoveSpanStructure(commandContext, specification, spanSegmentGraphElement.StructureIndex);

                if (removeSpanStructure.IsSuccess)
                {
                    _eventStore.Aggregates.Store(spanEquipmentAR);
                    NotifyExternalServicesAboutSpanEquipmentChange(spanEquipment.Id, interestQueryResult.Value.Interests[spanEquipment.WalkOfInterestId].RouteNetworkElementRefs);
                }

                return(Task.FromResult(removeSpanStructure));
            }
        }