private RouteNetworkInterest[] GetInterestsRelatedToRouteNetworkElements(RouteNetworkElementIdList routeNetworkElementIds) { Dictionary <Guid, RouteNetworkInterest> interestsToBeAddedToResult = new Dictionary <Guid, RouteNetworkInterest>(); var interestsProjection = _eventStore.Projections.Get <InterestsProjection>(); foreach (var routeElementId in routeNetworkElementIds) { // Add relations to the route network element var interestRelationsResult = interestsProjection.GetInterestsByRouteNetworkElementId(routeElementId); if (interestRelationsResult.IsFailed) { throw new ApplicationException($"Unexpected error querying interests related to route network element with id: {routeElementId} {interestRelationsResult.Errors.First()}"); } foreach (var interestRelation in interestRelationsResult.Value) { if (!interestsToBeAddedToResult.ContainsKey(interestRelation.Item1.Id)) { interestsToBeAddedToResult.Add(interestRelation.Item1.Id, interestRelation.Item1); } } } return(interestsToBeAddedToResult.Values.ToArray()); }
public async void CreateValidWalkOfWithNonAjacentSegments_ShouldReturnSuccess() { // Route network subset used in this test: // S5-S6-S9-S11 var interestId = Guid.NewGuid(); var walk = new RouteNetworkElementIdList() { TestRouteNetwork.S9, TestRouteNetwork.S11, TestRouteNetwork.S6, TestRouteNetwork.S5 }; // Act var registerWalkOfInterestCommand = new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interestId, walk); Result registerWalkOfInterestCommandResult = await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> >(registerWalkOfInterestCommand); var routeNetworkQuery = new GetRouteNetworkDetails(new RouteNetworkElementIdList() { TestRouteNetwork.J_2 }) { RelatedInterestFilter = RelatedInterestFilterOptions.ReferencesFromRouteElementAndInterestObjects }; Result <GetRouteNetworkDetailsResult> routeNetworkQueryResult = await _queryDispatcher.HandleAsync <GetRouteNetworkDetails, Result <GetRouteNetworkDetailsResult> >(routeNetworkQuery); // Assert registerWalkOfInterestCommandResult.IsSuccess.Should().BeTrue(); routeNetworkQueryResult.IsSuccess.Should().BeTrue(); routeNetworkQueryResult.Value.Interests[interestId].RouteNetworkElementRefs.Count.Should().Be(9); //routeNetworkQueryResult.Value.Interests[interestId].RouteNetworkElementRefs.Should().Contain(TestRouteNetwork.CO_1); }
public Result <List <IRouteNetworkElement> > GetRouteElements(RouteNetworkElementIdList routeNetworkElementIds, bool createSubstitudesForMissingRouteNetworkElements = false) { var routeNetworkElementFetched = new List <IRouteNetworkElement>(); foreach (var routeElementId in routeNetworkElementIds) { var routeNetworkElement = _routeNetworkState.GetRouteNetworkElement(routeElementId); if (routeNetworkElement == null) { if (createSubstitudesForMissingRouteNetworkElements) { routeNetworkElement = new RouteNode(routeElementId, "[559000,6210000]") { NamingInfo = new NamingInfo() { Name = "#NA" } }; } else { return(Result.Fail <List <IRouteNetworkElement> >($"Cannot find any route network element with id: {routeElementId}")); } } routeNetworkElementFetched.Add(routeNetworkElement as IRouteNetworkElement); } return(Result.Ok <List <IRouteNetworkElement> >(routeNetworkElementFetched)); }
private List <Guid> GetRouteSegmentsBetweenNodes(RouteNetworkElementIdList walkIds, Guid startNodeId, Guid endNodeId) { List <Guid> result = new(); var startNodeIndex = walkIds.IndexOf(startNodeId); var endNodeIndex = walkIds.IndexOf(endNodeId); if (startNodeIndex < 0 || endNodeIndex < 0) { throw new ApplicationException($"Failed to find start node: {startNodeId} or end node {endNodeId} in walk."); } if (startNodeIndex < endNodeIndex) { for (int i = startNodeIndex + 1; i < endNodeIndex; i += 2) { result.Add(walkIds[i]); } } else { for (int i = startNodeIndex - 1; i > endNodeIndex; i -= 2) { result.Add(walkIds[i]); } } return(result); }
public async void ValidateValidWalkWithBothNodeAndSegmentIds_ShouldSucceed() { var walk = new RouteNetworkElementIdList() { TestRouteNetwork.CO_1, TestRouteNetwork.S1, TestRouteNetwork.HH_1, TestRouteNetwork.S2, TestRouteNetwork.HH_2, TestRouteNetwork.S4, TestRouteNetwork.CC_1 }; var validateInterestCommand = new ValidateWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), walk); var validateResult = await _commandDispatcher.HandleAsync <ValidateWalkOfInterest, Result <ValidatedRouteNetworkWalk> >(validateInterestCommand); // Assert validateResult.IsSuccess.Should().BeTrue(); validateResult.Value.NodeIds.Count.Should().Be(4); validateResult.Value.SegmentIds.Count.Should().Be(3); validateResult.Value.NodeIds[0].Should().Be(TestRouteNetwork.CO_1); validateResult.Value.NodeIds[1].Should().Be(TestRouteNetwork.HH_1); validateResult.Value.NodeIds[2].Should().Be(TestRouteNetwork.HH_2); validateResult.Value.NodeIds[3].Should().Be(TestRouteNetwork.CC_1); validateResult.Value.SegmentIds[0].Should().Be(TestRouteNetwork.S1); validateResult.Value.SegmentIds[1].Should().Be(TestRouteNetwork.S2); validateResult.Value.SegmentIds[2].Should().Be(TestRouteNetwork.S4); }
public ValidatedRouteNetworkWalk Reverse() { var newRouteNetworkElementRefs = new RouteNetworkElementIdList(); for (int i = 0; i < this.RouteNetworkElementRefs.Count; i++) { newRouteNetworkElementRefs.Add(RouteNetworkElementRefs[RouteNetworkElementRefs.Count - (i + 1)]); } return(new ValidatedRouteNetworkWalk(newRouteNetworkElementRefs)); }
public async void QueryByInterestId_ShouldSucced() { // Create two overlapping walk of interests that we can try to query on var interest1Id = Guid.NewGuid(); var walk1 = new RouteNetworkElementIdList() { TestRouteNetwork.S1 }; await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> >(new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interest1Id, walk1)); var interest2Id = Guid.NewGuid(); var walk2 = new RouteNetworkElementIdList() { TestRouteNetwork.S2 }; await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> >(new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interest2Id, walk2)); // Act var routeNetworkQuery = new GetRouteNetworkDetails(new InterestIdList() { interest1Id, interest2Id }) { RelatedInterestFilter = RelatedInterestFilterOptions.ReferencesFromRouteElementAndInterestObjects }; Result <GetRouteNetworkDetailsResult> queryResult = await _queryDispatcher.HandleAsync <GetRouteNetworkDetails, Result <GetRouteNetworkDetailsResult> >(routeNetworkQuery); // Assert queryResult.Value.Interests.ContainsKey(interest1Id).Should().BeTrue(); queryResult.Value.Interests.ContainsKey(interest2Id).Should().BeTrue(); queryResult.Value.RouteNetworkElements.ContainsKey(TestRouteNetwork.CO_1).Should().BeTrue(); queryResult.Value.RouteNetworkElements.ContainsKey(TestRouteNetwork.S1).Should().BeTrue(); queryResult.Value.RouteNetworkElements.ContainsKey(TestRouteNetwork.HH_1).Should().BeTrue(); queryResult.Value.RouteNetworkElements.ContainsKey(TestRouteNetwork.S2).Should().BeTrue(); queryResult.Value.RouteNetworkElements.ContainsKey(TestRouteNetwork.HH_2).Should().BeTrue(); queryResult.Value.RouteNetworkElements[TestRouteNetwork.CO_1].InterestRelations.Should().Contain(i => i.RefId == interest1Id && i.RelationKind == RouteNetworkInterestRelationKindEnum.Start); queryResult.Value.RouteNetworkElements[TestRouteNetwork.CO_1].InterestRelations.Should().NotContain(i => i.RefId == interest2Id); queryResult.Value.RouteNetworkElements[TestRouteNetwork.S1].InterestRelations.Should().Contain(i => i.RefId == interest1Id && i.RelationKind == RouteNetworkInterestRelationKindEnum.PassThrough); queryResult.Value.RouteNetworkElements[TestRouteNetwork.S1].InterestRelations.Should().NotContain(i => i.RefId == interest2Id); queryResult.Value.RouteNetworkElements[TestRouteNetwork.HH_1].InterestRelations.Should().Contain(i => i.RefId == interest1Id && i.RelationKind == RouteNetworkInterestRelationKindEnum.End); queryResult.Value.RouteNetworkElements[TestRouteNetwork.HH_1].InterestRelations.Should().Contain(i => i.RefId == interest2Id && i.RelationKind == RouteNetworkInterestRelationKindEnum.Start); queryResult.Value.RouteNetworkElements[TestRouteNetwork.S2].InterestRelations.Should().Contain(i => i.RefId == interest2Id && i.RelationKind == RouteNetworkInterestRelationKindEnum.PassThrough); queryResult.Value.RouteNetworkElements[TestRouteNetwork.S2].InterestRelations.Should().NotContain(i => i.RefId == interest1Id); queryResult.Value.RouteNetworkElements[TestRouteNetwork.HH_2].InterestRelations.Should().Contain(i => i.RefId == interest2Id && i.RelationKind == RouteNetworkInterestRelationKindEnum.End); queryResult.Value.RouteNetworkElements[TestRouteNetwork.HH_2].InterestRelations.Should().NotContain(i => i.RefId == interest1Id); }
public Result <RouteNetworkElementIdList> ValidateWalk(RouteNetworkElementIdList walkIds) { long versionId = _routeNetworkRepository.NetworkState.GetLatestCommitedVersion(); var lookupRouteNetworkObjectsResult = LookupRouteNetworkObjects(walkIds, versionId); // If some route network element could not be looked up then return failure if (lookupRouteNetworkObjectsResult.IsFailed) { return(Result.Fail <RouteNetworkElementIdList>(lookupRouteNetworkObjectsResult.Errors.First())); } // If only one id is specified, make sure it'a a route segment if (lookupRouteNetworkObjectsResult.Value.Count == 1 && !(lookupRouteNetworkObjectsResult.Value[0] is IRouteSegment)) { return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_WALK_SHOULD_CONTAIN_ROUTE_SEGMENT_IDS_ONLY, "If only one route network id is specified in a walk, it must be a route segment id"))); } var routeElementsSummary = GetRouteNetworkElementsListSummary(lookupRouteNetworkObjectsResult.Value); switch (routeElementsSummary) { case RouteElementListSummary.None: return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_WALK_CANNOT_BE_EMPTY, "A valid walk should contain at least one route segment id"))); case RouteElementListSummary.RouteNodesOnly: return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_WALK_SHOULD_CONTAIN_ROUTE_SEGMENT_IDS_ONLY, "A valid walk cannot contain route nodes only."))); case RouteElementListSummary.RouteSegmentsOnly: var sortedRouteNetworkObjectsResult = SortRouteSegments(lookupRouteNetworkObjectsResult.Value.OfType <RouteSegment>().ToList(), versionId); if (sortedRouteNetworkObjectsResult.IsFailed) { return(Result.Fail <RouteNetworkElementIdList>(sortedRouteNetworkObjectsResult.Errors.First())); } var routeSegments = sortedRouteNetworkObjectsResult.Value.OfType <RouteSegment>().ToList(); return(ValidateSegmentSequence(routeSegments, versionId)); case RouteElementListSummary.BothRouteNodesAndSegments: var validateResult = ValidateNodeSegmentSequence(lookupRouteNetworkObjectsResult.Value, versionId); if (validateResult.IsSuccess) { return(Result.Ok(walkIds)); } else { return(Result.Fail(validateResult.Errors.First())); } } return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_WALK_SHOULD_CONTAIN_ROUTE_SEGMENT_IDS_ONLY, "Unsupported type of route network id sequence"))); }
public async void ValidateInvalidWalkWithBothNodeAndSegmentIds_ShouldFail() { // There's a hole in this walk var walk = new RouteNetworkElementIdList() { TestRouteNetwork.HH_1, TestRouteNetwork.S1, TestRouteNetwork.CO_1, TestRouteNetwork.S1, TestRouteNetwork.HH_1, TestRouteNetwork.S4, TestRouteNetwork.CC_1 }; var validateInterestCommand = new ValidateWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), walk); var validateResult = await _commandDispatcher.HandleAsync <ValidateWalkOfInterest, Result <ValidatedRouteNetworkWalk> >(validateInterestCommand); // Assert validateResult.IsFailed.Should().BeTrue(); }
private Task <Result <GetRouteNetworkDetailsResult> > QueryByInterestIds(GetRouteNetworkDetails query) { RouteNetworkElementIdList routeElementsToQuery = new RouteNetworkElementIdList(); List <RouteNetworkInterest> interestsToReturn = new List <RouteNetworkInterest>(); // Find all interest to return and create a list of route network elements at the same time var interestsProjection = _eventStore.Projections.Get <InterestsProjection>(); foreach (var interestId in query.InterestIdsToQuery) { var interestQueryResult = interestsProjection.GetInterest(interestId); // Here we return a error result, because we're dealing with invalid interest ids provided by the client if (interestQueryResult.IsFailed) { return(Task.FromResult( Result.Fail <GetRouteNetworkDetailsResult>(new GetRouteNetworkDetailsError(GetRouteNetworkDetailsErrorCodes.INVALID_QUERY_ARGUMENT_ERROR_LOOKING_UP_SPECIFIED_INTEREST_BY_ID, $"Error looking up interest by id: {interestId}")). WithError(interestQueryResult.Errors.First()) )); } interestsToReturn.Add(interestQueryResult.Value); routeElementsToQuery.AddRange(interestQueryResult.Value.RouteNetworkElementRefs); } // TODO: Fix so that we don't create substitudes when something is deleted var getRouteNetworkElementsResult = _routeNodeRepository.GetRouteElements(routeElementsToQuery, true); // Here we create an exception, because this situation should not be allowed by the system if (getRouteNetworkElementsResult.IsFailed) { throw new ApplicationException($"Unexpected error querying route elements referenced by interests. All the interest exists and therefore the route network elements must also exists. Validation that route elements having interest cannot be deleted seems not to be working! Initial query:\r\n" + JsonConvert.SerializeObject(query)); } var mappedRouteNetworkElements = MapRouteElementDomainObjectsToQueryObjects(query.RouteNetworkElementFilter, getRouteNetworkElementsResult.Value); var queryResult = new GetRouteNetworkDetailsResult(mappedRouteNetworkElements, interestsToReturn.ToArray()); // Add interest reference information AddInterestReferencesToRouteNetworkElements(query, queryResult); return(Task.FromResult( Result.Ok <GetRouteNetworkDetailsResult>( queryResult ) )); }
public async void QueryReferencesFromRouteElementAndInterestObjects_ShouldReturnAllInterestInformation() { // Create interest (CO_1) <- (S1) -> (HH_1) that we can then try query var interestId = Guid.NewGuid(); var walk = new RouteNetworkElementIdList() { TestRouteNetwork.S1 }; var createInterestCommand = new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interestId, walk); await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> >(createInterestCommand); // Act: Query CO_1, S1, HH_1 and HH_2 var routeNetworkQuery = new GetRouteNetworkDetails(new RouteNetworkElementIdList() { TestRouteNetwork.CO_1, TestRouteNetwork.S1, TestRouteNetwork.HH_1, TestRouteNetwork.HH_2 }) { RelatedInterestFilter = RelatedInterestFilterOptions.ReferencesFromRouteElementAndInterestObjects }; Result <GetRouteNetworkDetailsResult> queryResult = await _queryDispatcher.HandleAsync <GetRouteNetworkDetails, Result <GetRouteNetworkDetailsResult> >(routeNetworkQuery); // Assert that we got information back on all 4 network elements queried Assert.True(queryResult.IsSuccess); Assert.Equal(4, queryResult.Value.RouteNetworkElements.Count); // Assert that we got back one interest related to the 3 network elements that the walk of interest covers Assert.NotNull(queryResult.Value.Interests); Assert.Contains(queryResult.Value.Interests, i => i.Id == interestId); Assert.Equal(RouteNetworkInterestKindEnum.WalkOfInterest, queryResult.Value.Interests[interestId].Kind); Assert.Equal(3, queryResult.Value.Interests[interestId].RouteNetworkElementRefs.Count); Assert.Contains(TestRouteNetwork.CO_1, queryResult.Value.Interests[interestId].RouteNetworkElementRefs); Assert.Contains(TestRouteNetwork.S1, queryResult.Value.Interests[interestId].RouteNetworkElementRefs); Assert.Contains(TestRouteNetwork.HH_1, queryResult.Value.Interests[interestId].RouteNetworkElementRefs); // Assert that route element 1 (CO_1) has interest information with correct relation type Assert.NotNull(queryResult.Value.RouteNetworkElements[TestRouteNetwork.CO_1].InterestRelations); Assert.Contains(queryResult.Value.RouteNetworkElements[TestRouteNetwork.CO_1].InterestRelations, r => r.RefId == interestId && r.RelationKind == RouteNetworkInterestRelationKindEnum.Start); // Assert that route element 2 (S1) has interest information with correct relation type Assert.NotNull(queryResult.Value.RouteNetworkElements[TestRouteNetwork.S1].InterestRelations); Assert.Contains(queryResult.Value.RouteNetworkElements[TestRouteNetwork.S1].InterestRelations, r => r.RefId == interestId && r.RelationKind == RouteNetworkInterestRelationKindEnum.PassThrough); // Assert that route element 3 (HH_1) has interest information with correct relation type Assert.NotNull(queryResult.Value.RouteNetworkElements[TestRouteNetwork.HH_1].InterestRelations); Assert.Contains(queryResult.Value.RouteNetworkElements[TestRouteNetwork.HH_1].InterestRelations, r => r.RefId == interestId && r.RelationKind == RouteNetworkInterestRelationKindEnum.End); }
public async void CreateInvalidWalkOfInterestWithNonExistingRouteNetworkElement_ShouldReturnFaliour() { var interestId = Guid.NewGuid(); var walk = new RouteNetworkElementIdList() { TestRouteNetwork.S1, TestRouteNetwork.S2, Guid.NewGuid() }; // Act var registerWalkOfInterestCommand = new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interestId, walk); Result registerWalkOfInterestCommandResult = await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> >(registerWalkOfInterestCommand); // Assert registerWalkOfInterestCommandResult.IsFailed.Should().BeTrue(); registerWalkOfInterestCommandResult.Errors.OfType <RegisterWalkOfInterestError>().Should().Contain(e => e.Code == RegisterWalkOfInterestErrorCodes.INVALID_WALK_CANNOT_FIND_ROUTE_NETWORK_ELEMENT); }
public void TestIndexingSingleWalkOfInterest() { // Create a walk of interest spanning 3 route elements out of 4 InMemInterestRelationIndex index = new InMemInterestRelationIndex(); var routeElement1 = Guid.NewGuid(); var routeElement2 = Guid.NewGuid(); var routeElement3 = Guid.NewGuid(); var routeElement4 = Guid.NewGuid(); var walkIds = new RouteNetworkElementIdList() { routeElement2, routeElement3, routeElement4 }; var walkOfInterest = new RouteNetworkInterest(Guid.NewGuid(), RouteNetworkInterestKindEnum.WalkOfInterest, walkIds); index.Add(walkOfInterest); // Act var routeElement1InterestRelations = index.GetRouteNetworkElementInterestRelations(routeElement1); var routeElement2InterestRelations = index.GetRouteNetworkElementInterestRelations(routeElement2); var routeElement3InterestRelations = index.GetRouteNetworkElementInterestRelations(routeElement3); var routeElement4InterestRelations = index.GetRouteNetworkElementInterestRelations(routeElement4); // Assert // Route element 1 has no relation to the interest Assert.Empty(routeElement1InterestRelations); // Route element 2 has a start relation to the interest Assert.Single(routeElement2InterestRelations); Assert.Equal(walkOfInterest.Id, routeElement2InterestRelations[0].Item1); Assert.Equal(RouteNetworkInterestRelationKindEnum.Start, routeElement2InterestRelations[0].Item2); // Route element 3 has a passthroug relation to the interest Assert.Single(routeElement3InterestRelations); Assert.Equal(walkOfInterest.Id, routeElement3InterestRelations[0].Item1); Assert.Equal(RouteNetworkInterestRelationKindEnum.PassThrough, routeElement3InterestRelations[0].Item2); // Route element 4 has an end relation to the interest Assert.Single(routeElement4InterestRelations); Assert.Equal(walkOfInterest.Id, routeElement4InterestRelations[0].Item1); Assert.Equal(RouteNetworkInterestRelationKindEnum.End, routeElement4InterestRelations[0].Item2); }
private Guid PlaceConduit(Guid specificationId, RouteNetworkElementIdList walkIds) { // Register walk of interest var walkOfInterestId = Guid.NewGuid(); var registerWalkOfInterestCommand = new RegisterWalkOfInterest(walkOfInterestId, walkIds); var registerWalkOfInterestCommandResult = _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> >(registerWalkOfInterestCommand).Result; // Place conduit var placeSpanEquipmentCommand = new PlaceSpanEquipmentInRouteNetwork(Guid.NewGuid(), specificationId, registerWalkOfInterestCommandResult.Value); var placeSpanEquipmentResult = _commandDispatcher.HandleAsync <PlaceSpanEquipmentInRouteNetwork, Result>(placeSpanEquipmentCommand).Result; if (placeSpanEquipmentResult.IsFailed) { throw new ApplicationException(placeSpanEquipmentResult.Errors.First().Message); } return(placeSpanEquipmentCommand.SpanEquipmentId); }
public async void CreateInvalidWalkOfInterestUsingTwoSeparatedSegments_ShouldReturnFaliour() { // Route network subset used in this test: // (CO_1) <- (S1) -> (HH_1) hole in the walk here (HH_2) -> (S4) -> (CC_1) var interestId = Guid.NewGuid(); var walk = new RouteNetworkElementIdList() { TestRouteNetwork.S1, TestRouteNetwork.S4 }; // Act var registerWalkOfInterestCommand = new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interestId, walk); Result registerWalkOfInterestCommandResult = await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> >(registerWalkOfInterestCommand); // Assert registerWalkOfInterestCommandResult.IsFailed.Should().BeTrue(); registerWalkOfInterestCommandResult.Errors.OfType <RegisterWalkOfInterestError>().Should().Contain(e => e.Code == RegisterWalkOfInterestErrorCodes.INVALID_WALK_SEGMENTS_ARE_NOT_ADJACENT); }
public async void CreateInvalidWalkOfInterestUsingOneNodeAndOneSegments_ShouldReturnFaliour() { // Route network subset used in this test: // (CO_1) <-> (S1) var interestId = Guid.NewGuid(); var walk = new RouteNetworkElementIdList() { TestRouteNetwork.CO_1, TestRouteNetwork.S1 }; // Act var registerWalkOfInterestCommand = new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interestId, walk); Result registerWalkOfInterestCommandResult = await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> >(registerWalkOfInterestCommand); // Assert registerWalkOfInterestCommandResult.IsFailed.Should().BeTrue(); registerWalkOfInterestCommandResult.Errors.OfType <RegisterWalkOfInterestError>().Should().Contain(e => e.Code == RegisterWalkOfInterestErrorCodes.INVALID_WALK_LAST_ROUTE_NETWORK_ELEMENT_MUST_BE_A_NODE); }
private Result <List <IRouteNetworkElement> > LookupRouteNetworkObjects(RouteNetworkElementIdList routeNetworkElementIds, long versionId) { List <IRouteNetworkElement> result = new List <IRouteNetworkElement>(); foreach (var networkElementId in routeNetworkElementIds) { var routeNetworkElement = _routeNetworkRepository.NetworkState.GetRouteNetworkElement(networkElementId, versionId); if (routeNetworkElement == null) { return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_WALK_CANNOT_FIND_ROUTE_NETWORK_ELEMENT, $"Cannot find any route network element with id: {networkElementId}"))); } else { result.Add(routeNetworkElement); } } return(Result.Ok <List <IRouteNetworkElement> >(result)); }
public async void CreateValidWalkOfInterestUsingOneSegmentIdOnly_ShouldReturnSuccess() { // Route network subset used in this test: // (CO_1) <- (S1) -> (HH_1) var interestId = Guid.NewGuid(); var walk = new RouteNetworkElementIdList() { TestRouteNetwork.S1 }; // Act var registerWalkOfInterestCommand = new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interestId, walk); var registerWalkOfInterestCommandResult = await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> > (registerWalkOfInterestCommand); var routeNetworkQuery = new GetRouteNetworkDetails(new RouteNetworkElementIdList() { TestRouteNetwork.CO_1 }) { RelatedInterestFilter = RelatedInterestFilterOptions.ReferencesFromRouteElementAndInterestObjects }; Result <GetRouteNetworkDetailsResult> routeNetworkQueryResult = await _queryDispatcher.HandleAsync <GetRouteNetworkDetails, Result <GetRouteNetworkDetailsResult> > (routeNetworkQuery); // Assert command result registerWalkOfInterestCommandResult.IsSuccess.Should().BeTrue(); registerWalkOfInterestCommandResult.Value.Kind.Should().Be(RouteNetworkInterestKindEnum.WalkOfInterest); registerWalkOfInterestCommandResult.Value.RouteNetworkElementRefs.Count.Should().Be(3); registerWalkOfInterestCommandResult.Value.RouteNetworkElementRefs.Should().Contain(TestRouteNetwork.CO_1); registerWalkOfInterestCommandResult.Value.RouteNetworkElementRefs.Should().Contain(TestRouteNetwork.S1); registerWalkOfInterestCommandResult.Value.RouteNetworkElementRefs.Should().Contain(TestRouteNetwork.HH_1); // Assert query result routeNetworkQueryResult.IsSuccess.Should().BeTrue(); routeNetworkQueryResult.Value.Interests[interestId].RouteNetworkElementRefs.Count.Should().Be(3); routeNetworkQueryResult.Value.Interests[interestId].RouteNetworkElementRefs.Should().Contain(TestRouteNetwork.CO_1); routeNetworkQueryResult.Value.Interests[interestId].RouteNetworkElementRefs.Should().Contain(TestRouteNetwork.S1); routeNetworkQueryResult.Value.Interests[interestId].RouteNetworkElementRefs.Should().Contain(TestRouteNetwork.HH_1); routeNetworkQueryResult.Value.Interests[interestId].RouteNetworkElementRefs.Should().NotContain(TestRouteNetwork.S2); }
public async void CreateAndRemoveWalkOfInterest_ShouldReturnSuccess() { // Route network subset used in this test: // (CO_1) <- (S1) -> (HH_1) var interestId = Guid.NewGuid(); var walk = new RouteNetworkElementIdList() { TestRouteNetwork.S1 }; var routeNetworkQuery = new GetRouteNetworkDetails(new RouteNetworkElementIdList() { TestRouteNetwork.CO_1 }) { RelatedInterestFilter = RelatedInterestFilterOptions.ReferencesFromRouteElementAndInterestObjects }; // Act var registerWalkOfInterestCommand = new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interestId, walk); var registerWalkOfInterestCommandResult = await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> > (registerWalkOfInterestCommand); Result <GetRouteNetworkDetailsResult> routeNetworkQueryResultBefore = await _queryDispatcher.HandleAsync <GetRouteNetworkDetails, Result <GetRouteNetworkDetailsResult> >(routeNetworkQuery); var unregisterWalkOfInterestCommand = new UnregisterInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interestId); var unregisterWalkOfInterestCommandResult = await _commandDispatcher.HandleAsync <UnregisterInterest, Result>(unregisterWalkOfInterestCommand); Result <GetRouteNetworkDetailsResult> routeNetworkQueryResultAfter = await _queryDispatcher.HandleAsync <GetRouteNetworkDetails, Result <GetRouteNetworkDetailsResult> >(routeNetworkQuery); // Assert command result registerWalkOfInterestCommandResult.IsSuccess.Should().BeTrue(); unregisterWalkOfInterestCommandResult.IsSuccess.Should().BeTrue(); // Assert query result routeNetworkQueryResultBefore.IsSuccess.Should().BeTrue(); routeNetworkQueryResultBefore.Value.Interests.ContainsKey(interestId).Should().BeTrue(); routeNetworkQueryResultAfter.IsSuccess.Should().BeTrue(); routeNetworkQueryResultAfter.Value.Interests.ContainsKey(interestId).Should().BeFalse(); }
private async void NotifyExternalServicesAboutChange(Guid spanEquipmentId, RouteNetworkElementIdList routeIdsAffected) { 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.StructuresAdded", idChangeSets: idChangeSets.ToArray(), affectedRouteNetworkElementIds: routeIdsAffected.ToArray() ); await _externalEventProducer.Produce(_topicName, updatedEvent); }
public async Task Place5x10Conduit_from_HH_1_to_HH_10() { // Place a 5x10 multi conduit here: // (HH_1) <- (S2) -> (HH_2) <- (S4) -> (CC_1) <- (S13) -> (HH_10) // First register the walk in the route network where we want to place the conduit var walkOfInterestId = Guid.NewGuid(); var walk = new RouteNetworkElementIdList() { TestRouteNetwork.S2, TestRouteNetwork.S4, TestRouteNetwork.S13 }; var registerWalkOfInterestCommand = new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), walkOfInterestId, walk); var registerWalkOfInterestCommandResult = await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> >(registerWalkOfInterestCommand); // Now place the conduit in walk var placeSpanEquipmentCommand = new PlaceSpanEquipmentInRouteNetwork(Guid.NewGuid(), new UserContext("test", Guid.Empty), TestConduits.Conduit_5x10_HH_1_to_HH_10, TestSpecifications.Multi_Ø40_5x10, registerWalkOfInterestCommandResult.Value); var placeSpanEquipmentResult = await _commandDispatcher.HandleAsync <PlaceSpanEquipmentInRouteNetwork, Result>(placeSpanEquipmentCommand); // Assert registerWalkOfInterestCommandResult.IsSuccess.Should().BeTrue(); placeSpanEquipmentResult.IsSuccess.Should().BeTrue(); }
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); }
public async Task PlaceØ40Flex_from_CC_1_to_SP_1() { // Place a Ø40 flex conduit here: // (CC_1) <- (S5) -> (SP_1) // First register the walk in the route network where we want to place the conduit var walkOfInterestId = Guid.NewGuid(); var walk = new RouteNetworkElementIdList() { TestRouteNetwork.S5 }; var registerWalkOfInterestCommand = new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), walkOfInterestId, walk); var registerWalkOfInterestCommandResult = await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> >(registerWalkOfInterestCommand); // Now place the conduit in walk var placeSpanEquipmentCommand = new PlaceSpanEquipmentInRouteNetwork(Guid.NewGuid(), new UserContext("test", Guid.Empty), Guid.NewGuid(), TestSpecifications.Flex_Ø40_Red, registerWalkOfInterestCommandResult.Value); var placeSpanEquipmentResult = await _commandDispatcher.HandleAsync <PlaceSpanEquipmentInRouteNetwork, Result>(placeSpanEquipmentCommand); // Assert registerWalkOfInterestCommandResult.IsSuccess.Should().BeTrue(); placeSpanEquipmentResult.IsSuccess.Should().BeTrue(); }
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); }
public async void QueryExplicitlyRequestingNoInterestInformation_ShouldReturnNoInterestInformation() { // Create interest (CO_1) <- (S1) -> (HH_1) that we can then try query var interestId = Guid.NewGuid(); var walk = new RouteNetworkElementIdList() { TestRouteNetwork.S1 }; var createInterestCommand = new RegisterWalkOfInterest(Guid.NewGuid(), new UserContext("test", Guid.Empty), interestId, walk); await _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> >(createInterestCommand); // Act: Query CO_1, S1, HH_1 and HH_2 var routeNetworkQuery = new GetRouteNetworkDetails(new RouteNetworkElementIdList() { TestRouteNetwork.CO_1, TestRouteNetwork.S1, TestRouteNetwork.HH_1, TestRouteNetwork.HH_2 }) { RelatedInterestFilter = RelatedInterestFilterOptions.None }; Result <GetRouteNetworkDetailsResult> queryResult = await _queryDispatcher.HandleAsync <GetRouteNetworkDetails, Result <GetRouteNetworkDetailsResult> >(routeNetworkQuery); // Assert that we got information back on all 4 network elements queried Assert.True(queryResult.IsSuccess); Assert.Equal(4, queryResult.Value.RouteNetworkElements.Count); // Assert that we did'nt get any interest object back Assert.Empty(queryResult.Value.Interests); // Assert that no route elements got interest relations Assert.Null(queryResult.Value.RouteNetworkElements[TestRouteNetwork.CO_1].InterestRelations); Assert.Null(queryResult.Value.RouteNetworkElements[TestRouteNetwork.S1].InterestRelations); Assert.Null(queryResult.Value.RouteNetworkElements[TestRouteNetwork.HH_1].InterestRelations); Assert.Null(queryResult.Value.RouteNetworkElements[TestRouteNetwork.HH_2].InterestRelations); }
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 RouteNetworkElementIdList CreateWalkFromSegmentSequence(List <RouteSegment> routeSegments, long versionId) { RouteNetworkElementIdList walkIds = new RouteNetworkElementIdList(); var routeSegmentPosition = 0; // If only one route segment, inV and outV will be the node sequence if (routeSegments.Count == 1) { walkIds.Add(routeSegments[0].InV(versionId).Id); walkIds.Add(routeSegments[0].Id); walkIds.Add(routeSegments[0].OutV(versionId).Id); return(walkIds); } // We're dealing with multi segments, if we reach this code foreach (var routeSegment in routeSegments) { if (routeSegmentPosition > 0) { var prevSegment = routeSegments[routeSegmentPosition - 1]; var sharedRouteNode = FindSharedNode(prevSegment, routeSegment, versionId); // If prevSegment is the first segment then remember to add it incl. the first node and shared node if (routeSegmentPosition == 1) { if (prevSegment.InV(versionId) != sharedRouteNode) { walkIds.Add(prevSegment.InV(versionId).Id); } else { walkIds.Add(prevSegment.OutV(versionId).Id); } // Add prev segment walkIds.Add(prevSegment.Id); // Add shared node walkIds.Add(sharedRouteNode.Id); } // Add current segment and non shared node walkIds.Add(routeSegment.Id); if (routeSegment.InV(versionId) != sharedRouteNode) { walkIds.Add(routeSegment.InV(versionId).Id); } else { walkIds.Add(routeSegment.OutV(versionId).Id); } } routeSegmentPosition++; } return(walkIds); }
public Task <Result> HandleAsync(MoveSpanEquipment command) { var utilityNetwork = _eventStore.Projections.Get <UtilityNetworkProjection>(); // Because the client is allowed to provide either a span equipment or segment id, we need look it up via the utility network graph if (!utilityNetwork.TryGetEquipment <SpanEquipment>(command.SpanEquipmentOrSegmentId, out SpanEquipment spanEquipment)) { return(Task.FromResult(Result.Fail(new MoveSpanEquipmentError(MoveSpanEquipmentErrorCodes.SPAN_EQUIPMENT_NOT_FOUND, $"Cannot find any span equipment or segment in the utility graph with id: {command.SpanEquipmentOrSegmentId}")))); } // Get interest information from existing span equipment var existingWalk = GetInterestInformation(spanEquipment); // Validate the new walk var newWalkValidationResult = _commandDispatcher.HandleAsync <ValidateWalkOfInterest, Result <ValidatedRouteNetworkWalk> >(new ValidateWalkOfInterest(command.NewWalkIds)).Result; // If the new walk fails to validate, return the error to the client if (newWalkValidationResult.IsFailed) { return(Task.FromResult(Result.Fail(newWalkValidationResult.Errors.First()))); } var newWalk = newWalkValidationResult.Value; // If the walk has not changed return error as well if (existingWalk.Equals(newWalk)) { return(Task.FromResult(Result.Fail(new MoveSpanEquipmentError(MoveSpanEquipmentErrorCodes.NEW_WALK_EQUALS_EXISTING_WALK, $"The new walk specified is not different from the existing walk of the span equipment.")))); } // Reverse new walk if one of its ends are opposite of existing walk ends if (newWalk.FromNodeId == existingWalk.ToNodeId || newWalk.ToNodeId == existingWalk.FromNodeId) { newWalk = newWalk.Reverse(); } // Try to do the move of the span equipment var spanEquipmentAR = _eventStore.Aggregates.Load <SpanEquipmentAR>(spanEquipment.Id); var commandContext = new CommandContext(command.CorrelationId, command.CmdId, command.UserContext); var moveSpanEquipmentResult = spanEquipmentAR.Move(commandContext, newWalk, existingWalk); if (moveSpanEquipmentResult.IsFailed) { return(Task.FromResult(Result.Fail(moveSpanEquipmentResult.Errors.First()))); } // If we got to here, then the span equipment move was validated fine, so we can update the walk of interest var newSegmentIds = new RouteNetworkElementIdList(); newSegmentIds.AddRange(newWalk.SegmentIds); var updateWalkOfInterestCommand = new UpdateWalkOfInterest(spanEquipment.WalkOfInterestId, newSegmentIds) { UserContext = commandContext.UserContext }; var updateWalkOfInterestCommandResult = _commandDispatcher.HandleAsync <UpdateWalkOfInterest, Result <RouteNetworkInterest> >(updateWalkOfInterestCommand).Result; if (updateWalkOfInterestCommandResult.IsFailed) { throw new ApplicationException($"Got unexpected error result: {updateWalkOfInterestCommandResult.Errors.First().Message} trying to update walk of interest belonging to span equipment with id: {spanEquipment.Id} while processing the MoveSpanEquipment command: " + JsonConvert.SerializeObject(command)); } _eventStore.Aggregates.Store(spanEquipmentAR); NotifyExternalServicesAboutSpanEquipmentChange(spanEquipment.Id, existingWalk, newWalk); return(Task.FromResult(moveSpanEquipmentResult)); }
public ValidatedRouteNetworkWalk(RouteNetworkElementIdList routeNetworkElementRefs) { RouteNetworkElementRefs = routeNetworkElementRefs; }
private void PlaceConduit(string externalId, Guid specificationId, List <Guid> segmentIds, List <Guid> additionalStructureSpecIds, string markingColor) { Guid correlationId = Guid.NewGuid(); RouteNetworkElementIdList walkIds = new RouteNetworkElementIdList(); walkIds.AddRange(segmentIds); // Register walk of interest var walkOfInterestId = Guid.NewGuid(); var registerWalkOfInterestCommand = new RegisterWalkOfInterest(correlationId, new UserContext("conversion", _bentleyMultiConduitConversion), walkOfInterestId, walkIds); var registerWalkOfInterestCommandResult = _commandDispatcher.HandleAsync <RegisterWalkOfInterest, Result <RouteNetworkInterest> >(registerWalkOfInterestCommand).Result; if (registerWalkOfInterestCommandResult.IsFailed) { _logger.LogInformation("Failed to add conduit: " + externalId + " Error: " + registerWalkOfInterestCommandResult.Errors.First().Message); return; } // conduit name var nextConduitSeqStr = _eventStore.Sequences.GetNextVal("conduit").ToString(); var conduitName = "R" + nextConduitSeqStr.PadLeft(6, '0'); var namingInfo = new NamingInfo(conduitName, null); // Place conduit var placeSpanEquipmentCommand = new PlaceSpanEquipmentInRouteNetwork(correlationId, new UserContext("conversion", _bentleyMultiConduitConversion), Guid.NewGuid(), specificationId, registerWalkOfInterestCommandResult.Value) { MarkingInfo = markingColor != null ? new MarkingInfo() { MarkingColor = markingColor } : null, NamingInfo = namingInfo }; var placeSpanEquipmentResult = _commandDispatcher.HandleAsync <PlaceSpanEquipmentInRouteNetwork, Result>(placeSpanEquipmentCommand).Result; if (placeSpanEquipmentResult.IsFailed) { _logger.LogInformation("Failed to add conduit: " + externalId + " Error: " + placeSpanEquipmentResult.Errors.First().Message); return; } // Place additional structures if (additionalStructureSpecIds.Count > 0) { var addStructure = new PlaceAdditionalStructuresInSpanEquipment(correlationId, new UserContext("conversion", _bentleyMultiConduitConversion), spanEquipmentId: placeSpanEquipmentCommand.SpanEquipmentId, structureSpecificationIds: additionalStructureSpecIds.ToArray() ); var addStructureResult = _commandDispatcher.HandleAsync <PlaceAdditionalStructuresInSpanEquipment, Result>(addStructure).Result; if (addStructureResult.IsFailed) { _logger.LogInformation("Failed to add additional structures to: " + externalId + " Error: " + placeSpanEquipmentResult.Errors.First().Message); return; } } }