public async Task <List <INotification> > CreateUpdatedEvent(RouteNode before, RouteNode after) { if (before is null || after is null) { throw new ArgumentNullException($"Parameter {nameof(before)} or {nameof(after)} cannot be null"); } var shadowTableNode = await _geoDatabase.GetRouteNodeShadowTable(after.Mrid); if (shadowTableNode is null) { return new List <INotification> { new DoNothing($"{nameof(RouteNode)} is already deleted, so do nothing.") } } ; if (AlreadyUpdated(after, shadowTableNode)) { return new List <INotification> { new DoNothing($"{nameof(RouteNode)} with id: '{after.Mrid}' was already updated therefore do nothing.") } } ; await _geoDatabase.UpdateRouteNodeShadowTable(after); if (!(await IsValidNodeUpdate(before, after))) { return new List <INotification> { new RollbackInvalidRouteNode(before, "Is not a valid route node update") } } ; // We roll back in-case the update-command intersects with new route-segments var intersectingRouteSegments = await _geoDatabase.GetIntersectingRouteSegments(after); if (intersectingRouteSegments.Count > 0) { var previousIntersectingRouteSegments = await _geoDatabase.GetIntersectingRouteSegments(before.Coord); var newIntersectingRouteSegments = intersectingRouteSegments .Where(x => !previousIntersectingRouteSegments.Any(y => y.Mrid == x.Mrid)).ToList(); if (newIntersectingRouteSegments.Count > 0) { return new List <INotification> { new RollbackInvalidRouteNode(before, "Update to route node is invalid because it is insecting with route-segments.") } } ; } if (after.MarkAsDeleted) { return new List <INotification> { new RouteNodeDeleted { RouteNode = after } } } ; return(new List <INotification> { new RouteNodeLocationChanged { RouteNodeAfter = after, RouteNodeBefore = before } }); }