public async void TestQuerySpanEquipmentByInterestId_ShouldSucceed() { // Setup var specs = new TestSpecifications(_commandDispatcher, _queryDispatcher).Run(); var walkOfInterest = new RouteNetworkInterest(Guid.NewGuid(), RouteNetworkInterestKindEnum.WalkOfInterest, new RouteNetworkElementIdList() { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() }); var placeSpanEquipmentCommand = new PlaceSpanEquipmentInRouteNetwork(Guid.NewGuid(), TestSpecifications.Multi_Ø32_3x10, walkOfInterest); // Act var placeSpanEquipmentResult = await _commandDispatcher.HandleAsync <PlaceSpanEquipmentInRouteNetwork, Result>(placeSpanEquipmentCommand); var spanEquipmentQueryResult = await _queryDispatcher.HandleAsync <GetEquipmentDetails, Result <GetEquipmentDetailsResult> >( new GetEquipmentDetails(new InterestIdList() { walkOfInterest.Id }) ); // Assert placeSpanEquipmentResult.IsSuccess.Should().BeTrue(); spanEquipmentQueryResult.IsSuccess.Should().BeTrue(); #pragma warning disable CS8602 // Dereference of a possibly null reference. spanEquipmentQueryResult.Value.SpanEquipment[placeSpanEquipmentCommand.SpanEquipmentId].Id.Should().Be(placeSpanEquipmentCommand.SpanEquipmentId); #pragma warning restore CS8602 // Dereference of a possibly null reference. }
public void TestIndexingSingleNodeOfInterest() { // 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 nodeOfInterest = new RouteNetworkInterest(Guid.NewGuid(), RouteNetworkInterestKindEnum.NodeOfInterest, new RouteNetworkElementIdList() { routeElement2 }); // Act index.Add(nodeOfInterest); var routeElement1InterestRelations = index.GetRouteNetworkElementInterestRelations(routeElement1); var routeElement2InterestRelations = index.GetRouteNetworkElementInterestRelations(routeElement2); // Assert // Route element 1 has no relation to the interest Assert.Empty(routeElement1InterestRelations); // Route element 2 has an inside node relation to the interest Assert.Single(routeElement2InterestRelations); Assert.Equal(nodeOfInterest.Id, routeElement2InterestRelations[0].Item1); Assert.Equal(RouteNetworkInterestRelationKindEnum.InsideNode, routeElement2InterestRelations[0].Item2); }
public Result PlaceNodeContainerInRouteNetworkNode( CommandContext cmdContext, LookupCollection <NodeContainer> nodeContainers, LookupCollection <NodeContainerSpecification> nodeContainerSpecifications, Guid nodeContainerId, Guid nodeContainerSpecificationId, RouteNetworkInterest nodeOfInterest, NamingInfo?namingInfo, LifecycleInfo?lifecycleInfo, Guid?manufacturerId ) { this.Id = nodeContainerId; if (nodeContainerId == Guid.Empty) { return(Result.Fail(new PlaceNodeContainerInRouteNetworkError(PlaceNodeContainerInRouteNetworkErrorCodes.INVALID_NODE_CONTAINER_ID_CANNOT_BE_EMPTY, "Node container id cannot be empty. A unique id must be provided by client."))); } if (nodeContainers.ContainsKey(nodeContainerId)) { return(Result.Fail(new PlaceNodeContainerInRouteNetworkError(PlaceNodeContainerInRouteNetworkErrorCodes.INVALID_NODE_CONTAINER_ID_ALREADY_EXISTS, $"A node container with id: {nodeContainerId} already exists."))); } if (nodeOfInterest.Kind != RouteNetworkInterestKindEnum.NodeOfInterest) { return(Result.Fail(new PlaceNodeContainerInRouteNetworkError(PlaceNodeContainerInRouteNetworkErrorCodes.INVALID_INTEREST_KIND_MUST_BE_NODE_OF_INTEREST, "Interest kind must be NodeOfInterest. You can only put node container into route nodes!"))); } if (!nodeContainerSpecifications.ContainsKey(nodeContainerSpecificationId)) { return(Result.Fail(new PlaceNodeContainerInRouteNetworkError(PlaceNodeContainerInRouteNetworkErrorCodes.INVALID_NODE_CONTAINER_SPECIFICATION_ID_NOT_FOUND, $"Cannot find node container specification with id: {nodeContainerSpecificationId}"))); } if (nodeContainers.Any(n => n.RouteNodeId == nodeOfInterest.RouteNetworkElementRefs[0])) { return(Result.Fail(new PlaceNodeContainerInRouteNetworkError(PlaceNodeContainerInRouteNetworkErrorCodes.NODE_CONTAINER_ALREADY_EXISTS_IN_ROUTE_NODE, $"A node container already exist in the route node with id: {nodeOfInterest.RouteNetworkElementRefs[0]} Only one node container is allowed per route node."))); } var nodeContainer = new NodeContainer(nodeContainerId, nodeContainerSpecificationId, nodeOfInterest.Id, nodeOfInterest.RouteNetworkElementRefs[0]) { ManufacturerId = manufacturerId, NamingInfo = namingInfo, LifecycleInfo = lifecycleInfo }; var nodeContainerPlaceInRouteNetworkEvent = new NodeContainerPlacedInRouteNetwork(nodeContainer) { CorrelationId = cmdContext.CorrelationId, IncitingCmdId = cmdContext.CmdId, UserName = cmdContext.UserContext?.UserName, WorkTaskId = cmdContext.UserContext?.WorkTaskId }; RaiseEvent(nodeContainerPlaceInRouteNetworkEvent); return(Result.Ok()); }
public void TestRemoveWalkOfInterestFromIndex() { // Setup InMemInterestRelationIndex index = new InMemInterestRelationIndex(); var routeElement1 = Guid.NewGuid(); var routeElement2 = Guid.NewGuid(); var routeElement3 = Guid.NewGuid(); var routeElement4 = Guid.NewGuid(); // Create walk of interest spanning route element 1,2,3 var walkOfInterest1 = new RouteNetworkInterest(Guid.NewGuid(), RouteNetworkInterestKindEnum.WalkOfInterest, new RouteNetworkElementIdList() { routeElement1, routeElement2, routeElement3 }); index.Add(walkOfInterest1); // Create walk of interest spanning route element 2,3,4 var walkOfInterest2 = new RouteNetworkInterest(Guid.NewGuid(), RouteNetworkInterestKindEnum.WalkOfInterest, new RouteNetworkElementIdList() { routeElement2, routeElement3, routeElement4 }); index.Add(walkOfInterest2); // Remove the first interest index.Remove(walkOfInterest1); 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(walkOfInterest2.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(walkOfInterest2.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(walkOfInterest2.Id, routeElement4InterestRelations[0].Item1); Assert.Equal(RouteNetworkInterestRelationKindEnum.End, routeElement4InterestRelations[0].Item2); }
public void TestIndexingMultipleWalkOfInterest() { // Setup InMemInterestRelationIndex index = new InMemInterestRelationIndex(); var routeElement1 = Guid.NewGuid(); var routeElement2 = Guid.NewGuid(); var routeElement3 = Guid.NewGuid(); var routeElement4 = Guid.NewGuid(); // Create walk of interest spanning route element 1,2,3 var walkOfInterest1 = new RouteNetworkInterest(Guid.NewGuid(), RouteNetworkInterestKindEnum.WalkOfInterest, new RouteNetworkElementIdList() { routeElement1, routeElement2, routeElement3 }); index.Add(walkOfInterest1); // Create walk of interest spanning route element 2,3,4 var walkOfInterest2 = new RouteNetworkInterest(Guid.NewGuid(), RouteNetworkInterestKindEnum.WalkOfInterest, new RouteNetworkElementIdList() { routeElement2, routeElement3, routeElement4 }); index.Add(walkOfInterest2); 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 a relation to interest 1 only Assert.Single(routeElement1InterestRelations); Assert.Equal(walkOfInterest1.Id, routeElement1InterestRelations[0].Item1); Assert.Equal(RouteNetworkInterestRelationKindEnum.Start, routeElement1InterestRelations[0].Item2); // Route element 2 has a relation to both interest 1 and 2 Assert.Equal(2, routeElement2InterestRelations.Count); Assert.True(routeElement2InterestRelations.Exists(r => r.Item1 == walkOfInterest1.Id && r.Item2 == RouteNetworkInterestRelationKindEnum.PassThrough)); Assert.True(routeElement2InterestRelations.Exists(r => r.Item1 == walkOfInterest2.Id && r.Item2 == RouteNetworkInterestRelationKindEnum.Start)); // Route element 3 has a relation to both interest 1 and 2 Assert.Equal(2, routeElement3InterestRelations.Count); Assert.True(routeElement3InterestRelations.Exists(r => r.Item1 == walkOfInterest1.Id && r.Item2 == RouteNetworkInterestRelationKindEnum.End)); Assert.True(routeElement3InterestRelations.Exists(r => r.Item1 == walkOfInterest2.Id && r.Item2 == RouteNetworkInterestRelationKindEnum.PassThrough)); // Route element 4 has a relation to interest 2 only Assert.Single(routeElement4InterestRelations); Assert.Equal(walkOfInterest2.Id, routeElement4InterestRelations[0].Item1); Assert.Equal(RouteNetworkInterestRelationKindEnum.End, routeElement4InterestRelations[0].Item2); }
public void TestUpdatingIndex() { InMemInterestRelationIndex index = new InMemInterestRelationIndex(); var routeElement1 = Guid.NewGuid(); var routeElement2 = Guid.NewGuid(); var routeElement3 = Guid.NewGuid(); var routeElement4 = Guid.NewGuid(); // Create a walk of interest spanning the first 3 route network elements var walkOfInterest = new RouteNetworkInterest(Guid.NewGuid(), RouteNetworkInterestKindEnum.WalkOfInterest, new RouteNetworkElementIdList() { routeElement1, routeElement2, routeElement3 }); index.Add(walkOfInterest); // Create a walk of interest spanning the last 3 route network elements var updatedWalkOfInterest = new RouteNetworkInterest(walkOfInterest.Id, RouteNetworkInterestKindEnum.WalkOfInterest, new RouteNetworkElementIdList() { routeElement2, routeElement3, routeElement4 }); index.Update(updatedWalkOfInterest, walkOfInterest); 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); }
public async void TestPlaceTwoSpanEquipmentWithSameId_SecondOneShouldFail() { // Setup var specs = new TestSpecifications(_commandDispatcher, _queryDispatcher).Run(); var walkOfInterest = new RouteNetworkInterest(Guid.NewGuid(), RouteNetworkInterestKindEnum.WalkOfInterest, new RouteNetworkElementIdList() { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() }); var placeSpanEquipmentCommand = new PlaceSpanEquipmentInRouteNetwork(Guid.NewGuid(), TestSpecifications.Multi_Ø32_3x10, walkOfInterest); // Act var placeSpanEquipmentResult = await _commandDispatcher.HandleAsync <PlaceSpanEquipmentInRouteNetwork, Result>(placeSpanEquipmentCommand); var placeSpanEquipmentResult2 = await _commandDispatcher.HandleAsync <PlaceSpanEquipmentInRouteNetwork, Result>(placeSpanEquipmentCommand); // Assert placeSpanEquipmentResult.IsSuccess.Should().BeTrue(); placeSpanEquipmentResult2.IsSuccess.Should().BeFalse(); }
public Result <RouteNetworkInterest> UpdateRouteNetworkElements(CommandContext cmdContext, RouteNetworkInterest walkOfInterest, InterestsProjection interestProjection, WalkValidator walkValidator) { if (walkOfInterest.Kind != RouteNetworkInterestKindEnum.WalkOfInterest) { return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_KIND_MUST_BE_WALK_OF_INTEREST, "Interest kind must be WalkOfInterest"))); } if (walkOfInterest.Id == Guid.Empty) { return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_ID_CANNOT_BE_EMPTY, $"{RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_ID_CANNOT_BE_EMPTY}: Interest id cannot be empty"))); } if (interestProjection.GetInterest(walkOfInterest.Id).IsFailed) { return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_DONT_EXISTS, $"{RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_DONT_EXISTS}: An interest with id: {walkOfInterest.Id} could not be found"))); } var walkValidationResult = walkValidator.ValidateWalk(walkOfInterest.RouteNetworkElementRefs); if (walkValidationResult.IsFailed) { return(Result.Fail(walkValidationResult.Errors.First())); } if (_interest == null) { throw new ApplicationException("Unexpected aggreagate state. Interest state must be non-null when this event is processed."); } // Reverse walk if one of its ends are opposite of existing walk ends var existingWalk = new ValidatedRouteNetworkWalk(_interest.RouteNetworkElementRefs); var newWalk = new ValidatedRouteNetworkWalk(walkValidationResult.Value); if (newWalk.FromNodeId == existingWalk.ToNodeId || newWalk.ToNodeId == existingWalk.FromNodeId) { newWalk = newWalk.Reverse(); } RaiseEvent( new WalkOfInterestRouteNetworkElementsModified(this.Id, newWalk.RouteNetworkElementRefs) { CorrelationId = cmdContext.CorrelationId, IncitingCmdId = cmdContext.CmdId, UserName = cmdContext.UserContext?.UserName, WorkTaskId = cmdContext.UserContext?.WorkTaskId } ); if (_interest == null) { throw new ApplicationException("Unexpected aggreagate state. Interest must be non-null after WalkOfInterestRegistered has been raised."); } return(Result.Ok <RouteNetworkInterest>(_interest)); }
public Result <RouteNetworkInterest> RegisterWalkOfInterest(CommandContext cmdContext, RouteNetworkInterest interest, InterestsProjection interestsProjection, WalkValidator walkValidator) { if (interest.Kind != RouteNetworkInterestKindEnum.WalkOfInterest) { return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_KIND_MUST_BE_WALK_OF_INTEREST, "Interest kind must be WalkOfInterest"))); } if (interest.Id == Guid.Empty) { return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_ID_CANNOT_BE_EMPTY, $"{RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_ID_CANNOT_BE_EMPTY}: Interest id cannot be empty"))); } if (interestsProjection.GetInterest(interest.Id).IsSuccess) { return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_ALREADY_EXISTS, $"{RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_ALREADY_EXISTS}: An interest with id: {interest.Id} already exists"))); } var walkValidationResult = walkValidator.ValidateWalk(interest.RouteNetworkElementRefs); if (walkValidationResult.IsFailed) { return(Result.Fail(walkValidationResult.Errors.First())); } var interestWithValidatedWalk = interest with { RouteNetworkElementRefs = walkValidationResult.Value }; RaiseEvent( new WalkOfInterestRegistered(interestWithValidatedWalk) { CorrelationId = cmdContext.CorrelationId, IncitingCmdId = cmdContext.CmdId, UserName = cmdContext.UserContext?.UserName, WorkTaskId = cmdContext.UserContext?.WorkTaskId } ); if (_interest == null) { throw new ApplicationException("Unexpected aggreagate state. Interest must be non-null after WalkOfInterestRegistered has been raised."); } return(Result.Ok <RouteNetworkInterest>(_interest)); }
public Result <RouteNetworkInterest> RegisterNodeOfInterest(CommandContext cmdContext, RouteNetworkInterest interest, InterestsProjection interestsProjection) { if (interest.Kind != RouteNetworkInterestKindEnum.NodeOfInterest) { return(Result.Fail(new RegisterNodeOfInterestError(RegisterNodeOfInterestErrorCodes.INVALID_INTEREST_KIND_MUST_BE_NODE_OF_INTEREST, "Interest kind must be NodeOfInterest"))); } if (interest.Id == Guid.Empty) { return(Result.Fail(new RegisterNodeOfInterestError(RegisterNodeOfInterestErrorCodes.INVALID_INTEREST_ID_CANNOT_BE_EMPTY, $"{RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_ID_CANNOT_BE_EMPTY}: Interest id cannot be empty"))); } if (interestsProjection.GetInterest(interest.Id).IsSuccess) { return(Result.Fail(new RegisterNodeOfInterestError(RegisterNodeOfInterestErrorCodes.INVALID_INTEREST_ALREADY_EXISTS, $"{RegisterNodeOfInterestErrorCodes.INVALID_INTEREST_ALREADY_EXISTS}: An interest with id: {interest.Id} already exists"))); } RaiseEvent( new NodeOfInterestRegistered(interest) { CorrelationId = cmdContext.CorrelationId, IncitingCmdId = cmdContext.CmdId, UserName = cmdContext.UserContext?.UserName, WorkTaskId = cmdContext.UserContext?.WorkTaskId } ); if (_interest == null) { throw new ApplicationException("Unexpected aggreagate state. Interest must be non-null after NodeOfInterestRegistered has been raised."); } return(Result.Ok <RouteNetworkInterest>(_interest)); }