diff --git a/README.md b/README.md index 024baa7b..efece5e9 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ List of additional rules: * `NoInvalidReferenceToPricingPlansInVehicleStatus` * `NoInvalidReferenceToPricingPlansInVehicleTypes` * `NoInvalidReferenceToRegionInStationInformation` +* `NoInvalidReferenceToStation` * `NoInvalidReferenceToVehicleTypesInStationStatus` * `NoMissingVehicleTypesAvailableWhenVehicleTypesExists` * `NoMissingOrInvalidVehicleTypeIdInVehicleStatusWhenVehicleTypesExist` diff --git a/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/rules/NoInvalidReferenceToStation.java b/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/rules/NoInvalidReferenceToStation.java new file mode 100644 index 00000000..eb2fe80c --- /dev/null +++ b/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/rules/NoInvalidReferenceToStation.java @@ -0,0 +1,70 @@ +/* + * + * * + * * + * * * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by + * * * the European Commission - subsequent versions of the EUPL (the "Licence"); + * * * You may not use this work except in compliance with the Licence. + * * * You may obtain a copy of the Licence at: + * * * + * * * https://joinup.ec.europa.eu/software/page/eupl + * * * + * * * Unless required by applicable law or agreed to in writing, software + * * * distributed under the Licence is distributed on an "AS IS" basis, + * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * See the Licence for the specific language governing permissions and + * * * limitations under the Licence. + * * + * + */ + +package org.entur.gbfs.validation.validator.rules; + +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; +import java.util.Map; +import org.json.JSONArray; +import org.json.JSONObject; + +/** + * References to stations in station_information must exist in station_status file and vice versa. + */ +public class NoInvalidReferenceToStation implements CustomRuleSchemaPatcher { + + public static final String STATION_IDS_SCHEMA_PATH = + "$.properties.data.properties.stations.items.properties.station_id"; + + private final String stationReferenceFileName; + + public NoInvalidReferenceToStation(String stationReferenceFileName) { + this.stationReferenceFileName = stationReferenceFileName; + } + + /** + * Adds an enum to the station_id schema of stations.station_id with the station ids from station_status.json + */ + @Override + public DocumentContext addRule( + DocumentContext rawSchemaDocumentContext, + Map feeds + ) { + JSONObject stationReferenceFeed = feeds.get(stationReferenceFileName); + + JSONObject stationIdSchema = rawSchemaDocumentContext.read( + STATION_IDS_SCHEMA_PATH + ); + + JSONArray stationIds = stationReferenceFeed != null + ? JsonPath + .parse(stationReferenceFeed) + .read("$.data.stations[*].station_id") + : new JSONArray(); + + stationIdSchema.put("enum", stationIds); + + return rawSchemaDocumentContext.set( + STATION_IDS_SCHEMA_PATH, + stationIdSchema + ); + } +} diff --git a/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version21.java b/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version21.java index 844e9905..59266735 100644 --- a/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version21.java +++ b/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version21.java @@ -23,6 +23,7 @@ import java.util.Map; import org.entur.gbfs.validation.validator.rules.CustomRuleSchemaPatcher; import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToRegionInStationInformation; +import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToStation; import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToVehicleTypesInStationStatus; import org.entur.gbfs.validation.validator.rules.NoMissingCurrentRangeMetersInVehicleStatusForMotorizedVehicles; import org.entur.gbfs.validation.validator.rules.NoMissingOrInvalidVehicleTypeIdInVehicleStatusWhenVehicleTypesExist; @@ -54,7 +55,8 @@ public class Version21 extends AbstractVersion { "station_status", List.of( new NoInvalidReferenceToVehicleTypesInStationStatus(), - new NoMissingVehicleTypesAvailableWhenVehicleTypesExists() + new NoMissingVehicleTypesAvailableWhenVehicleTypesExists(), + new NoInvalidReferenceToStation("station_information") ), "free_bike_status", List.of( @@ -68,7 +70,10 @@ public class Version21 extends AbstractVersion { "system_information", List.of(new NoMissingStoreUriInSystemInformation("free_bike_status")), "station_information", - List.of(new NoInvalidReferenceToRegionInStationInformation()) + List.of( + new NoInvalidReferenceToRegionInStationInformation(), + new NoInvalidReferenceToStation("station_status") + ) ); protected Version21() { diff --git a/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version22.java b/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version22.java index df536b2b..f5ae4d00 100644 --- a/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version22.java +++ b/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version22.java @@ -24,6 +24,7 @@ import org.entur.gbfs.validation.validator.rules.CustomRuleSchemaPatcher; import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToPricingPlansInVehicleStatus; import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToRegionInStationInformation; +import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToStation; import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToVehicleTypesInStationStatus; import org.entur.gbfs.validation.validator.rules.NoMissingCurrentRangeMetersInVehicleStatusForMotorizedVehicles; import org.entur.gbfs.validation.validator.rules.NoMissingOrInvalidVehicleTypeIdInVehicleStatusWhenVehicleTypesExist; @@ -55,7 +56,8 @@ public class Version22 extends AbstractVersion { "station_status", List.of( new NoInvalidReferenceToVehicleTypesInStationStatus(), - new NoMissingVehicleTypesAvailableWhenVehicleTypesExists() + new NoMissingVehicleTypesAvailableWhenVehicleTypesExists(), + new NoInvalidReferenceToStation("station_information") ), "free_bike_status", List.of( @@ -70,7 +72,10 @@ public class Version22 extends AbstractVersion { "system_information", List.of(new NoMissingStoreUriInSystemInformation("free_bike_status")), "station_information", - List.of(new NoInvalidReferenceToRegionInStationInformation()) + List.of( + new NoInvalidReferenceToRegionInStationInformation(), + new NoInvalidReferenceToStation("station_status") + ) ); protected Version22() { diff --git a/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version23.java b/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version23.java index ab7c9fd6..9e78b1d5 100644 --- a/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version23.java +++ b/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version23.java @@ -25,6 +25,7 @@ import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToPricingPlansInVehicleStatus; import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToPricingPlansInVehicleTypes; import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToRegionInStationInformation; +import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToStation; import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToVehicleTypesInStationStatus; import org.entur.gbfs.validation.validator.rules.NoMissingCurrentRangeMetersInVehicleStatusForMotorizedVehicles; import org.entur.gbfs.validation.validator.rules.NoMissingOrInvalidVehicleTypeIdInVehicleStatusWhenVehicleTypesExist; @@ -58,7 +59,8 @@ public class Version23 extends AbstractVersion { "station_status", List.of( new NoInvalidReferenceToVehicleTypesInStationStatus(), - new NoMissingVehicleTypesAvailableWhenVehicleTypesExists() + new NoMissingVehicleTypesAvailableWhenVehicleTypesExists(), + new NoInvalidReferenceToStation("station_information") ), "free_bike_status", List.of( @@ -73,7 +75,10 @@ public class Version23 extends AbstractVersion { "system_information", List.of(new NoMissingStoreUriInSystemInformation("free_bike_status")), "station_information", - List.of(new NoInvalidReferenceToRegionInStationInformation()) + List.of( + new NoInvalidReferenceToRegionInStationInformation(), + new NoInvalidReferenceToStation("station_status") + ) ); protected Version23() { diff --git a/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version30.java b/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version30.java index 6dfca8f9..f4d0c78d 100644 --- a/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version30.java +++ b/gbfs-validator-java/src/main/java/org/entur/gbfs/validation/validator/versions/Version30.java @@ -25,6 +25,7 @@ import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToPricingPlansInVehicleStatus; import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToPricingPlansInVehicleTypes; import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToRegionInStationInformation; +import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToStation; import org.entur.gbfs.validation.validator.rules.NoInvalidReferenceToVehicleTypesInStationStatus; import org.entur.gbfs.validation.validator.rules.NoMissingCurrentRangeMetersInVehicleStatusForMotorizedVehicles; import org.entur.gbfs.validation.validator.rules.NoMissingOrInvalidVehicleTypeIdInVehicleStatusWhenVehicleTypesExist; @@ -57,7 +58,8 @@ public class Version30 extends AbstractVersion { "station_status", List.of( new NoInvalidReferenceToVehicleTypesInStationStatus(), - new NoMissingVehicleTypesAvailableWhenVehicleTypesExists() + new NoMissingVehicleTypesAvailableWhenVehicleTypesExists(), + new NoInvalidReferenceToStation("station_information") ), "vehicle_status", List.of( @@ -72,7 +74,10 @@ public class Version30 extends AbstractVersion { "system_information", List.of(new NoMissingStoreUriInSystemInformation("vehicle_status")), "station_information", - List.of(new NoInvalidReferenceToRegionInStationInformation()) + List.of( + new NoInvalidReferenceToRegionInStationInformation(), + new NoInvalidReferenceToStation("station_status") + ) ); protected Version30() { diff --git a/gbfs-validator-java/src/test/resources/fixtures/v2.1/station_information.json b/gbfs-validator-java/src/test/resources/fixtures/v2.1/station_information.json index fe885af5..ee1104e6 100644 --- a/gbfs-validator-java/src/test/resources/fixtures/v2.1/station_information.json +++ b/gbfs-validator-java/src/test/resources/fixtures/v2.1/station_information.json @@ -5,7 +5,7 @@ "data": { "stations": [ { - "station_id": "pga", + "station_id": "station1", "name": "Parking garage A", "lat": 12.345678, "lon": 45.678901, @@ -13,6 +13,16 @@ "abc123": 7, "def456": 9 } + }, + { + "station_id": "station2", + "name": "SE Belmont & SE 10th", + "lat": 45.516445, + "lon": -122.655775, + "vehicle_type_capacity": { + "abc123": 0, + "def456": 0 + } } ] } diff --git a/gbfs-validator-java/src/test/resources/fixtures/v2.1/station_information_virtual.json b/gbfs-validator-java/src/test/resources/fixtures/v2.1/station_information_virtual.json index 83458b32..c06633be 100644 --- a/gbfs-validator-java/src/test/resources/fixtures/v2.1/station_information_virtual.json +++ b/gbfs-validator-java/src/test/resources/fixtures/v2.1/station_information_virtual.json @@ -5,7 +5,7 @@ "data":{ "stations":[ { - "station_id":"station12", + "station_id":"station2", "station_name":"SE Belmont & SE 10 th ", "is_valet_station":false, "is_virtual_station":true, diff --git a/gbfs-validator-java/src/test/resources/fixtures/v2.1/station_status.json b/gbfs-validator-java/src/test/resources/fixtures/v2.1/station_status.json index 805fa19b..15c8dd26 100644 --- a/gbfs-validator-java/src/test/resources/fixtures/v2.1/station_status.json +++ b/gbfs-validator-java/src/test/resources/fixtures/v2.1/station_status.json @@ -5,7 +5,7 @@ "data": { "stations": [ { - "station_id": "station 1", + "station_id": "station1", "is_installed": true, "is_renting": true, "is_returning": true, @@ -27,7 +27,7 @@ "count": 0 }] }, { - "station_id": "station 2", + "station_id": "station2", "is_installed": true, "is_renting": true, "is_returning": true, diff --git a/gbfs-validator-java/src/test/resources/fixtures/v2.2/station_information.json b/gbfs-validator-java/src/test/resources/fixtures/v2.2/station_information.json index 20a6f749..f3dc198c 100644 --- a/gbfs-validator-java/src/test/resources/fixtures/v2.2/station_information.json +++ b/gbfs-validator-java/src/test/resources/fixtures/v2.2/station_information.json @@ -5,7 +5,7 @@ "data": { "stations": [ { - "station_id": "pga", + "station_id": "station1", "name": "Parking garage A", "lat": 12.345678, "lon": 45.678901, @@ -13,6 +13,16 @@ "abc123": 7, "def456": 9 } + }, + { + "station_id": "station2", + "name": "SE Belmont & SE 10th", + "lat": 45.516445, + "lon": -122.655775, + "vehicle_type_capacity": { + "abc123": 0, + "def456": 0 + } } ] } diff --git a/gbfs-validator-java/src/test/resources/fixtures/v2.2/station_information_virtual.json b/gbfs-validator-java/src/test/resources/fixtures/v2.2/station_information_virtual.json index 91da9b51..9a7f247e 100644 --- a/gbfs-validator-java/src/test/resources/fixtures/v2.2/station_information_virtual.json +++ b/gbfs-validator-java/src/test/resources/fixtures/v2.2/station_information_virtual.json @@ -5,7 +5,7 @@ "data":{ "stations":[ { - "station_id":"station12", + "station_id":"station2", "station_name":"SE Belmont & SE 10 th ", "is_valet_station":false, "is_virtual_station":true, diff --git a/gbfs-validator-java/src/test/resources/fixtures/v2.2/station_status.json b/gbfs-validator-java/src/test/resources/fixtures/v2.2/station_status.json index 97a9c2c1..2c044c9e 100644 --- a/gbfs-validator-java/src/test/resources/fixtures/v2.2/station_status.json +++ b/gbfs-validator-java/src/test/resources/fixtures/v2.2/station_status.json @@ -5,7 +5,7 @@ "data": { "stations": [ { - "station_id": "station 1", + "station_id": "station1", "is_installed": true, "is_renting": true, "is_returning": true, @@ -27,7 +27,7 @@ "count": 0 }] }, { - "station_id": "station 2", + "station_id": "station2", "is_installed": true, "is_renting": true, "is_returning": true, diff --git a/gbfs-validator-java/src/test/resources/fixtures/v2.3/station_information.json b/gbfs-validator-java/src/test/resources/fixtures/v2.3/station_information.json index 2dd61f2d..5751189a 100644 --- a/gbfs-validator-java/src/test/resources/fixtures/v2.3/station_information.json +++ b/gbfs-validator-java/src/test/resources/fixtures/v2.3/station_information.json @@ -5,7 +5,7 @@ "data": { "stations": [ { - "station_id": "pga", + "station_id": "station1", "name": "Parking garage A", "lat": 12.345678, "lon": 45.678901, @@ -17,6 +17,16 @@ "abc123": 7, "def456": 9 } + }, + { + "station_id": "station2", + "name": "SE Belmont & SE 10th", + "lat": 45.516445, + "lon": -122.655775, + "vehicle_type_capacity": { + "abc123": 0, + "def456": 0 + } } ] } diff --git a/gbfs-validator-java/src/test/resources/fixtures/v2.3/station_information_virtual.json b/gbfs-validator-java/src/test/resources/fixtures/v2.3/station_information_virtual.json index 3190f511..86af50d0 100644 --- a/gbfs-validator-java/src/test/resources/fixtures/v2.3/station_information_virtual.json +++ b/gbfs-validator-java/src/test/resources/fixtures/v2.3/station_information_virtual.json @@ -5,7 +5,7 @@ "data": { "stations": [ { - "station_id": "station12", + "station_id": "station2", "name": "SE Belmont & SE 10 th", "lat": 45.516445, "lon": -122.655775, diff --git a/gbfs-validator-java/src/test/resources/fixtures/v3.0/station_information.json b/gbfs-validator-java/src/test/resources/fixtures/v3.0/station_information.json index 78ebaa3c..94e0f9ab 100644 --- a/gbfs-validator-java/src/test/resources/fixtures/v3.0/station_information.json +++ b/gbfs-validator-java/src/test/resources/fixtures/v3.0/station_information.json @@ -5,7 +5,7 @@ "data": { "stations": [ { - "station_id": "pga", + "station_id": "station1", "name": [ { "text": "Parking garage A", @@ -31,7 +31,7 @@ ] }, { - "station_id": "station12", + "station_id": "station2", "name": [ { "text": "SE Belmont & SE 10th",