diff --git a/Dockerfile b/Dockerfile index c91cb67cd77299c22cac329cc25583697b50ceb1..bbdca32411825b8a009b6f10732527916e80d254 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,6 +33,7 @@ COPY gradlew . COPY nshmp-lib ../nshmp-lib COPY settings.gradle . COPY src src +COPY openapi.properties . RUN ./gradlew --no-daemon assemble \ && mv ${libs_dir}/*-all.jar ${jar_file} diff --git a/build.gradle b/build.gradle index 21bccd4e49d40b33e478fddeab2ec2555fc35ed2..f57cf204c1fdcfb6cf0314dfc6c900d7ca875499 100644 --- a/build.gradle +++ b/build.gradle @@ -49,8 +49,9 @@ dependencies { runtimeOnly "ch.qos.logback:logback-classic:${logbackVersion}" // Swagger - annotationProcessor("io.micronaut.configuration:micronaut-openapi:${swaggerVersion}") + annotationProcessor("io.micronaut.configuration:micronaut-openapi:${mnOpenAPIVersion}") implementation("io.swagger.core.v3:swagger-annotations:${swaggerVersion}") + implementation("io.swagger.core.v3:swagger-models:${swaggerVersion}") // junit testAnnotationProcessor "io.micronaut:micronaut-inject-java:${mnVersion}" @@ -62,6 +63,10 @@ dependencies { testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine" } +ext { + swaggerDir = "swagger-files" +} + test { useJUnitPlatform() } @@ -99,3 +104,18 @@ tasks.withType(com.github.spotbugs.SpotBugsTask) { html.enabled = true } } + +task swagger(type: JavaExec) { + doFirst { + mkdir swaggerDir + } + classpath sourceSets.main.runtimeClasspath + main = "gov.usgs.earthquake.nshmp.netcdf.swagger.UpdateSwagger" +} + +task swaggerClean(type: Delete) { + delete swaggerDir +} + +clean.dependsOn swaggerClean +assemble.dependsOn swagger diff --git a/gradle.properties b/gradle.properties index df92924b30e774ba1df0c38de7e474e9a66a5308..17f0e3514c60deaffdf5c3d95699838c9d2e5c59 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,4 +5,5 @@ logbackVersion = 1.2.3 mnVersion = 1.3.2 netcdfVersion = 5.1.0 slfVersion = 1.7.30 -swaggerVersion = 1.4.0 +swaggerVersion = 2.1.1 +mnOpenAPIVersion = 1.4.0 diff --git a/openapi.properties b/openapi.properties index 626d1e43053fde40c7f14ad0e275a477e385b86a..3f88279c7ecf8e0b404ca95acae374469195acec 100644 --- a/openapi.properties +++ b/openapi.properties @@ -1 +1 @@ -micronaut.openapi.target.file = build/resources/main/swagger/netcdf-swagger.yml +micronaut.openapi.target.file = build/classes/java/main/META-INF/swagger/nshmp-netcdf-openapi.yml diff --git a/src/main/java/gov/usgs/earthquake/nshmp/netcdf/NshmGroup.java b/src/main/java/gov/usgs/earthquake/nshmp/netcdf/NshmGroup.java index 0f6d079d6dc08fff83336b232b2ddc3ca3e13d31..e3adbaab9289e20290f5126e37341ddac750bf84 100644 --- a/src/main/java/gov/usgs/earthquake/nshmp/netcdf/NshmGroup.java +++ b/src/main/java/gov/usgs/earthquake/nshmp/netcdf/NshmGroup.java @@ -1,5 +1,7 @@ package gov.usgs.earthquake.nshmp.netcdf; +import com.google.common.base.CaseFormat; + public enum NshmGroup { CONUS_2018( @@ -22,6 +24,10 @@ public enum NshmGroup { return display; } + public String model() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name()); + } + /** * Returns the NetCDF target base group to read. */ diff --git a/src/main/java/gov/usgs/earthquake/nshmp/netcdf/swagger/UpdateSwagger.java b/src/main/java/gov/usgs/earthquake/nshmp/netcdf/swagger/UpdateSwagger.java new file mode 100644 index 0000000000000000000000000000000000000000..9f70441a2e2b89bab4c85ffe6a1dad919b0caec6 --- /dev/null +++ b/src/main/java/gov/usgs/earthquake/nshmp/netcdf/swagger/UpdateSwagger.java @@ -0,0 +1,152 @@ +package gov.usgs.earthquake.nshmp.netcdf.swagger; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; +import java.util.Properties; + +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; + +import gov.usgs.earthquake.nshmp.netcdf.NshmGroup; + +import io.swagger.v3.oas.models.PathItem; + +/** + * Create Swagger files for each model and update context path. + * + * @author U.S. Geological Survey + */ +class UpdateSwagger { + + private static final Path SWAGGER_DIR = Paths.get("swagger-files"); + private static final Path TARGET_FILE; + private static final String OPENAPI_TARGET = "micronaut.openapi.target.file"; + + static { + try (var file = new FileInputStream("openapi.properties")) { + var properties = new Properties(); + properties.load(file); + var openapi = properties.getProperty(OPENAPI_TARGET); + TARGET_FILE = Paths.get(openapi); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static void main(String[] args) { + run(); + } + + private static void run() { + for (var nshmGroup : NshmGroup.values()) { + updateSwaggerFile(TARGET_FILE, nshmGroup.model()); + } + } + + private static void updateSwaggerFile(Path yamlPath, String contextPath) { + var options = new DumperOptions(); + options.setPrettyFlow(true); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + + var yaml = new Yaml(options); + var out = SWAGGER_DIR.resolve("netcdf-swagger-" + contextPath + ".yml"); + + try { + var yamlFile = yaml.loadAs(new FileReader(yamlPath.toFile()), Swagger.class); + var paths = new io.swagger.v3.oas.models.Paths(); + + for (var entry : yamlFile.getPaths().entrySet()) { + paths.addPathItem("/" + contextPath + entry.getKey(), entry.getValue()); + } + + yamlFile.paths = paths; + yaml.dump(yamlFile, new FileWriter(out.toFile())); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException("Could not write to [" + out + "]"); + } + } + + public static class Swagger { + String openapi = "3.0.1"; + Object info; + Map<String, PathItem> paths; + Object externalDocs; + Object servers; + Object tags; + Object components; + Map<String, Object> extensions; + + public String getOpenapi() { + return openapi; + } + + public Object getInfo() { + return info; + } + + public Map<String, PathItem> getPaths() { + return paths; + } + + public Object getExternalDocs() { + return externalDocs; + } + + public Object getServers() { + return servers; + } + + public Object getTags() { + return tags; + } + + public Object getComponents() { + return components; + } + + public Map<String, Object> getExtension() { + return extensions; + } + + public void setOpenapi(String openapi) { + this.openapi = openapi; + } + + public void setInfo(Object info) { + this.info = info; + } + + public void setPaths(Map<String, PathItem> paths) { + this.paths = paths; + } + + public void setExternalDocs(Object externalDocs) { + this.externalDocs = externalDocs; + } + + public void setServers(Object servers) { + this.servers = servers; + } + + public void setTags(Object tags) { + this.tags = tags; + } + + public void setComponents(Object components) { + this.components = components; + } + + public void setExtension(Map<String, Object> extensions) { + this.extensions = extensions; + } + } + +} diff --git a/src/main/resources/swagger/index.js b/src/main/resources/swagger/index.js index 4d3c03f3b2a22b78111eba39ee2e986c678d48fa..88964dd75e471fb14cc8ca4024496461e0fd369c 100644 --- a/src/main/resources/swagger/index.js +++ b/src/main/resources/swagger/index.js @@ -30,7 +30,7 @@ window.onload = function() { }; }, ui = SwaggerUIBundle({ - url: contextPath + "/swagger/netcdf-services.yml", + url: contextPath + "/swagger/nshmp-netcdf-openapi.yml", dom_id: "#swagger-ui", tagsSorter: 'alpha', presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],