public Task <Unit> Handle(CutInnerConduitCommand request, CancellationToken cancellationToken) { // Id check if (request.InnerConduitId == null && request.MultiConduitId == null) { throw new ArgumentException("Either InnerConduitId or MultiConduitId + InnerConduitSequenceNumber must be provided."); } if (request.MultiConduitId == null || request.MultiConduitId == Guid.Empty) { var conduitRelations = conduitNetworkQueryService.GetConduitSegmentsRelatedToPointOfInterest(request.PointOfInterestId); if (!conduitRelations.Any(c => c.Segment.Line.Id == request.InnerConduitId)) { throw new ArgumentException("Cannot find inner conduit with id: " + request.InnerConduitId + " in point of interest: " + request.PointOfInterestId); } var innerConduitSegment = conduitRelations.Find(c => c.Segment.Line.Id == request.InnerConduitId); request.MultiConduitId = ((ConduitInfo)innerConduitSegment.Segment.Line).GetRootConduit().Id; request.InnerConduitSequenceNumber = innerConduitSegment.Segment.Line.SequenceNumber; } var multiConduit = repo.Load <MultiConduit>(request.MultiConduitId); multiConduit.CutInnerConduit(request.InnerConduitSequenceNumber, request.PointOfInterestId, routeNetworkQueryService, conduitNetworkQueryService); repo.Store(multiConduit); return(Unit.Task); }
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++; */ }
public MultiConduitCommandHandler(IMediator commandBus, IConduitClosureRepository conduitClosureRepository, IRouteNetworkState routeNetwork, IConduitNetworkQueryService conduitNetwork) { Description = "API for sending commands to the multi conduit aggregate root"; Field <ConduitInfoType>( "cutOuterConduitCommand", description: "Cut the outer conduit of a multi conduit", arguments: new QueryArguments( new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "pointOfInterestId" }, new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "multiConduitId" } ), resolve: context => { var cutOuterConduitCmd = new CutOuterConduitCommand() { MultiConduitId = context.GetArgument <Guid>("multiConduitId"), PointOfInterestId = context.GetArgument <Guid>("pointOfInterestId") }; try { commandBus.Send(cutOuterConduitCmd).Wait(); } catch (Exception ex) { context.Errors.Add(new ExecutionError(ex.Message, ex)); return(null); } return(conduitNetwork.GetMultiConduitInfo(cutOuterConduitCmd.MultiConduitId)); } ); Field <ConduitInfoType>( "cutInnerConduitCommand", description: "Cut the outer conduit of a multi conduit", arguments: new QueryArguments( new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "pointOfInterestId" }, new QueryArgument <IdGraphType> { Name = "innerConduitId" }, new QueryArgument <IdGraphType> { Name = "multiConduitId" }, new QueryArgument <IntGraphType> { Name = "innerConduitNumber" } ), resolve: context => { var cutInnerConduitCmd = new CutInnerConduitCommand() { MultiConduitId = context.GetArgument <Guid>("multiConduitId"), InnerConduitId = context.GetArgument <Guid>("innerConduitId"), PointOfInterestId = context.GetArgument <Guid>("pointOfInterestId"), InnerConduitSequenceNumber = context.GetArgument <int>("innerConduitNumber") }; try { commandBus.Send(cutInnerConduitCmd).Wait(); } catch (Exception ex) { context.Errors.Add(new ExecutionError(ex.Message, ex)); return(null); } return(conduitNetwork.GetMultiConduitInfo(cutInnerConduitCmd.MultiConduitId)); } ); Field <ConduitInfoType>( "connectInnerConduitToJunction", description: "Connect an inner conduit of the multi conduit to a junction (single conduit connector). The junction/connector will be created automatically.", arguments: new QueryArguments( new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "pointOfInterestId" }, new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "multiConduitId" }, new QueryArgument <NonNullGraphType <ConduitEndKindEnumType> > { Name = "conduitEndKind" }, new QueryArgument <NonNullGraphType <IntGraphType> > { Name = "innerConduitNumber" }, new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "junctionConnectorId" } ), resolve: context => { var connectToJunction = new ConnectInnerConduitToJunction() { MultiConduitId = context.GetArgument <Guid>("multiConduitId"), ConnectedEndKind = context.GetArgument <ConduitEndKindEnum>("conduitEndKind"), PointOfInterestId = context.GetArgument <Guid>("pointOfInterestId"), InnerConduitSequenceNumber = context.GetArgument <int>("innerConduitNumber"), ConnectedJunctionId = context.GetArgument <Guid>("junctionConnectorId") }; try { commandBus.Send(connectToJunction).Wait(); } catch (Exception ex) { context.Errors.Add(new ExecutionError(ex.Message, ex)); return(null); } return(conduitNetwork.GetMultiConduitInfo(connectToJunction.MultiConduitId)); } ); Field <ConduitInfoType>( "connectConduitSegmentToConduitSegment", description: "A convenience function for connecting conduits together. It will automatically create junctions. Also, if the to conduit segment is a multi conduit, the function will automatically create an inner conduit in the to multi conduit of same type as the from single conduit.", arguments: new QueryArguments( new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "pointOfInterestId" }, new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "fromConduitSegmentId" }, new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "toConduitSegmentId" } ), resolve: context => { var connectConduitSegmentCmd = new ConnectConduitSegmentCommand() { PointOfInterestId = context.GetArgument <Guid>("pointOfInterestId"), FromConduitSegmentId = context.GetArgument <Guid>("fromConduitSegmentId"), ToConduitSegmentId = context.GetArgument <Guid>("toConduitSegmentId") }; try { commandBus.Send(connectConduitSegmentCmd).Wait(); } catch (Exception ex) { context.Errors.Add(new ExecutionError(ex.Message, ex)); return(null); } return(null); } ); }