public void ContinueInnerConduitIntoAnotherMultiConduit(Guid pointOfInterestId, Guid fromConduitSegmentId, Guid toConduitSegmentId, IRouteNetworkState routeNetworkQueryService, IConduitNetworkQueryService conduitNetworkQueryService) { var multiConduitInfo = conduitNetworkQueryService.GetMultiConduitInfo(Id); var fromSegment = multiConduitInfo.Segments.Find(s => s.Id == fromConduitSegmentId); // Junction id Guid junctionId = Guid.NewGuid(); // Find from direction ConduitEndKindEnum fromEndKind = ConduitEndKindEnum.Incomming; if (fromSegment.FromRouteNodeId == pointOfInterestId) { fromEndKind = ConduitEndKindEnum.Outgoing; } RaiseEvent(new MultiConduitInnerConduitConnected { MultiConduitId = Id, PointOfInterestId = pointOfInterestId, InnerConduitSequenceNumber = fromSegment.Line.SequenceNumber, ConnectedEndKind = fromEndKind, ConnectedJunctionId = junctionId }); }
public Task <Unit> Handle(ConnectConduitSegmentCommand request, CancellationToken cancellationToken) { var conduitRelations = conduitNetworkQueryService.GetConduitSegmentsRelatedToPointOfInterest(request.PointOfInterestId); if (!conduitRelations.Any(c => c.Segment.Id == request.FromConduitSegmentId)) { throw new ArgumentException("Cannot find from conduit segment: " + request.FromConduitSegmentId + " in point of interest: " + request.PointOfInterestId); } if (!conduitRelations.Any(c => c.Segment.Id == request.ToConduitSegmentId)) { throw new ArgumentException("Cannot find to conduit segment: " + request.ToConduitSegmentId + " in point of interest: " + request.PointOfInterestId); } var fromConduitSegmentRel = conduitRelations.Single(c => c.Segment.Id == request.FromConduitSegmentId); var toConduitSegmentRel = conduitRelations.Single(c => c.Segment.Id == request.ToConduitSegmentId); // Junction id Guid junctionId = Guid.NewGuid(); // Find from direction ConduitEndKindEnum fromEndKind = ConduitEndKindEnum.Incomming; if (fromConduitSegmentRel.Segment.RelationType(request.PointOfInterestId) == SegmentRelationTypeEnum.Incomming) { fromEndKind = ConduitEndKindEnum.Incomming; } else if (fromConduitSegmentRel.Segment.RelationType(request.PointOfInterestId) == SegmentRelationTypeEnum.Outgoing) { fromEndKind = ConduitEndKindEnum.Outgoing; } else { throw new ArgumentException("From conduit segment: " + request.FromConduitSegmentId + " is " + fromConduitSegmentRel.Segment.RelationType(request.PointOfInterestId).ToString() + ". Must be incomming or outgoing (cut in node) to be connected"); } // Find to direction ConduitEndKindEnum toEndKind = ConduitEndKindEnum.Incomming; if (toConduitSegmentRel.Segment.RelationType(request.PointOfInterestId) == SegmentRelationTypeEnum.Incomming) { toEndKind = ConduitEndKindEnum.Incomming; } else if (toConduitSegmentRel.Segment.RelationType(request.PointOfInterestId) == SegmentRelationTypeEnum.Outgoing) { toEndKind = ConduitEndKindEnum.Outgoing; } else { throw new ArgumentException("To conduit segment: " + request.ToConduitSegmentId + " is " + toConduitSegmentRel.Segment.RelationType(request.PointOfInterestId).ToString() + ". Must be incomming or outgoing (cut in node) to be connected"); } // If connection between inner conduit and multi conduit (flex situation) if (fromConduitSegmentRel.Segment.Line.LineKind == LineKindEnum.InnerConduit && toConduitSegmentRel.Segment.Line.LineKind == LineKindEnum.MultiConduit) { // Connect to inner conduit to junction var fromMultiConduit = repo.Load <MultiConduit>(fromConduitSegmentRel.Segment.Line.Parent.Id); fromMultiConduit.ConnectInnerConduit(request.PointOfInterestId, fromConduitSegmentRel.Segment.Line.SequenceNumber, fromEndKind, junctionId, routeNetworkQueryService, conduitNetworkQueryService); repo.Store(fromMultiConduit); // Create inner conduit in multi conduit var toMultiConduit = repo.Load <MultiConduit>(toConduitSegmentRel.Segment.Line.Id); var toInnerConduitSeqNo = toMultiConduit.AddInnerConduit(((ConduitSegmentInfo)fromConduitSegmentRel.Segment).Conduit.Color, ((ConduitSegmentInfo)fromConduitSegmentRel.Segment).Conduit.OuterDiameter, ((ConduitSegmentInfo)fromConduitSegmentRel.Segment).Conduit.InnerDiameter, routeNetworkQueryService, conduitNetworkQueryService); repo.Store(toMultiConduit); // Connect new inner conduit to junction toMultiConduit.ConnectInnerConduit(request.PointOfInterestId, toInnerConduitSeqNo, toEndKind, junctionId, routeNetworkQueryService, conduitNetworkQueryService); repo.Store(toMultiConduit); } // If connection between inner conduit and inner conduit else if (fromConduitSegmentRel.Segment.Line.LineKind == LineKindEnum.InnerConduit && toConduitSegmentRel.Segment.Line.LineKind == LineKindEnum.InnerConduit) { // Connect from inner conduit to junction var fromMultiConduit = repo.Load <MultiConduit>(fromConduitSegmentRel.Segment.Line.Parent.Id); fromMultiConduit.ConnectInnerConduit(request.PointOfInterestId, fromConduitSegmentRel.Segment.Line.SequenceNumber, fromEndKind, junctionId, routeNetworkQueryService, conduitNetworkQueryService); repo.Store(fromMultiConduit); // Connect from inner conduit to junction var toMultiConduit = repo.Load <MultiConduit>(toConduitSegmentRel.Segment.Line.Parent.Id); toMultiConduit.ConnectInnerConduit(request.PointOfInterestId, toConduitSegmentRel.Segment.Line.SequenceNumber, toEndKind, junctionId, routeNetworkQueryService, conduitNetworkQueryService); repo.Store(toMultiConduit); } else { throw new NotSupportedException("This kind of connection is not supported. Please check code where from this message is thrown"); } return(Unit.Task); }
internal void Connect(Guid pointOfInterestId, ConduitEndKindEnum endKind, Guid junctionId, IRouteNetworkState routeNetworkQueryService, IConduitNetworkQueryService conduitNetworkQueryService) { var singleConduitInfo = conduitNetworkQueryService.GetSingleConduitInfo(Id); // endKind check if (endKind == 0) { throw new ArgumentException("End kind must be specified. Otherwise the system don't know with end of the segment to connect, if a conduit has been cut into two pieces in a node."); } if (!singleConduitInfo.Segments.Exists(s => s.FromRouteNodeId == pointOfInterestId || s.ToRouteNodeId == pointOfInterestId)) { throw new ArgumentException("The single conduit: " + Id + " is not cut at: " + pointOfInterestId); } // Check that conduit is connected at a node part of conduit walk of interest var walkOfInterest = routeNetworkQueryService.GetWalkOfInterestInfo(singleConduitInfo.GetRootConduit().WalkOfInterestId); if (!walkOfInterest.AllNodeIds.Contains(pointOfInterestId)) { throw new ArgumentException("The point of interest: " + pointOfInterestId + " was not found in walk of interest:" + singleConduitInfo.WalkOfInterestId + " of single conduit: " + Id); } ISegment connectingSegment = null; // Check incomming if (endKind == ConduitEndKindEnum.Incomming) { if (!singleConduitInfo.Segments.Exists(s => s.ToRouteNodeId == pointOfInterestId)) { throw new ArgumentException("No segments are incomming to point of interest: " + pointOfInterestId + " in single conduit: " + Id); } connectingSegment = singleConduitInfo.Segments.Find(s => s.ToRouteNodeId == pointOfInterestId); // Check if already connect to a junction if (connectingSegment.ToNodeId != Guid.Empty) { throw new ArgumentException("the incomming segment: " + connectingSegment.Id + " is already connected to a junction: " + connectingSegment.ToNodeId); } } // Check outgoing else { if (!singleConduitInfo.Segments.Exists(s => s.FromRouteNodeId == pointOfInterestId)) { throw new ArgumentException("No segments are outgoing from point of interest: " + pointOfInterestId + " in single conduit: " + Id); } connectingSegment = singleConduitInfo.Segments.Find(s => s.FromRouteNodeId == pointOfInterestId); // Check if already connect to a junction if (connectingSegment.FromNodeId != Guid.Empty) { throw new ArgumentException("the outgoing segment: " + connectingSegment.Id + " is already connected to a junction: " + connectingSegment.FromNodeId); } } RaiseEvent(new SingleConduitConnected { SingleConduitId = Id, PointOfInterestId = pointOfInterestId, ConnectedEndKind = endKind, ConnectedJunctionId = junctionId }); }
internal void ConnectInnerConduit(Guid pointOfInterestId, int sequenceNumber, ConduitEndKindEnum endKind, Guid junctionId, IRouteNetworkState routeNetworkQueryService, IConduitNetworkQueryService conduitNetworkQueryService) { // Point of interest id check if (pointOfInterestId == null || pointOfInterestId == Guid.Empty) { throw new ArgumentException("PointOfInterestId cannot be null or empty"); } // endKind check if (endKind == 0) { throw new ArgumentException("End kind must be specified. Otherwise the system don't know with end of the segment to connect, if a conduit has been cut into two pieces in a node."); } var multiConduitInfo = conduitNetworkQueryService.GetMultiConduitInfo(Id); // Inner conduit number check if (!multiConduitInfo.Children.OfType <ConduitInfo>().Any(i => i.SequenceNumber == sequenceNumber)) { throw new ArgumentException("Cannot find inner conduit number: " + sequenceNumber + " in multi conduit: " + Id); } var singleConduitInfo = conduitNetworkQueryService.GetSingleConduitInfo(multiConduitInfo.Children.OfType <ConduitInfo>().Single(i => i.SequenceNumber == sequenceNumber).Id); if (!singleConduitInfo.Segments.Exists(s => s.FromRouteNodeId == pointOfInterestId || s.ToRouteNodeId == pointOfInterestId)) { throw new ArgumentException("Inner conduit number: " + sequenceNumber + " in multi conduit: " + Id + " is not cut at: " + pointOfInterestId); } // Check that conduit is connected at a node part of conduit walk of interest var walkOfInterest = routeNetworkQueryService.GetWalkOfInterestInfo(multiConduitInfo.WalkOfInterestId); if (!walkOfInterest.AllNodeIds.Contains(pointOfInterestId)) { throw new ArgumentException("The point of interest: " + pointOfInterestId + " was not found in walk of interest:" + multiConduitInfo.WalkOfInterestId + " of multi conduit: " + Id); } // Check incomming if (endKind == ConduitEndKindEnum.Incomming && !multiConduitInfo.Segments.Exists(s => s.ToRouteNodeId == pointOfInterestId)) { throw new ArgumentException("No segments are incomming to point of interest: " + pointOfInterestId + " in multi conduit: " + Id); } // Check outgoing if (endKind == ConduitEndKindEnum.Outgoing && !multiConduitInfo.Segments.Exists(s => s.FromRouteNodeId == pointOfInterestId)) { throw new ArgumentException("No segments are outgoing from point of interest: " + pointOfInterestId + " in multi conduit: " + Id); } ISegment connectingSegment = null; // Check incomming inner conduit if (endKind == ConduitEndKindEnum.Incomming) { if (!singleConduitInfo.Segments.Exists(s => s.ToRouteNodeId == pointOfInterestId)) { throw new ArgumentException("No inner conduit segments are incomming to point of interest: " + pointOfInterestId + " in single conduit: " + Id); } connectingSegment = singleConduitInfo.Segments.Find(s => s.ToRouteNodeId == pointOfInterestId); // Check if already connect to a junction if (connectingSegment.ToNodeId != Guid.Empty) { throw new ArgumentException("the incomming inner conduit segment: " + connectingSegment.Id + " is already connected to a junction: " + connectingSegment.ToNodeId); } } // Check outgoing inner conduit else { if (!singleConduitInfo.Segments.Exists(s => s.FromRouteNodeId == pointOfInterestId)) { throw new ArgumentException("No inner conduit segments are outgoing from point of interest: " + pointOfInterestId + " in single conduit: " + Id); } connectingSegment = singleConduitInfo.Segments.Find(s => s.FromRouteNodeId == pointOfInterestId); // Check if already connect to a junction if (connectingSegment.FromNodeId != Guid.Empty) { throw new ArgumentException("the outgoing inner conduit segment: " + connectingSegment.Id + " is already connected to a junction: " + connectingSegment.FromNodeId); } } RaiseEvent(new MultiConduitInnerConduitConnected { MultiConduitId = Id, PointOfInterestId = pointOfInterestId, InnerConduitSequenceNumber = sequenceNumber, ConnectedEndKind = endKind, ConnectedJunctionId = junctionId }); }
private void ConnectTerminals(ConduitClosureInfo conduitClosure, ConduitInfo singleConduit, Guid pointOfInterestId, Guid junctionId, ConduitEndKindEnum endKind) { var relatedSegments = FindRelatedSegmentInfo(singleConduit, pointOfInterestId, endKind); if (relatedSegments.Count == 1) { var segment = relatedSegments[0].Segment; // Check if terminal with such segment exists if (conduitClosure.Sides.Exists(s => s.Ports.Exists(p => p.Terminals.Exists(t => t.LineSegmentId == segment.Id)))) { var side = conduitClosure.Sides.Find(s => s.Ports.Exists(p => p.Terminals.Exists(t => t.LineSegmentId == segment.Id))); var port = side.Ports.Find(p => p.Terminals.Exists(t => t.LineSegmentId == segment.Id)); var terminal = port.Terminals.Find(t => t.LineSegmentId == segment.Id); ConduitSegmentInfo connectedSegment = null; // Get the segment on the other side of the junction if (segment.FromNodeId == junctionId && segment.FromNode.NeighborElements.OfType <ConduitSegmentInfo>().Any(n => n != segment)) { connectedSegment = segment.FromNode.NeighborElements.OfType <ConduitSegmentInfo>().First(n => n != segment); } else if (segment.ToNodeId == junctionId && segment.ToNode.NeighborElements.OfType <ConduitSegmentInfo>().Any(n => n != segment)) { connectedSegment = segment.ToNode.NeighborElements.OfType <ConduitSegmentInfo>().First(n => n != segment); } // Check if terminal with related segment exisits if (connectedSegment != null && conduitClosure.Sides.Exists(s => s.Ports.Exists(p => p.Terminals.Exists(t => t.LineSegmentId == connectedSegment.Id)))) { var connectedSide = conduitClosure.Sides.Find(s => s.Ports.Exists(p => p.Terminals.Exists(t => t.LineSegmentId == connectedSegment.Id))); var connectedPort = connectedSide.Ports.Find(p => p.Terminals.Exists(t => t.LineSegmentId == connectedSegment.Id)); var connectedTerminal = connectedPort.Terminals.Find(t => t.LineSegmentId == connectedSegment.Id); // Okay, we're safe to connect the two terminals together terminal.ConnectionKind = ConduitClosureInternalConnectionKindEnum.Connected; terminal.ConnectedToSide = connectedSide.Position; terminal.ConnectedToPort = connectedPort.Position; terminal.ConnectedToTerminal = connectedTerminal.Position; connectedTerminal.ConnectionKind = ConduitClosureInternalConnectionKindEnum.Connected; connectedTerminal.ConnectedToSide = side.Position; connectedTerminal.ConnectedToPort = port.Position; connectedTerminal.ConnectedToTerminal = terminal.Position; } } } }
public static void Run(IConduitNetworkQueryService conduitNetworkQueryService, IMediator CommandBus) { Dictionary <string, ConduitBuildInfo> conduitBuildInfos = new Dictionary <string, ConduitBuildInfo>(); // First find all main conduits. // Format ConduitSpecCode-ConduitNumber-(Marking) - i.e. "G10F-1-BL" // Having no underscores (which are used on single conduits that must connected to multi conduits) foreach (var segmentBuildCode in RouteNetworkBuilder._segmentBuildCodes) { var segmentId = segmentBuildCode.Key; var buildCodes = segmentBuildCode.Value; foreach (var buildCode in buildCodes) { // Single conduits (that is connected to a multi conduit) have "_" in spec code if (buildCode.Contains("_")) { var newConduitBuildInfo = new ConduitBuildInfo(); newConduitBuildInfo.BuildCode = buildCode; newConduitBuildInfo.MultiConduit = false; newConduitBuildInfo.BuildCodeSpecificationCode = "Ø12"; // Create build conduit info object, if not exists if (!conduitBuildInfos.ContainsKey(buildCode)) { conduitBuildInfos.Add(buildCode, newConduitBuildInfo); } var conduitBuildInfo = conduitBuildInfos[buildCode]; // Add segment id to build info object conduitBuildInfo.AddRelatedRouteSegmentIdBuildInfo(segmentId); } else // We're delaing with a multi conduit or single conduit not connected { var newConduitBuildInfo = new ConduitBuildInfo(); newConduitBuildInfo.BuildCode = buildCode; string[] buildCodeSplit = buildCode.Split('-'); newConduitBuildInfo.BuildCodeSpecificationCode = buildCodeSplit[0]; newConduitBuildInfo.BuildCodeConduitId = Int32.Parse(buildCodeSplit[1]); if (buildCode.StartsWith("S")) { newConduitBuildInfo.MultiConduit = false; } else { newConduitBuildInfo.MultiConduit = true; } if (buildCodeSplit.Length > 2) { newConduitBuildInfo.BuildCodeMarking = buildCodeSplit[2]; } // Create build conduit info object, if not exists if (!conduitBuildInfos.ContainsKey(buildCode)) { conduitBuildInfos.Add(buildCode, newConduitBuildInfo); } var conduitBuildInfo = conduitBuildInfos[buildCode]; // Add segment id to build info object conduitBuildInfo.AddRelatedRouteSegmentIdBuildInfo(segmentId); } } } // Sort and validate all conduit build infos foreach (var conduitBuildInfo in conduitBuildInfos) { conduitBuildInfo.Value.Prepare(RouteNetworkBuilder._routeGraph); var registerWalkOfInterestCmd = new RegisterWalkOfInterestCommand(); registerWalkOfInterestCmd.WalkOfInterestId = conduitBuildInfo.Value.WalkOfInterestId; // First create walk of interest registerWalkOfInterestCmd.RouteElementIds = RouteNetworkBuilder._routeGraph.GetNodeLinkPathFromLinkPath(conduitBuildInfo.Value.relatedRouteSegmentIds); CommandBus.Send(registerWalkOfInterestCmd).Wait(); // Create multi conduit if (conduitBuildInfo.Value.MultiConduit) { var placeMultiConduitCommand = new PlaceMultiConduitCommand() { MultiConduitId = conduitBuildInfo.Value.Id, WalkOfInterestId = conduitBuildInfo.Value.WalkOfInterestId, DemoDataSpec = conduitBuildInfo.Key }; CommandBus.Send(placeMultiConduitCommand).Wait(); } // Create single conduit else { var placeSingleConduitCommand = new PlaceSingleConduitCommand() { SingleConduitId = conduitBuildInfo.Value.Id, WalkOfInterestId = conduitBuildInfo.Value.WalkOfInterestId, DemoDataSpec = conduitBuildInfo.Key }; CommandBus.Send(placeSingleConduitCommand).Wait(); } } // Do the cuts and connections HashSet <string> cutAlreadDone = new HashSet <string>(); foreach (var segmentBuildCode in RouteNetworkBuilder._segmentBuildCodes) { var segmentId = segmentBuildCode.Key; var buildCodes = segmentBuildCode.Value; foreach (var buildCode in buildCodes) { // Build codes containing _, is where conduits should be connected to each other if (buildCode.Contains("_") && !cutAlreadDone.Contains(buildCode)) { cutAlreadDone.Add(buildCode); // Extract the different values from build code string string[] buildCodeSplit = buildCode.Split('_'); int innerConduitNumberToCut = Int32.Parse(buildCodeSplit[1]); // Find multi conduit to breakout/connect var multiConduitBuildInfo = conduitBuildInfos[buildCodeSplit[0]]; var multiConduitWalkOfInterest = RouteNetworkBuilder._routeGraph.GetNodeLinkPathFromLinkPath(multiConduitBuildInfo.relatedRouteSegmentIds); // Find single conduit that has to be connected to the multi conduit var singleConduitBuildInfo = conduitBuildInfos[buildCode]; var singleConduitSegments = RouteNetworkBuilder._segmentBuildCodes.Where(n => n.Value.Contains(buildCode)).ToList(); // Find segment that har start or end in multi conduit Link singleConduitLink = null; foreach (var singleConduitSegmentId in singleConduitSegments) { singleConduitLink = RouteNetworkBuilder._routeGraph.Links[singleConduitSegmentId.Key]; if (multiConduitWalkOfInterest.Contains(Guid.Parse(singleConduitLink.StartNode.Id))) { break; } if (multiConduitWalkOfInterest.Contains(Guid.Parse(singleConduitLink.EndNode.Id))) { break; } } // find the point of interest (the node where the single conduit connected witht the multi conduit) Guid pointOfInterest = Guid.Empty; ConduitEndKindEnum customerConduitConnectKind = ConduitEndKindEnum.Outgoing; if (multiConduitWalkOfInterest.Contains(Guid.Parse(singleConduitLink.StartNode.Id))) { pointOfInterest = Guid.Parse(singleConduitLink.StartNode.Id); } else if (multiConduitWalkOfInterest.Contains(Guid.Parse(singleConduitLink.EndNode.Id))) { pointOfInterest = Guid.Parse(singleConduitLink.EndNode.Id); customerConduitConnectKind = ConduitEndKindEnum.Outgoing; } if (buildCode == "G12F-1-BL_3") { } // Cut the inner conduit in the multi conduit, if not end if (!(multiConduitWalkOfInterest[0] == pointOfInterest || multiConduitWalkOfInterest[multiConduitWalkOfInterest.Count - 1] == pointOfInterest)) { // First cut the outer conduit, if not already cut if (!conduitNetworkQueryService.CheckIfConduitIsCut(multiConduitBuildInfo.Id, pointOfInterest)) { var cutOuterConduitCommand = new CutOuterConduitCommand() { MultiConduitId = multiConduitBuildInfo.Id, PointOfInterestId = pointOfInterest, }; CommandBus.Send(cutOuterConduitCommand).Wait(); } // Cut the inner conduit var cutInnerConduitCommand = new CutInnerConduitCommand() { MultiConduitId = multiConduitBuildInfo.Id, PointOfInterestId = pointOfInterest, InnerConduitSequenceNumber = innerConduitNumberToCut }; CommandBus.Send(cutInnerConduitCommand).Wait(); } // Junction Guid newJunctionId = Guid.NewGuid(); // Connect inner conduit in the multi conduit var connectInnerConduitCommand = new ConnectInnerConduitToJunction() { MultiConduitId = multiConduitBuildInfo.Id, PointOfInterestId = pointOfInterest, InnerConduitSequenceNumber = innerConduitNumberToCut, ConnectedJunctionId = newJunctionId, ConnectedEndKind = ConduitNetwork.Events.Model.ConduitEndKindEnum.Incomming }; CommandBus.Send(connectInnerConduitCommand).Wait(); // Connect customer conduit to the multi conduit var connectCustomerConduitCommand = new ConnectSingleConduitToJunction() { SingleConduitId = singleConduitBuildInfo.Id, PointOfInterestId = pointOfInterest, ConnectedJunctionId = newJunctionId, ConnectedEndKind = customerConduitConnectKind }; CommandBus.Send(connectCustomerConduitCommand).Wait(); } } } /* * RouteWalkRelationTypeEnum type = RouteWalkRelationTypeEnum.StartNode; * * // Create conduit walk of interests objects * foreach (var networkElementId in nodeLinkIds) * { * migrationBuilder.InsertData( * table: "RouteElementWalkOfInterestRelations", * columns: new[] { "RouteElementId", "WalkOfInterestId", "SeqNo", "Type" }, * values: new object[] { * networkElementId, * walkOfInterestId, * seqNo, * (int)type * } * ); * * if (type == RouteWalkRelationTypeEnum.IntermediateSegment && (seqNo == (nodeLinkIds.Count - 1))) * type = RouteWalkRelationTypeEnum.EndNode; * else if (type == RouteWalkRelationTypeEnum.IntermediateSegment) * type = RouteWalkRelationTypeEnum.IntermediateNode; * else if (type == RouteWalkRelationTypeEnum.StartNode || type == RouteWalkRelationTypeEnum.IntermediateNode) * type = RouteWalkRelationTypeEnum.IntermediateSegment; * else if (type == RouteWalkRelationTypeEnum.EndNode) * { * // do nothing we're finish * } * else * { * throw new NotSupportedException("Something went wrong in route walk relation write logic. Code broken!"); * } * * seqNo++; */ }