diff --git a/application/src/ext-test/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceTest.java index 761971bc56f..84161c00484 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceTest.java @@ -7,6 +7,7 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; import org.opentripplanner.updater.spi.HttpHeaders; class SmooveBikeRentalDataSourceTest { @@ -18,7 +19,8 @@ void makeStation() { "file:src/ext-test/resources/smoovebikerental/smoove.json", null, true, - HttpHeaders.empty() + HttpHeaders.empty(), + RentalPickupType.ALL ) ); assertTrue(source.update()); @@ -84,7 +86,8 @@ void makeStationWithoutOverloading() { "file:src/ext-test/resources/smoovebikerental/smoove.json", null, false, - HttpHeaders.empty() + HttpHeaders.empty(), + RentalPickupType.ALL ) ); assertTrue(source.update()); diff --git a/application/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceParameters.java b/application/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceParameters.java index 5aa834554c7..a04ea004bf0 100644 --- a/application/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceParameters.java +++ b/application/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceParameters.java @@ -1,6 +1,8 @@ package org.opentripplanner.ext.smoovebikerental; +import java.util.Set; import javax.annotation.Nullable; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_rental.VehicleRentalSourceType; import org.opentripplanner.updater.vehicle_rental.datasources.params.VehicleRentalDataSourceParameters; @@ -12,7 +14,8 @@ public record SmooveBikeRentalDataSourceParameters( String url, String network, boolean overloadingAllowed, - HttpHeaders httpHeaders + HttpHeaders httpHeaders, + Set rentalPickupTypes ) implements VehicleRentalDataSourceParameters { /** @@ -29,4 +32,9 @@ public String getNetwork(String defaultValue) { public VehicleRentalSourceType sourceType() { return VehicleRentalSourceType.SMOOVE; } + + @Override + public boolean allowRentalType(RentalPickupType rentalPickupType) { + return rentalPickupTypes.contains(rentalPickupType); + } } diff --git a/application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java b/application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java index 03b0acd59cd..dc0fa2868ec 100644 --- a/application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java @@ -18,6 +18,7 @@ import org.opentripplanner.updater.spi.GraphUpdater; import org.opentripplanner.updater.vehicle_rental.VehicleRentalUpdater; import org.opentripplanner.updater.vehicle_rental.datasources.VehicleRentalDataSourceFactory; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -110,7 +111,9 @@ private static List buildListOfNetworksFr networkName, networkParams.geofencingZones(), // overloadingAllowed - not part of GBFS, not supported here - false + false, + // rentalPickupType not supported + RentalPickupType.ALL ) ); } else { diff --git a/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/sources/VehicleRentalSourceFactory.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/sources/VehicleRentalSourceFactory.java index aa548977c7e..e58b5e96ae8 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/sources/VehicleRentalSourceFactory.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/sources/VehicleRentalSourceFactory.java @@ -1,16 +1,20 @@ package org.opentripplanner.standalone.config.routerconfig.updaters.sources; +import static org.opentripplanner.standalone.config.framework.json.EnumMapper.docEnumValueList; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V1_5; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_1; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_2; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_3; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_7; +import java.util.Set; import org.opentripplanner.ext.smoovebikerental.SmooveBikeRentalDataSourceParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.routerconfig.updaters.HttpHeadersConfig; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_rental.VehicleRentalSourceType; import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; import org.opentripplanner.updater.vehicle_rental.datasources.params.VehicleRentalDataSourceParameters; /** @@ -43,13 +47,15 @@ public VehicleRentalDataSourceParameters create() { headers(), network(), geofencingZones(), - overloadingAllowed() + overloadingAllowed(), + rentalPickupTypes() ); case SMOOVE -> new SmooveBikeRentalDataSourceParameters( url(), network(), overloadingAllowed(), - headers() + headers(), + rentalPickupTypes() ); }; } @@ -121,4 +127,13 @@ private boolean geofencingZones() { ) .asBoolean(false); } + + private Set rentalPickupTypes() { + return c + .of("rentalPickupTypes") + .since(V2_7) + .summary(RentalPickupType.STATION.typeDescription()) + .description(docEnumValueList(RentalPickupType.values())) + .asEnumSet(RentalPickupType.class, RentalPickupType.ALL); + } } diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java index e3e86981bc8..331c4a15a70 100644 --- a/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java @@ -22,6 +22,7 @@ import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.model.VehicleRentalSystem; import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -75,43 +76,44 @@ public List getUpdates() { final Map vehicleTypes = getVehicleTypes(system); List stations = new LinkedList<>(); - - // Both station information and status are required for all systems using stations - GBFSStationInformation stationInformation = loader.getFeed(GBFSStationInformation.class); - GBFSStationStatus stationStatus = loader.getFeed(GBFSStationStatus.class); - if (stationInformation != null && stationStatus != null) { - // Index all the station status entries on their station ID. - Map statusLookup = stationStatus - .getData() - .getStations() - .stream() - .collect(Collectors.toMap(GBFSStation::getStationId, Function.identity())); - GbfsStationStatusMapper stationStatusMapper = new GbfsStationStatusMapper( - statusLookup, - vehicleTypes - ); - GbfsStationInformationMapper stationInformationMapper = new GbfsStationInformationMapper( - system, - vehicleTypes, - params.allowKeepingRentedVehicleAtDestination(), - params.overloadingAllowed() - ); - - // Iterate over all known stations, and if we have any status information add it to those station objects. - stations.addAll( - stationInformation + if (params.allowRentalType(RentalPickupType.STATION)) { + // Both station information and status are required for all systems using stations + GBFSStationInformation stationInformation = loader.getFeed(GBFSStationInformation.class); + GBFSStationStatus stationStatus = loader.getFeed(GBFSStationStatus.class); + if (stationInformation != null && stationStatus != null) { + // Index all the station status entries on their station ID. + Map statusLookup = stationStatus .getData() .getStations() .stream() - .map(stationInformationMapper::mapStationInformation) - .filter(Objects::nonNull) - .peek(stationStatusMapper::fillStationStatus) - .toList() - ); + .collect(Collectors.toMap(GBFSStation::getStationId, Function.identity())); + GbfsStationStatusMapper stationStatusMapper = new GbfsStationStatusMapper( + statusLookup, + vehicleTypes + ); + GbfsStationInformationMapper stationInformationMapper = new GbfsStationInformationMapper( + system, + vehicleTypes, + params.allowKeepingRentedVehicleAtDestination(), + params.overloadingAllowed() + ); + + // Iterate over all known stations, and if we have any status information add it to those station objects. + stations.addAll( + stationInformation + .getData() + .getStations() + .stream() + .map(stationInformationMapper::mapStationInformation) + .filter(Objects::nonNull) + .peek(stationStatusMapper::fillStationStatus) + .toList() + ); + } } // Append the floating bike stations. - if (OTPFeature.FloatingBike.isOn()) { + if (OTPFeature.FloatingBike.isOn() && params.allowRentalType(RentalPickupType.FREE_FLOATING)) { GBFSFreeBikeStatus freeBikeStatus = loader.getFeed(GBFSFreeBikeStatus.class); if (freeBikeStatus != null) { GbfsFreeVehicleStatusMapper freeVehicleStatusMapper = new GbfsFreeVehicleStatusMapper( diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/GbfsVehicleRentalDataSourceParameters.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/GbfsVehicleRentalDataSourceParameters.java index 7d7a6c75a5d..31c81079046 100644 --- a/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/GbfsVehicleRentalDataSourceParameters.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/GbfsVehicleRentalDataSourceParameters.java @@ -1,5 +1,7 @@ package org.opentripplanner.updater.vehicle_rental.datasources.params; +import java.util.Objects; +import java.util.Set; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_rental.VehicleRentalSourceType; @@ -10,11 +12,20 @@ public record GbfsVehicleRentalDataSourceParameters( HttpHeaders httpHeaders, String network, boolean geofencingZones, - boolean overloadingAllowed + boolean overloadingAllowed, + Set rentalPickupTypes ) implements VehicleRentalDataSourceParameters { + public GbfsVehicleRentalDataSourceParameters { + Objects.requireNonNull(rentalPickupTypes); + } @Override public VehicleRentalSourceType sourceType() { return VehicleRentalSourceType.GBFS; } + + @Override + public boolean allowRentalType(RentalPickupType rentalPickupType) { + return rentalPickupTypes.contains(rentalPickupType); + } } diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/RentalPickupType.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/RentalPickupType.java new file mode 100644 index 00000000000..e117f59d9c1 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/RentalPickupType.java @@ -0,0 +1,38 @@ +package org.opentripplanner.updater.vehicle_rental.datasources.params; + +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; +import org.opentripplanner.framework.doc.DocumentedEnum; + +/** + * This is temporary and will be removed in a future version of OTP. + * + * Enum to specify the type of rental data that is allowed to be read from the data source. + */ +public enum RentalPickupType implements DocumentedEnum { + STATION("Stations are imported."), + FREE_FLOATING("Free-floating vehicles are imported."); + + public static final Set ALL = Collections.unmodifiableSet( + EnumSet.allOf(RentalPickupType.class) + ); + + private final String description; + + RentalPickupType(String description) { + this.description = description.stripIndent().trim(); + } + + @Override + public String typeDescription() { + return ( + "This is temporary and will be removed in a future version of OTP. Use this to specify the type of rental data that is allowed to be read from the data source." + ); + } + + @Override + public String enumValueDescription() { + return description; + } +} diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/VehicleRentalDataSourceParameters.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/VehicleRentalDataSourceParameters.java index cdff994ab18..e87e7909bc5 100644 --- a/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/VehicleRentalDataSourceParameters.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/VehicleRentalDataSourceParameters.java @@ -13,4 +13,6 @@ public interface VehicleRentalDataSourceParameters { VehicleRentalSourceType sourceType(); HttpHeaders httpHeaders(); + + boolean allowRentalType(RentalPickupType rentalPickupType); } diff --git a/application/src/test/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterTest.java index 2ca93a10f28..f48faef3180 100644 --- a/application/src/test/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterTest.java +++ b/application/src/test/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterTest.java @@ -20,6 +20,7 @@ import org.opentripplanner.updater.GraphWriterRunnable; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_rental.datasources.VehicleRentalDatasource; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; import org.opentripplanner.updater.vehicle_rental.datasources.params.VehicleRentalDataSourceParameters; class VehicleRentalUpdaterTest { @@ -103,5 +104,10 @@ public VehicleRentalSourceType sourceType() { public HttpHeaders httpHeaders() { return HttpHeaders.empty(); } + + @Override + public boolean allowRentalType(RentalPickupType rentalPickupType) { + return true; + } } } diff --git a/application/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java index 7b062bcc17c..b238b22f305 100644 --- a/application/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java +++ b/application/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java @@ -16,6 +16,7 @@ import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; /** * This tests the mapping between data coming from a {@link GbfsFeedLoader} to OTP station models. @@ -32,7 +33,8 @@ void makeStationFromV22() { HttpHeaders.empty(), null, false, - false + false, + RentalPickupType.ALL ), new OtpHttpClientFactory() ); @@ -123,7 +125,8 @@ void geofencing() { HttpHeaders.empty(), null, true, - false + false, + RentalPickupType.ALL ), new OtpHttpClientFactory() ); @@ -165,7 +168,8 @@ void makeStationFromV10() { HttpHeaders.empty(), network, false, - true + true, + RentalPickupType.ALL ), new OtpHttpClientFactory() ); diff --git a/doc/user/UpdaterConfig.md b/doc/user/UpdaterConfig.md index cc5e1d75901..f61cce12f54 100644 --- a/doc/user/UpdaterConfig.md +++ b/doc/user/UpdaterConfig.md @@ -313,18 +313,19 @@ GBFS form factors: -| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | -|---------------------------------------------------------------------------------------|:---------------:|---------------------------------------------------------------------------------|:----------:|---------------|:-----:| -| type = "vehicle-rental" | `enum` | The type of the updater. | *Required* | | 1.5 | -| [allowKeepingRentedVehicleAtDestination](#u_1_allowKeepingRentedVehicleAtDestination) | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.1 | -| frequency | `duration` | How often the data should be updated. | *Optional* | `"PT1M"` | 1.5 | -| [geofencingZones](#u_1_geofencingZones) | `boolean` | Compute rental restrictions based on GBFS 2.2 geofencing zones. | *Optional* | `false` | 2.3 | -| language | `string` | TODO | *Optional* | | 2.1 | -| [network](#u_1_network) | `string` | The name of the network to override the one derived from the source data. | *Optional* | | 1.5 | -| overloadingAllowed | `boolean` | Allow leaving vehicles at a station even though there are no free slots. | *Optional* | `false` | 2.2 | -| [sourceType](#u_1_sourceType) | `enum` | What source of vehicle rental updater to use. | *Required* | | 1.5 | -| url | `string` | The URL to download the data from. | *Required* | | 1.5 | -| [headers](#u_1_headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 1.5 | +| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | +|---------------------------------------------------------------------------------------|:---------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| +| type = "vehicle-rental" | `enum` | The type of the updater. | *Required* | | 1.5 | +| [allowKeepingRentedVehicleAtDestination](#u_1_allowKeepingRentedVehicleAtDestination) | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.1 | +| frequency | `duration` | How often the data should be updated. | *Optional* | `"PT1M"` | 1.5 | +| [geofencingZones](#u_1_geofencingZones) | `boolean` | Compute rental restrictions based on GBFS 2.2 geofencing zones. | *Optional* | `false` | 2.3 | +| language | `string` | TODO | *Optional* | | 2.1 | +| [network](#u_1_network) | `string` | The name of the network to override the one derived from the source data. | *Optional* | | 1.5 | +| overloadingAllowed | `boolean` | Allow leaving vehicles at a station even though there are no free slots. | *Optional* | `false` | 2.2 | +| [sourceType](#u_1_sourceType) | `enum` | What source of vehicle rental updater to use. | *Required* | | 1.5 | +| url | `string` | The URL to download the data from. | *Required* | | 1.5 | +| [headers](#u_1_headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 1.5 | +| [rentalPickupTypes](#u_1_rentalPickupTypes) | `enum set` | This is temporary and will be removed in a future version of OTP. Use this to specify the type of rental data that is allowed to be read from the data source. | *Optional* | | 2.7 | ##### Parameter details @@ -383,6 +384,18 @@ What source of vehicle rental updater to use. HTTP headers to add to the request. Any header key, value can be inserted. +

rentalPickupTypes

+ +**Since version:** `2.7` ∙ **Type:** `enum set` ∙ **Cardinality:** `Optional` +**Path:** /updaters/[1] +**Enum values:** `station` | `free-floating` + +This is temporary and will be removed in a future version of OTP. Use this to specify the type of rental data that is allowed to be read from the data source. + + - `station` Stations are imported. + - `free-floating` Free-floating vehicles are imported. + + ##### Example configuration