Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 57 additions & 3 deletions cwms-data-api/src/main/java/cwms/cda/data/dao/JsonRatingUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import hec.data.RatingException;
import hec.data.cwmsRating.RatingSet;
Expand Down Expand Up @@ -54,15 +56,67 @@ public static String jsonToXml(String json) throws IOException, TransformerExcep
ObjectMapper om = new ObjectMapper();

JsonNode jsonNode = om.readTree(json);

ObjectWriter writer;
XmlMapper mapper = new XmlMapper();
ObjectWriter writer = mapper.writer()
.withRootName("ratings");
JsonNode ratings = jsonNode.findPath("ratings");
writer = mapper.writer()
.withRootName("ratings");
if (!ratings.isEmpty()) {
jsonNode = transformJsonStructure(ratings);
}
String xml = writer.writeValueAsString(jsonNode);

return cleanupXml(xml);
}

private static JsonNode transformJsonStructure(JsonNode ratingInput) {
String ratingSpecs = "rating-specs";
String simpleRating = "simple-rating";
String ratingTemplates = "rating-templates";
String ratings = "ratings";
String name = "name";
String parametersString = "parameters-string";
ObjectMapper mapper = new ObjectMapper();
ObjectNode transformed = mapper.createObjectNode();

if (ratingInput.has(ratingSpecs)) {
JsonNode ratingSpec = ratingInput.get(ratingSpecs).get(0);
ObjectNode temp = mapper.createObjectNode();
ratingSpec.forEachEntry(temp::set);
if (temp.has("name")) {
temp.set("rating-spec-id", temp.get("name"));
temp.remove("name");
}
temp.set("active", JsonNodeFactory.instance.booleanNode(true));
transformed.set("rating-spec", temp);
}
if (ratingInput.has(ratingTemplates)) {
JsonNode ratingTemplate = ratingInput.get(ratingTemplates).get(0);
ObjectNode temp = mapper.createObjectNode();
ratingTemplate.forEachEntry(temp::set);
if (temp.has(parametersString)) {
temp.set("parameters-id", temp.get(parametersString));
temp.remove(parametersString);
}
if (temp.has(name)) {
temp.set("template-id", temp.get(name));
temp.remove(name);
}
transformed.set("rating-template", temp);
}
if (ratingInput.has(ratings) && ratingInput.get(ratings).get(0).has(simpleRating)) {
JsonNode rating = ratingInput.get(ratings).get(0).get(simpleRating);
ObjectNode temp = mapper.createObjectNode();
rating.forEachEntry(temp::set);
if (temp.has(name)) {
temp.set("rating-spec-id", temp.get(name));
temp.remove(name);
}
transformed.set(simpleRating, temp);
}
return transformed;
}

private static String cleanupXml(String xml) throws TransformerException {
// Doing this in steps b/c I'm not good enough at xslt to make it happen at once.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,13 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import cwms.cda.data.dto.VerticalDatumInfo;
import cwms.cda.data.dto.rating.RatingSpec;
import hec.data.RatingException;
import hec.data.cwmsRating.RatingSet;
import java.io.IOException;
import java.sql.Connection;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.List;

import mil.army.usace.hec.cwms.rating.io.jdbc.ConnectionProvider;
import mil.army.usace.hec.cwms.rating.io.jdbc.RatingJdbcFactory;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -66,6 +64,12 @@ private static String extractOfficeId(String ratingSet) throws JsonProcessingExc
if (!values.isEmpty()) {
//Getting the last instance since the order is template, spec, rating
office = values.get(values.size() - 1).textValue();
} else {
values = node.findValues("office");
if (!values.isEmpty()) {
//Getting the last instance since the order is template, spec, rating
office = values.get(values.size() - 1).textValue();
}
}
return office;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,21 @@
</xsl:copy>
</xsl:template>

<xsl:template match="*[./office]">
<xsl:copy>
<xsl:attribute name='office-id'>
<xsl:value-of select="./office"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

<!-- drop office-id elements-->
<xsl:template match="office-id"/>

<!-- drop office elements-->
<xsl:template match="office"/>

<!-- drop noNamespaceSchemaLocation elements-->
<xsl:template match="noNamespaceSchemaLocation"/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -546,5 +546,44 @@
.statusCode(is(HttpServletResponse.SC_CREATED));
}

@Test
void test_1758_rating_post() throws IOException {
TestAccounts.KeyUser user = TestAccounts.KeyUser.SPK_NORMAL;
String ratingId = "FSMI.Stage;Flow.EXSA.PRODUCTION";
ratingId = ratingId.replaceAll("FSMI", EXISTING_LOC);
String body = readResourceFile("cwms/cda/data/dto/rating/rating_post.json");
body = body.replaceAll("FSMI", EXISTING_LOC);
// Create the set
given()
.log().ifValidationFails(LogDetail.ALL,true)
.contentType(Formats.JSONV2)
.accept(Formats.JSONV2)
.body(body)
.header("Authorization", user.toHeaderValue())
.queryParam(OFFICE, SPK)
.when()
.redirects().follow(true)
.redirects().max(3)
.post("/ratings")
.then()
.log().ifValidationFails(LogDetail.ALL,true)
.assertThat()
.statusCode(is(HttpServletResponse.SC_CREATED));

Check failure on line 571 in cwms-data-api/src/test/java/cwms/cda/api/rating/RatingsControllerTestIT.java

View workflow job for this annotation

GitHub Actions / build and test (jdk 11, schema latest)

RatingsControllerTestIT.RatingsControllerTestIT.test_1758_rating_post (schema: latest-dev)

java.lang.AssertionError: 1 expectation failed. Expected status code is <201> but was <500>.

given()
.log().ifValidationFails(LogDetail.ALL,true)
.accept(Formats.JSONV2)
.queryParam(OFFICE, SPK)
.when()
.redirects().follow(true)
.redirects().max(3)
.get("/ratings/" + ratingId)
.then()
.log().ifValidationFails(LogDetail.ALL,true)
.assertThat()
.statusCode(is(HttpServletResponse.SC_OK))
.contentType(is(Formats.JSONV2))
.body("office-id", is(SPK));
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
{
"ratings": {
"query-info": {
"time-of-query": "2026-06-01T16:52:08Z",
"process-query": "PT3.394S",
"format-output": "PT3.050S",
"requested-format": "JSON",
"requested-office-id": "SPK",
"requested-start-time": "2026-05-31T16:52:08Z",
"requested-end-time": "2026-06-01T16:52:08Z",
"requested-items": [
{
"name": "FSMI.Stage;Flow.EXSA.PRODUCTION",
"unit": "NATIVE",
"datum": "NATIVE"
}
],
"templates-retrieved": 1,
"total-specifications-retrieved": 1,
"unique-specifications-retrieved": 1,
"total-ratings-retrieved": 1,
"unique-ratings-retrieved": 1
},
"rating-templates": [
{
"office": "SPK",
"name": "Stage;Flow.EXSA",
"parameters-string": "Stage;Flow",
"version": "EXSA",
"ind-parameters": [
{
"name": "Stage",
"value-lookup-in-range": "LINEAR",
"value-lookup-below-range": "NEAREST",
"value-lookup-above-range": "NEAREST"
}
],
"dep-parameter": "Flow",
"description": null
}
],
"rating-specs": [
{
"office": "SPK",
"name": "FSMI.Stage;Flow.EXSA.PRODUCTION",
"location": "FSMI",
"version": "PRODUCTION",
"source-agency": null,
"time-lookup-in-range": "PREVIOUS",
"time-lookup-before-first": "NEAREST",
"time-lookup-after-last": "PREVIOUS",
"rounding": {
"ind-parameters": [
"2223456784"
],
"dep-parameter": "2223456784"
},
"description": "FSMI Expanded, Shift-Adjusted PRODUCTION Stream Rating"
}
],
"ratings": [
{
"simple-rating": {
"office": "SPK",
"name": "FSMI.Stage;Flow.EXSA.PRODUCTION",
"ind-parameters": [
"Stage (ft)"
],
"dep-parameter": "Flow (cfs)",
"effective-date": "2007-07-11T20:38:00Z",
"description": null,
"values": [
[
17,
114000
],
[
18.75,
140000
],
[
20.47,
165558
],
[
30,
313800
],
[
30.4,
320500
],
[
30.84,
328800
],
[
31,
332200
],
[
31.29,
339300
],
[
31.4,
342500
],
[
31.62,
349500
],
[
32.26,
372000
],
[
36,
520000
]
]
}
}
]
}
}
Loading