-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement SIRI extra calls #6493
base: dev-2.x
Are you sure you want to change the base?
Conversation
868510b
to
fd300a7
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev-2.x #6493 +/- ##
===========================================
Coverage 70.98% 70.98%
- Complexity 18272 18294 +22
===========================================
Files 2000 2002 +2
Lines 75871 76004 +133
Branches 7785 7811 +26
===========================================
+ Hits 53856 53953 +97
- Misses 19268 19293 +25
- Partials 2747 2758 +11 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
fd300a7
to
1177d2c
Compare
1177d2c
to
9c5928e
Compare
10ed14c
to
70c89ea
Compare
70c89ea
to
70b3593
Compare
2817d38
to
c32be07
Compare
((vehicleJourney.getRecordedCalls() != null && | ||
vehicleJourney | ||
.getRecordedCalls() | ||
.getRecordedCalls() | ||
.stream() | ||
.anyMatch(recordedCall -> Boolean.TRUE.equals(recordedCall.isExtraCall()))) || | ||
(vehicleJourney.getEstimatedCalls() != null && | ||
vehicleJourney | ||
.getEstimatedCalls() | ||
.getEstimatedCalls() | ||
.stream() | ||
.anyMatch(estimatedCall -> Boolean.TRUE.equals(estimatedCall.isExtraCall())))) | ||
) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probaby beyond the scope of the PR but what do you think of extracting these very wordy calls to vehicleJourney into a re-usable wrapper type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a few other pieces of code that could be moved into it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already create a list of callwrappers on line 130 in this file so you could pass that into this method to make the check for extra calls cleaner.
var aimedArrivalTime = call.getAimedArrivalTime() != null | ||
? call.getAimedArrivalTime() | ||
: call.getAimedDepartureTime(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't there be a method in CallWrapper
for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you only moved this piece of code. But it is a bit strange:
According to the spec the aimedArrivalTime should never be null except for possibly at the first stop. But a bit lower down on line 67 we ignore this value if isFirstStop
is true. So in practice we will never use the departure time value except for if the message is violating the spec.
I think we should change this code to strictly reject messages that don't have an aimedArrivalTime (unless they are the first call). But maybe you don't want to do that change of behaviour in this PR?
} | ||
|
||
//TODO move to helper | ||
private static String getFirstNameFromList(List<NaturalLanguageStringStructure> names) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove or resolve the TODO?
/** | ||
* Types of SIRI update messages. | ||
*/ | ||
private enum SiriUpdateType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think of Henrik's idea of using an algebraic data type?
sealed interface SiriUpdate
record TripUpdate(
VehicleJourney vehicleJourney
...
) implements SiriUpdate
record ReplacementDeparture implementes SiriUpdate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Genereally speaking this works however, I wonder if we can move the ugly check methods into a wrapper type. This doesn't need to happen in this PR.
EstimatedVehicleJourney estimatedVehicleJourney, | ||
TransitEditorService transitService, | ||
EntityResolver entityResolver, | ||
Function<Trip, FeedScopedId> getTripPatternId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about calling this tripPatternIdGenerator
or generateTripPatternId
instead? Otherwise it looks like we are getting an existing id.
((vehicleJourney.getRecordedCalls() != null && | ||
vehicleJourney | ||
.getRecordedCalls() | ||
.getRecordedCalls() | ||
.stream() | ||
.anyMatch(recordedCall -> Boolean.TRUE.equals(recordedCall.isExtraCall()))) || | ||
(vehicleJourney.getEstimatedCalls() != null && | ||
vehicleJourney | ||
.getEstimatedCalls() | ||
.getEstimatedCalls() | ||
.stream() | ||
.anyMatch(estimatedCall -> Boolean.TRUE.equals(estimatedCall.isExtraCall())))) | ||
) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already create a list of callwrappers on line 130 in this file so you could pass that into this method to make the check for extra calls cleaner.
/** | ||
* Map the call to the aimed StopTime or return null if the stop cannot be found in the site repository. | ||
*/ | ||
StopTime createAimedStopTime( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be @Nullable
var aimedArrivalTime = call.getAimedArrivalTime() != null | ||
? call.getAimedArrivalTime() | ||
: call.getAimedDepartureTime(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you only moved this piece of code. But it is a bit strange:
According to the spec the aimedArrivalTime should never be null except for possibly at the first stop. But a bit lower down on line 67 we ignore this value if isFirstStop
is true. So in practice we will never use the departure time value except for if the message is violating the spec.
I think we should change this code to strictly reject messages that don't have an aimedArrivalTime (unless they are the first call). But maybe you don't want to do that change of behaviour in this PR?
Summary
This PR adds support for the SIRI feature "extra call".
An extra-call consists in adding unplanned stops to a scheduled trip.
It differs from the 2 other currently supported types of update:
Validation rules:
As of today Entur does not receive any SIRI feed that contains extra calls, so this feature may be revisited later on when tested against real data.
There is a limited effort in this PR to de-duplicate logic shared between AddedTripBuilder and ExtraCallBuilder, the idea being that the code should be refactored anyway into a more generic model.
Implementation note: The two pre-existing methods on CallWrapper:
return a wrapper object instead of a primitive boolean. This makes boolean comparison error-prone. This should be refactored in a follow-up PR using the same model as
CallWrapper.isExtraCall()
.Issue
Closes #6188
Unit tests
Added unit tests
Documentation
No