From 5e18c0a245d23ff2585a48b47ef83720b6e9643a Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Mon, 2 Sep 2024 13:53:40 +0300 Subject: [PATCH 01/27] GTFS graphql API supports querying itinerary leg status --- .../apis/gtfs/datafetchers/LegImpl.java | 11 +++++++++++ .../apis/gtfs/datafetchers/QueryTypeImpl.java | 11 +++++++++++ .../apis/gtfs/generated/GraphQLDataFetchers.java | 2 ++ .../org/opentripplanner/apis/gtfs/schema.graphqls | 4 +++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index 9ec83a4bf67..f6c53f1c84f 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -1,5 +1,6 @@ package org.opentripplanner.apis.gtfs.datafetchers; +import graphql.relay.Relay; import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import java.util.List; @@ -23,6 +24,7 @@ import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.TransitLeg; import org.opentripplanner.model.plan.WalkStep; +import org.opentripplanner.model.plan.legreference.LegReferenceSerializer; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.alternativelegs.AlternativeLegs; import org.opentripplanner.routing.alternativelegs.AlternativeLegsFilter; @@ -324,4 +326,13 @@ public DataFetcher> nextLegs() { public DataFetcher accessibilityScore() { return environment -> NumberMapper.toDouble(getSource(environment).accessibilityScore()); } + + @Override + public DataFetcher id() { + return environment -> + new Relay.ResolvedGlobalId( + "Leg", + LegReferenceSerializer.encode(getSource(environment).getLegReference()) + ); + } } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index 0e70c13074b..604cf585357 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -42,6 +42,8 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.gtfs.mapping.DirectionMapper; import org.opentripplanner.model.TripTimeOnDate; +import org.opentripplanner.model.plan.legreference.LegReference; +import org.opentripplanner.model.plan.legreference.LegReferenceSerializer; import org.opentripplanner.routing.alertpatch.EntitySelector; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.api.request.RouteRequest; @@ -445,6 +447,15 @@ public DataFetcher node() { // TODO: Add geometry return new NearbyStop(stop, Integer.parseInt(parts[0]), null, null); } + case "Leg": + if (id.isBlank()) { + return null; + } + LegReference ref = LegReferenceSerializer.decode(id); + if (ref == null) { + return null; + } + return ref.getLeg(transitService); case "TicketType": return null; //TODO case "Trip": diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index 67944543580..36d262ef164 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -482,6 +482,8 @@ public interface GraphQLLeg { public DataFetcher headsign(); + public DataFetcher id(); + public DataFetcher interlineWithPreviousLeg(); public DataFetcher intermediatePlace(); diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 927af19f8b1..85c2fb8b722 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -611,7 +611,7 @@ type Itinerary { walkTime: Long } -type Leg { +type Leg implements Node { """ Computes a numeric accessibility score between 0 and 1. @@ -669,6 +669,8 @@ type Leg { For non-transit legs, null. """ headsign: String + "An identifier for the leg, which can be used to re-fetch the information." + id: ID! """ Interlines with previous leg. This is true when the same vehicle is used for the previous leg as for this leg From 021e07cd1e623fe2a6160a53622eb296b4f5da33 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Thu, 5 Sep 2024 11:44:48 +0300 Subject: [PATCH 02/27] Catch non-transit legs properly --- .../opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index 604cf585357..421899b2ce0 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -75,7 +75,6 @@ import org.opentripplanner.updater.GtfsRealtimeFuzzyTripMatcher; public class QueryTypeImpl implements GraphQLDataFetchers.GraphQLQueryType { - // TODO: figure out a runtime solution private static final DirectionMapper DIRECTION_MAPPER = new DirectionMapper( DataImportIssueStore.NOOP @@ -448,7 +447,7 @@ public DataFetcher node() { return new NearbyStop(stop, Integer.parseInt(parts[0]), null, null); } case "Leg": - if (id.isBlank()) { + if (id.equals("null") || id.isBlank()) { return null; } LegReference ref = LegReferenceSerializer.decode(id); From 01b460d8bdcfdd3e73a6fcfbd60e1219105219a4 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Thu, 5 Sep 2024 11:45:47 +0300 Subject: [PATCH 03/27] Add type resolver for Leg --- .../apis/gtfs/datafetchers/NodeTypeResolver.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java index 437d75e03e9..ae712f17252 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java @@ -8,6 +8,7 @@ import graphql.schema.TypeResolver; import org.opentripplanner.ext.fares.model.FareRuleSet; import org.opentripplanner.model.TripTimeOnDate; +import org.opentripplanner.model.plan.Leg; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.graphfinder.NearbyStop; import org.opentripplanner.routing.graphfinder.PatternAtStop; @@ -85,6 +86,9 @@ public GraphQLObjectType getType(TypeResolutionEnvironment environment) { if (o instanceof Trip) { return schema.getObjectType("Trip"); } + if (o instanceof Leg) { + return schema.getObjectType("Leg"); + } return null; } From 218206650fa648f83c5c45ecf1c7369f3e38c049 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Thu, 5 Sep 2024 13:48:09 +0300 Subject: [PATCH 04/27] Fix formatting --- .../opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index 421899b2ce0..5a2f016fbe1 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -75,6 +75,7 @@ import org.opentripplanner.updater.GtfsRealtimeFuzzyTripMatcher; public class QueryTypeImpl implements GraphQLDataFetchers.GraphQLQueryType { + // TODO: figure out a runtime solution private static final DirectionMapper DIRECTION_MAPPER = new DirectionMapper( DataImportIssueStore.NOOP From 7e2033f04d3199cc2d52037d8635c82a5356648d Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Fri, 6 Sep 2024 08:57:07 +0300 Subject: [PATCH 05/27] Do not encode null reference as 'null' string --- .../apis/gtfs/datafetchers/LegImpl.java | 10 +++++----- .../apis/gtfs/datafetchers/QueryTypeImpl.java | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index f6c53f1c84f..292a60876c7 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -329,10 +329,10 @@ public DataFetcher accessibilityScore() { @Override public DataFetcher id() { - return environment -> - new Relay.ResolvedGlobalId( - "Leg", - LegReferenceSerializer.encode(getSource(environment).getLegReference()) - ); + return environment -> { + var ref = getSource(environment).getLegReference(); + var id = (ref == null) ? "" : LegReferenceSerializer.encode(ref); + return new Relay.ResolvedGlobalId("Leg", id); + }; } } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index 5a2f016fbe1..604cf585357 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -448,7 +448,7 @@ public DataFetcher node() { return new NearbyStop(stop, Integer.parseInt(parts[0]), null, null); } case "Leg": - if (id.equals("null") || id.isBlank()) { + if (id.isBlank()) { return null; } LegReference ref = LegReferenceSerializer.decode(id); From 6b927413562a5d8f511432b0f7af6f64fbce12c0 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Fri, 6 Sep 2024 10:03:15 +0300 Subject: [PATCH 06/27] More accurate docs about leg query --- .../apis/transmodel/TransmodelGraphQLSchema.java | 2 +- .../opentripplanner/apis/transmodel/model/plan/LegType.java | 4 +++- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 2 +- .../org/opentripplanner/apis/transmodel/schema.graphql | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java b/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java index 9ad43606420..65243af34d3 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java @@ -1596,7 +1596,7 @@ private GraphQLSchema create() { GraphQLFieldDefinition .newFieldDefinition() .name("leg") - .description("Refetch a single leg based on its id") + .description("Refetch a single transit leg based on its id") .withDirective(gqlUtil.timingData) .type(LegType.REF) .argument( diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java index be05d00e16d..ca48dce882a 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java @@ -63,7 +63,9 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("id") - .description("An identifier for the leg, which can be used to re-fetch the information.") + .description( + "An identifier for the leg, which can be used to re-fetch transit leg information." + ) .type(Scalars.GraphQLID) .dataFetcher(env -> LegReferenceSerializer.encode(leg(env).getLegReference())) .build() diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 85c2fb8b722..a4121eaae6c 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -669,7 +669,7 @@ type Leg implements Node { For non-transit legs, null. """ headsign: String - "An identifier for the leg, which can be used to re-fetch the information." + "An identifier for the leg, which can be used to re-fetch transit leg information." id: ID! """ Interlines with previous leg. diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index 0d2bf71dcc6..37ca2f34945 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -325,7 +325,7 @@ type Leg { fromPlace: Place! "Generalized cost or weight of the leg. Used for debugging." generalizedCost: Int - "An identifier for the leg, which can be used to re-fetch the information." + "An identifier for the leg, which can be used to re-fetch transit leg information." id: ID interchangeFrom: Interchange interchangeTo: Interchange @@ -647,7 +647,7 @@ type QueryType { groupOfLines(id: String!): GroupOfLines "Get all groups of lines" groupsOfLines: [GroupOfLines!]! - "Refetch a single leg based on its id" + "Refetch a single transit leg based on its id" leg(id: ID!): Leg @timingData "Get a single line based on its id" line(id: ID!): Line @timingData From e489f0534bc160e8915c3ee927d3d8c56307c12e Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Fri, 6 Sep 2024 11:03:57 +0300 Subject: [PATCH 07/27] Add leg id to plan query test --- .../apis/gtfs/expectations/plan-extended.json | 14 +++++++++----- .../apis/gtfs/queries/plan-extended.graphql | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json index ea58480be8e..55da843bdfa 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json +++ b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json @@ -64,7 +64,8 @@ "intermediatePlaces" : null, "alerts" : [ ], "rideHailingEstimate" : null, - "accessibilityScore" : null + "accessibilityScore" : null, + "id" : "TGVnOg" }, { "mode" : "BUS", @@ -154,7 +155,8 @@ ], "alerts" : [ ], "rideHailingEstimate" : null, - "accessibilityScore" : null + "accessibilityScore" : null, + "id": "TGVnOnJPMEFCWGRCQUJoVFEwaEZSRlZNUlVSZlZGSkJUbE5KVkY5TVJVZGZWak1BQlVZNk1USXlBQW95TURJd0xUQXlMVEF5QUFBQUJRQUFBQWNBQTBZNlFnQURSanBEQUFBPQ" }, { "mode" : "RAIL", @@ -264,7 +266,8 @@ } ], "rideHailingEstimate" : null, - "accessibilityScore" : null + "accessibilityScore" : null, + "id": "TGVnOnJPMEFCWGRCQUJoVFEwaEZSRlZNUlVSZlZGSkJUbE5KVkY5TVJVZGZWak1BQlVZNk5ETTVBQW95TURJd0xUQXlMVEF5QUFBQUJRQUFBQWNBQTBZNlF3QURSanBFQUFBPQ" }, { "mode" : "CAR", @@ -334,11 +337,12 @@ }, "arrival" : "PT10M" }, - "accessibilityScore" : null + "accessibilityScore" : null, + "id" : "TGVnOg" } ] } ] } } -} \ No newline at end of file +} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql index 76bf8aa84e0..a96eeca5e7a 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql +++ b/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql @@ -151,6 +151,7 @@ arrival } accessibilityScore + id } } } From 6bd5d041b058aaeaa51aa08c3e8e59f3e8dc910a Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Mon, 9 Sep 2024 09:48:59 +0300 Subject: [PATCH 08/27] Use self-documenting value for non-transit leg ids Also, move all encoding/decoding logig to LegReferenceSerializer class. --- .../org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java | 2 +- .../apis/gtfs/datafetchers/QueryTypeImpl.java | 3 --- .../model/plan/legreference/LegReferenceSerializer.java | 6 ++++-- .../model/plan/legreference/LegReferenceSerializerTest.java | 4 ++-- .../apis/gtfs/expectations/plan-extended.json | 4 ++-- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index 292a60876c7..1d8b72ac173 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -331,7 +331,7 @@ public DataFetcher accessibilityScore() { public DataFetcher id() { return environment -> { var ref = getSource(environment).getLegReference(); - var id = (ref == null) ? "" : LegReferenceSerializer.encode(ref); + var id = LegReferenceSerializer.encode(ref); return new Relay.ResolvedGlobalId("Leg", id); }; } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index 604cf585357..b064582f5d8 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -448,9 +448,6 @@ public DataFetcher node() { return new NearbyStop(stop, Integer.parseInt(parts[0]), null, null); } case "Leg": - if (id.isBlank()) { - return null; - } LegReference ref = LegReferenceSerializer.decode(id); if (ref == null) { return null; diff --git a/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializer.java b/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializer.java index 0ceae6cb456..9e1424d3d47 100644 --- a/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializer.java +++ b/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializer.java @@ -18,6 +18,8 @@ */ public class LegReferenceSerializer { + public static final String notAvailable = "NotAvailable"; + private static final Logger LOG = LoggerFactory.getLogger(LegReferenceSerializer.class); /** private constructor to prevent instantiating this utility class */ @@ -26,7 +28,7 @@ private LegReferenceSerializer() {} @Nullable public static String encode(LegReference legReference) { if (legReference == null) { - return null; + return notAvailable; } LegReferenceType typeEnum = LegReferenceType .forClass(legReference.getClass()) @@ -47,7 +49,7 @@ public static String encode(LegReference legReference) { @Nullable public static LegReference decode(String legReference) { - if (legReference == null) { + if (legReference.equals(notAvailable)) { return null; } diff --git a/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java b/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java index 2d7df788ad3..8422e98fe69 100644 --- a/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java +++ b/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java @@ -89,8 +89,8 @@ void testScheduledTransitLegReferenceLegacyV2Deserialize() { } @Test - void testNullSerializedLegReference() { - assertNull(LegReferenceSerializer.decode(null)); + void testUnresolvedSerializedLegReference() { + assertNull(LegReferenceSerializer.decode(LegReferenceSerializer.notAvailable)); } @Test diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json index 55da843bdfa..0a9ebd9807e 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json +++ b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json @@ -65,7 +65,7 @@ "alerts" : [ ], "rideHailingEstimate" : null, "accessibilityScore" : null, - "id" : "TGVnOg" + "id" : "TGVnOk5vdEF2YWlsYWJsZQ" }, { "mode" : "BUS", @@ -338,7 +338,7 @@ "arrival" : "PT10M" }, "accessibilityScore" : null, - "id" : "TGVnOg" + "id": "TGVnOk5vdEF2YWlsYWJsZQ" } ] } From a998e52bbf5cee7188a8c849c6e8429dcce411af Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Mon, 9 Sep 2024 09:58:35 +0300 Subject: [PATCH 09/27] Add more docs about leg re-fetching into gtfs graphql schema --- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index a4121eaae6c..4c9b25c1048 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -669,7 +669,11 @@ type Leg implements Node { For non-transit legs, null. """ headsign: String - "An identifier for the leg, which can be used to re-fetch transit leg information." + """ + An identifier for the leg, which can be used to re-fetch transit leg information. + Re-fetching fails when the underlying transit data no longer exists. + Non-transit legs cannot be refetched using their id. + """ id: ID! """ Interlines with previous leg. From cf37e89dffbf00e4a9e61548410f3c43466943cd Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Wed, 11 Sep 2024 08:10:58 +0300 Subject: [PATCH 10/27] Support querying leg's realTimeState in GTFS graphql api --- .../opentripplanner/apis/gtfs/datafetchers/LegImpl.java | 3 +-- src/main/java/org/opentripplanner/model/plan/Leg.java | 5 +++++ .../opentripplanner/model/plan/ScheduledTransitLeg.java | 7 +++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index 1d8b72ac173..4f54eadb3c0 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -191,10 +191,9 @@ public DataFetcher realTime() { return environment -> getSource(environment).getRealTime(); } - // TODO @Override public DataFetcher realtimeState() { - return environment -> null; + return environment -> getSource(environment).getRealTimeState().name(); } @Override diff --git a/src/main/java/org/opentripplanner/model/plan/Leg.java b/src/main/java/org/opentripplanner/model/plan/Leg.java index 2a0b6726560..218907f3ca8 100644 --- a/src/main/java/org/opentripplanner/model/plan/Leg.java +++ b/src/main/java/org/opentripplanner/model/plan/Leg.java @@ -22,6 +22,7 @@ import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.organization.Operator; import org.opentripplanner.transit.model.site.FareZone; +import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.booking.BookingInfo; @@ -244,6 +245,10 @@ default boolean getRealTime() { return false; } + default RealTimeState getRealTimeState() { + return RealTimeState.SCHEDULED; + } + /** * Whether this Leg describes a flexible trip. The reason we need this is that FlexTrip does not * inherit from Trip, so that the information that the Trip is flexible would be lost when diff --git a/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java b/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java index d94ec1895c2..25b329ed055 100644 --- a/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java +++ b/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java @@ -34,6 +34,7 @@ import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.organization.Operator; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.TripTimes; @@ -227,6 +228,11 @@ public boolean getRealTime() { ); } + @Override + public RealTimeState getRealTimeState() { + return tripTimes.getRealTimeState(); + } + @Override public double getDistanceMeters() { return distanceMeters; @@ -427,6 +433,7 @@ public String toString() { .addEnum("alightRule", getAlightRule()) .addObj("transferFromPrevLeg", transferFromPrevLeg) .addObj("transferToNextLeg", transferToNextLeg) + .addEnum("realtimeState", getRealTimeState()) .toString(); } From cd54cbe378d8bb4691b6a88bffed87ed5cf820c4 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Wed, 11 Sep 2024 08:39:07 +0300 Subject: [PATCH 11/27] Query realtimeState in extended plan test --- .../apis/gtfs/expectations/plan-extended.json | 12 ++++++++---- .../apis/gtfs/queries/plan-extended.graphql | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json index 0a9ebd9807e..939df7dce3c 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json +++ b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json @@ -65,7 +65,8 @@ "alerts" : [ ], "rideHailingEstimate" : null, "accessibilityScore" : null, - "id" : "TGVnOk5vdEF2YWlsYWJsZQ" + "id" : "TGVnOk5vdEF2YWlsYWJsZQ", + "realtimeState": "SCHEDULED" }, { "mode" : "BUS", @@ -156,7 +157,8 @@ "alerts" : [ ], "rideHailingEstimate" : null, "accessibilityScore" : null, - "id": "TGVnOnJPMEFCWGRCQUJoVFEwaEZSRlZNUlVSZlZGSkJUbE5KVkY5TVJVZGZWak1BQlVZNk1USXlBQW95TURJd0xUQXlMVEF5QUFBQUJRQUFBQWNBQTBZNlFnQURSanBEQUFBPQ" + "id": "TGVnOnJPMEFCWGRCQUJoVFEwaEZSRlZNUlVSZlZGSkJUbE5KVkY5TVJVZGZWak1BQlVZNk1USXlBQW95TURJd0xUQXlMVEF5QUFBQUJRQUFBQWNBQTBZNlFnQURSanBEQUFBPQ", + "realtimeState": "UPDATED" }, { "mode" : "RAIL", @@ -267,7 +269,8 @@ ], "rideHailingEstimate" : null, "accessibilityScore" : null, - "id": "TGVnOnJPMEFCWGRCQUJoVFEwaEZSRlZNUlVSZlZGSkJUbE5KVkY5TVJVZGZWak1BQlVZNk5ETTVBQW95TURJd0xUQXlMVEF5QUFBQUJRQUFBQWNBQTBZNlF3QURSanBFQUFBPQ" + "id": "TGVnOnJPMEFCWGRCQUJoVFEwaEZSRlZNUlVSZlZGSkJUbE5KVkY5TVJVZGZWak1BQlVZNk5ETTVBQW95TURJd0xUQXlMVEF5QUFBQUJRQUFBQWNBQTBZNlF3QURSanBFQUFBPQ", + "realtimeState": "UPDATED" }, { "mode" : "CAR", @@ -338,7 +341,8 @@ "arrival" : "PT10M" }, "accessibilityScore" : null, - "id": "TGVnOk5vdEF2YWlsYWJsZQ" + "id": "TGVnOk5vdEF2YWlsYWJsZQ", + "realtimeState": "SCHEDULED" } ] } diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql index a96eeca5e7a..7823ae91bab 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql +++ b/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql @@ -152,6 +152,7 @@ } accessibilityScore id + realtimeState } } } From 4025d5b60d12d2e6807a76e4770892599d9cf56d Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Fri, 13 Sep 2024 08:22:25 +0300 Subject: [PATCH 12/27] Revert LegReferenceSerializer changes --- .../model/plan/legreference/LegReferenceSerializer.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializer.java b/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializer.java index 9e1424d3d47..0ceae6cb456 100644 --- a/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializer.java +++ b/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializer.java @@ -18,8 +18,6 @@ */ public class LegReferenceSerializer { - public static final String notAvailable = "NotAvailable"; - private static final Logger LOG = LoggerFactory.getLogger(LegReferenceSerializer.class); /** private constructor to prevent instantiating this utility class */ @@ -28,7 +26,7 @@ private LegReferenceSerializer() {} @Nullable public static String encode(LegReference legReference) { if (legReference == null) { - return notAvailable; + return null; } LegReferenceType typeEnum = LegReferenceType .forClass(legReference.getClass()) @@ -49,7 +47,7 @@ public static String encode(LegReference legReference) { @Nullable public static LegReference decode(String legReference) { - if (legReference.equals(notAvailable)) { + if (legReference == null) { return null; } From b206ce18b3d153a4a436ef7d9b1abb1e729fe8a1 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Fri, 13 Sep 2024 08:23:47 +0300 Subject: [PATCH 13/27] Generate unique id for non-transit legs --- .../apis/gtfs/datafetchers/LegImpl.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index 4f54eadb3c0..4b3ddf9019d 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -329,8 +329,22 @@ public DataFetcher accessibilityScore() { @Override public DataFetcher id() { return environment -> { + var leg = getSource(environment); var ref = getSource(environment).getLegReference(); - var id = LegReferenceSerializer.encode(ref); + String id; + + if (ref == null) { + id = + String.join( + "", + leg.start().time().toString(), + leg.end().time().toString(), + leg.getFrom().toStringShort(), + leg.getTo().toStringShort() + ); + } else { + id = LegReferenceSerializer.encode(ref); + } return new Relay.ResolvedGlobalId("Leg", id); }; } From 15f1f3486ec69276013c0ec8c13c390ceea2371b Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Fri, 13 Sep 2024 08:29:31 +0300 Subject: [PATCH 14/27] Restore LegReferenceSerializer null test --- .../model/plan/legreference/LegReferenceSerializerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java b/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java index 8422e98fe69..2d7df788ad3 100644 --- a/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java +++ b/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java @@ -89,8 +89,8 @@ void testScheduledTransitLegReferenceLegacyV2Deserialize() { } @Test - void testUnresolvedSerializedLegReference() { - assertNull(LegReferenceSerializer.decode(LegReferenceSerializer.notAvailable)); + void testNullSerializedLegReference() { + assertNull(LegReferenceSerializer.decode(null)); } @Test From 20f855a7059cd9fd3d2c825bcd406616518cd36b Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Fri, 13 Sep 2024 08:38:34 +0300 Subject: [PATCH 15/27] Update plan-extended expoctations to use unique leg ids --- .../opentripplanner/apis/gtfs/expectations/plan-extended.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json index 939df7dce3c..348b10c816a 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json +++ b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json @@ -65,7 +65,7 @@ "alerts" : [ ], "rideHailingEstimate" : null, "accessibilityScore" : null, - "id" : "TGVnOk5vdEF2YWlsYWJsZQ", + "id": "TGVnOjIwMjAtMDItMDJUMTE6MDBaMjAyMC0wMi0wMlQxMTowMDoyMFpBIChGOkEpQiAoRjpCKQ", "realtimeState": "SCHEDULED" }, { @@ -341,7 +341,7 @@ "arrival" : "PT10M" }, "accessibilityScore" : null, - "id": "TGVnOk5vdEF2YWlsYWJsZQ", + "id": "TGVnOjIwMjAtMDItMDJUMTE6NTBaMjAyMC0wMi0wMlQxMjowMFpEIChGOkQpRSAoRjpFKQ", "realtimeState": "SCHEDULED" } ] From 9b3c4d5e66fd829bd604ae7c7acf8ed601053b71 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Tue, 24 Sep 2024 09:00:07 +0300 Subject: [PATCH 16/27] Revert "Generate unique id for non-transit legs" This reverts commit b206ce18b3d153a4a436ef7d9b1abb1e729fe8a1. --- .../apis/gtfs/datafetchers/LegImpl.java | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index 4b3ddf9019d..4f54eadb3c0 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -329,22 +329,8 @@ public DataFetcher accessibilityScore() { @Override public DataFetcher id() { return environment -> { - var leg = getSource(environment); var ref = getSource(environment).getLegReference(); - String id; - - if (ref == null) { - id = - String.join( - "", - leg.start().time().toString(), - leg.end().time().toString(), - leg.getFrom().toStringShort(), - leg.getTo().toStringShort() - ); - } else { - id = LegReferenceSerializer.encode(ref); - } + var id = LegReferenceSerializer.encode(ref); return new Relay.ResolvedGlobalId("Leg", id); }; } From 14fd13eb7205540cb4f15a642efd5f346572af5f Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Tue, 24 Sep 2024 09:53:18 +0300 Subject: [PATCH 17/27] Remove node interface from LegType and add leg query --- .../apis/gtfs/datafetchers/LegImpl.java | 3 +++ .../apis/gtfs/datafetchers/QueryTypeImpl.java | 21 +++++++++++++------ .../opentripplanner/apis/gtfs/schema.graphqls | 8 ++++--- .../apis/gtfs/expectations/plan-extended.json | 4 ++-- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index 4f54eadb3c0..69a0e7b2f5e 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -330,6 +330,9 @@ public DataFetcher accessibilityScore() { public DataFetcher id() { return environment -> { var ref = getSource(environment).getLegReference(); + if (ref == null) { + return null; + } var id = LegReferenceSerializer.encode(ref); return new Relay.ResolvedGlobalId("Leg", id); }; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index b064582f5d8..c817d723a2c 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -42,6 +42,7 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.gtfs.mapping.DirectionMapper; import org.opentripplanner.model.TripTimeOnDate; +import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.legreference.LegReference; import org.opentripplanner.model.plan.legreference.LegReferenceSerializer; import org.opentripplanner.routing.alertpatch.EntitySelector; @@ -364,6 +365,20 @@ public DataFetcher> nearest() { }; } + @Override + public DataFetcher leg() { + return environment -> { + TransitService transitService = getTransitService(environment); + var args = new GraphQLTypes.GraphQLQueryTypeLegArgs(environment.getArguments()); + String id = args.getGraphQLId().getId(); + LegReference ref = LegReferenceSerializer.decode(id); + if (ref == null) { + return null; + } + return ref.getLeg(transitService); + }; + } + @Override public DataFetcher node() { return environment -> { @@ -447,12 +462,6 @@ public DataFetcher node() { // TODO: Add geometry return new NearbyStop(stop, Integer.parseInt(parts[0]), null, null); } - case "Leg": - LegReference ref = LegReferenceSerializer.decode(id); - if (ref == null) { - return null; - } - return ref.getLeg(transitService); case "TicketType": return null; //TODO case "Trip": diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 4c9b25c1048..1d93c5bfa9a 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -611,7 +611,7 @@ type Itinerary { walkTime: Long } -type Leg implements Node { +type Leg { """ Computes a numeric accessibility score between 0 and 1. @@ -674,7 +674,7 @@ type Leg implements Node { Re-fetching fails when the underlying transit data no longer exists. Non-transit legs cannot be refetched using their id. """ - id: ID! + id: ID """ Interlines with previous leg. This is true when the same vehicle is used for the previous leg as for this leg @@ -1171,7 +1171,9 @@ type QueryType { "Departure time of the trip, format: seconds since midnight of the departure date" time: Int! ): Trip - """ + "Try refetching the current state of a transit leg using its ID" + leg(id: String!): Leg + """ Get all places (stops, stations, etc. with coordinates) within the specified radius from a location. The returned type is a Relay connection (see https://facebook.github.io/relay/graphql/connections.htm). The placeAtDistance diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json index 348b10c816a..ab98d95e7ad 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json +++ b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json @@ -65,7 +65,7 @@ "alerts" : [ ], "rideHailingEstimate" : null, "accessibilityScore" : null, - "id": "TGVnOjIwMjAtMDItMDJUMTE6MDBaMjAyMC0wMi0wMlQxMTowMDoyMFpBIChGOkEpQiAoRjpCKQ", + "id": null, "realtimeState": "SCHEDULED" }, { @@ -341,7 +341,7 @@ "arrival" : "PT10M" }, "accessibilityScore" : null, - "id": "TGVnOjIwMjAtMDItMDJUMTE6NTBaMjAyMC0wMi0wMlQxMjowMFpEIChGOkQpRSAoRjpFKQ", + "id": null, "realtimeState": "SCHEDULED" } ] From 71a63154c1d1244f81a4d9c307668d8923a9e465 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Tue, 24 Sep 2024 10:50:48 +0300 Subject: [PATCH 18/27] Update auto generated files --- .../gtfs/generated/GraphQLDataFetchers.java | 2 ++ .../apis/gtfs/generated/GraphQLTypes.java | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index 36d262ef164..4e63e87438b 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -781,6 +781,8 @@ public interface GraphQLQueryType { public DataFetcher fuzzyTrip(); + public DataFetcher leg(); + public DataFetcher> nearest(); public DataFetcher node(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java index ed3e9afefc9..3cd98b15652 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java @@ -2432,6 +2432,25 @@ public void setGraphQLTime(Integer time) { } } + public static class GraphQLQueryTypeLegArgs { + + private String id; + + public GraphQLQueryTypeLegArgs(Map args) { + if (args != null) { + this.id = (String) args.get("id"); + } + } + + public String getGraphQLId() { + return this.id; + } + + public void setGraphQLId(String id) { + this.id = id; + } + } + public static class GraphQLQueryTypeNearestArgs { private String after; From cd660b2bec216b398612af0952d727ce93aa1b7f Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Tue, 24 Sep 2024 11:15:09 +0300 Subject: [PATCH 19/27] Fix schema formatting --- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 6635f9bbba5..af0fd5dd6be 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -1173,7 +1173,7 @@ type QueryType { ): Trip "Try refetching the current state of a transit leg using its ID" leg(id: String!): Leg - """ + """ Get all places (stops, stations, etc. with coordinates) within the specified radius from a location. The returned type is a Relay connection (see https://facebook.github.io/relay/graphql/connections.htm). The placeAtDistance From 97d21803d7939db8afc6cc7baf026f5c8d4ba254 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Tue, 24 Sep 2024 11:15:28 +0300 Subject: [PATCH 20/27] Fix leg id access --- .../opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index 266574f546b..95984ba6dd0 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -370,7 +370,7 @@ public DataFetcher leg() { return environment -> { TransitService transitService = getTransitService(environment); var args = new GraphQLTypes.GraphQLQueryTypeLegArgs(environment.getArguments()); - String id = args.getGraphQLId().getId(); + String id = args.getGraphQLId(); LegReference ref = LegReferenceSerializer.decode(id); if (ref == null) { return null; From b75c047f0bcfa48385c014255da513fb80ec5d29 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Tue, 24 Sep 2024 14:09:18 +0300 Subject: [PATCH 21/27] Remove leg resolver from node type --- .../apis/gtfs/datafetchers/NodeTypeResolver.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java index ae712f17252..f83e088024e 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java @@ -86,9 +86,6 @@ public GraphQLObjectType getType(TypeResolutionEnvironment environment) { if (o instanceof Trip) { return schema.getObjectType("Trip"); } - if (o instanceof Leg) { - return schema.getObjectType("Leg"); - } return null; } From 1a43221cb8ff1b1b1dbeb419f1c8eac66186ec0e Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Tue, 24 Sep 2024 14:43:16 +0300 Subject: [PATCH 22/27] Use ID parameter type for leg query --- .../apis/gtfs/datafetchers/QueryTypeImpl.java | 2 +- .../opentripplanner/apis/gtfs/generated/GraphQLTypes.java | 8 ++++---- .../org/opentripplanner/apis/gtfs/schema.graphqls | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index 95984ba6dd0..266574f546b 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -370,7 +370,7 @@ public DataFetcher leg() { return environment -> { TransitService transitService = getTransitService(environment); var args = new GraphQLTypes.GraphQLQueryTypeLegArgs(environment.getArguments()); - String id = args.getGraphQLId(); + String id = args.getGraphQLId().getId(); LegReference ref = LegReferenceSerializer.decode(id); if (ref == null) { return null; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java index 3cd98b15652..d0ab004e654 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java @@ -2434,19 +2434,19 @@ public void setGraphQLTime(Integer time) { public static class GraphQLQueryTypeLegArgs { - private String id; + private graphql.relay.Relay.ResolvedGlobalId id; public GraphQLQueryTypeLegArgs(Map args) { if (args != null) { - this.id = (String) args.get("id"); + this.id = (graphql.relay.Relay.ResolvedGlobalId) args.get("id"); } } - public String getGraphQLId() { + public graphql.relay.Relay.ResolvedGlobalId getGraphQLId() { return this.id; } - public void setGraphQLId(String id) { + public void setGraphQLId(graphql.relay.Relay.ResolvedGlobalId id) { this.id = id; } } diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index af0fd5dd6be..561ec9e38cc 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -1172,7 +1172,7 @@ type QueryType { time: Int! ): Trip "Try refetching the current state of a transit leg using its ID" - leg(id: String!): Leg + leg(id: ID!): Leg """ Get all places (stops, stations, etc. with coordinates) within the specified radius from a location. The returned type is a Relay connection (see From 58b382fbfa384278ea50c8c7cf99a7ffb7553f06 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Thu, 26 Sep 2024 08:23:28 +0300 Subject: [PATCH 23/27] Update src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls Co-authored-by: Leonard Ehrenfried --- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 561ec9e38cc..9bfb5f8af93 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -1171,7 +1171,10 @@ type QueryType { "Departure time of the trip, format: seconds since midnight of the departure date" time: Int! ): Trip - "Try refetching the current state of a transit leg using its ID" + """ + Try refetching the current state of a transit leg using its ID. + This fails when the underlying transit data (mostly IDs) has changed or are no longer available. + """ leg(id: ID!): Leg """ Get all places (stops, stations, etc. with coordinates) within the specified From f6a8d8f57043a2571373e9e99ac44fdac642eded Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Thu, 26 Sep 2024 09:04:05 +0300 Subject: [PATCH 24/27] Suggested review changes --- .../org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java | 5 ++++- .../apis/gtfs/datafetchers/NodeTypeResolver.java | 1 - src/main/java/org/opentripplanner/model/plan/Leg.java | 2 +- .../org/opentripplanner/model/plan/ScheduledTransitLeg.java | 1 - .../apis/gtfs/expectations/plan-extended.json | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index 69a0e7b2f5e..832364fac70 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -193,7 +193,10 @@ public DataFetcher realTime() { @Override public DataFetcher realtimeState() { - return environment -> getSource(environment).getRealTimeState().name(); + return environment -> { + var state = getSource(environment).getRealTimeState(); + return (state != null) ? state.name() : null; + }; } @Override diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java index f83e088024e..437d75e03e9 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java @@ -8,7 +8,6 @@ import graphql.schema.TypeResolver; import org.opentripplanner.ext.fares.model.FareRuleSet; import org.opentripplanner.model.TripTimeOnDate; -import org.opentripplanner.model.plan.Leg; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.graphfinder.NearbyStop; import org.opentripplanner.routing.graphfinder.PatternAtStop; diff --git a/src/main/java/org/opentripplanner/model/plan/Leg.java b/src/main/java/org/opentripplanner/model/plan/Leg.java index 218907f3ca8..d9e3a4589d8 100644 --- a/src/main/java/org/opentripplanner/model/plan/Leg.java +++ b/src/main/java/org/opentripplanner/model/plan/Leg.java @@ -246,7 +246,7 @@ default boolean getRealTime() { } default RealTimeState getRealTimeState() { - return RealTimeState.SCHEDULED; + return null; } /** diff --git a/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java b/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java index 25b329ed055..e774c9e0dbc 100644 --- a/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java +++ b/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java @@ -433,7 +433,6 @@ public String toString() { .addEnum("alightRule", getAlightRule()) .addObj("transferFromPrevLeg", transferFromPrevLeg) .addObj("transferToNextLeg", transferToNextLeg) - .addEnum("realtimeState", getRealTimeState()) .toString(); } diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json index ab98d95e7ad..1148a8792b0 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json +++ b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json @@ -66,7 +66,7 @@ "rideHailingEstimate" : null, "accessibilityScore" : null, "id": null, - "realtimeState": "SCHEDULED" + "realtimeState": null }, { "mode" : "BUS", @@ -342,7 +342,7 @@ }, "accessibilityScore" : null, "id": null, - "realtimeState": "SCHEDULED" + "realtimeState": null } ] } From ba100e8dafc1cef3e49032acb89926e555a6ad6d Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Fri, 27 Sep 2024 08:16:02 +0300 Subject: [PATCH 25/27] Use string type instead of relay ID type for transit leg identification --- .../opentripplanner/apis/gtfs/datafetchers/LegImpl.java | 5 ++--- .../apis/gtfs/datafetchers/QueryTypeImpl.java | 2 +- .../apis/gtfs/generated/GraphQLDataFetchers.java | 2 +- .../opentripplanner/apis/gtfs/generated/GraphQLTypes.java | 8 ++++---- .../org/opentripplanner/apis/gtfs/schema.graphqls | 6 +++--- .../apis/gtfs/expectations/plan-extended.json | 4 ++-- 6 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index 832364fac70..9714b4106fa 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -330,14 +330,13 @@ public DataFetcher accessibilityScore() { } @Override - public DataFetcher id() { + public DataFetcher id() { return environment -> { var ref = getSource(environment).getLegReference(); if (ref == null) { return null; } - var id = LegReferenceSerializer.encode(ref); - return new Relay.ResolvedGlobalId("Leg", id); + return LegReferenceSerializer.encode(ref); }; } } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index 266574f546b..95984ba6dd0 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -370,7 +370,7 @@ public DataFetcher leg() { return environment -> { TransitService transitService = getTransitService(environment); var args = new GraphQLTypes.GraphQLQueryTypeLegArgs(environment.getArguments()); - String id = args.getGraphQLId().getId(); + String id = args.getGraphQLId(); LegReference ref = LegReferenceSerializer.decode(id); if (ref == null) { return null; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index 4e63e87438b..2dbcf7d1998 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -482,7 +482,7 @@ public interface GraphQLLeg { public DataFetcher headsign(); - public DataFetcher id(); + public DataFetcher id(); public DataFetcher interlineWithPreviousLeg(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java index d0ab004e654..3cd98b15652 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java @@ -2434,19 +2434,19 @@ public void setGraphQLTime(Integer time) { public static class GraphQLQueryTypeLegArgs { - private graphql.relay.Relay.ResolvedGlobalId id; + private String id; public GraphQLQueryTypeLegArgs(Map args) { if (args != null) { - this.id = (graphql.relay.Relay.ResolvedGlobalId) args.get("id"); + this.id = (String) args.get("id"); } } - public graphql.relay.Relay.ResolvedGlobalId getGraphQLId() { + public String getGraphQLId() { return this.id; } - public void setGraphQLId(graphql.relay.Relay.ResolvedGlobalId id) { + public void setGraphQLId(String id) { this.id = id; } } diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 9bfb5f8af93..f2e1aa61163 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -674,7 +674,7 @@ type Leg { Re-fetching fails when the underlying transit data no longer exists. Non-transit legs cannot be refetched using their id. """ - id: ID + id: String """ Interlines with previous leg. This is true when the same vehicle is used for the previous leg as for this leg @@ -1172,10 +1172,10 @@ type QueryType { time: Int! ): Trip """ - Try refetching the current state of a transit leg using its ID. + Try refetching the current state of a transit leg using its id. This fails when the underlying transit data (mostly IDs) has changed or are no longer available. """ - leg(id: ID!): Leg + leg(id: String!): Leg """ Get all places (stops, stations, etc. with coordinates) within the specified radius from a location. The returned type is a Relay connection (see diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json index 1148a8792b0..c899606bd0b 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json +++ b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json @@ -157,7 +157,7 @@ "alerts" : [ ], "rideHailingEstimate" : null, "accessibilityScore" : null, - "id": "TGVnOnJPMEFCWGRCQUJoVFEwaEZSRlZNUlVSZlZGSkJUbE5KVkY5TVJVZGZWak1BQlVZNk1USXlBQW95TURJd0xUQXlMVEF5QUFBQUJRQUFBQWNBQTBZNlFnQURSanBEQUFBPQ", + "id": "rO0ABXdBABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMABUY6MTIyAAoyMDIwLTAyLTAyAAAABQAAAAcAA0Y6QgADRjpDAAA=", "realtimeState": "UPDATED" }, { @@ -269,7 +269,7 @@ ], "rideHailingEstimate" : null, "accessibilityScore" : null, - "id": "TGVnOnJPMEFCWGRCQUJoVFEwaEZSRlZNUlVSZlZGSkJUbE5KVkY5TVJVZGZWak1BQlVZNk5ETTVBQW95TURJd0xUQXlMVEF5QUFBQUJRQUFBQWNBQTBZNlF3QURSanBFQUFBPQ", + "id": "rO0ABXdBABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMABUY6NDM5AAoyMDIwLTAyLTAyAAAABQAAAAcAA0Y6QwADRjpEAAA=", "realtimeState": "UPDATED" }, { From 45d6f983ee7ff0d7b17447da5b083a12030c0e60 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Fri, 27 Sep 2024 10:14:35 +0300 Subject: [PATCH 26/27] Update src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java Co-authored-by: Joel Lappalainen --- .../java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index 9714b4106fa..950e3d9bba5 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -1,6 +1,5 @@ package org.opentripplanner.apis.gtfs.datafetchers; -import graphql.relay.Relay; import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import java.util.List; From 857b815efd79a8a3896f34f449a822fc7f09c116 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Fri, 27 Sep 2024 10:15:30 +0300 Subject: [PATCH 27/27] Update src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls Co-authored-by: Joel Lappalainen --- src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index f2e1aa61163..9c3fc2cf730 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -672,7 +672,6 @@ type Leg { """ An identifier for the leg, which can be used to re-fetch transit leg information. Re-fetching fails when the underlying transit data no longer exists. - Non-transit legs cannot be refetched using their id. """ id: String """