diff --git a/src/aashto/build.gradle b/src/aashto/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..747bdaf3abdb2fccdeb72b6c9154a6b395fdb254 --- /dev/null +++ b/src/aashto/build.gradle @@ -0,0 +1,4 @@ + +dependencies { + implementation project(":src:lib") +} diff --git a/src/aashto/openapi.properties b/src/aashto/openapi.properties new file mode 100644 index 0000000000000000000000000000000000000000..75e362540a617f22719aa540e333d8a469f33b0b --- /dev/null +++ b/src/aashto/openapi.properties @@ -0,0 +1 @@ +micronaut.openapi.target.file = build/classes/java/main/META-INF/swagger/nshmp-ws-static.yml diff --git a/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/NetcdfGroundMotions.java b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/NetcdfGroundMotions.java new file mode 100644 index 0000000000000000000000000000000000000000..3a9c943b3b74a5f31ff24cbf626dcb54537f0359 --- /dev/null +++ b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/NetcdfGroundMotions.java @@ -0,0 +1,62 @@ +package gov.usgs.earthquake.nshmp.netcdf; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.io.IOException; +import java.nio.file.Path; + +import gov.usgs.earthquake.nshmp.data.XySequence; +import gov.usgs.earthquake.nshmp.geo.Location; +import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass; +import gov.usgs.earthquake.nshmp.netcdf.data.BoundingData; +import gov.usgs.earthquake.nshmp.netcdf.data.NetcdfData; +import gov.usgs.earthquake.nshmp.netcdf.data.StaticData; +import gov.usgs.earthquake.nshmp.netcdf.reader.BoundingReaderGroundMotions; +import gov.usgs.earthquake.nshmp.netcdf.reader.ReaderGroundMotions; + +import ucar.nc2.dataset.NetcdfDatasets; + +/** + * NetCDF data for ground motions. + * + * @author U.S. Geological Survey + */ +public class NetcdfGroundMotions extends Netcdf<XySequence> { + + public NetcdfGroundMotions(Path netcdfPath) { + super(netcdfPath); + } + + @Override + public BoundingData<XySequence> boundingData(Location site) { + return new BoundingReaderGroundMotions(this, site).boundingData(); + } + + @Override + public NetcdfData netcdfData() { + return netcdfData; + } + + @Override + public StaticData<XySequence> staticData(Location site) { + return boundingData(site).get(site); + } + + @Override + public XySequence staticData(Location site, NehrpSiteClass siteClass) { + checkArgument( + netcdfData.siteClasses().contains(siteClass), + "Site class [" + siteClass + "] not supported"); + return staticData(site).get(siteClass); + } + + @Override + ReaderGroundMotions getNetcdfData(Path netcdfPath) { + try (var ncd = NetcdfDatasets.openDataset(netcdfPath.toString())) { + var group = ncd.getRootGroup(); + return new ReaderGroundMotions(group); + } catch (IOException e) { + throw new RuntimeException("Could not read Netcdf file [" + netcdfPath + " ]"); + } + } +} diff --git a/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/BoundingReaderGroundMotions.java b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/BoundingReaderGroundMotions.java new file mode 100644 index 0000000000000000000000000000000000000000..1923bfd08d08719360b9832e3a879fbdb5bc35fa --- /dev/null +++ b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/BoundingReaderGroundMotions.java @@ -0,0 +1,194 @@ +package gov.usgs.earthquake.nshmp.netcdf.reader; + +import java.io.IOException; +import java.util.List; + +import gov.usgs.earthquake.nshmp.data.XySequence; +import gov.usgs.earthquake.nshmp.geo.Location; +import gov.usgs.earthquake.nshmp.gmm.Imt; +import gov.usgs.earthquake.nshmp.netcdf.Netcdf; +import gov.usgs.earthquake.nshmp.netcdf.NetcdfGroundMotions; +import gov.usgs.earthquake.nshmp.netcdf.data.BoundingData; +import gov.usgs.earthquake.nshmp.netcdf.data.NetcdfShape.IndexKey; +import gov.usgs.earthquake.nshmp.netcdf.data.StaticData; +import gov.usgs.earthquake.nshmp.netcdf.reader.NetcdfUtils.Key; + +import ucar.ma2.Array; +import ucar.ma2.DataType; +import ucar.ma2.InvalidRangeException; +import ucar.nc2.dataset.NetcdfDatasets; + +/** + * Creates the bounding locations and data associated with a specific site for + * ground motions. + * + * @author U.S. Geological Survey + */ +public class BoundingReaderGroundMotions extends BoundingReader<XySequence> { + + public static final double PGA_VALUE = 0.001; + public static final double PGV_VALUE = 0.0001; + + public BoundingReaderGroundMotions(NetcdfGroundMotions netcdf, Location site) { + super(netcdf, site); + } + + @Override + StaticData<XySequence> calculateTargetData( + List<BoundingLocation> boundingLocations, + BoundingData<XySequence> boundingData, + double fracLon, + double fracLat) { + var westTarget = getTargetData( + boundingData.get(boundingLocations.get(0).location), + boundingData.get(boundingLocations.get(1).location), + fracLat); + + var eastTarget = getTargetData( + boundingData.get(boundingLocations.get(3).location), + boundingData.get(boundingLocations.get(2).location), + fracLat); + + return getTargetData(westTarget, eastTarget, fracLon); + } + + @Override + BoundingData<XySequence> extractDataAt( + Netcdf<XySequence> netcdf, + List<BoundingLocation> boundingLocations, + int idxLonLL, + int idxLatLL) { + try (var ncd = NetcdfDatasets.openDataset(netcdf.netcdfPath().toString())) { + var netcdfData = netcdf.netcdfData(); + var boundingData = BoundingData.<XySequence> builder(); + var targetGroup = ncd.getRootGroup(); + var netcdfShape = netcdf.netcdfShape(); + + // Build origin array, e.g. [lon, lat, 0, 0] + var targetOrigin = netcdfShape.buildShape() + .add(IndexKey.LATITUDE, idxLatLL) + .add(IndexKey.LONGITUDE, idxLonLL) + .build(); + + // Build target shape array, e.g. [2, 2, nImt, nSiteClass] + var targetShape = netcdfShape.buildShape() + .add(IndexKey.SITE_CLASS, netcdfData.siteClasses().size()) + .add(IndexKey.LATITUDE, 2) + .add(IndexKey.LONGITUDE, 2) + .add(IndexKey.IMT, netcdfData.imts().size()) + .build(); + + var groundMotionArray = targetGroup + .findVariableLocal(Key.GROUND_MOTION) + .read(targetOrigin, targetShape); + + // Main data shape, e.g. [1, 1, nImt, nSiteClass] + var shape = netcdfShape.buildShape() + .add(IndexKey.SITE_CLASS, netcdfData.siteClasses().size()) + .add(IndexKey.LATITUDE, 1) + .add(IndexKey.LONGITUDE, 1) + .add(IndexKey.IMT, netcdfData.imts().size()) + .build(); + + for (var boundingLocation : boundingLocations) { + boundingData.put( + boundingLocation.location, + mapDataFromArray(netcdf, groundMotionArray.section(boundingLocation.origin, shape))); + } + + return boundingData.build(); + } catch (IOException | InvalidRangeException e) { + throw new RuntimeException( + "Could not read Netcdf file [" + netcdf.netcdfPath() + "]. " + e.getMessage()); + } + } + + @Override + StaticData<XySequence> getTargetData( + StaticData<XySequence> d1, + StaticData<XySequence> d2, + double frac) { + NetcdfUtils.checkBoundingGroundMotion(d1, d2); + return frac == 0.0 ? d1 + : frac == 1.0 ? d2 : NetcdfUtils.linearInterpolateGroundMotions(d1, d2, frac); + } + + @Override + StaticData<XySequence> mapDataFromArray( + Netcdf<XySequence> netcdf, + Array array) { + var netcdfData = netcdf.netcdfData(); + var staticData = StaticData.<XySequence> builder(); + + for (int iSiteClass = 0; iSiteClass < netcdfData.siteClasses().size(); iSiteClass++) { + var siteClass = netcdfData.siteClasses().get(iSiteClass); + + var imts = netcdfData.imts(); + var periods = imts.stream() + .mapToDouble(imt -> { + if (imt == Imt.PGA) { + return PGA_VALUE; + } else if (imt == Imt.PGV) { + return PGV_VALUE; + } + return imt.period(); + }) + .toArray(); + + // Build origin array, e.g [0, siteClass] + var origin = netcdf.netcdfShape().buildShape() + .add(IndexKey.IMT, 0) + .add(IndexKey.SITE_CLASS, iSiteClass) + .reduce() + .build(); + + // Build shape array, e.g. [nImts, 1] + var shape = netcdf.netcdfShape().buildShape() + .add(IndexKey.IMT, imts.size()) + .add(IndexKey.SITE_CLASS, 1) + .reduce() + .build(); + + try { + var xySequence = XySequence.create( + periods, + (double[]) array.section(origin, shape).reduce().get1DJavaArray(DataType.DOUBLE)); + + staticData.put(siteClass, xySequence); + } catch (InvalidRangeException e) { + throw new RuntimeException(e.getMessage()); + } + } + + return staticData.build(); + } + + @Override + BoundingData<XySequence> setBoundingData( + Netcdf<XySequence> netcdf, + Location site, + List<BoundingLocation> boundingLocations) { + var netcdfGroundMotions = (NetcdfGroundMotions) netcdf; + var netcdfData = netcdfGroundMotions.netcdfData(); + var longitudes = netcdfData.longitudes(); + var latitudes = netcdfData.latitudes(); + var idxLonLL = NetcdfUtils.getIdxLTEQ(longitudes, site.longitude); + var idxLatLL = NetcdfUtils.getIdxLTEQ(latitudes, site.latitude); + + var groundMotions = + extractDataAt(netcdfGroundMotions, boundingLocations, idxLonLL, idxLatLL); + var fracLon = NetcdfUtils.calcGridFrac(longitudes, idxLonLL, site.longitude); + var fracLat = NetcdfUtils.calcGridFrac(latitudes, idxLatLL, site.latitude); + + var builder = BoundingData.<XySequence> builder(); + groundMotions.forEach((key, value) -> builder.put(key, value)); + builder.put( + site, + calculateTargetData(boundingLocations, groundMotions, fracLon, fracLat)) + .build(); + var boundingData = builder.build(); + + NetcdfUtils.checkBoundingGroundMotions(boundingData, boundingLocations.get(0).location); + return boundingData; + } +} diff --git a/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/ReaderGroundMotions.java b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/ReaderGroundMotions.java new file mode 100644 index 0000000000000000000000000000000000000000..f45da139d717469be4fc52160892913a4d392736 --- /dev/null +++ b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/ReaderGroundMotions.java @@ -0,0 +1,32 @@ +package gov.usgs.earthquake.nshmp.netcdf.reader; + +import java.io.IOException; + +import gov.usgs.earthquake.nshmp.netcdf.data.NetcdfShape; +import gov.usgs.earthquake.nshmp.netcdf.data.NetcdfShape.IndexKey; +import gov.usgs.earthquake.nshmp.netcdf.reader.NetcdfUtils.Key; + +import ucar.nc2.Group; + +/** + * Read in ground motions NetCDF files + * + * @author U.S. Geological Survey + */ +public class ReaderGroundMotions extends Reader { + + public ReaderGroundMotions(Group targetGroup) throws IOException { + super(targetGroup); + } + + @Override + NetcdfShape buildNetcdfShape(Group group) { + var vData = group.findVariableLocal(Key.GROUND_MOTION); + return NetcdfShape.builder() + .add(IndexKey.IMT, vData.findDimensionIndex(Key.IMT)) + .add(IndexKey.LATITUDE, vData.findDimensionIndex(Key.LAT)) + .add(IndexKey.LONGITUDE, vData.findDimensionIndex(Key.LON)) + .add(IndexKey.SITE_CLASS, vData.findDimensionIndex(Key.SITE_CLASS)) + .build(); + } +} diff --git a/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/Application.java b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/Application.java new file mode 100644 index 0000000000000000000000000000000000000000..85cdcf7d29737c2ec14c04923e168bad6666c0ab --- /dev/null +++ b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/Application.java @@ -0,0 +1,21 @@ +package gov.usgs.earthquake.nshmp.netcdf.www; + +import io.micronaut.runtime.Micronaut; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; + +@OpenAPIDefinition( + info = @Info( + title = "AASHTO Ground Motion Data", + description = "### Get static curves\n" + + "See the service usage for supported longitudes, " + + "latitudes, and site classes")) +public class Application { + + public static void main(String[] args) { + Micronaut.build(args) + .mainClass(Application.class) + .start(); + } + +} diff --git a/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfController.java b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfController.java new file mode 100644 index 0000000000000000000000000000000000000000..0d3fa24ef6e36f13ecbead81df6d139406fd0d4b --- /dev/null +++ b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfController.java @@ -0,0 +1,135 @@ +package gov.usgs.earthquake.nshmp.netcdf.www; + +import java.nio.file.Path; + +import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass; +import gov.usgs.earthquake.nshmp.netcdf.NetcdfGroundMotions; +import gov.usgs.earthquake.nshmp.www.NshmpMicronautServlet; + +import io.micronaut.context.annotation.Value; +import io.micronaut.context.event.StartupEvent; +import io.micronaut.core.annotation.Nullable; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.HttpResponse; +import io.micronaut.http.MediaType; +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.micronaut.runtime.event.annotation.EventListener; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.inject.Inject; + +/** + * Micronaut controller for getting static hazards or ground motions from a + * NetCDF file. + * + * @see NetcdfService + * + * @author U.S. Geological Survey + */ +@Tag(name = "Static Ground Motion Data") +@Controller("/ground-motions") +public class NetcdfController { + + @Inject + private NshmpMicronautServlet servlet; + + @Value("${nshmp-ws-static.netcdf-file}") + Path netcdfPath; + + NetcdfServiceGroundMotions service; + + /** + * Read in data type and return the appropriate service to use. + */ + @EventListener + void startup(StartupEvent event) { + var netcdfHazard = new NetcdfGroundMotions(netcdfPath); + service = new NetcdfServiceGroundMotions(netcdfHazard); + } + + /** + * GET method to return a static curve using URL query. + * + * @param request The HTTP request + * @param longitude The longitude of the site + * @param latitude Latitude of the site + * @param siteClass The site class (optional) + */ + @Operation( + summary = "Returns curve(s) given a longitude, latitude, and/or a site class", + description = "Retrieve static curve(s) from a NSHM NetCDF file.\n\n" + + "For supported longitudes, latitudes, and site classes see the usage information.", + operationId = "netcdf_data_doGetHazard") + @ApiResponse( + description = "Returns a static curve from the NetCDF file", + responseCode = "200", + content = @Content( + schema = @Schema(type = "string"))) + @Get(uri = "{?longitude,latitude,siteClass}", produces = MediaType.APPLICATION_JSON) + public HttpResponse<String> doGet( + HttpRequest<?> request, + @Schema(required = true) @QueryValue @Nullable Double longitude, + @Schema(required = true) @QueryValue @Nullable Double latitude, + @QueryValue @Nullable NehrpSiteClass siteClass) { + var query = new Query(longitude, latitude, siteClass); + return service.handleServiceCall(request, query); + } + + /** + * GET method to return static curves using slash delimited. + * + * @param request The HTTP request + * @param longitude The longitude of the site + * @param latitude Latitude of the site + * @param siteClass The site class + */ + @Operation( + summary = "Returns static curves given a longitude, latitude, and site class.", + description = "Retrieve static curves from a NetCDF file.\n\n" + + "For supported longitudes, latitudes, and site classes see the usage information.", + operationId = "netcdf_data_doGetHazardSlashWithSiteClass") + @ApiResponse( + description = "Returns static curves from the NetCDF file", + responseCode = "200", + content = @Content( + schema = @Schema(type = "string"))) + @Get(uri = "/{longitude}/{latitude}/{siteClass}", produces = MediaType.APPLICATION_JSON) + public HttpResponse<String> doGetSlashBySite( + HttpRequest<?> request, + @Schema(required = true) @PathVariable @Nullable Double longitude, + @Schema(required = true) @PathVariable @Nullable Double latitude, + @Schema(required = true) @PathVariable @Nullable NehrpSiteClass siteClass) { + return doGet(request, longitude, latitude, siteClass); + } + + /** + * GET method to return hazard curves using slash delimited. + * + * @param request The HTTP request + * @param longitude The longitude of the site + * @param latitude Latitude of the site + */ + @Operation( + summary = "Returns static curves given a longitude and latitude.", + description = "Retrieve static curves from a NetCDF file.\n\n" + + "For supported longitudes and latitudes see the usage information.", + operationId = "netcdf_data_doGetHazardSlash") + @ApiResponse( + description = "Returns static curves from the NSHM NetCDF file", + responseCode = "200", + content = @Content( + schema = @Schema(type = "string"))) + @Get(uri = "/{longitude}/{latitude}", produces = MediaType.APPLICATION_JSON) + public HttpResponse<String> doGetSlash( + HttpRequest<?> request, + @Schema(required = true) @PathVariable @Nullable Double longitude, + @Schema(required = true) @PathVariable @Nullable Double latitude) { + return doGet(request, longitude, latitude, null); + } +} diff --git a/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfServiceGroundMotions.java b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfServiceGroundMotions.java new file mode 100644 index 0000000000000000000000000000000000000000..1e045cc5d527ba560e5724619f076bcfec3d382d --- /dev/null +++ b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfServiceGroundMotions.java @@ -0,0 +1,135 @@ +package gov.usgs.earthquake.nshmp.netcdf.www; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import gov.usgs.earthquake.nshmp.data.XySequence; +import gov.usgs.earthquake.nshmp.geo.Location; +import gov.usgs.earthquake.nshmp.gmm.Imt; +import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass; +import gov.usgs.earthquake.nshmp.netcdf.NetcdfGroundMotions; +import gov.usgs.earthquake.nshmp.netcdf.data.StaticData; +import gov.usgs.earthquake.nshmp.netcdf.reader.BoundingReaderGroundMotions; +import gov.usgs.earthquake.nshmp.netcdf.www.NetcdfWsUtils.Key; +import gov.usgs.earthquake.nshmp.netcdf.www.Query.Service; +import gov.usgs.earthquake.nshmp.www.Response; +import gov.usgs.earthquake.nshmp.www.WsUtils; +import gov.usgs.earthquake.nshmp.www.meta.Status; + +import io.micronaut.http.HttpRequest; + +/** + * Handles service calls for ground motions. + * + * @see NetcdfController + * + * @author U.S. Geological Survey + */ +public class NetcdfServiceGroundMotions extends NetcdfService { + + static final String SERVICE_DESCRIPTION = "Get static ground motions from a NetCDF file"; + static final String SERVICE_NAME = "Static Ground Motions"; + static final String X_LABEL = "Period (s)"; + static final String Y_LABEL = "Median Ground Motion (g)"; + + public NetcdfServiceGroundMotions(NetcdfGroundMotions netcdf) { + super(netcdf); + } + + @Override + Response<String, Metadata> getMetadataResponse(HttpRequest<?> request) { + var metadata = new Metadata(request, SERVICE_DESCRIPTION); + var url = request.getUri().toString(); + return new Response<>(Status.USAGE, SERVICE_NAME, url, metadata, url); + } + + @Override + String getServiceName() { + return SERVICE_NAME; + } + + @Override + NetcdfGroundMotions netcdf() { + return (NetcdfGroundMotions) netcdf; + } + + @Override + Response<?, ?> processRequest(HttpRequest<?> httpRequest, Query query, Service service) { + var site = Location.create(query.longitude, query.latitude); + var requestData = new RequestData(site); + var url = httpRequest.getUri().toString(); + + switch (service) { + case CURVES: + return processCurves(requestData, url); + case CURVES_BY_SITE_CLASS: + requestData = new RequestDataSiteClass(site, query.siteClass); + return processCurvesSiteClass( + (RequestDataSiteClass) requestData, url); + default: + throw new RuntimeException("Netcdf service [" + service + "] not found"); + } + } + + @Override + Response<RequestDataSiteClass, ResponseData<ResponseMetadata>> processCurvesSiteClass( + RequestDataSiteClass request, + String url) { + WsUtils.checkValue(Key.LATITUDE, request.site.latitude); + WsUtils.checkValue(Key.LONGITUDE, request.site.longitude); + WsUtils.checkValue(Key.SITE_CLASS, request.siteClass); + var curves = netcdf().staticData(request.site, request.siteClass); + var responseData = toResponseData(request, curves); + return new Response<>(Status.SUCCESS, SERVICE_NAME, request, responseData, url); + } + + @Override + Response<RequestData, List<ResponseData<ResponseMetadata>>> processCurves(RequestData request, + String url) { + WsUtils.checkValue(Key.LATITUDE, request.site.latitude); + WsUtils.checkValue(Key.LONGITUDE, request.site.longitude); + var curves = netcdf().staticData(request.site); + var responseData = toList(request.site, curves); + return new Response<>(Status.SUCCESS, SERVICE_NAME, request, responseData, url); + } + + List<ResponseData<ResponseMetadata>> toList( + Location site, + StaticData<XySequence> curves) { + return curves.entrySet().stream() + .map(entry -> { + var request = new RequestDataSiteClass(site, entry.getKey()); + return toResponseData(request, entry.getValue()); + }) + .collect(Collectors.toList()); + } + + ResponseData<ResponseMetadata> toResponseData( + RequestDataSiteClass request, + XySequence curves) { + var metadata = new ResponseMetadataGroundMotions( + X_LABEL, + Y_LABEL, + request.site, + request.siteClass); + return new ResponseData<>(metadata, curves); + } + + static class ResponseMetadataGroundMotions extends ResponseMetadata { + Map<String, Double> imtValues; + + ResponseMetadataGroundMotions( + String xLabel, + String yLabel, + Location site, + NehrpSiteClass siteClass) { + super(xLabel, yLabel, site, siteClass); + imtValues = Map.of( + Imt.PGA.name(), + BoundingReaderGroundMotions.PGA_VALUE, + Imt.PGV.name(), + BoundingReaderGroundMotions.PGV_VALUE); + } + } +} diff --git a/src/aashto/src/main/resources/aashto-example.nc b/src/aashto/src/main/resources/aashto-example.nc new file mode 100644 index 0000000000000000000000000000000000000000..0b4e8d883e15107bd60ed7fc8bde3a9da0066427 Binary files /dev/null and b/src/aashto/src/main/resources/aashto-example.nc differ diff --git a/src/aashto/src/main/resources/application.yml b/src/aashto/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..a6bdb5f70547e8371b49cd2d8e491ed617f5f259 --- /dev/null +++ b/src/aashto/src/main/resources/application.yml @@ -0,0 +1,14 @@ +micronaut: + io: + watch: + paths: src + restart: true + router: + static-resources: + swagger: + enabled: true + paths: classpath:swagger + mapping: /** + +nshmp-ws-static: + netcdf-file: ${netcdf:src/main/resources/aashto-example.nc} diff --git a/src/aashto/src/main/resources/logback.xml b/src/aashto/src/main/resources/logback.xml new file mode 100644 index 0000000000000000000000000000000000000000..f74e41693090ae1b24cabe0642f4ec814564c4a1 --- /dev/null +++ b/src/aashto/src/main/resources/logback.xml @@ -0,0 +1,17 @@ +<configuration> + + <appender name="STDOUT" + class="ch.qos.logback.core.ConsoleAppender"> + <withJansi>true</withJansi> + <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder + by default --> + <encoder> + <pattern>%cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) + %highlight(%-5level) %magenta(%logger{36}) - %msg%n</pattern> + </encoder> + </appender> + + <root level="info"> + <appender-ref ref="STDOUT" /> + </root> +</configuration>