Skip to content

Commit 4ed3bb8

Browse files
authored
Merge pull request #634 from ibi-group/feature/DT-530-additional-feed-source-summary-fields
Additional feed summary params
2 parents 0d6af31 + f1b8d77 commit 4ed3bb8

19 files changed

Lines changed: 865 additions & 448 deletions

src/main/java/com/conveyal/datatools/manager/controllers/DumpController.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.conveyal.datatools.manager.controllers;
22

3-
import com.conveyal.datatools.common.status.MonitorableJob;
43
import com.conveyal.datatools.manager.auth.Auth0UserProfile;
54
import com.conveyal.datatools.manager.jobs.ProcessSingleFeedJob;
65
import com.conveyal.datatools.manager.jobs.ValidateFeedJob;
6+
import com.conveyal.datatools.manager.jobs.ValidateGtfsPlusFeedJob;
77
import com.conveyal.datatools.manager.jobs.ValidateMobilityDataFeedJob;
88
import com.conveyal.datatools.manager.models.Deployment;
99
import com.conveyal.datatools.manager.models.ExternalFeedSourceProperty;
@@ -365,6 +365,7 @@ public static boolean validateAll (boolean load, boolean force, String filterFee
365365
} else {
366366
JobUtils.heavyExecutor.execute(new ValidateFeedJob(version, systemUser, false));
367367
JobUtils.heavyExecutor.execute(new ValidateMobilityDataFeedJob(version, systemUser, false));
368+
JobUtils.heavyExecutor.execute(new ValidateGtfsPlusFeedJob(version, systemUser, false));
368369
}
369370
}
370371
// ValidateAllFeedsJob validateAllFeedsJob = new ValidateAllFeedsJob("system", force, load);

src/main/java/com/conveyal/datatools/manager/controllers/api/GtfsPlusController.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,17 +249,17 @@ private static String publishGtfsPlusFile(Request req, Response res) {
249249
}
250250

251251
/**
252-
* HTTP endpoint that validates GTFS+ tables for a specific feed version (or its saved/edited GTFS+).
252+
* HTTP endpoint that validates GTFS+ tables for a specific feed version (or its saved/edited GTFS+). If the feed
253+
* version already has GTFS+ validation results, those will be returned instead of re-validating.
253254
*/
254255
private static GtfsPlusValidation getGtfsPlusValidation(Request req, Response res) {
255-
String feedVersionId = req.params("versionid");
256-
GtfsPlusValidation gtfsPlusValidation = null;
257256
try {
258-
gtfsPlusValidation = GtfsPlusValidation.validate(feedVersionId);
257+
String feedVersionId = req.params("versionid");
258+
return GtfsPlusValidation.validate(feedVersionId);
259259
} catch(Exception e) {
260260
logMessageAndHalt(req, 500, "Could not read GTFS+ zip file", e);
261261
}
262-
return gtfsPlusValidation;
262+
return null;
263263
}
264264

265265
/**

src/main/java/com/conveyal/datatools/manager/gtfsplus/GtfsPlusValidation.java

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,47 @@ private GtfsPlusValidation (String feedVersionId) {
4949
this.feedVersionId = feedVersionId;
5050
}
5151

52+
public GtfsPlusValidation(String feedVersionId, boolean published, List<ValidationIssue> issues) {
53+
this(feedVersionId);
54+
this.published = published;
55+
this.issues = issues;
56+
}
57+
58+
public GtfsPlusValidation() {
59+
this(null);
60+
// Constructor for serialization.
61+
}
62+
5263
/**
53-
* Validate a GTFS+ feed and return a list of issues encountered.
54-
* FIXME: For now this uses the MapDB-backed GTFSFeed class. Which actually suggests that this might
55-
* should be contained within a MonitorableJob.
64+
* Overload method to retrieve the feed version.
5665
*/
5766
public static GtfsPlusValidation validate(String feedVersionId) throws Exception {
58-
GtfsPlusValidation validation = new GtfsPlusValidation(feedVersionId);
67+
FeedVersion feedVersion = Persistence.feedVersions.getById(feedVersionId);
68+
if (feedVersion != null) {
69+
if (feedVersion.gtfsPlusValidation != null) {
70+
return feedVersion.gtfsPlusValidation;
71+
}
72+
GtfsPlusValidation gtfsPlusValidation = validate(feedVersion);
73+
feedVersion.gtfsPlusValidation = gtfsPlusValidation;
74+
Persistence.feedVersions.replace(feedVersion.id, feedVersion);
75+
return gtfsPlusValidation;
76+
}
77+
return null;
78+
}
79+
80+
/**
81+
* Validate a GTFS+ feed and return a list of issues encountered.
82+
*/
83+
public static GtfsPlusValidation validate(FeedVersion feedVersion) throws Exception {
5984
if (!DataManager.isModuleEnabled("gtfsplus")) {
6085
throw new IllegalStateException("GTFS+ module must be enabled in server.yml to run GTFS+ validation.");
6186
}
62-
LOG.info("Validating GTFS+ for {}", feedVersionId);
87+
GtfsPlusValidation validation = new GtfsPlusValidation(feedVersion.id);
88+
LOG.info("Validating GTFS+ for {}", feedVersion.id);
6389

64-
FeedVersion feedVersion = Persistence.feedVersions.getById(feedVersionId);
6590
// Load the main GTFS file.
6691
// FIXME: Swap MapDB-backed GTFSFeed for use of SQL data?
67-
File gtfsFeedDbFile = gtfsPlusStore.getFeedFile(feedVersionId + ".db");
92+
File gtfsFeedDbFile = gtfsPlusStore.getFeedFile(feedVersion.id + ".db");
6893
String gtfsFeedDbFilePath = gtfsFeedDbFile.getAbsolutePath();
6994
GTFSFeed gtfsFeed;
7095
try {
@@ -87,7 +112,7 @@ public static GtfsPlusValidation validate(String feedVersionId) throws Exception
87112
}
88113

89114
// check for saved GTFS+ data
90-
File file = gtfsPlusStore.getFeed(feedVersionId);
115+
File file = gtfsPlusStore.getFeed(feedVersion.id);
91116
if (file == null) {
92117
validation.published = true;
93118
LOG.warn("GTFS+ Validation -- Modified GTFS+ file not found, loading from main version GTFS.");

src/main/java/com/conveyal/datatools/manager/gtfsplus/ValidationIssue.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ public class ValidationIssue implements Serializable {
1010
public int rowIndex;
1111
public String description;
1212

13+
public ValidationIssue() {
14+
// Empty constructor for serialization
15+
}
16+
1317
public ValidationIssue(String tableId, String fieldName, int rowIndex, String description) {
1418
this.tableId = tableId;
1519
this.fieldName = fieldName;

src/main/java/com/conveyal/datatools/manager/jobs/ProcessSingleFeedJob.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class ProcessSingleFeedJob extends FeedVersionJob {
4141
public static boolean ENABLE_MTC_TRANSFORMATIONS = true;
4242

4343
// Used in testing to skip validation and speed up response times.
44-
public static boolean VALIDATE_MOBILITY_DATA = true;
44+
public static boolean ENABLE_ADDITIONAL_VALIDATION = true;
4545

4646
/**
4747
* Create a job for the given feed version.
@@ -131,8 +131,9 @@ public void jobLogic() {
131131

132132
// Next, validate the feed.
133133
addNextJob(new ValidateFeedJob(feedVersion, owner, isNewVersion));
134-
if (VALIDATE_MOBILITY_DATA) {
134+
if (ENABLE_ADDITIONAL_VALIDATION) {
135135
addNextJob(new ValidateMobilityDataFeedJob(feedVersion, owner, isNewVersion));
136+
addNextJob(new ValidateGtfsPlusFeedJob(feedVersion, owner, isNewVersion));
136137
}
137138

138139
// We only need to snapshot the feed if there are transformations at the database level. In the case that there
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.conveyal.datatools.manager.jobs;
2+
3+
import com.conveyal.datatools.common.status.FeedVersionJob;
4+
import com.conveyal.datatools.manager.auth.Auth0UserProfile;
5+
import com.conveyal.datatools.manager.models.FeedVersion;
6+
import com.fasterxml.jackson.annotation.JsonProperty;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
10+
/**
11+
* This job handles the GTFS+ validation of a given feed version. If the version is not new, it will simply
12+
* replace the existing version with the version object that has updated validation info.
13+
*/
14+
public class ValidateGtfsPlusFeedJob extends FeedVersionJob {
15+
public static final Logger LOG = LoggerFactory.getLogger(ValidateGtfsPlusFeedJob.class);
16+
17+
private final FeedVersion feedVersion;
18+
private final boolean isNewVersion;
19+
20+
public ValidateGtfsPlusFeedJob(FeedVersion version, Auth0UserProfile owner, boolean isNewVersion) {
21+
super(owner, "Validating GTFS+", JobType.VALIDATE_FEED);
22+
feedVersion = version;
23+
this.isNewVersion = isNewVersion;
24+
status.update("Waiting to begin GTFS+ validation...", 0);
25+
}
26+
27+
@Override
28+
public void jobLogic () {
29+
LOG.info("Running ValidateGtfsPlusFeedJob for {}", feedVersion.id);
30+
feedVersion.validateGtfsPlus(status);
31+
}
32+
33+
@Override
34+
public void jobFinished () {
35+
if (!status.error) {
36+
if (parentJobId != null && JobType.PROCESS_FEED.equals(parentJobType)) {
37+
// Validate stage is happening as part of an overall process feed job.
38+
// At this point all GTFS data has been loaded and validated, so we record
39+
// the FeedVersion into mongo.
40+
// This happens here because otherwise we would have to wait for other jobs,
41+
// such as BuildTransportNetwork, to finish. If those subsequent jobs fail,
42+
// the version won't get loaded into MongoDB (even though it exists in postgres).
43+
feedVersion.persistFeedVersionAfterValidation(isNewVersion);
44+
}
45+
status.completeSuccessfully("GTFS+ validation finished!");
46+
} else {
47+
// If the version was not stored successfully, call FeedVersion#delete to reset things to before the version
48+
// was uploaded/fetched. Note: delete calls made to MongoDB on the version ID will not succeed, but that is
49+
// expected.
50+
feedVersion.delete();
51+
}
52+
}
53+
54+
/**
55+
* Getter that allows a client to know the ID of the feed version that will be created as soon as the upload is
56+
* initiated; however, we will not store the FeedVersion in the mongo application database until the upload and
57+
* processing is completed. This prevents clients from manipulating GTFS data before it is entirely imported.
58+
*/
59+
@JsonProperty
60+
public String getFeedVersionId () {
61+
return feedVersion.id;
62+
}
63+
64+
@JsonProperty
65+
public String getFeedSourceId () {
66+
return feedVersion.parentFeedSource().id;
67+
}
68+
69+
70+
}

0 commit comments

Comments
 (0)