public static SpanEquipment Apply(SpanEquipment existingSpanEquipment, SpanEquipmentMerged @event)
 {
     return(existingSpanEquipment with
     {
         NodesOfInterestIds = @event.NodesOfInterestIds
     });
 }
        private ValidatedRouteNetworkWalk GetInterestInformation(SpanEquipment spanEquipment)
        {
            // Get interest information from existing span equipment
            var interestQueryResult = _queryDispatcher.HandleAsync <GetRouteNetworkDetails, Result <GetRouteNetworkDetailsResult> >(new GetRouteNetworkDetails(new InterestIdList()
            {
                spanEquipment.WalkOfInterestId
            })).Result;

            if (interestQueryResult.IsFailed)
            {
                throw new ApplicationException($"Got unexpected error result: {interestQueryResult.Errors.First().Message} trying to query interest information for span equipment: {spanEquipment.Id} walk of interest id: {spanEquipment.WalkOfInterestId}");
            }

            if (interestQueryResult.Value.Interests == null)
            {
                throw new ApplicationException($"Error querying interest information belonging to span equipment with id: {spanEquipment.Id}. No interest information returned from route network service.");
            }

            if (!interestQueryResult.Value.Interests.TryGetValue(spanEquipment.WalkOfInterestId, out var routeNetworkInterest))
            {
                throw new ApplicationException($"Error querying interest information belonging to span equipment with id: {spanEquipment.Id}. No interest information returned from route network service.");
            }

            return(new ValidatedRouteNetworkWalk(routeNetworkInterest.RouteNetworkElementRefs));
        }
 public static SpanEquipment Apply(SpanEquipment existingSpanEquipment, SpanEquipmentManufacturerChanged @event)
 {
     return(existingSpanEquipment with
     {
         ManufacturerId = @event.ManufacturerId
     });
 }
 public static SpanEquipment Apply(SpanEquipment existingSpanEquipment, SpanEquipmentMarkingInfoChanged @event)
 {
     return(existingSpanEquipment with
     {
         MarkingInfo = @event.MarkingInfo
     });
 }
        public static bool IsPassThrough(this SpanEquipment spanEquipment, RouteNetworkElementRelatedData data)
        {
            if (spanEquipment.NodesOfInterestIds.First() != data.RouteNetworkElementId && spanEquipment.NodesOfInterestIds.Last() != data.RouteNetworkElementId)
            {
                return(true);
            }

            return(false);
        }
        public static SpanEquipment Apply(SpanEquipment existingSpanEquipment, SpanSegmentsConnectedToSimpleTerminals @event)
        {
            List <SpanStructure> newStructures = new List <SpanStructure>();

            // Create dictionary of cuts for fast lookup
            Dictionary <Guid, SpanSegmentToSimpleTerminalConnectInfo> spanSegmentConnectInfoBySegmentId = @event.Connects.ToDictionary(c => c.SegmentId);

            // Loop though all span structures
            for (UInt16 structureIndex = 0; structureIndex < existingSpanEquipment.SpanStructures.Length; structureIndex++)
            {
                var existingSpanStructure = existingSpanEquipment.SpanStructures[structureIndex];

                List <SpanSegment> newSegments = new List <SpanSegment>();

                // Loop through all span segments
                foreach (var existingSegment in existingSpanStructure.SpanSegments)
                {
                    // If connect info exists
                    if (spanSegmentConnectInfoBySegmentId.TryGetValue(existingSegment.Id, out var spanSegmentConnectInfo))
                    {
                        if (spanSegmentConnectInfo.ConnectionDirection == SpanSegmentToTerminalConnectionDirection.FromSpanSegmentToTerminal)
                        {
                            newSegments.Add(
                                existingSegment with {
                                ToTerminalId = spanSegmentConnectInfo.TerminalId
                            }
                                );
                        }
                        else
                        {
                            newSegments.Add(
                                existingSegment with {
                                FromTerminalId = spanSegmentConnectInfo.TerminalId
                            }
                                );
                        }
                    }
                    else
                    {
                        newSegments.Add(existingSegment);
                    }
                }

                newStructures.Add(
                    existingSpanStructure with
                {
                    SpanSegments = newSegments.ToArray()
                }
                    );
            }

            return(existingSpanEquipment with
            {
                SpanStructures = newStructures.ToArray()
            });
        }
        public void AddDisconnectedSegment(SpanEquipment spanEquipment, UInt16 structureIndex, UInt16 segmentIndex)
        {
            var spanSegment = spanEquipment.SpanStructures[structureIndex].SpanSegments[segmentIndex];

            var disconnectedGraphSegment = new UtilityGraphDisconnectedSegment(spanEquipment.Id, structureIndex, segmentIndex);

            if (!_graphElementsById.TryAdd(spanSegment.Id, disconnectedGraphSegment))
            {
                throw new ArgumentException($"A span segment with id: {spanSegment.Id} already exists in the graph.");
            }
        }
        public static SpanEquipment Apply(SpanEquipment existingSpanEquipment, SpanSegmentDisconnectedFromTerminal @event)
        {
            List <SpanStructure> newStructures = new List <SpanStructure>();

            // Loop though all span structures
            for (UInt16 structureIndex = 0; structureIndex < existingSpanEquipment.SpanStructures.Length; structureIndex++)
            {
                var existingSpanStructure = existingSpanEquipment.SpanStructures[structureIndex];

                List <SpanSegment> newSegments = new List <SpanSegment>();

                // Loop through all span segments
                foreach (var existingSegment in existingSpanStructure.SpanSegments)
                {
                    // If disconnect
                    if (existingSegment.Id == @event.SpanSegmentId)
                    {
                        if (existingSegment.FromTerminalId == @event.TerminalId)
                        {
                            newSegments.Add(
                                existingSegment with {
                                FromTerminalId = Guid.Empty
                            }
                                );
                        }
                        else if (existingSegment.ToTerminalId == @event.TerminalId)
                        {
                            newSegments.Add(
                                existingSegment with {
                                ToTerminalId = Guid.Empty
                            }
                                );
                        }
                    }
                    else
                    {
                        newSegments.Add(existingSegment);
                    }
                }

                newStructures.Add(
                    existingSpanStructure with
                {
                    SpanSegments = newSegments.ToArray()
                }
                    );
            }

            return(existingSpanEquipment with
            {
                SpanStructures = newStructures.ToArray()
            });
        }
        public static SpanEquipment Apply(SpanEquipment existingSpanEquipment, AdditionalStructuresAddedToSpanEquipment @event)
        {
            List <SpanStructure> newStructures = new List <SpanStructure>();

            // Copy all span structures
            foreach (var existingStructure in existingSpanEquipment.SpanStructures)
            {
                newStructures.Add(existingStructure);
            }

            // Add new ones
            newStructures.AddRange(@event.SpanStructuresToAdd);

            return(existingSpanEquipment with
            {
                SpanStructures = newStructures.ToArray()
            });
        }
        public static SpanEquipment Apply(SpanEquipment existingSpanEquipment, SpanEquipmentAffixedToContainer spanEquipmentAffixedToContainer)
        {
            var newListOfAffixes = new List <SpanEquipmentNodeContainerAffix>();

            if (existingSpanEquipment.NodeContainerAffixes != null)
            {
                foreach (var existingAffix in existingSpanEquipment.NodeContainerAffixes)
                {
                    newListOfAffixes.Add(existingAffix);
                }
            }

            newListOfAffixes.Add(spanEquipmentAffixedToContainer.Affix);

            return(existingSpanEquipment with
            {
                NodeContainerAffixes = newListOfAffixes.ToArray()
            });
        }
        public static SpanEquipment Apply(SpanEquipment existingSpanEquipment, SpanEquipmentDetachedFromContainer @event)
        {
            var newListOfAffixes = new List <SpanEquipmentNodeContainerAffix>();

            if (existingSpanEquipment.NodeContainerAffixes != null)
            {
                foreach (var existingAffix in existingSpanEquipment.NodeContainerAffixes)
                {
                    if (existingAffix.NodeContainerId != @event.NodeContainerId)
                    {
                        newListOfAffixes.Add(existingAffix);
                    }
                }
            }

            return(existingSpanEquipment with
            {
                NodeContainerAffixes = newListOfAffixes.ToArray()
            });
        }
        public static bool IsAttachedToNodeContainer(this SpanEquipment spanEquipment, RouteNetworkElementRelatedData data)
        {
            if (data.NodeContainer == null)
            {
                return(false);
            }

            if (spanEquipment.NodeContainerAffixes != null)
            {
                foreach (var affix in spanEquipment.NodeContainerAffixes)
                {
                    if (affix.NodeContainerId == data.NodeContainer.Id)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        public static SpanEquipment Apply(SpanEquipment existingSpanEquipment, SpanEquipmentSpecificationChanged @event)
        {
            List <SpanStructure> newSpanStructures = new List <SpanStructure>();

            Dictionary <Guid, StructureModificationInstruction> modificationInstructionByStructureId = @event.StructureModificationInstructions.ToDictionary(s => s.StructureId);

            // Modify and delete the existing structures
            foreach (var existingSpanStructure in existingSpanEquipment.SpanStructures)
            {
                if (modificationInstructionByStructureId.ContainsKey(existingSpanStructure.Id))
                {
                    var instruction = modificationInstructionByStructureId[existingSpanStructure.Id];

                    if (instruction.StructureToBeDeleted == true)
                    {
                        // Don't copy the existing structure
                    }
                    else if (instruction.StructureSpecificationIdToBeUpdated != null)
                    {
                        newSpanStructures.Add(existingSpanStructure with {
                            SpecificationId = instruction.StructureSpecificationIdToBeUpdated.Value
                        });
                    }
                }
            }

            // Add eventually new structures
            foreach (var instruction in @event.StructureModificationInstructions)
            {
                if (instruction.NewStructureToBeInserted != null)
                {
                    newSpanStructures.Add(instruction.NewStructureToBeInserted);
                }
            }

            return(existingSpanEquipment with
            {
                SpecificationId = @event.NewSpecificationId,
                SpanStructures = newSpanStructures.ToArray()
            });
        }
        internal void ApplySegmentDisconnect(SpanEquipment spanEquipment, Guid spanSegmentId, Guid terminalId)
        {
            if (!TryGetGraphElement <UtilityGraphConnectedSegment>(spanSegmentId, out var existingSegmentGraphElement))
            {
                throw new ApplicationException($"Cannot find connected span segment graph element with id: {spanSegmentId} processing segment to terminal disconnect.");
            }

            if (!spanEquipment.TryGetSpanSegment(spanSegmentId, out var spanSegmentWithIndexInfo))
            {
                throw new ApplicationException($"Cannot find span segment with id: {spanSegmentId} in span equipment with id: {spanEquipment.Id} ");
            }

            var version = _objectManager.GetLatestCommitedVersion();

            if (existingSegmentGraphElement.InV(version)?.Id == terminalId)
            {
                var trans = _objectManager.CreateTransaction();

                var existingToTerminal     = (UtilityGraphConnectedTerminal)existingSegmentGraphElement.OutV(version);
                var newSegmentGraphElement = new UtilityGraphConnectedSegment(spanSegmentId, null, existingToTerminal, spanEquipment.Id, spanSegmentWithIndexInfo.StructureIndex, spanSegmentWithIndexInfo.SegmentIndex);
                trans.Update(newSegmentGraphElement);
                trans.Commit();

                UpdateDict(spanSegmentId, newSegmentGraphElement);
            }
            else if (existingSegmentGraphElement.OutV(version)?.Id == terminalId)
            {
                var trans = _objectManager.CreateTransaction();

                var existingFromTerminal   = (UtilityGraphConnectedTerminal)existingSegmentGraphElement.InV(version);
                var newSegmentGraphElement = new UtilityGraphConnectedSegment(spanSegmentId, existingFromTerminal, null, spanEquipment.Id, spanSegmentWithIndexInfo.StructureIndex, spanSegmentWithIndexInfo.SegmentIndex);
                trans.Update(newSegmentGraphElement);

                trans.Commit();
                UpdateDict(spanSegmentId, newSegmentGraphElement);
            }
            else
            {
                throw new ApplicationException($"Cannot find any connection to terminal with id: {terminalId} in span segment with id: {spanSegmentId} in span equipment with id: {spanEquipment.Id}");
            }
        }
        private static Guid[] CreateNewNodeOfInterestIdListWith(SpanEquipment existingSpanEquipment, Guid cutNodeOfInterestId, UInt16 newNodeOfInterestIndex)
        {
            if (existingSpanEquipment.NodesOfInterestIds.Contains(cutNodeOfInterestId))
            {
                return(existingSpanEquipment.NodesOfInterestIds);
            }

            var result = new List <Guid>();

            for (UInt16 i = 0; i < newNodeOfInterestIndex; i++)
            {
                result.Add(existingSpanEquipment.NodesOfInterestIds[i]);
            }

            result.Add(cutNodeOfInterestId);

            for (UInt16 i = newNodeOfInterestIndex; i < existingSpanEquipment.NodesOfInterestIds.Length; i++)
            {
                result.Add(existingSpanEquipment.NodesOfInterestIds[i]);
            }

            return(result.ToArray());
        }
        public static SpanEquipment Apply(SpanEquipment existingSpanEquipment, SpanStructureRemoved @event)
        {
            List <SpanStructure> newStructures = new();

            // Copy all span structures
            foreach (var existingStructure in existingSpanEquipment.SpanStructures)
            {
                if (existingStructure.Id == @event.SpanStructureId)
                {
                    newStructures.Add(existingStructure with {
                        Deleted = true
                    });
                }
                else
                {
                    newStructures.Add(existingStructure);
                }
            }

            return(existingSpanEquipment with
            {
                SpanStructures = newStructures.ToArray()
            });
        }
        public static SpanEquipment Apply(SpanEquipment existingSpanEquipment, SpanSegmentsCut spanSegmentsCutEvent)
        {
            // Cut them segments
            List <SpanStructure> newStructures = new List <SpanStructure>();

            // Create dictionary of cuts for fast lookup
            Dictionary <Guid, SpanSegmentCutInfo> spanSegmentCutInfoBySegmentId = spanSegmentsCutEvent.Cuts.ToDictionary(c => c.OldSpanSegmentId);

            // First create a new nodes of interest list with the cut node added
            Guid[] newNodeOfInterestIdList = CreateNewNodeOfInterestIdListWith(existingSpanEquipment, spanSegmentsCutEvent.CutNodeOfInterestId, spanSegmentsCutEvent.CutNodeOfInterestIndex);

            bool nodeOfInterestAlreadyExists = existingSpanEquipment.NodesOfInterestIds.Contains(spanSegmentsCutEvent.CutNodeOfInterestId);

            // Loop though all span structures
            for (UInt16 structureIndex = 0; structureIndex < existingSpanEquipment.SpanStructures.Length; structureIndex++)
            {
                var existingSpanStructure = existingSpanEquipment.SpanStructures[structureIndex];

                List <SpanSegment> newSegments = new List <SpanSegment>();

                // Loop throughh all span segments
                foreach (var existingSegment in existingSpanStructure.SpanSegments)
                {
                    UInt16 fromNodeOfInterestIndexToUse = existingSegment.FromNodeOfInterestIndex;
                    UInt16 toNodeOfInterestIndexToUse   = existingSegment.ToNodeOfInterestIndex;

                    if (!nodeOfInterestAlreadyExists)
                    {
                        if (fromNodeOfInterestIndexToUse >= spanSegmentsCutEvent.CutNodeOfInterestIndex)
                        {
                            fromNodeOfInterestIndexToUse++;
                        }

                        if (toNodeOfInterestIndexToUse >= spanSegmentsCutEvent.CutNodeOfInterestIndex)
                        {
                            toNodeOfInterestIndexToUse++;
                        }
                    }

                    // If cut info exists
                    if (spanSegmentCutInfoBySegmentId.TryGetValue(existingSegment.Id, out var spanSegmentCutInfo))
                    {
                        // Add the first segment
                        newSegments.Add(
                            new SpanSegment(
                                id: spanSegmentCutInfo.NewSpanSegmentId1,
                                fromNodeOfInterestIndex: fromNodeOfInterestIndexToUse,
                                toNodeOfInterestIndex: spanSegmentsCutEvent.CutNodeOfInterestIndex
                                )
                        {
                            FromTerminalId = existingSegment.FromTerminalId
                        }
                            );

                        // Add the second segment
                        newSegments.Add(
                            new SpanSegment(
                                id: spanSegmentCutInfo.NewSpanSegmentId2,
                                fromNodeOfInterestIndex: spanSegmentsCutEvent.CutNodeOfInterestIndex,
                                toNodeOfInterestIndex: toNodeOfInterestIndexToUse
                                )
                        {
                            ToTerminalId = existingSegment.ToTerminalId
                        }
                            );
                    }
                    // If no cut info exists
                    else
                    {
                        if (!nodeOfInterestAlreadyExists)
                        {
                            var newSegment = existingSegment with {
                                FromNodeOfInterestIndex = fromNodeOfInterestIndexToUse, ToNodeOfInterestIndex = toNodeOfInterestIndexToUse
                            };
                            newSegments.Add(newSegment);
                        }
                        else
                        {
                            newSegments.Add(existingSegment);
                        }
                    }
                }

                newStructures.Add(
                    existingSpanStructure with
                {
                    SpanSegments = newSegments.ToArray()
                });
            }

            return(existingSpanEquipment with
            {
                NodesOfInterestIds = newNodeOfInterestIdList,
                SpanStructures = newStructures.ToArray()
            });
        }
 public SpanEquipmentWithConnectsHolder(SpanEquipment spanEquipment)
 {
     SpanEquipment = spanEquipment;
     Connects      = new();
 }
        public void ApplySegmentCut(SpanEquipment spanEquipment, SpanSegmentCutInfo spanSegmentCutInfo)
        {
            var version = _objectManager.GetLatestCommitedVersion();

            var trans = _objectManager.CreateTransaction();

            try
            {
                if (!_graphElementsById.TryGetValue(spanSegmentCutInfo.OldSpanSegmentId, out var oldSegmentGraphElement))
                {
                    throw new ApplicationException($"Cannot find span segment graph element with id: {spanSegmentCutInfo.OldSpanSegmentId} processing segment cut.");
                }

                if (!spanEquipment.TryGetSpanSegment(spanSegmentCutInfo.NewSpanSegmentId1, out var segment1withIndexInfo))
                {
                    throw new ApplicationException($"Cannot find span segment with id: {spanSegmentCutInfo.OldSpanSegmentId} in span equipment: {spanEquipment.Id} ");
                }

                if (!spanEquipment.TryGetSpanSegment(spanSegmentCutInfo.NewSpanSegmentId2, out var segment2withIndexInfo))
                {
                    throw new ApplicationException($"Cannot find span segment with id: {spanSegmentCutInfo.OldSpanSegmentId} in span equipment: {spanEquipment.Id} ");
                }

                // We need to go through all new span segments in the structure, and check if we need update the graph element due to segment index shift
                for (int newSegmentIndex = 0; newSegmentIndex < spanEquipment.SpanStructures[segment1withIndexInfo.StructureIndex].SpanSegments.Length; newSegmentIndex++)
                {
                    var newSegment = spanEquipment.SpanStructures[segment1withIndexInfo.StructureIndex].SpanSegments[newSegmentIndex];

                    if (TryGetGraphElement <IUtilityGraphSegmentRef>(newSegment.Id, out var existingUtilityGraphSegmentRef))
                    {
                        if (existingUtilityGraphSegmentRef.SegmentIndex != newSegmentIndex)
                        {
                            var newUtilityGraphElement = existingUtilityGraphSegmentRef.CreateWithNewSegmentIndex((ushort)newSegmentIndex);

                            if (newUtilityGraphElement is UtilityGraphConnectedSegment)
                            {
                                trans.Update((UtilityGraphConnectedSegment)newUtilityGraphElement);
                            }

                            UpdateDict(newSegment.Id, newUtilityGraphElement);
                        }
                    }
                }

                // If existing segment is disconnected, it's not in the graph either
                if (oldSegmentGraphElement is UtilityGraphDisconnectedSegment)
                {
                    AddDisconnectedSegment(spanEquipment, segment1withIndexInfo.StructureIndex, segment1withIndexInfo.SegmentIndex);
                    AddDisconnectedSegment(spanEquipment, segment2withIndexInfo.StructureIndex, segment2withIndexInfo.SegmentIndex);
                    RemoveFromDict(spanSegmentCutInfo.OldSpanSegmentId);
                }
                else
                {
                    var oldConnectedGraphElement = (UtilityGraphConnectedSegment)oldSegmentGraphElement;

                    // Create first/left segment
                    if (oldConnectedGraphElement.InV(version) != null)
                    {
                        var newSegment1GraphElement = new UtilityGraphConnectedSegment(spanSegmentCutInfo.NewSpanSegmentId1, (UtilityGraphConnectedTerminal)oldConnectedGraphElement.InV(version), null, spanEquipment.Id, segment1withIndexInfo.StructureIndex, segment1withIndexInfo.SegmentIndex);
                        trans.Add(newSegment1GraphElement);
                        AddToDict(newSegment1GraphElement.Id, newSegment1GraphElement);
                    }
                    // If InV is null, then we end with a disconnected segment
                    else
                    {
                        var newSegment1DisconnectedGraphElement = new UtilityGraphDisconnectedSegment(spanEquipment.Id, segment1withIndexInfo.StructureIndex, segment1withIndexInfo.SegmentIndex);
                        AddToDict(spanSegmentCutInfo.NewSpanSegmentId1, newSegment1DisconnectedGraphElement);
                    }



                    // Create second/right segment
                    if (oldConnectedGraphElement.OutV(version) != null)
                    {
                        var newSegment2GraphElement = new UtilityGraphConnectedSegment(spanSegmentCutInfo.NewSpanSegmentId2, null, (UtilityGraphConnectedTerminal)oldConnectedGraphElement.OutV(version), spanEquipment.Id, segment2withIndexInfo.StructureIndex, segment2withIndexInfo.SegmentIndex);
                        trans.Add(newSegment2GraphElement);
                        AddToDict(newSegment2GraphElement.Id, newSegment2GraphElement);
                    }
                    // If OutV is null, then we end with a disconnected segment
                    else
                    {
                        var newSegment2DisconnectedGraphElement = new UtilityGraphDisconnectedSegment(spanEquipment.Id, segment2withIndexInfo.StructureIndex, segment2withIndexInfo.SegmentIndex);
                        AddToDict(spanSegmentCutInfo.NewSpanSegmentId2, newSegment2DisconnectedGraphElement);
                    }

                    // Remove old segment
                    trans.Delete(oldConnectedGraphElement.Id);
                    RemoveFromDict(oldConnectedGraphElement.Id);
                }
            }
            finally
            {
                trans.Commit();
            }
        }
        internal void ApplySegmentConnect(SpanEquipment spanEquipment, SpanSegmentToSimpleTerminalConnectInfo spanSegmentToConnect)
        {
            if (!_graphElementsById.TryGetValue(spanSegmentToConnect.SegmentId, out var existingSegmentGraphElement))
            {
                throw new ApplicationException($"Cannot find span segment graph element with id: {spanSegmentToConnect.SegmentId} processing segment to terminal connection.");
            }

            if (!spanEquipment.TryGetSpanSegment(spanSegmentToConnect.SegmentId, out var spanSegmentWithIndexInfo))
            {
                throw new ApplicationException($"Cannot find span segment with id: {spanSegmentToConnect.SegmentId} in span equipment with id: {spanEquipment.Id} ");
            }

            var version = _objectManager.GetLatestCommitedVersion();

            var trans = _objectManager.CreateTransaction();

            try
            {
                // Find or create terminal
                var terminalToConnect = _objectManager.GetObject(spanSegmentToConnect.TerminalId, version) as UtilityGraphConnectedTerminal;

                if (terminalToConnect == null)
                {
                    var terminalNodeOfInterestId = spanSegmentToConnect.ConnectionDirection == SpanSegmentToTerminalConnectionDirection.FromSpanSegmentToTerminal ? spanEquipment.NodesOfInterestIds[spanSegmentWithIndexInfo.SpanSegment.ToNodeOfInterestIndex] : spanEquipment.NodesOfInterestIds[spanSegmentWithIndexInfo.SpanSegment.FromNodeOfInterestIndex];
                    terminalToConnect = new UtilityGraphConnectedTerminal(spanSegmentToConnect.TerminalId, terminalNodeOfInterestId);
                    trans.Add(terminalToConnect);
                }

                // If segment has never been connected before
                if (existingSegmentGraphElement is UtilityGraphDisconnectedSegment)
                {
                    var fromNodeToConnect = spanSegmentToConnect.ConnectionDirection == SpanSegmentToTerminalConnectionDirection.FromTerminalToSpanSegment ? terminalToConnect : null;
                    var toNodeToConnect   = spanSegmentToConnect.ConnectionDirection == SpanSegmentToTerminalConnectionDirection.FromSpanSegmentToTerminal ? terminalToConnect : null;

                    var newSegmentGraphElement = new UtilityGraphConnectedSegment(spanSegmentToConnect.SegmentId, fromNodeToConnect, toNodeToConnect, spanEquipment.Id, spanSegmentWithIndexInfo.StructureIndex, spanSegmentWithIndexInfo.SegmentIndex);

                    trans.Add(newSegmentGraphElement);

                    UpdateDict(spanSegmentToConnect.SegmentId, newSegmentGraphElement);
                }
                // We're dealing with update to a segment already connected
                else
                {
                    if (spanSegmentToConnect.ConnectionDirection == SpanSegmentToTerminalConnectionDirection.FromSpanSegmentToTerminal)
                    {
                        var existingFromTerminal = (UtilityGraphConnectedTerminal)((UtilityGraphConnectedSegment)existingSegmentGraphElement).InV(version);

                        var newSegmentGraphElement = new UtilityGraphConnectedSegment(spanSegmentToConnect.SegmentId, existingFromTerminal, terminalToConnect, spanEquipment.Id, spanSegmentWithIndexInfo.StructureIndex, spanSegmentWithIndexInfo.SegmentIndex);
                        trans.Update(newSegmentGraphElement);

                        UpdateDict(spanSegmentToConnect.SegmentId, newSegmentGraphElement);
                    }
                    else
                    {
                        var existingToTerminal = (UtilityGraphConnectedTerminal)((UtilityGraphConnectedSegment)existingSegmentGraphElement).OutV(version);

                        var newSegmentGraphElement = new UtilityGraphConnectedSegment(spanSegmentToConnect.SegmentId, terminalToConnect, existingToTerminal, spanEquipment.Id, spanSegmentWithIndexInfo.StructureIndex, spanSegmentWithIndexInfo.SegmentIndex);
                        trans.Update(newSegmentGraphElement);

                        UpdateDict(spanSegmentToConnect.SegmentId, newSegmentGraphElement);
                    }
                }
            }
            finally
            {
                trans.Commit();
            }
        }
Example #21
0
        public Task <Result> HandleAsync(DisconnectSpanSegmentsAtRouteNode command)
        {
            var utilityNetwork = _eventStore.Projections.Get <UtilityNetworkProjection>();

            if (command.SpanSegmentsToDisconnect.Length != 2)
            {
                return(Task.FromResult(Result.Fail(new DisconnectSpanSegmentsAtRouteNodeError(DisconnectSpanSegmentsAtRouteNodeErrorCodes.INVALID_SPAN_SEGMENT_LIST_MUST_CONTAIN_TWO_SPAN_SEGMENT_IDS, "The list of span segments to connect must contain two span segment ids."))));
            }

            // Because the client do not provide the span equipment ids, but span segment ids only,
            // we need lookup the span equipments via the the utility network graph
            SpanEquipment[] spanEquipmentsToDisconnect = new SpanEquipment[2];

            // Lookup the first span equipment
            if (!utilityNetwork.Graph.TryGetGraphElement <IUtilityGraphSegmentRef>(command.SpanSegmentsToDisconnect[0], out var firstSpanSegmentGraphElement))
            {
                return(Task.FromResult(Result.Fail(new DisconnectSpanSegmentsAtRouteNodeError(DisconnectSpanSegmentsAtRouteNodeErrorCodes.SPAN_SEGMENT_NOT_FOUND, $"Cannot find any span segment in the utility graph with id: {command.SpanSegmentsToDisconnect[0]}"))));
            }

            var firstSpanEquipment = firstSpanSegmentGraphElement.SpanEquipment(utilityNetwork);
            var firstSpanSegment   = firstSpanSegmentGraphElement.SpanSegment(utilityNetwork);

            // Lookup the second span equipment
            if (!utilityNetwork.Graph.TryGetGraphElement <IUtilityGraphSegmentRef>(command.SpanSegmentsToDisconnect[1], out var secondSpanSegmentGraphElement))
            {
                return(Task.FromResult(Result.Fail(new DisconnectSpanSegmentsAtRouteNodeError(DisconnectSpanSegmentsAtRouteNodeErrorCodes.SPAN_SEGMENT_NOT_FOUND, $"Cannot find any span segment in the utility graph with id: {command.SpanSegmentsToDisconnect[1]}"))));
            }

            var secondSpanEquipment = secondSpanSegmentGraphElement.SpanEquipment(utilityNetwork);
            var secondSpanSegment   = secondSpanSegmentGraphElement.SpanSegment(utilityNetwork);

            // Check that the two span segments specified is not the same
            if (firstSpanSegment.Id == secondSpanSegment.Id)
            {
                return(Task.FromResult(Result.Fail(new DisconnectSpanSegmentsAtRouteNodeError(DisconnectSpanSegmentsAtRouteNodeErrorCodes.CANNOT_DISCONNECT_SPAN_SEGMENT_TO_ITSELF, $"Cannot connect the same span segment to itself"))));
            }

            // Check that first span segment is connected to route node
            if (firstSpanEquipment.NodesOfInterestIds[firstSpanSegment.FromNodeOfInterestIndex] != command.RouteNodeId &&
                firstSpanEquipment.NodesOfInterestIds[firstSpanSegment.ToNodeOfInterestIndex] != command.RouteNodeId)
            {
                return(Task.FromResult(Result.Fail(new DisconnectSpanSegmentsAtRouteNodeError(DisconnectSpanSegmentsAtRouteNodeErrorCodes.SPAN_SEGMENT_IS_NOT_RELATED_TO_ROUTE_NODE, $"The span segment with id: {firstSpanSegment.Id} is not related to route node: {command.RouteNodeId} in any way. Please check command arguments."))));
            }

            // Check that second span segment is connected to route node
            if (secondSpanEquipment.NodesOfInterestIds[secondSpanSegment.FromNodeOfInterestIndex] != command.RouteNodeId &&
                secondSpanEquipment.NodesOfInterestIds[secondSpanSegment.ToNodeOfInterestIndex] != command.RouteNodeId)
            {
                return(Task.FromResult(Result.Fail(new DisconnectSpanSegmentsAtRouteNodeError(DisconnectSpanSegmentsAtRouteNodeErrorCodes.SPAN_SEGMENT_IS_NOT_RELATED_TO_ROUTE_NODE, $"The span segment with id: {secondSpanSegment.Id} is not related to route node: {command.RouteNodeId} in any way. Please check command arguments."))));
            }

            // Check that the two segments are connected
            HashSet <Guid> firstSegmentTerminalIds = new HashSet <Guid>();

            if (firstSpanSegment.FromTerminalId != Guid.Empty)
            {
                firstSegmentTerminalIds.Add(firstSpanSegment.FromTerminalId);
            }
            if (firstSpanSegment.ToTerminalId != Guid.Empty)
            {
                firstSegmentTerminalIds.Add(firstSpanSegment.ToTerminalId);
            }

            Guid sharedTerminalId = Guid.Empty;

            if (firstSegmentTerminalIds.Contains(secondSpanSegment.FromTerminalId))
            {
                sharedTerminalId = secondSpanSegment.FromTerminalId;
            }
            else if (firstSegmentTerminalIds.Contains(secondSpanSegment.ToTerminalId))
            {
                sharedTerminalId = secondSpanSegment.ToTerminalId;
            }

            if (sharedTerminalId == Guid.Empty)
            {
                return(Task.FromResult(Result.Fail(new DisconnectSpanSegmentsAtRouteNodeError(DisconnectSpanSegmentsAtRouteNodeErrorCodes.SPAN_SEGMENTS_ARE_NOT_CONNECTED, $"The span segment with id: {firstSpanSegment.Id} and The span segment with id: {secondSpanSegment.Id} is not connected in route node: {command.RouteNodeId}. Please check command arguments."))));
            }

            var commandContext = new CommandContext(command.CorrelationId, command.CmdId, command.UserContext);

            if (firstSpanEquipment.Id != secondSpanEquipment.Id)
            {
                // Disconnect the first span equipment from the terminal
                var firstSpanEquipmentAR = _eventStore.Aggregates.Load <SpanEquipmentAR>(firstSpanEquipment.Id);

                var firstSpanEquipmentConnectResult = firstSpanEquipmentAR.DisconnectSegmentFromTerminal(
                    cmdContext: commandContext,
                    spanSegmentId: firstSpanSegment.Id,
                    terminalId: sharedTerminalId
                    );

                if (!firstSpanEquipmentConnectResult.IsSuccess)
                {
                    return(Task.FromResult(firstSpanEquipmentConnectResult));
                }

                // Disconnect the second span equipment from the terminal
                var secondSpanEquipmentAR = _eventStore.Aggregates.Load <SpanEquipmentAR>(secondSpanEquipment.Id);

                var secondSpanEquipmentConnectResult = secondSpanEquipmentAR.DisconnectSegmentFromTerminal(
                    cmdContext: commandContext,
                    spanSegmentId: secondSpanSegment.Id,
                    terminalId: sharedTerminalId
                    );

                if (!secondSpanEquipmentConnectResult.IsSuccess)
                {
                    return(Task.FromResult(secondSpanEquipmentConnectResult));
                }

                _eventStore.Aggregates.Store(firstSpanEquipmentAR);
                _eventStore.Aggregates.Store(secondSpanEquipmentAR);

                NotifyExternalServicesAboutChange(command.RouteNodeId, new Guid[] { firstSpanEquipment.Id, secondSpanEquipment.Id });
            }
            else
            {
                // Disconnect the first span equipment from the terminal
                var spanEquipmentAR = _eventStore.Aggregates.Load <SpanEquipmentAR>(firstSpanEquipment.Id);

                var firstConnectResult = spanEquipmentAR.DisconnectSegmentFromTerminal(
                    cmdContext: commandContext,
                    spanSegmentId: firstSpanSegment.Id,
                    terminalId: sharedTerminalId
                    );

                if (!firstConnectResult.IsSuccess)
                {
                    return(Task.FromResult(firstConnectResult));
                }

                var secondConnectResult = spanEquipmentAR.DisconnectSegmentFromTerminal(
                    cmdContext: commandContext,
                    spanSegmentId: secondSpanSegment.Id,
                    terminalId: sharedTerminalId
                    );

                if (!secondConnectResult.IsSuccess)
                {
                    return(Task.FromResult(secondConnectResult));
                }

                _eventStore.Aggregates.Store(spanEquipmentAR);

                NotifyExternalServicesAboutChange(command.RouteNodeId, new Guid[] { spanEquipmentAR.Id });
            }

            return(Task.FromResult(Result.Ok()));
        }
Example #22
0
 private string GetOrderByKey(SpanEquipment spanSegment)
 {
     return(spanSegment.SpecificationId.ToString() + (spanSegment.MarkingInfo?.MarkingColor));
 }
 public static bool IsMultiLevel(this SpanEquipment spanEquipment, RouteNetworkElementRelatedData data)
 {
     return(data.SpanEquipmentSpecifications[spanEquipment.SpecificationId].IsMultiLevel);
 }