From 83a8ec1026895b92f80b3354d429426a93b363d0 Mon Sep 17 00:00:00 2001 From: Evan Siroky Date: Mon, 8 Jun 2020 16:37:20 -0700 Subject: [PATCH 1/2] perf(project): return summarized project info on collection get api routes --- .../controllers/api/ProjectController.java | 33 +++++++++++-------- .../datatools/manager/models/Project.java | 14 +++++++- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/conveyal/datatools/manager/controllers/api/ProjectController.java b/src/main/java/com/conveyal/datatools/manager/controllers/api/ProjectController.java index dc695ebfc..456df2f78 100644 --- a/src/main/java/com/conveyal/datatools/manager/controllers/api/ProjectController.java +++ b/src/main/java/com/conveyal/datatools/manager/controllers/api/ProjectController.java @@ -44,9 +44,6 @@ */ @SuppressWarnings({"unused", "ThrowableNotThrown"}) public class ProjectController { - - // TODO We can probably replace this with something from Mongo so we use one JSON serializer / deserializer throughout - private static JsonManager json = new JsonManager<>(Project.class, JsonViews.UserInterface.class); private static final Logger LOG = LoggerFactory.getLogger(ProjectController.class); /** @@ -316,20 +313,28 @@ private static Project thirdPartySync(Request req, Response res) { * A bit too static/global for an OO language, but that's how Spark works. */ public static void register (String apiPrefix) { - get(apiPrefix + "secure/project/:id", ProjectController::getProject, json::write); - get(apiPrefix + "secure/project", ProjectController::getAllProjects, json::write); - post(apiPrefix + "secure/project", ProjectController::createProject, json::write); - put(apiPrefix + "secure/project/:id", ProjectController::updateProject, json::write); - delete(apiPrefix + "secure/project/:id", ProjectController::deleteProject, json::write); - get(apiPrefix + "secure/project/:id/thirdPartySync/:type", ProjectController::thirdPartySync, json::write); - post(apiPrefix + "secure/project/:id/fetch", ProjectController::fetch, json::write); - post(apiPrefix + "secure/project/:id/deployPublic", ProjectController::publishPublicFeeds, json::write); + // Construct JSON managers which help serialize the response. Slim JSON is the generic JSON view. Full JSON + // contains additional fields (at the moment just #otpServers) and should only be used when the controller + // returns a single project (slimJson is better suited for a collection). If fullJson is attempted for use + // with a collection, massive performance issues will ensure (mainly due to multiple calls to AWS EC2). + JsonManager slimJson = new JsonManager<>(Project.class, JsonViews.UserInterface.class); + JsonManager fullJson = new JsonManager<>(Project.class, JsonViews.UserInterface.class); + fullJson.addMixin(Project.class, Project.ProjectWithOtpServers.class); + + get(apiPrefix + "secure/project/:id", ProjectController::getProject, fullJson::write); + get(apiPrefix + "secure/project", ProjectController::getAllProjects, slimJson::write); + post(apiPrefix + "secure/project", ProjectController::createProject, fullJson::write); + put(apiPrefix + "secure/project/:id", ProjectController::updateProject, fullJson::write); + delete(apiPrefix + "secure/project/:id", ProjectController::deleteProject, fullJson::write); + get(apiPrefix + "secure/project/:id/thirdPartySync/:type", ProjectController::thirdPartySync, fullJson::write); + post(apiPrefix + "secure/project/:id/fetch", ProjectController::fetch, fullJson::write); + post(apiPrefix + "secure/project/:id/deployPublic", ProjectController::publishPublicFeeds, fullJson::write); get(apiPrefix + "secure/project/:id/download", ProjectController::mergeProjectFeeds); - get(apiPrefix + "secure/project/:id/downloadtoken", ProjectController::getFeedDownloadCredentials, json::write); + get(apiPrefix + "secure/project/:id/downloadtoken", ProjectController::getFeedDownloadCredentials, fullJson::write); - get(apiPrefix + "public/project/:id", ProjectController::getProject, json::write); - get(apiPrefix + "public/project", ProjectController::getAllProjects, json::write); + get(apiPrefix + "public/project/:id", ProjectController::getProject, fullJson::write); + get(apiPrefix + "public/project", ProjectController::getAllProjects, slimJson::write); get(apiPrefix + "downloadprojectfeed/:token", ProjectController::downloadMergedFeedWithToken); } diff --git a/src/main/java/com/conveyal/datatools/manager/models/Project.java b/src/main/java/com/conveyal/datatools/manager/models/Project.java index 203fb004f..c85c6cdee 100644 --- a/src/main/java/com/conveyal/datatools/manager/models/Project.java +++ b/src/main/java/com/conveyal/datatools/manager/models/Project.java @@ -43,7 +43,6 @@ public class Project extends Model { * project as well as those that belong to no project. * @return */ - @JsonProperty("otpServers") public List availableOtpServers() { return Persistence.servers.getFiltered(or( eq("projectId", this.id), @@ -111,4 +110,17 @@ public void delete() { // Finally, delete the project. Persistence.projects.removeById(this.id); } + + /** + * A MixIn to be applied to this deployment, for returning a single deployment, so that the list of ec2Instances is + * included in the JSON response. + * + * Usually a mixin would be used on an external class, but since we are changing one thing about a single class, it seemed + * unnecessary to define a new view. + */ + public abstract static class ProjectWithOtpServers { + + @JsonProperty("otpServers") + public abstract Collection availableOtpServers (); + } } From 39ee8f054b062a92afaf52fe4c887ac843ab1c03 Mon Sep 17 00:00:00 2001 From: Evan Siroky Date: Tue, 9 Jun 2020 16:15:01 -0700 Subject: [PATCH 2/2] refactor(docs): correct javadoc copypasta --- .../java/com/conveyal/datatools/manager/models/Project.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/conveyal/datatools/manager/models/Project.java b/src/main/java/com/conveyal/datatools/manager/models/Project.java index c85c6cdee..79163ab90 100644 --- a/src/main/java/com/conveyal/datatools/manager/models/Project.java +++ b/src/main/java/com/conveyal/datatools/manager/models/Project.java @@ -112,11 +112,11 @@ public void delete() { } /** - * A MixIn to be applied to this deployment, for returning a single deployment, so that the list of ec2Instances is + * A MixIn to be applied to this project, for returning a single project, so that the list of otpServers is * included in the JSON response. * - * Usually a mixin would be used on an external class, but since we are changing one thing about a single class, it seemed - * unnecessary to define a new view. + * Usually a mixin would be used on an external class, but since we are changing one thing about a single class, it + * seemed unnecessary to define a new view. */ public abstract static class ProjectWithOtpServers {