Store all alerts and add support for route_type and direction_id selectors - #3780
Conversation
…egacy graphQL API
…and add routeType to Route
optionsome
left a comment
There was a problem hiding this comment.
I'm a bit unsure if we should store the alerts with the original selectors and expose them through APIs that way or, for example, create as many pattern selectors as there are patterns for a direction in route's direction and expose the route_id+direction_id alerts directly through the pattern/trip types in APIs and hide the original selector structure from the API users. I think there are some use cases where users would want to display alerts that are targeted for a "super type" that covers multiple "entities" differently than when an alert is directly targeted for an individual entity.
| TripPattern tripPattern = getRoutingService(environment).getTripPatternForId(id); | ||
| return getAlertEntityOrUnknown(tripPattern, id.toString(), "trip pattern"); | ||
| } | ||
| if (entitySelector instanceof EntitySelector.StopAndRoute) { |
There was a problem hiding this comment.
We could also validate that the stop is actually on the route/trip but I think it's a valid use case that you create an alert "Route x no longer stops at stop y" and want to display that on route, for example.
There was a problem hiding this comment.
Decided that alerts should have the original XandY entity type even though they are not really linked together (anymore).
| trip -> alerts.addAll(alertService.getTripAlerts(trip.getId(), null))); | ||
| break; | ||
| case StopsOnRoute: | ||
| getStops(environment).forEach(stop -> { |
There was a problem hiding this comment.
After I implemented this so it checks that the alerts for stops that are on route, I realised that maybe it would make sense to just fetch all StopAndRoute type alerts that have the route defined here as it might be useful to display alerts that warn that a stop is no longer on the route, for example.
There was a problem hiding this comment.
Changed this so that the stop doesn't need to be on the route/trip/pattern nor do the route/trip have to go through the stop in order to return these StopAndRoute/Trip alerts.
| situationNumber | ||
| ); | ||
| } | ||
| alert.addEntity(new EntitySelector.Unknown("Alert had no entities that could be handled")); |
There was a problem hiding this comment.
Maybe it would also be possible to add Unknown selector each time a selector was ignored because we don't handle it yet instead of adding one Unknown selector at the end like this.
There was a problem hiding this comment.
Should the "add unknown entity" be inside the if-block?
There was a problem hiding this comment.
Indeed... I'll fix that and update tests a bit so they will catch if suddenly new entities appear.
There was a problem hiding this comment.
Fixed it now and changed tests so that they test that only the intended entities get added instead of checking that x type entities don't get added.
| Direction on a route. In practice, | ||
| this means the trips/patterns of a route that have the defined direction. | ||
| """ | ||
| type DirectionOnRoute { |
There was a problem hiding this comment.
Maybe it would be useful to expose the affected trips/patterns through this type.
There was a problem hiding this comment.
Removed this type and instead generated Pattern selectors from the DirectionAndRoute entity selector.
| Route type entity which covers all agencies if agency is null, | ||
| otherwise only relevant for one agency. | ||
| """ | ||
| type RouteType { |
There was a problem hiding this comment.
Maybe it would be useful to expose the affected routes through this type.
| } else { | ||
| direction = -1; | ||
| int directionId = MISSING_INT_FIELD_VALUE; | ||
| if (informed.hasDirectionId()) { |
There was a problem hiding this comment.
Should we also handle informed.getTrip().getDirectionId() here. I'm not quite sure what is the difference between them other than that the trip descriptor's direction was added to the spec first(?). I have a feeling that the trip descriptor's directionId should be used for fuzzy trip matching to find individual trips instead of using it just together with the route_id.
There was a problem hiding this comment.
We decided that the TripDescriptor's direction_id should only be used for fuzzy matching.
| new FeedScopedId(feedId, routeId) | ||
| )); | ||
| } else if (directionId != MISSING_INT_FIELD_VALUE) { | ||
| alertText.addEntity(new EntitySelector.DirectionAndRoute( |
There was a problem hiding this comment.
I decided to add this new DirectionAndRoute type instead of using the Pattern selector. The pattern selector is not being used for anything, can it be removed or should this be changed to use it?
There was a problem hiding this comment.
Removed TripPattern entity selector as it is not being used for anything and couldn't think of a way it could be used in the near future either.
…ate alerts for patterns
leonardehrenfried
left a comment
There was a problem hiding this comment.
I would really like to see the filter logic being made a lot more readable by reducing the multi-line, multi-indented filter functions into smaller bits.
Also, I think the filter classes can share a significant part of the code. I see lots of repetition.
|
We discussed this PR today, at the developer meeting. I agree with @leonardehrenfried that both GraphQL APIs is kind of ugly, but I hope we can get rid of them, not too long time into the future. They are also both considered "Sandbox" features so I am unsure if they are the right place to spent time cleaning up. @optionsome wrote:
I can only give a general advice here, but this what I think: OTP is a travel planner and we keep some relevant information (like the Index API). To solve the problem (OTP features) we sometimes transform input models(pattern selectors) into simpler or easier to work with data structures - if these are not sufficient to recreate the input, then we kindly ask the consumer requesting the information to look at the input instead. @optionsome you know much better than me, what is right in this case. You have my support if you want to reduce the "information value" if that lead to a simpler API for most clients or the maintenance of OTP become easier. |
|
Indeed there is a lot of room for improvement in the GraphQL API code, both to make it more readable and also to optimize the performance. I was aware while writing this code that at least some parts of it need to be rewritten soon anyway as @t2gran said, therefore I didn't spend too much time on polishing the code. We should consider @leonardehrenfried 's comments when implementing the new API but I also feel like that maybe we shouldn't spend too much time on improving the legacy GraphQL API at this point. I refactored the siri test changes as it was easy to do while keeping it still simple to read hopefully 2eb024a. |
|
Does anyone have a clue why the code suddenly doesn't build in github actions? I only touched some tests a bit after last successful build and locally it compiles for me at least? |
t2gran
left a comment
There was a problem hiding this comment.
I do not have much to contribute here, but as @leonardehrenfried alreaddy pointed out there are some repetition between the two APIs - and it seem that the APIs also do quite a bit of generic business logic - if so that logic belongs in the core of OTP, not in the API mapping.
A good guidance is that logic witch is use-case specific should remain in the API mappers while reusable logic should be pushed to domain model. We can do this cleanup as part of this PR or later, when doing the new API.
We will clean up the APIs when working on the new API
Summary
Issue
closes #3779, #3486
Unit tests
Added unit tests for the alert updaters
Code style
Have you followed the suggested code style?
Yes
Documentation
Is there some documentation that should be updated?
Changelog
From title and added changelog for sandbox features