diff --git a/CHANGELOG.md b/CHANGELOG.md index bdb69ea6..14c7d873 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added +- Add `hazardDatasets` field to TornadoDataset, TornadoModel and EarthquakeModel class [#213](https://github.com/IN-CORE/incore-services/issues/213) + ### Changed - Use Java models to represent semantics [#239](https://github.com/IN-CORE/incore-services/issues/239) - Sort Semantic Definition Alphabetically [#238](https://github.com/IN-CORE/incore-services/issues/238) diff --git a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/Engine.java b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/Engine.java index 969cb5d6..22d8f90f 100644 --- a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/Engine.java +++ b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/Engine.java @@ -118,14 +118,14 @@ private void storeEarthquakeResults(Job job) { String earthquakeId = job.getObjectId(); EarthquakeModel earthquake = (EarthquakeModel) repository.getEarthquakeById(earthquakeId); - String demandType = earthquake.getRasterDataset().getDemandType(); + String demandType = earthquake.getHazardDatasets().get(0).getDemandType(); String username = earthquake.getCreator(); String description = "Earthquake visualization"; String userGroups = "{\"groups\": [\"incore_user\"]}"; try { String datasetId = ServiceUtil.createRasterDataset(hazardFile, demandType + " hazard", username, userGroups, description, HazardConstants.DETERMINISTIC_EARTHQUAKE_HAZARD_SCHEMA); - earthquake.getRasterDataset().setDatasetId(datasetId); + earthquake.getHazardDatasets().get(0).setDatasetId(datasetId); repository.addEarthquake(earthquake); log.debug("eq id is = " + earthquakeId); diff --git a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/controllers/EarthquakeController.java b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/controllers/EarthquakeController.java index 295f1e10..18f5e9af 100644 --- a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/controllers/EarthquakeController.java +++ b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/controllers/EarthquakeController.java @@ -12,8 +12,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import dev.morphia.annotations.Property; -import dev.morphia.annotations.experimental.Name; import edu.illinois.ncsa.incore.common.AllocationConstants; import edu.illinois.ncsa.incore.common.HazardConstants; import edu.illinois.ncsa.incore.common.auth.Authorizer; @@ -222,7 +220,7 @@ public Earthquake createEarthquake( rasterDataset.setDemandUnits(scenarioEarthquake.getVisualizationParameters().getDemandUnits()); rasterDataset.setPeriod(Double.parseDouble(demandComponents[0])); - scenarioEarthquake.setHazardDataset(rasterDataset); + scenarioEarthquake.addEarthquakeHazardDataset(rasterDataset); // add creator using username info earthquake.setCreator(this.username); earthquake.setOwner(this.username); @@ -1080,8 +1078,10 @@ public Earthquake deleteEarthquake(@Parameter(name = "Earthquake Id", required = // delete associated datasets if (eq != null && eq instanceof EarthquakeModel) { EarthquakeModel scenarioEarthquake = (EarthquakeModel) eq; - if (ServiceUtil.deleteDataset(scenarioEarthquake.getRasterDataset().getDatasetId(), this.username, this.userGroups) == null) { - spaceRepository.addToOrphansSpace(scenarioEarthquake.getRasterDataset().getDatasetId()); + for (HazardDataset dataset : scenarioEarthquake.getHazardDatasets()) { + if (ServiceUtil.deleteDataset(dataset.getDatasetId(), this.username, this.userGroups) == null) { + spaceRepository.addToOrphansSpace(dataset.getDatasetId()); + } } } else if (eq != null && eq instanceof EarthquakeDataset) { EarthquakeDataset eqDataset = (EarthquakeDataset) eq; diff --git a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/controllers/TornadoController.java b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/controllers/TornadoController.java index a87c397d..7cbb7714 100644 --- a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/controllers/TornadoController.java +++ b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/controllers/TornadoController.java @@ -182,7 +182,6 @@ public List getTornadoDemands() { @Operation(summary = "Creates a new tornado, the newly created tornado is returned.", description = "Additionally, a GeoTiff (raster) is created by default and publish to data repository. " + "User can create both model tornadoes and dataset-based tornadoes with GeoTiff files uploaded.") - @RequestBody(description = "Tornado json and files.", required = true, content = @Content(mediaType = MediaType.APPLICATION_FORM_URLENCODED, schema = @Schema(type = "object", @@ -263,7 +262,14 @@ public Tornado createTornado( // Store the dataset datasetId = ServiceUtil.createDataset(datasetObject, this.username, this.userGroups, files); - tornadoModel.setDatasetId(datasetId); + // Assuming only one hazardDataset will be created here. + // construct tornado hazardDatasets + TornadoHazardDataset hazardDataset = new TornadoHazardDataset(); + hazardDataset.setDatasetId(datasetId); + hazardDataset.setDemandType(TornadoHazard.DEMAND_TYPE); + hazardDataset.setDemandUnits(TornadoHazard.WIND_MPH); + hazardDataset.setThreshold(null); + tornadoModel.addTornadoHazardDataset(hazardDataset); tornado.setCreator(this.username); tornado.setOwner(this.username); @@ -271,12 +277,13 @@ public Tornado createTornado( addTornadoToSpace(tornado, this.username); } else if (tornado != null && tornado instanceof TornadoDataset) { TornadoDataset tornadoDataset = (TornadoDataset) tornado; - datasetId = null; + if (fileParts != null && !fileParts.isEmpty() && TornadoUtils.validateDatasetTypes(fileParts)) { // Create dataset object representation for storing shapefile JSONObject datasetObject = TornadoUtils.getTornadoDatasetObject("Tornado Hazard", "EF Boxes representing tornado"); // Store the dataset datasetId = ServiceUtil.createDataset(datasetObject, this.username, this.userGroups); + if (datasetId != null) { // attach files to the dataset int statusCode = ServiceUtil.attachFileToTornadoDataset(datasetId, this.username, this.userGroups, fileParts); @@ -285,11 +292,18 @@ public Tornado createTornado( logger.error(tornadoErrorMsg); throw new IncoreHTTPException(Response.Status.BAD_REQUEST, tornadoErrorMsg); } + + // construct tornado hazardDatasets + TornadoHazardDataset hazardDataset = new TornadoHazardDataset(); + hazardDataset.setDatasetId(datasetId); + hazardDataset.setDemandType(TornadoHazard.DEMAND_TYPE); + hazardDataset.setDemandUnits(TornadoHazard.WIND_MPH); + hazardDataset.setThreshold(null); + tornadoDataset.addTornadoHazardDataset(hazardDataset); } else { logger.error(tornadoJsonErrorMsg); throw new IncoreHTTPException(Response.Status.BAD_REQUEST, tornadoJsonErrorMsg); } - ((TornadoDataset) tornado).setDatasetId(datasetId); tornado.setCreator(this.username); tornado.setOwner(this.username); @@ -314,7 +328,6 @@ public Tornado createTornado( } ServiceUtil.deleteDataset(datasetId, this.username, this.userGroups); throw new IncoreHTTPException(Response.Status.BAD_REQUEST, tornadoErrorMsg); - } @GET @@ -531,14 +544,17 @@ public Tornado deleteTornado(@Parameter(name = "Tornado Id", required = true) @P // delete associated datasets if (tornado != null && tornado instanceof TornadoModel) { TornadoModel tModel = (TornadoModel) tornado; - if (ServiceUtil.deleteDataset(tModel.getDatasetId(), this.username, this.userGroups) == null) { - spaceRepository.addToOrphansSpace(tModel.getDatasetId()); + for (TornadoHazardDataset dataset: tModel.getHazardDatasets()) { + if (ServiceUtil.deleteDataset(dataset.getDatasetId(), this.username, this.userGroups) == null) { + spaceRepository.addToOrphansSpace(dataset.getDatasetId()); + } } } else if (tornado != null && tornado instanceof TornadoDataset) { TornadoDataset tDataset = (TornadoDataset) tornado; - ServiceUtil.deleteDataset(tDataset.getDatasetId(), this.username, this.userGroups); - if (ServiceUtil.deleteDataset(tDataset.getDatasetId(), this.username, this.userGroups) == null) { - spaceRepository.addToOrphansSpace(tDataset.getDatasetId()); + for (TornadoHazardDataset dataset: tDataset.getHazardDatasets()) { + if (ServiceUtil.deleteDataset(dataset.getDatasetId(), this.username, this.userGroups) == null) { + spaceRepository.addToOrphansSpace(dataset.getDatasetId()); + } } } diff --git a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/eq/EarthquakeModel.java b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/eq/EarthquakeModel.java index 7debaa17..4f34ce2f 100644 --- a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/eq/EarthquakeModel.java +++ b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/eq/EarthquakeModel.java @@ -8,6 +8,8 @@ import dev.morphia.annotations.Entity; +import java.util.LinkedList; +import java.util.List; import java.util.Map; @Entity("EarthquakeModel") @@ -23,21 +25,23 @@ public class EarthquakeModel extends Earthquake { private final String siteAmplification; // Visualization raster - private HazardDataset rasterDataset; + private List hazardDatasets = new LinkedList(); public EarthquakeModel() { defaultSiteClass = NEHRPSoilType.D; siteAmplification = "NEHRP"; } - public void setHazardDataset(HazardDataset rasterDataset) { - this.rasterDataset = rasterDataset; + public void setHazardDataset(List hazardDatasets) { + this.hazardDatasets = hazardDatasets; } - public HazardDataset getRasterDataset() { - return this.rasterDataset; + public List getHazardDatasets() { + return this.hazardDatasets; } + public void addEarthquakeHazardDataset(HazardDataset hazardDataset) { this.hazardDatasets.add(hazardDataset); } + public Map getAttenuations() { return this.attenuations; } diff --git a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/TornadoDataset.java b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/TornadoDataset.java index 8aa8e2a8..8ed2d570 100644 --- a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/TornadoDataset.java +++ b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/TornadoDataset.java @@ -7,19 +7,29 @@ package edu.illinois.ncsa.incore.service.hazard.models.tornado; import dev.morphia.annotations.Entity; +import java.util.LinkedList; +import java.util.List; @Entity("TornadoDataset") public class TornadoDataset extends Tornado { // CMN: this could be moved to the parent if we determine there will be no difference between probabilistic and // deterministic tornadoes. If there would be multiple files with different probabilities, this should be // modified similar to the Earthquake HazardDataset and the Tsunami hazard dataset - private String datasetId; - public String getDatasetId() { - return datasetId; + private List hazardDatasets; + + public TornadoDataset(){ + this.hazardDatasets = new LinkedList<>(); + } + + public List getHazardDatasets() { + return hazardDatasets; } - public void setDatasetId(String datasetId) { - this.datasetId = datasetId; + public void setHazardDatasets(List hazardDatasets) { + this.hazardDatasets = hazardDatasets; } + + public void addTornadoHazardDataset(TornadoHazardDataset hazardDataset) { this.hazardDatasets.add(hazardDataset); } + } diff --git a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/TornadoHazardDataset.java b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/TornadoHazardDataset.java new file mode 100644 index 00000000..0a51ccbc --- /dev/null +++ b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/TornadoHazardDataset.java @@ -0,0 +1,50 @@ +package edu.illinois.ncsa.incore.service.hazard.models.tornado; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import dev.morphia.annotations.Embedded; + +@Embedded +public class TornadoHazardDataset { + private String datasetId; + private String demandType; + private String demandUnits; + private Double threshold = null; + + public String getDatasetId() { + return datasetId; + } + + public String getDemandType() { + return demandType; + } + + public String getDemandUnits() { + return demandUnits; + } + + public Double getThreshold() { + return threshold; + } + + public void setDatasetId(String datasetId) { + this.datasetId = datasetId; + } + + public void setDemandType(String demandType) { + this.demandType = demandType; + } + + public void setDemandUnits(String demandUnits) { + this.demandUnits = demandUnits; + } + + public void setThreshold(Double threshold) { + this.threshold = threshold; + } + + @JsonIgnore + public String getThresholdJsonString(){ + return String.format("{'%s': {'value': %s, 'unit': '%s'}}", + this.demandType, this.threshold, this.demandUnits); + } +} diff --git a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/TornadoModel.java b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/TornadoModel.java index 6e3de014..6d9983a1 100644 --- a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/TornadoModel.java +++ b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/TornadoModel.java @@ -12,6 +12,7 @@ import dev.morphia.annotations.Entity; import edu.illinois.ncsa.incore.service.hazard.models.tornado.types.EFBox; +import java.util.LinkedList; import java.util.List; @Entity("TornadoModel") @@ -21,7 +22,22 @@ public class TornadoModel extends Tornado { private TornadoParameters tornadoParameters; private List tornadoWidth; private List efBoxes; - private String datasetId; + + private List hazardDatasets; + + public TornadoModel(){ + this.hazardDatasets = new LinkedList<>(); + } + + public List getHazardDatasets() { + return hazardDatasets; + } + + public void setHazardDatasets(List hazardDatasets) { + this.hazardDatasets = hazardDatasets; + } + + public void addTornadoHazardDataset(TornadoHazardDataset hazardDataset) { this.hazardDatasets.add(hazardDataset); } public List getTornadoWidth() { return tornadoWidth; @@ -56,11 +72,4 @@ public void setTornadoModel(String tornadoModel) { this.tornadoModel = tornadoModel; } - public String getDatasetId() { - return datasetId; - } - - public void setDatasetId(String datasetId) { - this.datasetId = datasetId; - } } diff --git a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/utils/TornadoCalc.java b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/utils/TornadoCalc.java index 0651c590..38144076 100644 --- a/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/utils/TornadoCalc.java +++ b/server/hazard-service/src/main/java/edu/illinois/ncsa/incore/service/hazard/models/tornado/utils/TornadoCalc.java @@ -63,7 +63,7 @@ public static WindHazardResult getWindHazardAtSite(Tornado tornado, Point localS scenarioTornado.getTornadoParameters(), seed); } else { TornadoDataset tornadoDataset = (TornadoDataset) tornado; - Object obj = GISUtil.getFeatureCollection(tornadoDataset.getDatasetId(), username, userGroups); + Object obj = GISUtil.getFeatureCollection(tornadoDataset.getHazardDatasets().get(0).getDatasetId(), username, userGroups); if (obj == null) { throw new IOException(" Could not calculate the grid coverage for the raster. Possibly because the dataset files are " + "unreadable or not found.");