Skip to content

Commit

Permalink
Updated latest rating retrieval to use JOOQ calls
Browse files Browse the repository at this point in the history
  • Loading branch information
zack-rma committed Dec 17, 2024
1 parent edc5efb commit 04bf70b
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;
import cwms.cda.data.dao.JsonRatingUtils;
import cwms.cda.data.dao.RatingDao;
import cwms.cda.data.dao.RatingSetDao;
import cwms.cda.formatters.ContentType;
import cwms.cda.formatters.Formats;

import hec.data.RatingException;
Expand All @@ -52,6 +52,7 @@
import io.javalin.plugin.openapi.annotations.OpenApiResponse;

import java.io.IOException;

import org.jetbrains.annotations.NotNull;
import org.jooq.DSLContext;

Expand Down Expand Up @@ -93,7 +94,8 @@ protected RatingDao getRatingDao(DSLContext dsl) {
},
responses = {
@OpenApiResponse(status = STATUS_200, content = {
@OpenApiContent(type = Formats.JSONV2)})
@OpenApiContent(type = Formats.JSONV2),
@OpenApiContent(type = Formats.XMLV2)})
},
description = "Returns CWMS Rating Data",
tags = {TAG})
Expand All @@ -102,30 +104,46 @@ public void handle(@NotNull Context ctx) throws Exception {
try (final Timer.Context ignored = markAndTime(GET_ONE)) {
String rating = ctx.pathParam(RATING_ID);

ContentType contentType = new ContentType(ctx.contentType() != null ? ctx.contentType() : Formats.JSONV2);

String officeId = ctx.queryParam(OFFICE);

RatingSet.DatabaseLoadMethod method = ctx.queryParamAsClass(METHOD,
RatingSet.DatabaseLoadMethod.class)
.getOrDefault(RatingSet.DatabaseLoadMethod.EAGER);

String body = getLatestRatingSet(ctx, method, officeId, rating);
if (!contentType.toString().equals(Formats.JSONV2) && !contentType.toString().equals(Formats.XMLV2)) {
ctx.status(HttpCode.UNSUPPORTED_MEDIA_TYPE);
}

String body = getLatestRatingSet(ctx, method, officeId, rating, contentType);
ctx.contentType(contentType.toString());
if (body != null) {
ctx.result(body);
ctx.contentType(Formats.JSONV2);
ctx.status(HttpCode.OK);
} else {
ctx.status(HttpCode.NOT_FOUND);
}
}
}

private String getLatestRatingSet(Context ctx, RatingSet.DatabaseLoadMethod method,
String officeId, String rating) throws IOException, RatingException {
String officeId, String rating, ContentType contentType) throws IOException, RatingException {
String ratingSet = null;
try (final Timer.Context ignored = markAndTime("getLatestRatingSet")) {
DSLContext dsl = getDslContext(ctx);

RatingDao ratingDao = getRatingDao(dsl);
RatingSet returnedSet = ratingDao.retrieveLatest(method, officeId, rating);
ratingSet = JsonRatingUtils.toJson(returnedSet);

if (contentType.toString().equals(Formats.JSONV2)) {
ratingSet = ratingDao.retrieveLatestJSON(method, officeId, rating);

} else if (contentType.toString().equals(Formats.XMLV2)) {
ratingSet = ratingDao.retrieveLatestXML(officeId, rating);
} else {

return null;
}
}

return ratingSet;
Expand Down
6 changes: 4 additions & 2 deletions cwms-data-api/src/main/java/cwms/cda/data/dao/RatingDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ public interface RatingDao {
RatingSet retrieve(RatingSet.DatabaseLoadMethod method, String officeId, String specificationId,
Instant start, Instant end) throws IOException, RatingException;

RatingSet retrieveLatest(RatingSet.DatabaseLoadMethod method, String officeId, String specificationId)
throws IOException, RatingException;
String retrieveLatestXML(String officeId, String specificationId);

String retrieveLatestJSON(RatingSet.DatabaseLoadMethod method, String officeId, String specificationId)
throws RatingException;

String retrieveRatings(String format, String names, String unit, String datum, String office,
String start, String end, String timezone);
Expand Down
126 changes: 32 additions & 94 deletions cwms-data-api/src/main/java/cwms/cda/data/dao/RatingSetDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,8 @@

package cwms.cda.data.dao;

import static org.jooq.impl.DSL.asterisk;
import static org.jooq.impl.DSL.dateDiff;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.partitionBy;
import static org.jooq.impl.DSL.rank;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.toDate;
import static org.jooq.impl.DSL.unquotedName;
import static org.jooq.impl.DSL.val;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
Expand All @@ -43,21 +34,18 @@
import hec.data.cwmsRating.RatingSet;
import java.io.IOException;
import java.sql.Connection;
import java.sql.Date;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
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.jooq.DSLContext;
import org.jooq.DatePart;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.exception.DataAccessException;
import usace.cwms.db.jooq.codegen.packages.CWMS_RATING_PACKAGE;
import usace.cwms.db.jooq.codegen.tables.AV_RATING_LOCAL;
import usace.cwms.db.jooq.codegen.udt.records.RATING_T;
import usace.cwms.db.jooq.codegen.udt.records.RATING_TAB_T;


public class RatingSetDao extends JooqDao<RatingSet> implements RatingDao {
Expand Down Expand Up @@ -101,90 +89,40 @@ private static String extractOfficeId(String ratingSet) throws JsonProcessingExc
return office;
}

public RatingSet retrieveLatest(RatingSet.DatabaseLoadMethod method, String officeId,
String specificationId) throws IOException, RatingException {
AV_RATING_LOCAL view = AV_RATING_LOCAL.AV_RATING_LOCAL;

final RatingSet[] retval = new RatingSet[1];
try {
@Override
public String retrieveLatestXML(String officeId,
String specificationId) {
return connectionResult(dsl, c -> {
DSLContext context = getDslContext(c, officeId);
return CWMS_RATING_PACKAGE.call_RETRIEVE_EFF_RATINGS_XML_F(context.configuration(), specificationId,
Timestamp.from(Instant.now()), Timestamp.from(Instant.now()), null, officeId);
});
}

if (method == null) {
method = RatingSet.DatabaseLoadMethod.EAGER;
}
@Override
public String retrieveLatestJSON(RatingSet.DatabaseLoadMethod method, String officeId,
String specificationId) throws RatingException {

RatingSet.DatabaseLoadMethod finalMethod = method;
RATING_TAB_T res = connectionResult(dsl, c -> {
DSLContext context = getDslContext(c, officeId);
return CWMS_RATING_PACKAGE.call_RETRIEVE_EFF_RATINGS_OBJ_F(context.configuration(), specificationId,
Timestamp.from(Instant.now()), Timestamp.from(Instant.now()), null, officeId);
});

ZoneId utcZone = ZoneId.of("UTC");
Name rank = unquotedName("rank");
Name alias1 = unquotedName("a");
Name alias2 = unquotedName("b");
Name alias3 = unquotedName("c");
Name alias4 = unquotedName("d");
Name diff = unquotedName("difference");
Name effectiveDateName = unquotedName("effective_date");
Name ratingIdName = unquotedName("rating_id");
Name activeFlag = unquotedName("active_flag");
String dateFormat = "dd-MMM-YYYY H:mm:ss";
String oracleDateFormat = "DD-MON-YYYY HH24:MI:SS";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat)
.withZone(utcZone);
String formattedDate = formatter.format(Instant.now());

String ratingId = null;
Record result = connectionResult(dsl, c ->
dsl.select(asterisk())
.from(
select(
field(name(alias1, effectiveDateName)),
field(name(alias1, ratingIdName)),
field(name(alias1, activeFlag)),
rank().over(partitionBy(field(alias3))
.orderBy(field(diff).asc()))
.as(rank)
)
.from(
select(
field(name(effectiveDateName)),
field(name(alias2, ratingIdName)),
field(name(alias2, ratingIdName)).as(alias3),
field(name(alias2, activeFlag)),
dateDiff(DatePart.DAY,
field(name(effectiveDateName)).cast(Date.class),
toDate(formattedDate, inline(oracleDateFormat)))
.as(diff))
.from(view.as(alias2))
.asTable(alias1).where(field(diff).ge(val(0)))).asTable(alias4))
.where(field(rank).eq(inline(1)).and(field(activeFlag).eq("T")))
.fetchOne()
);
Timestamp effectiveDate = result.getValue(field(name(alias4, effectiveDateName).unquotedName()),
Timestamp.class);
ratingId = result.getValue(field(name(alias4, ratingIdName).unquotedName()), String.class);

if (ratingId == null) {
return null;
}
Instant effectiveInstant = Instant.parse(
String.format("%sZ", effectiveDate.toString().replace(" ", "T")));
final long finalStartTime = effectiveInstant.toEpochMilli();
final String ratingIdFinal = ratingId;
final long finalEndTime = effectiveInstant.toEpochMilli();
connection(dsl, c -> retval[0] =
RatingJdbcFactory.ratingSet(finalMethod, new RatingConnectionProvider(c), officeId,
ratingIdFinal, finalStartTime,
finalEndTime, false));
} catch (DataAccessException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RatingException) {
if (cause.getMessage().contains("contains no rating templates")) {
return null;
}
Name effectiveDateName = unquotedName("EFFECTIVE_DATE");
Name ratingIdName = unquotedName("RATING_SPEC_ID");
RATING_T rating = res.get(0);

throw (RatingException) cause;
}
throw new IOException("Failed to retrieve Rating", ex);
if (rating == null) {
return null;
}
return retval[0];

String ratingIdFinal = rating.get(field(ratingIdName), String.class);
long finalTime = rating.get(field(effectiveDateName), Timestamp.class).toInstant().toEpochMilli();

return JsonRatingUtils.toJson(connectionResult(dsl, c ->
RatingJdbcFactory.ratingSet(method, new RatingConnectionProvider(c), officeId,
ratingIdFinal, finalTime, finalTime, false)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ void test_getOne(GetOneTest test)

@Test
void test_get_one_latest() {
// get latest json
ExtractableResponse<Response> response = given()
.log().ifValidationFails(LogDetail.ALL,true)
.contentType(Formats.JSONV2)
Expand All @@ -249,6 +250,29 @@ void test_get_one_latest() {
}
assertNotNull(effectiveDate);
assertEquals("2016-06-06T00:00:00Z", effectiveDate);

// get latest xml
response = given()
.log().ifValidationFails(LogDetail.ALL,true)
.contentType(Formats.XMLV2)
.queryParam(OFFICE, SPK)
.when()
.redirects().follow(true)
.redirects().max(3)
.get("/ratings/" + EXISTING_SPEC + "/latest")
.then()
.log().ifValidationFails(LogDetail.ALL,true)
.assertThat()
.statusCode(is(HttpServletResponse.SC_OK))
.contentType(is(Formats.XMLV2))
.extract();

effectiveDate = response.path("ratings.simple-rating[0].effective-date");
if (effectiveDate == null) {
effectiveDate = response.path("simple-rating.effective-date");
}
assertNotNull(effectiveDate);
assertEquals("2016-06-06T00:00:00Z", effectiveDate);
}

enum GetOneTest
Expand Down

0 comments on commit 04bf70b

Please sign in to comment.