Example #1
0
        public async void ValidatedWalkEqualTest_ShouldFail()
        {
            // We create two walks that are not equal
            var validateInterestCommand1 = new ValidateWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), new RouteNetworkElementIdList()
            {
                TestRouteNetwork.S1, TestRouteNetwork.S2
            });
            var validateResult1 = await _commandDispatcher.HandleAsync <ValidateWalkOfInterest, Result <ValidatedRouteNetworkWalk> >(validateInterestCommand1);

            var validateInterestCommand2 = new ValidateWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), new RouteNetworkElementIdList()
            {
                TestRouteNetwork.S1
            });
            var validateResult2 = await _commandDispatcher.HandleAsync <ValidateWalkOfInterest, Result <ValidatedRouteNetworkWalk> >(validateInterestCommand2);


            // Assert
            validateResult1.IsSuccess.Should().BeTrue();
            validateResult2.IsSuccess.Should().BeTrue();

            var walk1 = new ValidatedRouteNetworkWalk(validateResult1.Value.RouteNetworkElementRefs);
            var walk2 = new ValidatedRouteNetworkWalk(validateResult2.Value.RouteNetworkElementRefs);

            walk1.Equals(walk2).Should().BeFalse();
        }
Example #2
0
        public async void ValidatedWalkEqualTest_ShouldSucceed()
        {
            // We create two walks. One that goes CO_1 -> HH_1 -> HH_2 -> to CC_1, and one that goes the opposite way.
            // These two walks are to be treated as equal

            var validateInterestForwardCommand = new ValidateWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), new RouteNetworkElementIdList()
            {
                TestRouteNetwork.S2, TestRouteNetwork.S1, TestRouteNetwork.S4
            });
            var validateResultForward = await _commandDispatcher.HandleAsync <ValidateWalkOfInterest, Result <ValidatedRouteNetworkWalk> >(validateInterestForwardCommand);

            var validateInterestReversedCommand = new ValidateWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), new RouteNetworkElementIdList()
            {
                TestRouteNetwork.S4, TestRouteNetwork.S2, TestRouteNetwork.S1
            });
            var validateResultReversed = await _commandDispatcher.HandleAsync <ValidateWalkOfInterest, Result <ValidatedRouteNetworkWalk> >(validateInterestReversedCommand);


            // Assert
            validateResultForward.IsSuccess.Should().BeTrue();
            validateResultReversed.IsSuccess.Should().BeTrue();
            validateResultForward.Value.FromNodeId.Should().Be(TestRouteNetwork.CO_1);
            validateResultReversed.Value.FromNodeId.Should().Be(TestRouteNetwork.CC_1);

            var walk1 = new ValidatedRouteNetworkWalk(validateResultForward.Value.RouteNetworkElementRefs);
            var walk2 = new ValidatedRouteNetworkWalk(validateResultReversed.Value.RouteNetworkElementRefs);

            walk1.Equals(walk2).Should().BeTrue();
        }
        public Result <RouteNetworkInterest> UpdateRouteNetworkElements(CommandContext cmdContext, RouteNetworkInterest walkOfInterest, InterestsProjection interestProjection, WalkValidator walkValidator)
        {
            if (walkOfInterest.Kind != RouteNetworkInterestKindEnum.WalkOfInterest)
            {
                return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_KIND_MUST_BE_WALK_OF_INTEREST, "Interest kind must be WalkOfInterest")));
            }

            if (walkOfInterest.Id == Guid.Empty)
            {
                return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_ID_CANNOT_BE_EMPTY, $"{RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_ID_CANNOT_BE_EMPTY}: Interest id cannot be empty")));
            }

            if (interestProjection.GetInterest(walkOfInterest.Id).IsFailed)
            {
                return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_DONT_EXISTS, $"{RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_DONT_EXISTS}: An interest with id: {walkOfInterest.Id} could not be found")));
            }

            var walkValidationResult = walkValidator.ValidateWalk(walkOfInterest.RouteNetworkElementRefs);

            if (walkValidationResult.IsFailed)
            {
                return(Result.Fail(walkValidationResult.Errors.First()));
            }

            if (_interest == null)
            {
                throw new ApplicationException("Unexpected aggreagate state. Interest state must be non-null when this event is processed.");
            }

            // Reverse walk if one of its ends are opposite of existing walk ends
            var existingWalk = new ValidatedRouteNetworkWalk(_interest.RouteNetworkElementRefs);
            var newWalk      = new ValidatedRouteNetworkWalk(walkValidationResult.Value);

            if (newWalk.FromNodeId == existingWalk.ToNodeId || newWalk.ToNodeId == existingWalk.FromNodeId)
            {
                newWalk = newWalk.Reverse();
            }

            RaiseEvent(
                new WalkOfInterestRouteNetworkElementsModified(this.Id, newWalk.RouteNetworkElementRefs)
            {
                CorrelationId = cmdContext.CorrelationId,
                IncitingCmdId = cmdContext.CmdId,
                UserName      = cmdContext.UserContext?.UserName,
                WorkTaskId    = cmdContext.UserContext?.WorkTaskId
            }
                );

            if (_interest == null)
            {
                throw new ApplicationException("Unexpected aggreagate state. Interest must be non-null after WalkOfInterestRegistered has been raised.");
            }

            return(Result.Ok <RouteNetworkInterest>(_interest));
        }
        private RouteNetworkElementIdList MergeWalks(ValidatedRouteNetworkWalk firstSpanEquipmentWalk, ValidatedRouteNetworkWalk secondSpanEquipmentWalk)
        {
            var result = new RouteNetworkElementIdList();

            // first span equipment -> second span equipment
            if (firstSpanEquipmentWalk.ToNodeId == secondSpanEquipmentWalk.FromNodeId)
            {
                result.AddRange(firstSpanEquipmentWalk.SegmentIds);
                result.AddRange(secondSpanEquipmentWalk.SegmentIds);
            }
            // first span equipment -> second span equipment (reversed)
            else if (firstSpanEquipmentWalk.ToNodeId == secondSpanEquipmentWalk.ToNodeId)
            {
                secondSpanEquipmentWalk = secondSpanEquipmentWalk.Reverse();

                result.AddRange(firstSpanEquipmentWalk.SegmentIds);
                result.AddRange(secondSpanEquipmentWalk.SegmentIds);
            }
            // second span equipment -> first span equipment
            else if (firstSpanEquipmentWalk.FromNodeId == secondSpanEquipmentWalk.ToNodeId)
            {
                result.AddRange(secondSpanEquipmentWalk.SegmentIds);
                result.AddRange(firstSpanEquipmentWalk.SegmentIds);
            }
            // second span equipment (reversed) -> first span equipment
            else if (firstSpanEquipmentWalk.FromNodeId == secondSpanEquipmentWalk.FromNodeId)
            {
                secondSpanEquipmentWalk = secondSpanEquipmentWalk.Reverse();

                result.AddRange(secondSpanEquipmentWalk.SegmentIds);
                result.AddRange(firstSpanEquipmentWalk.SegmentIds);
            }
            else
            {
                throw new ApplicationException("Merge Walk logic is broken");
            }

            return(result);
        }
Example #5
0
        private RouteNetworkElementIdList CreateNewRouteNetworkElementIdListFromSplit(RouteNetworkElementIdList existingRouteNetworkElementIds, Guid removedSegmentId, Guid newNodeId, RouteSegmentAdded newFromSegmentEvent, RouteSegmentAdded newToSegmentEvent)
        {
            RouteNetworkElementIdList result = new RouteNetworkElementIdList();

            for (int i = 0; i < existingRouteNetworkElementIds.Count; i++)
            {
                var existingId = existingRouteNetworkElementIds[i];

                if (existingId == removedSegmentId)
                {
                    // Check if the from segment is the one connected to the from node of the removed segment in the walk
                    if (newFromSegmentEvent.FromNodeId == existingRouteNetworkElementIds[i - 1] || newFromSegmentEvent.ToNodeId == existingRouteNetworkElementIds[i - 1])
                    {
                        // The from segment is comming first
                        result.Add(newFromSegmentEvent.SegmentId);
                        result.Add(newNodeId);
                        result.Add(newToSegmentEvent.SegmentId);
                    }
                    else
                    {
                        // The to segment is comming first
                        result.Add(newToSegmentEvent.SegmentId);
                        result.Add(newNodeId);
                        result.Add(newFromSegmentEvent.SegmentId);
                    }
                }
                else
                {
                    result.Add(existingId);
                }
            }

            var walk = new ValidatedRouteNetworkWalk(result);
            RouteNetworkElementIdList segmentsOnly = new();

            segmentsOnly.AddRange(walk.SegmentIds);
            return(segmentsOnly);
        }
        private async void NotifyExternalServicesAboutSpanEquipmentChange(Guid spanEquipmentId, ValidatedRouteNetworkWalk existingWalk, ValidatedRouteNetworkWalk newWalk)
        {
            var routeIdsAffected = new RouteNetworkElementIdList();

            foreach (var id in existingWalk.RouteNetworkElementRefs)
            {
                routeIdsAffected.Add(id);
            }

            foreach (var id in newWalk.RouteNetworkElementRefs)
            {
                if (!routeIdsAffected.Contains(id))
                {
                    routeIdsAffected.Add(id);
                }
            }

            List <IdChangeSet> idChangeSets = new List <IdChangeSet>
            {
                new IdChangeSet("SpanEquipment", ChangeTypeEnum.Modification, new Guid[] { spanEquipmentId })
            };

            var updatedEvent =
                new RouteNetworkElementContainedEquipmentUpdated(
                    eventType: typeof(RouteNetworkElementContainedEquipmentUpdated).Name,
                    eventId: Guid.NewGuid(),
                    eventTimestamp: DateTime.UtcNow,
                    applicationName: "UtilityNetworkService",
                    applicationInfo: null,
                    category: "EquipmentModification.Moved",
                    idChangeSets: idChangeSets.ToArray(),
                    affectedRouteNetworkElementIds: routeIdsAffected.ToArray()
                    );

            await _externalEventProducer.Produce(_topicName, updatedEvent);
        }
Example #7
0
        private async void NotifyExternalServicesAboutSpanEquipmentChange(Guid spanEquipmentId, ValidatedRouteNetworkWalk walk)
        {
            List <IdChangeSet> idChangeSets = new List <IdChangeSet>
            {
                new IdChangeSet("SpanEquipment", ChangeTypeEnum.Modification, new Guid[] { spanEquipmentId })
            };

            var updatedEvent =
                new RouteNetworkElementContainedEquipmentUpdated(
                    eventType: typeof(RouteNetworkElementContainedEquipmentUpdated).Name,
                    eventId: Guid.NewGuid(),
                    eventTimestamp: DateTime.UtcNow,
                    applicationName: "UtilityNetworkService",
                    applicationInfo: null,
                    category: "EquipmentModification.PropertiesUpdated",
                    idChangeSets: idChangeSets.ToArray(),
                    affectedRouteNetworkElementIds: walk.RouteNetworkElementRefs.ToArray()
                    );

            await _externalEventProducer.Produce(_topicName, updatedEvent);
        }
Example #8
0
        private List <RoutingHop> BuildRouteHops(ValidatedRouteNetworkWalk cableWalk, List <ConduitTraceResult> conduitsTraceResult, string externalId)
        {
            List <RoutingHop> result = new();

            // route nodes hash list for quick lookup
            var shortestPathWalkNodeIdHash = cableWalk.NodeIds.ToHashSet <Guid>();

            List <Guid> directlyInRouteNetworkWalk = new();

            var nodeIds    = cableWalk.NodeIds;
            var segmentIds = cableWalk.SegmentIds;

            HashSet <Guid> alreadyUsedSpanSegmentIds = new();

            Guid conduitToNodeId = Guid.Empty;

            for (int nodeIndex = 0; nodeIndex < nodeIds.Count; nodeIndex++)
            {
                var shortestPathTraceNodeId = nodeIds[nodeIndex];

                var nodeIdToFindTraceFrom = conduitToNodeId != Guid.Empty ? conduitToNodeId : shortestPathTraceNodeId;

                System.Diagnostics.Debug.WriteLine($"Trying to find a conduit path from node: {nodeIdToFindTraceFrom}");

                var routeNetworkTrace = FindConduitTraceThatStartOrEndInNode(conduitsTraceResult, shortestPathWalkNodeIdHash, nodeIdToFindTraceFrom, alreadyUsedSpanSegmentIds);

                conduitToNodeId = Guid.Empty;

                if (routeNetworkTrace != null)
                {
                    System.Diagnostics.Debug.WriteLine($" Found conduit from node: {nodeIdToFindTraceFrom} to node: {routeNetworkTrace.ToNodeId}");
                    // If the conduit end on a a node in the shortest path trace we're lucky and happy
                    if (nodeIds.IndexOf(routeNetworkTrace.ToNodeId) > nodeIndex)
                    {
                        // First add eventually directly route network hop
                        if (directlyInRouteNetworkWalk.Count > 0)
                        {
                            directlyInRouteNetworkWalk.Add(segmentIds[nodeIndex - 1]);
                            directlyInRouteNetworkWalk.Add(shortestPathTraceNodeId);

                            result.Add(CreateRouteNetworkHop(directlyInRouteNetworkWalk, externalId));
                            directlyInRouteNetworkWalk.Clear();
                        }

                        result.Add(new RoutingHop(nodeIdToFindTraceFrom, routeNetworkTrace.SpanSegmentId));

                        // That's evil. We  forward the index in the loop to point to the end of trace. But it kind of feels good, like the good old C days :)
                        nodeIndex = nodeIds.IndexOf(routeNetworkTrace.ToNodeId) - 1;

                        // If we hit last node break
                        if (routeNetworkTrace.ToNodeId == cableWalk.ToNodeId)
                        {
                            break;
                        }
                    }
                    // If the conduit ends outside the shortest path trace, we set the next node to the trace end node, and hope a new related conduit is found from there
                    else
                    {
                        result.Add(new RoutingHop(nodeIdToFindTraceFrom, routeNetworkTrace.SpanSegmentId));

                        // We need to rely on the conduit to node, and hope there's a new conduit trace going from there
                        conduitToNodeId = routeNetworkTrace.ToNodeId;

                        // If we hit last node break
                        if (routeNetworkTrace.ToNodeId == cableWalk.ToNodeId)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($" Did not found any conduit paths going from node: {nodeIdToFindTraceFrom}");

                    if (nodeIndex == 0)
                    {
                        directlyInRouteNetworkWalk.Add(shortestPathTraceNodeId);
                    }
                    else
                    {
                        // The node
                        directlyInRouteNetworkWalk.Add(shortestPathTraceNodeId);

                        // Segment after node
                        if (segmentIds.Count > nodeIndex)
                        {
                            directlyInRouteNetworkWalk.Add(segmentIds[nodeIndex]);
                        }
                    }
                }
            }

            // First add eventually directly route network hop in the end of the cable route
            if (directlyInRouteNetworkWalk.Count > 0)
            {
                result.Add(CreateRouteNetworkHop(directlyInRouteNetworkWalk, externalId));
                directlyInRouteNetworkWalk.Clear();
            }

            return(result);
        }