From 84facd7a6be335caeb0112c28240bcba5e90bb55 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Mon, 28 Nov 2022 10:21:16 -0700
Subject: [PATCH] update to return fault sections

---
 .../nshmp/www/source/FeaturesController.java  |  67 ++++++-----
 .../nshmp/www/source/FeaturesService.java     | 107 +++++++++++++-----
 2 files changed, 115 insertions(+), 59 deletions(-)

diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeaturesController.java b/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeaturesController.java
index 3ff3662e..c9fa078e 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeaturesController.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeaturesController.java
@@ -3,14 +3,17 @@ package gov.usgs.earthquake.nshmp.www.source;
 import gov.usgs.earthquake.nshmp.www.NshmpMicronautServlet;
 import gov.usgs.earthquake.nshmp.www.ResponseBody;
 import gov.usgs.earthquake.nshmp.www.ServletUtil;
+import gov.usgs.earthquake.nshmp.www.source.FeaturesService.FaultType;
 import gov.usgs.earthquake.nshmp.www.source.FeaturesService.Metadata;
 import gov.usgs.earthquake.nshmp.www.source.FeaturesService.RequestData;
 
+import io.micronaut.core.annotation.Nullable;
 import io.micronaut.http.HttpRequest;
 import io.micronaut.http.HttpResponse;
 import io.micronaut.http.annotation.Controller;
 import io.micronaut.http.annotation.Get;
 import io.micronaut.http.annotation.PathVariable;
+import io.micronaut.http.annotation.QueryValue;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -39,28 +42,22 @@ public class FeaturesController {
   @Inject
   private NshmpMicronautServlet servlet;
 
-  /*
-   * Not sure we need metadata for this. Issue #542 describes the various groups
-   * that could be supported. However instead of 'all' one could consider just
-   * having no argument such that the root endpoint path would just return all
-   * features.
-   */
-
   @Operation(
-      summary = "Source model logic tree listing",
-      description = "Returns the ID's of logic trees in the model",
-      operationId = "source-feature-metadata")
+      summary = "Source model features listing",
+      description = "Returns the fault features in a source model",
+      operationId = "fault-sections")
   @ApiResponse(
       description = "Source logic tree metadata",
       responseCode = "200",
       content = @Content(
           schema = @Schema(
               implementation = MetadataResponse.class)))
-  @Get
-  @Deprecated
-  public HttpResponse<String> doGetMetadata(HttpRequest<?> http) {
+  @Get(uri = "{?faultType,raw}")
+  public HttpResponse<String> doGet(
+      HttpRequest<?> http, @QueryValue @Nullable FaultType faultType,
+      @QueryValue(defaultValue = "false") @Nullable Boolean raw) {
     try {
-      return FeaturesService.getMetadata(http);
+      return FeaturesService.getFaultSections(http, faultType, raw);
     } catch (Exception e) {
       return ServletUtil.error(
           FeaturesService.LOG, e,
@@ -69,29 +66,37 @@ public class FeaturesController {
     }
   }
 
-  /**
-   * @param id Source tree id
-   */
   @Operation(
-      summary = "Get the GeoJSON features in a source tree",
-      description = "Returns the features for the supplied ID",
-      operationId = "source-features")
+      summary = "Get the GeoJSON fault features in a source model",
+      description = "Returns the fault features for the supplied fault type",
+      operationId = "fault-sections-slash")
   @ApiResponse(
       description = "NSHM source features",
       responseCode = "200",
       content = @Content(
           schema = @Schema(implementation = TreeResponse.class)))
-  @Get(uri = "/{id}")
-  @Deprecated
-  public HttpResponse<String> doGetTree(HttpRequest<?> http, @PathVariable int id) {
-    try {
-      return FeaturesService.getTree(http, id);
-    } catch (Exception e) {
-      return ServletUtil.error(
-          FeaturesService.LOG, e,
-          FeaturesService.NAME,
-          http.getUri().toString());
-    }
+  @Get(uri = "/{faultType}")
+  public HttpResponse<String> doGetSlash(
+      HttpRequest<?> http,
+      @PathVariable FaultType faultType) {
+    return doGet(http, faultType, null);
+  }
+
+  @Operation(
+      summary = "Get the GeoJSON fault features in a source model",
+      description = "Returns the fault features for the supplied fault type",
+      operationId = "fault-sections-slash-raw")
+  @ApiResponse(
+      description = "NSHM source features",
+      responseCode = "200",
+      content = @Content(
+          schema = @Schema(implementation = TreeResponse.class)))
+  @Get(uri = "/{faultType}/{raw}")
+  public HttpResponse<String> doGetSlashRaw(
+      HttpRequest<?> http,
+      @PathVariable FaultType faultType,
+      @PathVariable Boolean raw) {
+    return doGet(http, faultType, raw);
   }
 
   // Swagger schema
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeaturesService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeaturesService.java
index f21bf57d..d81a8071 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeaturesService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeaturesService.java
@@ -1,14 +1,23 @@
 package gov.usgs.earthquake.nshmp.www.source;
 
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.CaseFormat;
+
 import gov.usgs.earthquake.nshmp.model.HazardModel;
 import gov.usgs.earthquake.nshmp.model.Models;
+import gov.usgs.earthquake.nshmp.model.SourceType;
 import gov.usgs.earthquake.nshmp.www.HazVersion;
 import gov.usgs.earthquake.nshmp.www.ResponseBody;
 import gov.usgs.earthquake.nshmp.www.ResponseMetadata;
 import gov.usgs.earthquake.nshmp.www.ServletUtil;
+import gov.usgs.earthquake.nshmp.www.meta.Parameter;
 import gov.usgs.earthquake.nshmp.www.source.SourceService.SourceModel;
 
 import io.micronaut.http.HttpRequest;
@@ -16,8 +25,6 @@ import io.micronaut.http.HttpResponse;
 import jakarta.inject.Singleton;
 
 /**
- * Source model tree feature handler for {@link FeaturesController}
- *
  * @author U.S. Geological Survey
  */
 @Singleton
@@ -26,8 +33,43 @@ public class FeaturesService {
   static final String NAME = "Model Features";
   static final Logger LOG = LoggerFactory.getLogger(FeaturesService.class);
 
-  @Deprecated
-  public static HttpResponse<String> getMetadata(HttpRequest<?> request) {
+  public static HttpResponse<String> getFaultSections(
+      HttpRequest<?> request,
+      FaultType faultType,
+      Boolean raw) {
+    if (faultType == null && raw == null) {
+      return metadata(request);
+    } else {
+      return processResponse(request, new RequestData(faultType, raw));
+    }
+  }
+
+  private static HttpResponse<String> processResponse(
+      HttpRequest<?> request,
+      RequestData requestData) {
+    var url = request.getUri().toString();
+
+    var features = requestData.faultType == FaultType.ALL
+        ? Models.features(ServletUtil.model(), Optional.empty())
+        : Models.features(ServletUtil.model(),
+            Optional.of(SourceType.valueOf(requestData.faultType.name())));
+
+    if (requestData.raw) {
+      return HttpResponse.ok(features.toJson());
+    } else {
+      var response = ResponseBody.success()
+          .name(NAME)
+          .url(url)
+          .metadata(new ResponseMetadata(HazVersion.appVersions()))
+          .request(requestData)
+          .response(features.toJsonTree())
+          .build();
+
+      return HttpResponse.ok(ServletUtil.GSON2.toJson(response));
+    }
+  }
+
+  private static HttpResponse<String> metadata(HttpRequest<?> request) {
     var url = request.getUri().toString();
     var metadata = new Metadata(ServletUtil.model());
     var response = ResponseBody.usage()
@@ -40,48 +82,57 @@ public class FeaturesService {
     return HttpResponse.ok(ServletUtil.GSON2.toJson(response));
   }
 
-  @Deprecated
-  public static HttpResponse<String> getTree(HttpRequest<?> request, Integer id) {
-    var url = request.getUri().toString();
-    var features = Models.features(ServletUtil.model(), id);
-    var requestData = new RequestData(id);
-    var response = ResponseBody.success()
-        .name(NAME)
-        .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
-        .request(requestData)
-        .response(features)
-        .build();
-    return HttpResponse.ok(ServletUtil.GSON2.toJson(response));
-  }
-
   static class RequestData {
-    final int id;
+    final FaultType faultType;
+    final boolean raw;
 
-    RequestData(int id) {
-      this.id = id;
+    RequestData(FaultType sourceType, Boolean raw) {
+      this.raw = raw == null ? false : raw;
+      this.faultType = sourceType;
     }
 
-    public int getId() {
-      return id;
+    public FaultType getFaultType() {
+      return faultType;
+    }
+
+    public boolean getRaw() {
+      return raw;
+    }
+  }
+
+  /**
+   * Subset of {@code SourceType}
+   */
+  static enum FaultType {
+    ALL,
+    DECOLLMENT,
+    FAULT,
+    INTERFACE,
+    ZONE;
+
+    @Override
+    public String toString() {
+      return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name());
     }
   }
 
   static class Metadata {
     final SourceModel model;
-    final Object trees;
+    final List<Parameter> faultType;
 
     Metadata(HazardModel model) {
       this.model = new SourceModel(model);
-      trees = Models.trees(model);
+      this.faultType = Arrays.stream(FaultType.values())
+          .map(faultType -> new Parameter(faultType.toString(), faultType.name()))
+          .collect(Collectors.toList());
     }
 
     public SourceModel getModel() {
       return model;
     }
 
-    public Object getTrees() {
-      return trees;
+    public List<Parameter> getSourceType() {
+      return faultType;
     }
   }
 }
-- 
GitLab