From f8d393dea5f4f447f78ca1a47c95bad2b6b680ce Mon Sep 17 00:00:00 2001 From: Landon Reed Date: Fri, 28 Jun 2019 10:26:35 -0400 Subject: [PATCH] fix(MtcFeedResource): properly initialize external feed props on create fixes #210 --- .../extensions/ExternalFeedResource.java | 2 +- .../extensions/mtc/MtcFeedResource.java | 22 ++++------- .../manager/extensions/mtc/RtdCarrier.java | 39 ++++++++++++++++++- .../datatools/manager/models/FeedSource.java | 9 +++-- 4 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/conveyal/datatools/manager/extensions/ExternalFeedResource.java b/src/main/java/com/conveyal/datatools/manager/extensions/ExternalFeedResource.java index d3c0c61b6..c761449de 100644 --- a/src/main/java/com/conveyal/datatools/manager/extensions/ExternalFeedResource.java +++ b/src/main/java/com/conveyal/datatools/manager/extensions/ExternalFeedResource.java @@ -16,7 +16,7 @@ public interface ExternalFeedResource { public void importFeedsForProject(Project project, String authHeader) throws Exception; - public void feedSourceCreated(FeedSource source, String authHeader); + public void feedSourceCreated(FeedSource source, String authHeader) throws Exception; public void propertyUpdated(ExternalFeedSourceProperty property, String previousValue, String authHeader) throws IOException; diff --git a/src/main/java/com/conveyal/datatools/manager/extensions/mtc/MtcFeedResource.java b/src/main/java/com/conveyal/datatools/manager/extensions/mtc/MtcFeedResource.java index 5b7eb075a..99e2125b9 100644 --- a/src/main/java/com/conveyal/datatools/manager/extensions/mtc/MtcFeedResource.java +++ b/src/main/java/com/conveyal/datatools/manager/extensions/mtc/MtcFeedResource.java @@ -120,16 +120,7 @@ public void importFeedsForProject(Project project, String authHeader) throws IOE // Create / update the properties LOG.info("Updating props for {}", source.name); - for(Field carrierField : carrier.getClass().getDeclaredFields()) { - String fieldName = carrierField.getName(); - String fieldValue = carrierField.get(carrier) != null ? carrierField.get(carrier).toString() : null; - ExternalFeedSourceProperty prop = new ExternalFeedSourceProperty(source, this.getResourceType(), fieldName, fieldValue); - if (Persistence.externalFeedSourceProperties.getById(prop.id) == null) { - Persistence.externalFeedSourceProperties.create(prop); - } else { - Persistence.externalFeedSourceProperties.updateField(prop.id, fieldName, fieldValue); - } - } + carrier.updateFields(source); } } catch(Exception ex) { LOG.error("Could not read feeds from MTC RTD API"); @@ -138,12 +129,15 @@ public void importFeedsForProject(Project project, String authHeader) throws IOE } /** - * Do nothing for now. Creating a new agency for RTD requires adding the AgencyId property (when it was previously - * null. See {@link #propertyUpdated(ExternalFeedSourceProperty, String, String)}. + * Generate blank external feed resource properties when a new feed source is created. Creating a new agency for RTD + * requires adding the AgencyId property (when it was previously null. See {@link #propertyUpdated(ExternalFeedSourceProperty, String, String)}. */ @Override - public void feedSourceCreated(FeedSource source, String authHeader) { - LOG.info("Processing new FeedSource {} for RTD. (No action taken.)", source.name); + public void feedSourceCreated(FeedSource source, String authHeader) throws IllegalAccessException { + LOG.info("Processing new FeedSource {} for RTD. Empty external feed properties being generated.", source.name); + // Create a blank carrier and update fields (will initialize all fields to null). + RtdCarrier carrier = new RtdCarrier(); + carrier.updateFields(source); } /** diff --git a/src/main/java/com/conveyal/datatools/manager/extensions/mtc/RtdCarrier.java b/src/main/java/com/conveyal/datatools/manager/extensions/mtc/RtdCarrier.java index 768acdf93..920d7ee32 100644 --- a/src/main/java/com/conveyal/datatools/manager/extensions/mtc/RtdCarrier.java +++ b/src/main/java/com/conveyal/datatools/manager/extensions/mtc/RtdCarrier.java @@ -1,12 +1,17 @@ package com.conveyal.datatools.manager.extensions.mtc; +import com.conveyal.datatools.manager.models.ExternalFeedSourceProperty; import com.conveyal.datatools.manager.models.FeedSource; import com.conveyal.datatools.manager.persistence.Persistence; import com.fasterxml.jackson.annotation.JsonProperty; +import java.lang.reflect.Field; + import static com.conveyal.datatools.manager.models.ExternalFeedSourceProperty.constructId; /** + * Represents all of the properties persisted on a carrier record by the external MTC database known as RTD. + * * Created by demory on 3/30/16. */ @@ -63,11 +68,12 @@ public class RtdCarrier { @JsonProperty String EditedDate; + /** Empty constructor needed for serialization (also used to create empty carrier). */ public RtdCarrier() { } /** - * Construct an RtdCarrier given the provided feed source. + * Construct an RtdCarrier given the provided feed source and initialize all field values from MongoDB. * @param source */ public RtdCarrier(FeedSource source) { @@ -93,9 +99,38 @@ private String getPropId(FeedSource source, String fieldName) { } /** - * FIXME: Are there cases where this might throw NPEs? + * Get the value stored in the database for a particular field. + * + * TODO: Are there cases where this might throw NPEs? */ private String getValueForField (FeedSource source, String fieldName) { return Persistence.externalFeedSourceProperties.getById(getPropId(source, fieldName)).value; } + + /** + * Use reflection to update (or create if field does not exist) all fields for a carrier instance and provided feed + * source. + * + * TODO: Perhaps we should not be using reflection, but it works pretty well here. + */ + public void updateFields(FeedSource feedSource) throws IllegalAccessException { + // Using reflection, iterate over every field in the class. + for(Field carrierField : this.getClass().getDeclaredFields()) { + String fieldName = carrierField.getName(); + String fieldValue = carrierField.get(this) != null ? carrierField.get(this).toString() : null; + // Construct external feed source property for field with value from carrier. + ExternalFeedSourceProperty prop = new ExternalFeedSourceProperty( + feedSource, + MtcFeedResource.RESOURCE_TYPE, + fieldName, + fieldValue + ); + // If field does not exist, create it. Otherwise, update value. + if (Persistence.externalFeedSourceProperties.getById(prop.id) == null) { + Persistence.externalFeedSourceProperties.create(prop); + } else { + Persistence.externalFeedSourceProperties.updateField(prop.id, fieldName, fieldValue); + } + } + } } \ No newline at end of file diff --git a/src/main/java/com/conveyal/datatools/manager/models/FeedSource.java b/src/main/java/com/conveyal/datatools/manager/models/FeedSource.java index 3f428a0b0..fa18e3aae 100644 --- a/src/main/java/com/conveyal/datatools/manager/models/FeedSource.java +++ b/src/main/java/com/conveyal/datatools/manager/models/FeedSource.java @@ -30,6 +30,7 @@ import java.util.Map; import static com.conveyal.datatools.manager.utils.StringUtils.getCleanName; +import static com.mongodb.client.model.Filters.and; import static com.mongodb.client.model.Filters.eq; /** @@ -391,10 +392,10 @@ public Map> externalProperties() { for(String resourceType : DataManager.feedResources.keySet()) { Map propTable = new HashMap<>(); - // FIXME: use mongo filters instead - Persistence.externalFeedSourceProperties.getAll().stream() - .filter(prop -> prop.feedSourceId.equals(this.id)) - .forEach(prop -> propTable.put(prop.name, prop.value)); + // Get all external properties for the feed source/resource type and fill prop table. + Persistence.externalFeedSourceProperties + .getFiltered(and(eq("feedSourceId", this.id), eq("resourceType", resourceType))) + .forEach(prop -> propTable.put(prop.name, prop.value)); resourceTable.put(resourceType, propTable); }