Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/filter-updater-data' into dev-2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
vesameskanen committed Nov 13, 2024
2 parents e40f485 + 993bed1 commit 7a754ec
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.AllowedRentalType;
import org.opentripplanner.updater.spi.HttpHeaders;

class SmooveBikeRentalDataSourceTest {
Expand All @@ -18,7 +19,8 @@ void makeStation() {
"file:src/ext-test/resources/smoovebikerental/smoove.json",
null,
true,
HttpHeaders.empty()
HttpHeaders.empty(),
AllowedRentalType.ALL
)
);
assertTrue(source.update());
Expand Down Expand Up @@ -84,7 +86,8 @@ void makeStationWithoutOverloading() {
"file:src/ext-test/resources/smoovebikerental/smoove.json",
null,
false,
HttpHeaders.empty()
HttpHeaders.empty(),
AllowedRentalType.ALL
)
);
assertTrue(source.update());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.opentripplanner.ext.smoovebikerental;

import javax.annotation.Nullable;
import org.opentripplanner.updater.vehicle_rental.datasources.params.AllowedRentalType;
import org.opentripplanner.updater.spi.HttpHeaders;
import org.opentripplanner.updater.vehicle_rental.VehicleRentalSourceType;
import org.opentripplanner.updater.vehicle_rental.datasources.params.VehicleRentalDataSourceParameters;
Expand All @@ -12,7 +13,8 @@ public record SmooveBikeRentalDataSourceParameters(
String url,
String network,
boolean overloadingAllowed,
HttpHeaders httpHeaders
HttpHeaders httpHeaders,
AllowedRentalType allowedRentalType
)
implements VehicleRentalDataSourceParameters {
/**
Expand All @@ -29,4 +31,9 @@ public String getNetwork(String defaultValue) {
public VehicleRentalSourceType sourceType() {
return VehicleRentalSourceType.SMOOVE;
}

@Override
public boolean allowRentalType(AllowedRentalType rentalType) {
return allowedRentalType == null || allowedRentalType == AllowedRentalType.ALL || rentalType == allowedRentalType;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.AllowedRentalType;
import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -110,7 +111,9 @@ private static List<GbfsVehicleRentalDataSourceParameters> buildListOfNetworksFr
networkName,
networkParams.geofencingZones(),
// overloadingAllowed - not part of GBFS, not supported here
false
false,
// allowedRentalType not supported
AllowedRentalType.ALL
)
);
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
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 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.AllowedRentalType;
import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters;
import org.opentripplanner.updater.vehicle_rental.datasources.params.VehicleRentalDataSourceParameters;

Expand Down Expand Up @@ -43,13 +46,15 @@ public VehicleRentalDataSourceParameters create() {
headers(),
network(),
geofencingZones(),
overloadingAllowed()
overloadingAllowed(),
allowedRentalType()
);
case SMOOVE -> new SmooveBikeRentalDataSourceParameters(
url(),
network(),
overloadingAllowed(),
headers()
headers(),
allowedRentalType()
);
};
}
Expand Down Expand Up @@ -121,4 +126,13 @@ private boolean geofencingZones() {
)
.asBoolean(false);
}

private AllowedRentalType allowedRentalType() {
return c
.of("allowedRentalType")
.since(V2_7)
.summary(AllowedRentalType.ALL.typeDescription())
.description(docEnumValueList(AllowedRentalType.values()))
.asEnum(AllowedRentalType.ALL);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.opentripplanner.service.vehiclerental.model.RentalVehicleType;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalSystem;
import org.opentripplanner.updater.vehicle_rental.datasources.params.AllowedRentalType;
import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters;
import org.opentripplanner.utils.tostring.ToStringBuilder;
import org.slf4j.Logger;
Expand Down Expand Up @@ -76,42 +77,44 @@ public List<VehicleRentalPlace> getUpdates() {

List<VehicleRentalPlace> 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<String, GBFSStation> 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(AllowedRentalType.STATIONS)) {
// 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<String, GBFSStation> 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(AllowedRentalType.VEHICLES)) {
GBFSFreeBikeStatus freeBikeStatus = loader.getFeed(GBFSFreeBikeStatus.class);
if (freeBikeStatus != null) {
GbfsFreeVehicleStatusMapper freeVehicleStatusMapper = new GbfsFreeVehicleStatusMapper(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.opentripplanner.updater.vehicle_rental.datasources.params;

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 AllowedRentalType implements DocumentedEnum<AllowedRentalType> {
STATIONS("Only station data is allowed."),
VEHICLES("Only vehicle data is allowed."),
ALL("All types of rental data are allowed.");

private final String description;

AllowedRentalType(String description) {
this.description = description.stripIndent().trim();
}

@Override
public String typeDescription() {
return (
"Temporary parameter. 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;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.opentripplanner.updater.vehicle_rental.datasources.params;

import java.util.Objects;
import org.opentripplanner.updater.spi.HttpHeaders;
import org.opentripplanner.updater.vehicle_rental.VehicleRentalSourceType;

Expand All @@ -10,11 +11,24 @@ public record GbfsVehicleRentalDataSourceParameters(
HttpHeaders httpHeaders,
String network,
boolean geofencingZones,
boolean overloadingAllowed
boolean overloadingAllowed,
AllowedRentalType allowedRentalType
)
implements VehicleRentalDataSourceParameters {
public GbfsVehicleRentalDataSourceParameters {
Objects.requireNonNull(allowedRentalType);
}
@Override
public VehicleRentalSourceType sourceType() {
return VehicleRentalSourceType.GBFS;
}

@Override
public boolean allowRentalType(AllowedRentalType rentalType) {
return (
allowedRentalType == null ||
allowedRentalType == AllowedRentalType.ALL ||
allowedRentalType == rentalType
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public interface VehicleRentalDataSourceParameters {
VehicleRentalSourceType sourceType();

HttpHeaders httpHeaders();

boolean allowRentalType(AllowedRentalType rentalType);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.AllowedRentalType;
import org.opentripplanner.updater.vehicle_rental.datasources.params.VehicleRentalDataSourceParameters;

class VehicleRentalUpdaterTest {
Expand Down Expand Up @@ -103,5 +104,10 @@ public VehicleRentalSourceType sourceType() {
public HttpHeaders httpHeaders() {
return HttpHeaders.empty();
}

@Override
public boolean allowRentalType(AllowedRentalType rentalType) {
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.opentripplanner.service.vehiclerental.model.RentalVehicleType;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace;
import org.opentripplanner.updater.spi.HttpHeaders;
import org.opentripplanner.updater.vehicle_rental.datasources.params.AllowedRentalType;
import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters;

/**
Expand All @@ -32,7 +33,8 @@ void makeStationFromV22() {
HttpHeaders.empty(),
null,
false,
false
false,
AllowedRentalType.ALL
),
new OtpHttpClientFactory()
);
Expand Down Expand Up @@ -123,7 +125,8 @@ void geofencing() {
HttpHeaders.empty(),
null,
true,
false
false,
AllowedRentalType.ALL
),
new OtpHttpClientFactory()
);
Expand Down Expand Up @@ -165,7 +168,8 @@ void makeStationFromV10() {
HttpHeaders.empty(),
network,
false,
true
true,
AllowedRentalType.ALL
),
new OtpHttpClientFactory()
);
Expand Down
38 changes: 26 additions & 12 deletions doc/user/UpdaterConfig.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,18 +313,19 @@ GBFS form factors:
<!-- vehicle-rental BEGIN -->
<!-- NOTE! This section is auto-generated. Do not change, change doc in code instead. -->

| 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 |
| [allowedRentalType](#u_1_allowedRentalType) | `enum` | Temporary parameter. Use this to specify the type of rental data that is allowed to be read from the data source. | *Optional* | `"all"` | 2.7 |
| 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 |


##### Parameter details
Expand All @@ -346,6 +347,19 @@ For this to be possible three things need to be configured:
- If keeping the vehicle at the destination should be discouraged, then `keepingRentedVehicleAtDestinationCost` (default: 0) may also be set in the routing defaults.


<h4 id="u_1_allowedRentalType">allowedRentalType</h4>

**Since version:** `2.7`**Type:** `enum`**Cardinality:** `Optional`**Default value:** `"all"`
**Path:** /updaters/[1]
**Enum values:** `stations` | `vehicles` | `all`

Temporary parameter. Use this to specify the type of rental data that is allowed to be read from the data source.

- `stations` Only station data is allowed.
- `vehicles` Only vehicle data is allowed.
- `all` All types of rental data are allowed.


<h4 id="u_1_geofencingZones">geofencingZones</h4>

**Since version:** `2.3`**Type:** `boolean`**Cardinality:** `Optional`**Default value:** `false`
Expand Down

0 comments on commit 7a754ec

Please sign in to comment.