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(); }
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); }
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); }
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); }
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); }