-
Notifications
You must be signed in to change notification settings - Fork 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
Add currentFuelPercent and currentRangeMeters to RentalVehichle in the GTFS GraphQL API #6272
base: dev-2.x
Are you sure you want to change the base?
Add currentFuelPercent and currentRangeMeters to RentalVehichle in the GTFS GraphQL API #6272
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev-2.x #6272 +/- ##
=============================================
- Coverage 69.79% 69.78% -0.01%
- Complexity 17943 17958 +15
=============================================
Files 2046 2048 +2
Lines 76685 76729 +44
Branches 7829 7836 +7
=============================================
+ Hits 53520 53546 +26
- Misses 20423 20439 +16
- Partials 2742 2744 +2 ☔ View full report in Codecov by Sentry. |
application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls
Outdated
Show resolved
Hide resolved
2eef86c
to
00a1e4b
Compare
application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls
Outdated
Show resolved
Hide resolved
application/src/test/java/org/opentripplanner/routing/core/DistanceTest.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/opentripplanner/transit/model/basic/Distance.java
Outdated
Show resolved
Hide resolved
...tion/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalVehicle.java
Outdated
Show resolved
Hide resolved
...tion/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalVehicle.java
Outdated
Show resolved
Hide resolved
...tion/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalVehicle.java
Outdated
Show resolved
Hide resolved
application/src/test/resources/org/opentripplanner/apis/gtfs/queries/rental-vehicle.graphql
Outdated
Show resolved
Hide resolved
Does the library we use validate that the fuel percent is between 0 and 1 or should we do it? |
The library validate if the value is between 0 and 1 in output (when generating the graphql response). {
"errors": [
{
"message": "Can't serialize value (/rentalVehicles[0]/currentFuelPercent) : Value is under 0 or greater than 1.",
"path": [
"rentalVehicles",
0,
"currentFuelPercent"
],
"extensions": {
"classification": "DataFetchingException"
}
}
],
"data": {
"rentalVehicles": [
{
"name": "Ninebot A200",
"lat": 43.772581,
"lon": 13.132542,
"currentFuelPercent": null
}
]
}
} The value is not checked when received in the gbfs mapper, do we need to check it also there? I saw that in the var ratio = (Double) GraphQLScalars.RATIO_SCALAR.getCoercing().parseValue(HALF); to parse a value. |
I would prefer to log some warning and ignore the value in the mapper instead of letting it be cause issues in the APIs. |
@testower do you know if there is some general policy in the GBFS java library for validating values (such as not allowing over 100% fuel percent or negative range meters)? |
The java model used in otp does not have validation annotations, so anything that can be deserialized is accepted. |
Is there an option to use validation annotations? I'm just wondering should we discuss the possibility in tomorrow's dev meeting, for example? |
Not with the current library. It is left out with intention. I don't think validation should be handled in the deserialization step anyway. This is runtime code / hot code path, so I think OTP should validate the data it needs to in the business layer. |
I should probably add some reasoning: I don't think it's desirable to reject the deserialization of a whole file update, because some particular piece of data in that update doesn't validate according to the validation annotations. The data may still be perfectly usable by OTP. |
...java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFreeVehicleStatusMapper.java
Outdated
Show resolved
Hide resolved
You need to resolve merge conflicts. |
b52ebca
to
284133a
Compare
// if the propulsion type has an engine current_range_meters is required | ||
if ( | ||
vehicle.getVehicleTypeId() != null && | ||
vehicleTypes.get(vehicle.getVehicleTypeId()) != null && |
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 added this check, can you double check if it's right?
I'm not sure but vehicle_type_id
is REQUIRED if the vehicle_types.json file is defined, that file is REQUIRED for systems with free_bike_status.json
and if this file is not included then all vehicles are non motorized bicycles.
Therefore if the vehicleTypeId is not present in the vehicleTypes map I can assume that the file vehicle_types.json
is not present and all vehicles are not motorized, so the propulsion type is human and range is not needed.
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 think this is correct, but this is in an area where a lot of feeds get things wrong so this validation might cause issues but I'm not sure if I'm against this or not.
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 spoke to @hbruch about this and he said that there are a number of feeds that don't include it where they should but he is in favour of enforcing the spec anyway. If we are not strict with data producers, they will never learn.
...ication/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleFuel.java
Outdated
Show resolved
Hide resolved
...ication/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleFuel.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/opentripplanner/transit/model/basic/Ratio.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/opentripplanner/transit/model/basic/Distance.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/opentripplanner/transit/model/basic/Distance.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/opentripplanner/transit/model/basic/Ratio.java
Outdated
Show resolved
Hide resolved
|
||
@Override | ||
public String toString() { | ||
return this.ratio.toString(); |
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.
Should the toString output the number as a percent (like 24.5%
), I'm not sure. With cost for example we have a custom toString format.
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 discussed this today in the dev meeting and decided that the to string should just return the double as string, not a percent.
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.
Ok, so it's fine as it is
vehicle.getCurrentFuelPercent(), | ||
e.getMessage() | ||
); | ||
} catch (NullPointerException e) {} |
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.
Do we need to catch npe, when would it happen?
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.
current_fuel_percent is an optional field so getCurrentFuelPercent
could return null
// if the propulsion type has an engine current_range_meters is required | ||
if ( | ||
vehicle.getVehicleTypeId() != null && | ||
vehicleTypes.get(vehicle.getVehicleTypeId()) != null && |
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 think this is correct, but this is in an area where a lot of feeds get things wrong so this validation might cause issues but I'm not sure if I'm against this or not.
RentalVehicleType.PropulsionType.HUMAN && | ||
rangeMeters == null | ||
) { | ||
return null; |
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 should log a warning here since the whole vehicle is ignored.
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 added the check to be compliant to the GBFS standard and I think it's better this way in the future but I see that it could be an issue if feeds get this wrong. I can remove the check if you say it's for the best, I don't think it would break anything.
Maybe I can add just a warning and return the object?
fc01a87
to
26d8d7d
Compare
application/src/main/java/org/opentripplanner/transit/model/basic/Ratio.java
Outdated
Show resolved
Hide resolved
import org.junit.jupiter.api.Test; | ||
import org.opentripplanner.transit.model.basic.Ratio; | ||
|
||
public class RatioTest { |
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.
Very nice.
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.
Thanks
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 looked the Ratio implementation and how to provide a factory method witch handles validation errors. As mentioned in the dev-meeting today, my first attempt was to use a Result object - this was rather ugly and did not increase the readability or lowered the complexity(maintenance cost). So, after a bit of refactoring I went for a solution witch uses an error-handler and return an Optional - this was easy to implement and looks good on the caller side.
Please merge in these changes:
https://github.com/opentripplanner/OpenTripPlanner/tree/pr-6272
or cherry-pick commits:
The the two commits in the branch above fixes ALL my suggestions below, but I wanted to leave the comments so you can understand why I changed the code.
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(this.ratio); |
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.
You should use the Double not Objects hash function here.
|
||
@Override | ||
public boolean equals(Object other) { | ||
if (other instanceof Ratio ratio) { |
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.
Do not use 'instanceof' in equals methods, follw the same practise as other value-objects.
*/ | ||
public class Ratio { | ||
|
||
private final Double ratio; |
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.
private final Double ratio; | |
private final double ratio; |
return this.ratio.toString(); | ||
} | ||
|
||
public Double asDouble() { |
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.
public Double asDouble() { | |
public double asDouble() { |
Just to be clear - We do not want "insane" values in OTP. The DTOs used to import can accept it, but not the core OTP model. In general there is two categories of data:
|
Summary
Add currentFuelPercent and currentRangeMeters fields to RentalVehicle in the graphql GTFS API
Issue
issue
I added currentRangeMeters on top of the issue because it is related
Unit tests
Write a few words on how the new code is tested.
graphiql
frontendpass the continuous integration service
? Yes
Documentation