Skip to content

Commit

Permalink
Merge pull request #686 from RyanM-RMA/bugfix/content_type_clob
Browse files Browse the repository at this point in the history
Adding Clob aliases for JSON and XML
  • Loading branch information
RyanM-RMA authored Jun 7, 2024
2 parents d48c21a + a8b64e1 commit d245ba4
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 64 deletions.
8 changes: 4 additions & 4 deletions cwms-data-api/src/main/java/cwms/cda/api/ClobController.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public void getAll(@NotNull Context ctx) {
String office = ctx.queryParam(OFFICE);

String formatHeader = ctx.header(Header.ACCEPT);
ContentType contentType = Formats.parseHeaderAndQueryParm(formatHeader, "");
ContentType contentType = Formats.parseHeader(formatHeader, Clobs.class);

String cursor = queryParamAsClass(ctx, new String[]{PAGE, CURSOR},
String.class, "", metrics, name(ClobController.class.getName(), GET_ALL));
Expand Down Expand Up @@ -185,7 +185,7 @@ public void getOne(@NotNull Context ctx, @NotNull String clobId) {
Optional<Clob> optAc = dao.getByUniqueName(clobId, office);

if (optAc.isPresent()) {
ContentType contentType = Formats.parseHeaderAndQueryParm(formatHeader, "");
ContentType contentType = Formats.parseHeader(formatHeader, Clob.class);

Clob clob = optAc.get();
String result = Formats.format(contentType, clob);
Expand Down Expand Up @@ -227,7 +227,7 @@ public void create(@NotNull Context ctx) {

boolean failIfExists = ctx.queryParamAsClass(FAIL_IF_EXISTS, Boolean.class).getOrDefault(true);

ContentType contentType = Formats.parseHeader(formatHeader);
ContentType contentType = Formats.parseHeader(formatHeader, Clob.class);
Clob clob = Formats.parseContent(contentType, ctx.bodyAsInputStream(), Clob.class);

if (clob.getOfficeId() == null) {
Expand Down Expand Up @@ -281,7 +281,7 @@ public void update(@NotNull Context ctx, @NotNull String clobId) {
String reqContentType = ctx.req.getContentType();
String formatHeader = reqContentType != null ? reqContentType : Formats.JSON;
ClobDao dao = new ClobDao(dsl);
ContentType contentType = Formats.parseHeader(formatHeader);
ContentType contentType = Formats.parseHeader(formatHeader, Clob.class);
Clob clob = Formats.parseContent(contentType, ctx.bodyAsInputStream(), Clob.class);

if (clob.getOfficeId() == null) {
Expand Down
7 changes: 4 additions & 3 deletions cwms-data-api/src/main/java/cwms/cda/data/dto/Clob.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
import cwms.cda.formatters.annotations.FormattableWith;
import cwms.cda.formatters.json.JsonV1;
import cwms.cda.formatters.json.JsonV2;
import cwms.cda.formatters.xml.XMLv1;
import cwms.cda.formatters.xml.XMLv2;


@JsonRootName("clob")
@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class)
@FormattableWith(contentType = Formats.JSON, formatter = JsonV1.class)
@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class)
@FormattableWith(contentType = Formats.XMLV2, formatter = XMLv2.class)
@FormattableWith(contentType = Formats.JSONV1, formatter = JsonV1.class)
@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class, aliases = {Formats.DEFAULT, Formats.JSON})
@FormattableWith(contentType = Formats.XMLV2, formatter = XMLv2.class, aliases = {Formats.XML})
public class Clob extends CwmsDTO {
@JsonProperty(required = true)
private String id;
Expand Down
6 changes: 3 additions & 3 deletions cwms-data-api/src/main/java/cwms/cda/data/dto/Clobs.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
import java.util.List;

@JsonRootName("clobs")
@FormattableWith(contentType = Formats.JSON, formatter = JsonV1.class)
@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class)
@FormattableWith(contentType = Formats.XMLV2, formatter = XMLv2.class)
@FormattableWith(contentType = Formats.JSONV1, formatter = JsonV1.class)
@FormattableWith(contentType = Formats.JSONV2, formatter = JsonV2.class, aliases = {Formats.DEFAULT, Formats.JSON})
@FormattableWith(contentType = Formats.XMLV2, formatter = XMLv2.class, aliases = {Formats.XML})
public class Clobs extends CwmsDTOPaginated {
@JacksonXmlElementWrapper
@JacksonXmlProperty(localName = "clob")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public class Formats {

static {
contentTypeList.addAll(
Stream.of(JSON, XML, XMLV2, WML2, JSONV2, TAB, CSV, GEOJSON, PGJSON, NAMED_PGJSON)
Stream.of(JSON, JSONV1, XML, XMLV1, XMLV2, WML2, JSONV2, TAB, CSV, GEOJSON, PGJSON, NAMED_PGJSON)
.map(ContentType::new)
.collect(Collectors.toList()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ void test_getOne_not_found() throws UnsupportedEncodingException {
@Test
void test_create_getOne() throws JsonProcessingException
{
// /* There is an issue with how javalin handles / in the path that are actually part
// of the object name (NOTE: good candidate for actually having a GUID or other "code"
// as part of the path and the actual name as a query parameter.
// */
/* There is an issue with how javalin handles / in the path that are actually part
of the object name (NOTE: good candidate for actually having a GUID or other "code"
as part of the path and the actual name as a query parameter.
*/

given()
.log().ifValidationFails(LogDetail.ALL, true)
Expand Down
148 changes: 99 additions & 49 deletions cwms-data-api/src/test/java/cwms/cda/api/ClobControllerTestIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,30 @@
import fixtures.TestAccounts;
import io.restassured.filter.log.LogDetail;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletResponse;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;

@Tag("integration")
public class ClobControllerTestIT extends DataApiTestIT {

public static final String SPK = "SPK";
private static final String EXISTING_CLOB_ID = "TEST/TEST_CLOBIT2";
private static final String EXISTING_CLOB_VALUE = "test value";
private static final String EXISTING_CLOB_DESC = "test description";

@Test
void test_getOne_not_found() throws UnsupportedEncodingException {
String clobId = "TEST";
String urlencoded = java.net.URLEncoder.encode(clobId, "UTF-8");

given()
.log().ifValidationFails(LogDetail.ALL,true)
.accept(Formats.JSONV2)
.queryParam(Controllers.OFFICE, SPK)
.when()
.get("/clobs/" + urlencoded)
.then()
.log().ifValidationFails(LogDetail.ALL,true)
.assertThat()
.statusCode(is(HttpServletResponse.SC_NOT_FOUND));
}

@Test
void test_create_getOne() throws JsonProcessingException {
String clobId = "TEST/TEST_CLOBIT2";

String origDesc = "test description";
String origValue = "test value";
Clob clob = new Clob(SPK, clobId, origDesc, origValue);
@BeforeAll
static void createExistingClob() throws Exception
{
Clob clob = new Clob(SPK, EXISTING_CLOB_ID, EXISTING_CLOB_DESC, EXISTING_CLOB_VALUE);
ObjectMapper om = JsonV2.buildObjectMapper();
String serializedClob = om.writeValueAsString(clob);
TestAccounts.KeyUser user = TestAccounts.KeyUser.SPK_NORMAL;

given()
.log().ifValidationFails(LogDetail.ALL,true)
.accept(Formats.JSONV2)
Expand All @@ -64,7 +51,28 @@ void test_create_getOne() throws JsonProcessingException {
.log().ifValidationFails(LogDetail.ALL,true)
.assertThat()
.statusCode(is(HttpServletResponse.SC_CREATED));
}

@Test
void test_getOne_notFound() throws UnsupportedEncodingException {
String clobId = "TEST";
String urlencoded = URLEncoder.encode(clobId, "UTF-8");

given()
.log().ifValidationFails(LogDetail.ALL,true)
.accept(Formats.JSONV2)
.queryParam(Controllers.OFFICE, SPK)
.when()
.get("/clobs/" + urlencoded)
.then()
.log().ifValidationFails(LogDetail.ALL,true)
.assertThat()
.statusCode(is(HttpServletResponse.SC_NOT_FOUND));
}

@Test
void test_getOne_jsonv2()
{
/* There is an issue with how javalin handles / in the path that are actually part
of the object name (NOTE: good candidate for actually having a GUID or other "code"
as part of the path and the actual name as a query parameter.
Expand All @@ -74,48 +82,90 @@ of the object name (NOTE: good candidate for actually having a GUID or other "co
.accept(Formats.JSONV2)
.log().ifValidationFails(LogDetail.ALL,true)
.queryParam(Controllers.OFFICE, SPK)
.queryParam(Controllers.CLOB_ID, clobId)
.queryParam(Controllers.CLOB_ID, EXISTING_CLOB_ID)
.when()
.get("/clobs/ignored")
.then()
.log().ifValidationFails(LogDetail.ALL,true)
.assertThat()
.statusCode(is(HttpServletResponse.SC_OK))
.body("office-id", is(SPK))
.body("id", is(clobId))
.body("description", is(origDesc))
.body("value", is(origValue));
.body("id", is(EXISTING_CLOB_ID))
.body("description", is(EXISTING_CLOB_DESC))
.body("value", is(EXISTING_CLOB_VALUE));
}

@Test
void test_getOne_plainText_withRange()
{
// We can now do Range requests!
given()
.accept("text/plain")
.log().ifValidationFails(LogDetail.ALL,true)
.queryParam(Controllers.OFFICE, SPK)
.queryParam(Controllers.CLOB_ID, EXISTING_CLOB_ID)
.header("Range"," bytes=3-")
.when()
.get("/clobs/ignored")
.then()
.log().ifValidationFails(LogDetail.ALL,true)
.assertThat()
.statusCode(is(HttpServletResponse.SC_PARTIAL_CONTENT))
.body( is("t value"));
}

@Test
void test_getOne_plain_text()
{
given()
.accept("text/plain")
.log().ifValidationFails(LogDetail.ALL,true)
.queryParam(Controllers.OFFICE, SPK)
.queryParam(Controllers.CLOB_ID, clobId)
.when()
.get("/clobs/ignored")
.then()
.log().ifValidationFails(LogDetail.ALL,true)
.assertThat()
.statusCode(is(HttpServletResponse.SC_OK))
.body( is(origValue))
;
.accept("text/plain")
.log().ifValidationFails(LogDetail.ALL,true)
.queryParam(Controllers.OFFICE, SPK)
.queryParam(Controllers.CLOB_ID, EXISTING_CLOB_ID)
.when()
.get("/clobs/ignored")
.then()
.log().ifValidationFails(LogDetail.ALL,true)
.assertThat()
.statusCode(is(HttpServletResponse.SC_OK))
.body( is(EXISTING_CLOB_VALUE));
}

// We can now do Range requests!

@ParameterizedTest
@EnumSource(GetAllTest.class)
void test_getAll_aliases(GetAllTest test)
{
given()
.accept("text/plain")
.log().ifValidationFails(LogDetail.ALL,true)
.queryParam(Controllers.OFFICE, SPK)
.queryParam(Controllers.CLOB_ID, clobId)
.header("Range"," bytes=3-")
.when()
.get("/clobs/ignored")
.then()
.accept(test._accept)
.when()
.get("/clobs/")
.then()
.log().ifValidationFails(LogDetail.ALL,true)
.assertThat()
.statusCode(is(HttpServletResponse.SC_PARTIAL_CONTENT))
.body( is("t value"))
.statusCode(is(HttpServletResponse.SC_OK))
.contentType(is(test._expectedContentType));
}

enum GetAllTest
{
DEFAULT(Formats.DEFAULT, Formats.JSONV2),
JSON(Formats.JSON, Formats.JSONV2),
JSONV1(Formats.JSONV1, Formats.JSONV1),
JSONV2(Formats.JSONV2, Formats.JSONV2),
XML(Formats.XML, Formats.XMLV2),
;

final String _accept;
final String _expectedContentType;

GetAllTest(String accept, String expectedContentType)
{
_accept = accept;
_expectedContentType = expectedContentType;
}
}
}

0 comments on commit d245ba4

Please sign in to comment.