Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add provider of updates as a dimension to metrics. #6199

Merged
merged 7 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,28 @@

/**
* Represents the real-time update of a single trip.
* @param pattern the pattern to which belongs the updated trip. This can be a new pattern created in real-time.
* @param updatedTripTimes the new trip times for the updated trip.
* @param serviceDate the service date for which this update applies (updates are valid only for one service date)
* @param addedTripOnServiceDate optionally if this trip update adds a new trip, the TripOnServiceDate corresponding to this new trip.
* @param tripCreation true if this update creates a new trip, not present in scheduled data.
* @param routeCreation true if an added trip cannot be registered under an existing route and a new route must be created.
*
* @param pattern the pattern to which belongs the updated trip. This can be a new
* pattern created in real-time.
* @param updatedTripTimes the new trip times for the updated trip.
* @param serviceDate the service date for which this update applies (updates are valid
* only for one service date)
* @param addedTripOnServiceDate optionally if this trip update adds a new trip, the
* TripOnServiceDate corresponding to this new trip.
* @param tripCreation true if this update creates a new trip, not present in scheduled
* data.
* @param routeCreation true if an added trip cannot be registered under an existing route
* and a new route must be created.
* @param producer the producer of the real-time update.
*/
public record RealTimeTripUpdate(
TripPattern pattern,
TripTimes updatedTripTimes,
LocalDate serviceDate,
@Nullable TripOnServiceDate addedTripOnServiceDate,
boolean tripCreation,
boolean routeCreation
boolean routeCreation,
@Nullable String producer
) {
public RealTimeTripUpdate {
Objects.requireNonNull(pattern);
Expand All @@ -38,6 +46,25 @@ public RealTimeTripUpdate(
TripTimes updatedTripTimes,
LocalDate serviceDate
) {
this(pattern, updatedTripTimes, serviceDate, null, false, false);
this(pattern, updatedTripTimes, serviceDate, null, false, false, null);
}

public RealTimeTripUpdate(
TripPattern pattern,
TripTimes updatedTripTimes,
LocalDate serviceDate,
@Nullable TripOnServiceDate addedTripOnServiceDate,
boolean tripCreation,
boolean routeCreation
) {
this(
pattern,
updatedTripTimes,
serviceDate,
addedTripOnServiceDate,
tripCreation,
routeCreation,
null
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,7 @@ public Result<UpdateSuccess, UpdateError> update(RealTimeTripUpdate realTimeTrip
}

// The time tables are finished during the commit

return Result.success(UpdateSuccess.noWarnings());
return Result.success(UpdateSuccess.noWarnings(realTimeTripUpdate.producer()));
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.opentripplanner.standalone.config.routerconfig.updaters;

import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_1;
import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_7;
import static org.opentripplanner.updater.siri.updater.google.SiriETGooglePubsubUpdaterParameters.INITIAL_GET_DATA_TIMEOUT;
import static org.opentripplanner.updater.siri.updater.google.SiriETGooglePubsubUpdaterParameters.RECONNECT_PERIOD;

Expand Down Expand Up @@ -79,6 +80,11 @@ If this parameter is set, the updater will be marked as initialized (primed) onl
.of("fuzzyTripMatching")
.since(V2_1)
.summary("If the trips should be matched fuzzily.")
.asBoolean(false),
c
.of("producerMetrics")
.since(V2_7)
.summary("If failure, success, and warning metrics should be collected per producer.")
.asBoolean(false)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0;
import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_3;
import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_7;

import java.time.Duration;
import org.opentripplanner.standalone.config.framework.json.NodeAdapter;
Expand Down Expand Up @@ -43,7 +44,12 @@ public static SiriETUpdaterParameters create(String configRef, NodeAdapter c) {
.since(V2_0)
.summary("If the fuzzy trip matcher should be used to match trips.")
.asBoolean(false),
HttpHeadersConfig.headers(c, V2_3)
HttpHeadersConfig.headers(c, V2_3),
c
.of("producerMetrics")
.since(V2_7)
.summary("If failure, success, and warning metrics should be collected per producer.")
.asBoolean(false)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public static boolean isValidString(String value) throws IllegalArgumentExceptio
/**
* Concatenate feedId and id into a string.
*/
public static String concatenateId(String feedId, String id) {
private static String concatenateId(String feedId, String id) {
return feedId + ID_SEPARATOR + id;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class AddedTripBuilder {
private final Function<Trip, FeedScopedId> getTripPatternId;
private final FeedScopedId tripId;
private final Operator operator;
private final String dataSource;
private final String lineRef;
private final Route replacedRoute;
private final LocalDate serviceDate;
Expand All @@ -81,11 +82,14 @@ class AddedTripBuilder {
Objects.requireNonNull(newServiceJourneyRef, "EstimatedVehicleJourneyCode is required");
tripId = entityResolver.resolveId(newServiceJourneyRef);

//OperatorRef of added trip
// OperatorRef of added trip
Objects.requireNonNull(estimatedVehicleJourney.getOperatorRef(), "OperatorRef is required");
String operatorRef = estimatedVehicleJourney.getOperatorRef().getValue();
operator = entityResolver.resolveOperator(operatorRef);

// DataSource of added trip
dataSource = estimatedVehicleJourney.getDataSource();

// LineRef of added trip
Objects.requireNonNull(estimatedVehicleJourney.getLineRef(), "LineRef is required");
lineRef = estimatedVehicleJourney.getLineRef().getValue();
Expand Down Expand Up @@ -135,7 +139,8 @@ class AddedTripBuilder {
boolean cancellation,
String shortName,
String headsign,
List<TripOnServiceDate> replacedTrips
List<TripOnServiceDate> replacedTrips,
String dataSource
) {
this.transitService = transitService;
this.entityResolver = entityResolver;
Expand All @@ -155,28 +160,29 @@ class AddedTripBuilder {
this.shortName = shortName;
this.headsign = headsign;
this.replacedTrips = replacedTrips;
this.dataSource = dataSource;
}

Result<TripUpdate, UpdateError> build() {
if (calls.size() < 2) {
return UpdateError.result(tripId, TOO_FEW_STOPS);
return UpdateError.result(tripId, TOO_FEW_STOPS, dataSource);
}

if (serviceDate == null) {
return UpdateError.result(tripId, NO_START_DATE);
return UpdateError.result(tripId, NO_START_DATE, dataSource);
}

FeedScopedId calServiceId = transitService.getOrCreateServiceIdForDate(serviceDate);
if (calServiceId == null) {
return UpdateError.result(tripId, NO_START_DATE);
return UpdateError.result(tripId, NO_START_DATE, dataSource);
}

boolean isAddedRoute = false;
Route route = entityResolver.resolveRoute(lineRef);
if (route == null) {
Agency agency = resolveAgency();
if (agency == null) {
return UpdateError.result(tripId, CANNOT_RESOLVE_AGENCY);
return UpdateError.result(tripId, CANNOT_RESOLVE_AGENCY, dataSource);
}
route = createRoute(agency);
isAddedRoute = true;
Expand All @@ -201,7 +207,7 @@ Result<TripUpdate, UpdateError> build() {

// Drop this update if the call refers to an unknown stop (not present in the site repository).
if (stopTime == null) {
return UpdateError.result(tripId, NO_VALID_STOPS);
return UpdateError.result(tripId, NO_VALID_STOPS, dataSource);
}

aimedStopTimes.add(stopTime);
Expand Down Expand Up @@ -256,7 +262,7 @@ Result<TripUpdate, UpdateError> build() {
try {
updatedTripTimes.validateNonIncreasingTimes();
} catch (DataValidationException e) {
return DataValidationExceptionMapper.toResult(e);
return DataValidationExceptionMapper.toResult(e, dataSource);
}

var tripOnServiceDate = TripOnServiceDate
Expand All @@ -273,7 +279,8 @@ Result<TripUpdate, UpdateError> build() {
serviceDate,
tripOnServiceDate,
pattern,
isAddedRoute
isAddedRoute,
dataSource
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class ModifiedTripBuilder {
private final boolean cancellation;
private final OccupancyEnumeration occupancy;
private final boolean predictionInaccurate;
private final String dataSource;

public ModifiedTripBuilder(
TripTimes existingTripTimes,
Expand All @@ -64,6 +65,7 @@ public ModifiedTripBuilder(
cancellation = TRUE.equals(journey.isCancellation());
predictionInaccurate = TRUE.equals(journey.isPredictionInaccurate());
occupancy = journey.getOccupancy();
dataSource = journey.getDataSource();
}

/**
Expand All @@ -78,7 +80,8 @@ public ModifiedTripBuilder(
List<CallWrapper> calls,
boolean cancellation,
OccupancyEnumeration occupancy,
boolean predictionInaccurate
boolean predictionInaccurate,
String dataSource
) {
this.existingTripTimes = existingTripTimes;
this.pattern = pattern;
Expand All @@ -89,6 +92,7 @@ public ModifiedTripBuilder(
this.cancellation = cancellation;
this.occupancy = occupancy;
this.predictionInaccurate = predictionInaccurate;
this.dataSource = dataSource;
}

/**
Expand All @@ -103,7 +107,9 @@ public Result<TripUpdate, UpdateError> build() {
if (cancellation || stopPattern.isAllStopsNonRoutable()) {
LOG.debug("Trip is cancelled");
newTimes.cancelTrip();
return Result.success(new TripUpdate(pattern.getStopPattern(), newTimes, serviceDate));
return Result.success(
new TripUpdate(pattern.getStopPattern(), newTimes, serviceDate, dataSource)
);
}

applyUpdates(newTimes);
Expand All @@ -116,7 +122,7 @@ public Result<TripUpdate, UpdateError> build() {
newTimes.setRealTimeState(RealTimeState.MODIFIED);
}

// TODO - Handle DataValidationException at the outemost level(pr trip)
// TODO - Handle DataValidationException at the outermost level (pr trip)
try {
newTimes.validateNonIncreasingTimes();
} catch (DataValidationException e) {
Expand All @@ -125,7 +131,7 @@ public Result<TripUpdate, UpdateError> build() {
newTimes.getTrip().getId(),
e.getMessage()
);
return DataValidationExceptionMapper.toResult(e);
return DataValidationExceptionMapper.toResult(e, dataSource);
}

int numStopsInUpdate = newTimes.getNumStops();
Expand All @@ -137,11 +143,11 @@ public Result<TripUpdate, UpdateError> build() {
numStopsInUpdate,
numStopsInPattern
);
return UpdateError.result(existingTripTimes.getTrip().getId(), TOO_FEW_STOPS);
return UpdateError.result(existingTripTimes.getTrip().getId(), TOO_FEW_STOPS, dataSource);
}

LOG.debug("A valid TripUpdate object was applied using the Timetable class update method.");
return Result.success(new TripUpdate(stopPattern, newTimes, serviceDate));
return Result.success(new TripUpdate(stopPattern, newTimes, serviceDate, dataSource));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ private Result<UpdateSuccess, UpdateError> apply(
/* commit */
return addTripToGraphAndBuffer(result.successValue());
} catch (DataValidationException e) {
return DataValidationExceptionMapper.toResult(e);
return DataValidationExceptionMapper.toResult(e, journey.getDataSource());
} catch (Exception e) {
LOG.warn(
"{} EstimatedJourney {} failed.",
Expand Down Expand Up @@ -217,20 +217,21 @@ private Result<TripUpdate, UpdateError> handleModifiedTrip(
EstimatedVehicleJourney estimatedVehicleJourney
) {
Trip trip = entityResolver.resolveTrip(estimatedVehicleJourney);
String dataSource = estimatedVehicleJourney.getDataSource();

// Check if EstimatedVehicleJourney is reported as NOT monitored, ignore the notMonitored-flag
// if the journey is NOT monitored because it has been cancelled
if (
!TRUE.equals(estimatedVehicleJourney.isMonitored()) &&
!TRUE.equals(estimatedVehicleJourney.isCancellation())
) {
return UpdateError.result(trip != null ? trip.getId() : null, NOT_MONITORED);
return UpdateError.result(trip != null ? trip.getId() : null, NOT_MONITORED, dataSource);
}

LocalDate serviceDate = entityResolver.resolveServiceDate(estimatedVehicleJourney);

if (serviceDate == null) {
return UpdateError.result(trip != null ? trip.getId() : null, NO_START_DATE);
return UpdateError.result(trip != null ? trip.getId() : null, NO_START_DATE, dataSource);
}

TripPattern pattern;
Expand All @@ -252,20 +253,20 @@ private Result<TripUpdate, UpdateError> handleModifiedTrip(
"No trips found for EstimatedVehicleJourney. {}",
DebugString.of(estimatedVehicleJourney)
);
return UpdateError.result(null, NO_FUZZY_TRIP_MATCH);
return UpdateError.result(null, NO_FUZZY_TRIP_MATCH, dataSource);
}

trip = tripAndPattern.trip();
pattern = tripAndPattern.tripPattern();
} else {
return UpdateError.result(null, TRIP_NOT_FOUND);
return UpdateError.result(null, TRIP_NOT_FOUND, dataSource);
}

Timetable currentTimetable = getCurrentTimetable(pattern, serviceDate);
TripTimes existingTripTimes = currentTimetable.getTripTimes(trip);
if (existingTripTimes == null) {
LOG.debug("tripId {} not found in pattern.", trip.getId());
return UpdateError.result(trip.getId(), TRIP_NOT_FOUND_IN_PATTERN);
return UpdateError.result(trip.getId(), TRIP_NOT_FOUND_IN_PATTERN, dataSource);
}
var updateResult = new ModifiedTripBuilder(
existingTripTimes,
Expand Down Expand Up @@ -315,7 +316,8 @@ private Result<UpdateSuccess, UpdateError> addTripToGraphAndBuffer(TripUpdate tr
serviceDate,
tripUpdate.addedTripOnServiceDate(),
tripUpdate.tripCreation(),
tripUpdate.routeCreation()
tripUpdate.routeCreation(),
tripUpdate.dataSource()
);
var result = snapshotManager.updateBuffer(realTimeTripUpdate);
LOG.debug("Applied real-time data for trip {} on {}", trip, serviceDate);
Expand Down
Loading
Loading