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