diff --git a/cwms-data-api/src/main/java/cwms/cda/api/RatingController.java b/cwms-data-api/src/main/java/cwms/cda/api/RatingController.java index edc330ced..b04d4ba39 100644 --- a/cwms-data-api/src/main/java/cwms/cda/api/RatingController.java +++ b/cwms-data-api/src/main/java/cwms/cda/api/RatingController.java @@ -31,6 +31,7 @@ import static cwms.cda.api.Controllers.DATE_FORMAT; import static cwms.cda.api.Controllers.DATUM; import static cwms.cda.api.Controllers.DELETE; +import static cwms.cda.api.Controllers.EFFECTIVE_DATE; import static cwms.cda.api.Controllers.END; import static cwms.cda.api.Controllers.EXAMPLE_DATE; import static cwms.cda.api.Controllers.FORMAT; @@ -296,19 +297,16 @@ public void getAll(@NotNull Context ctx) { ContentType contentType = Formats.parseHeaderAndQueryParm(header, format, RatingAliasMarker.class); - if (format.isEmpty()) - { + if (format.isEmpty()) { //Use the full content type here (i.e. application/json;version=2) ctx.contentType(contentType.toString()); - } - else - { + } else { //Legacy content type only includes the basic type (i.e. application/json) ctx.contentType(contentType.getType()); } - //At the moment, we still use the legacy formatting here, since we don't have a newer API for serializing/deserializing - //a collection of rating sets - unlike getOne. + //At the moment, we still use the legacy formatting here, since we don't have a newer API for + // serializing/deserializing a collection of rating sets - unlike getOne. String legacyFormat = Formats.getLegacyTypeFromContentType(contentType); String results = ratingDao.retrieveRatings(legacyFormat, names, unit, datum, office, start, end, timezone); @@ -322,7 +320,8 @@ public void getAll(@NotNull Context ctx) { @OpenApi( pathParams = { - @OpenApiParam(name = RATING_ID, required = true, description = "The rating-id of the effective dates to be retrieve. "), + @OpenApiParam(name = RATING_ID, required = true, description = "The rating-id of the effective " + + "dates to be retrieve. "), }, queryParams = { @OpenApiParam(name = OFFICE, required = true, description = @@ -339,6 +338,10 @@ public void getAll(@NotNull Context ctx) { + "otherwise specified), as well as the time zone of any times in the" + " response. If this field is not specified, the default time zone " + "of UTC shall be used."), + @OpenApiParam(name = EFFECTIVE_DATE, description = "Specifies the " + + "date to find the closest match to for retrieving a specific rating curve. This date is used " + + "instead of the time window specified by start and end. " + + "The format for this field is ISO 8601 extended."), @OpenApiParam(name = METHOD, description = "Specifies " + "the retrieval method used. If no method is provided EAGER will be used.", type = RatingSet.DatabaseLoadMethod.class), @@ -354,8 +357,13 @@ public void getAll(@NotNull Context ctx) { public void getOne(@NotNull Context ctx, @NotNull String rating) { try (final Timer.Context ignored = markAndTime(GET_ONE)) { - String officeId = ctx.queryParam(OFFICE); + String timezone = ctx.queryParamAsClass(TIMEZONE, String.class).getOrDefault("UTC"); + Instant effectiveDate = null; + String effectiveDateParam = ctx.queryParam(EFFECTIVE_DATE); + if (effectiveDateParam != null) { + effectiveDate = DateUtils.parseUserDate(effectiveDateParam, timezone).toInstant(); + } Instant beginInstant = null; String begin = ctx.queryParam(BEGIN); @@ -369,11 +377,13 @@ public void getOne(@NotNull Context ctx, @NotNull String rating) { endInstant = DateUtils.parseUserDate(end, timezone).toInstant(); } + String officeId = ctx.queryParam(OFFICE); + RatingSet.DatabaseLoadMethod method = ctx.queryParamAsClass(METHOD, RatingSet.DatabaseLoadMethod.class) .getOrDefault(RatingSet.DatabaseLoadMethod.EAGER); - String body = getRatingSetString(ctx, method, officeId, rating, beginInstant, endInstant); + String body = getRatingSetString(ctx, method, officeId, rating, beginInstant, endInstant, effectiveDate); if (body != null) { ctx.result(body); ctx.status(HttpCode.OK); @@ -385,7 +395,7 @@ public void getOne(@NotNull Context ctx, @NotNull String rating) { @Nullable private String getRatingSetString(Context ctx, RatingSet.DatabaseLoadMethod method, String officeId, String rating, Instant begin, - Instant end) { + Instant end, Instant effectiveDate) { String retval = null; try (final Timer.Context ignored = markAndTime("getRatingSetString")) { @@ -398,7 +408,7 @@ private String getRatingSetString(Context ctx, RatingSet.DatabaseLoadMethod meth if (isJson || isXml) { ctx.contentType(contentType.toString()); try { - RatingSet ratingSet = getRatingSet(ctx, method, officeId, rating, begin, end); + RatingSet ratingSet = getRatingSet(ctx, method, officeId, rating, begin, end, effectiveDate); if (ratingSet != null) { if (isJson) { retval = JsonRatingUtils.toJson(ratingSet); @@ -424,8 +434,7 @@ private String getRatingSetString(Context ctx, RatingSet.DatabaseLoadMethod meth } else { CdaError re = new CdaError("Currently supporting only: " + Formats.JSONV2 + " and " + Formats.XMLV2); - logger.log(Level.WARNING, "Provided accept header not recognized:" - + acceptHeader, re); + logger.log(Level.WARNING, String.format("Provided accept header not recognized: %s", acceptHeader), re); ctx.status(HttpServletResponse.SC_NOT_IMPLEMENTED); ctx.json(CdaError.notImplemented()); } @@ -437,13 +446,13 @@ private String getRatingSetString(Context ctx, RatingSet.DatabaseLoadMethod meth private RatingSet getRatingSet(Context ctx, RatingSet.DatabaseLoadMethod method, String officeId, String rating, Instant begin, - Instant end) throws IOException, RatingException { + Instant end, Instant effectiveDate) throws IOException, RatingException { RatingSet ratingSet; try (final Timer.Context ignored = markAndTime("getRatingSet")) { DSLContext dsl = getDslContext(ctx); RatingDao ratingDao = getRatingDao(dsl); - ratingSet = ratingDao.retrieve(method, officeId, rating, begin, end); + ratingSet = ratingDao.retrieve(method, officeId, rating, begin, end, effectiveDate); } return ratingSet; diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/RatingDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/RatingDao.java index 13240adf0..4715281cd 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/RatingDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/RatingDao.java @@ -34,12 +34,12 @@ public interface RatingDao { - static final Pattern officeMatcher = Pattern.compile(".*office-id=\"(.*?)\""); + Pattern officeMatcher = Pattern.compile(".*office-id=\"(.*?)\""); void create(String ratingSet, boolean storeTemplate) throws IOException, RatingException; RatingSet retrieve(RatingSet.DatabaseLoadMethod method, String officeId, String specificationId, - Instant start, Instant end) throws IOException, RatingException; + Instant start, Instant end, Instant effectiveDate) throws IOException, RatingException; String retrieveRatings(String format, String names, String unit, String datum, String office, String start, String end, String timezone); diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/RatingSetDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/RatingSetDao.java index 37374c40f..87fdeab06 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/RatingSetDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/RatingSetDao.java @@ -24,22 +24,42 @@ package cwms.cda.data.dao; +import static org.jooq.impl.DSL.abs; +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.table; +import static org.jooq.impl.DSL.toDate; +import static org.jooq.impl.DSL.unquotedName; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import hec.data.RatingException; 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 java.io.IOException; -import java.sql.Connection; -import java.sql.Timestamp; -import java.time.Instant; -import java.util.List; public class RatingSetDao extends JooqDao implements RatingDao { @@ -57,8 +77,7 @@ public void create(String ratingSetXml, boolean storeTemplate) throws IOExceptio DSLContext context = getDslContext(c, office); String errs = CWMS_RATING_PACKAGE.call_STORE_RATINGS_XML__5(context.configuration(), ratingSetXml, "T", storeTemplate ? "T" : "F"); - if (errs != null && !errs.isEmpty()) - { + if (errs != null && !errs.isEmpty()) { throw new DataAccessException(errs); } }); @@ -85,8 +104,9 @@ private static String extractOfficeId(String ratingSet) throws JsonProcessingExc @Override public RatingSet retrieve(RatingSet.DatabaseLoadMethod method, String officeId, - String specificationId, Instant startZdt, Instant endZdt + String specificationId, Instant startZdt, Instant endZdt, Instant effectiveDateParam ) throws IOException, RatingException { + AV_RATING_LOCAL view = AV_RATING_LOCAL.AV_RATING_LOCAL; final RatingSet[] retval = new RatingSet[1]; try { @@ -110,9 +130,66 @@ public RatingSet retrieve(RatingSet.DatabaseLoadMethod method, String officeId, RatingSet.DatabaseLoadMethod finalMethod = method; - connection(dsl, c -> retval[0] = - RatingJdbcFactory.ratingSet(finalMethod, new RatingConnectionProvider(c), officeId, - specificationId, start, end, false)); + if (effectiveDateParam != null) { + ZoneId utcZone = ZoneId.of("UTC"); + Name rank = unquotedName("rank"); + Name alias1 = unquotedName("a"); + Name alias2 = unquotedName("b"); + Name alias3 = unquotedName("c"); + Name diff = unquotedName("difference"); + Name effectiveDateName = unquotedName("effective_date"); + Name ratingIdName = unquotedName("rating_id"); + 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(effectiveDateParam); + + String ratingId = null; + Instant startInstant = null; + Instant endInstant = null; + Record result = connectionResult(dsl, c -> + dsl.select(asterisk()) + .from( + select( + table(alias1).asterisk(), + rank().over(partitionBy(field(alias3)) + .orderBy(field(diff).asc())) + .as(rank) + ) + .from( + select( + table(alias2).asterisk(), + field(name(alias2, ratingIdName)).as(alias3), + abs(dateDiff(DatePart.DAY, toDate(formattedDate, inline(oracleDateFormat)), + field(name(alias2, effectiveDateName)) + .cast(Date.class))) + .as(diff)) + .from(view.as(alias2)) + .asTable(alias1))) + .where(field(rank).eq(inline(1))) + .fetchOne() + ); + Timestamp effectiveDate = result.getValue(view.EFFECTIVE_DATE, Timestamp.class); + ratingId = result.getValue(view.RATING_ID); + startInstant = effectiveDate.toInstant().atZone(utcZone).toInstant(); + endInstant = effectiveDate.toInstant().atZone(utcZone).toInstant(); + + if (ratingId == null) { + return null; + } + final Instant finalStartInstant = startInstant; + final String ratingIdFinal = ratingId; + final Instant finalEndInstant = endInstant; + connection(dsl, c -> retval[0] = + RatingJdbcFactory.ratingSet(finalMethod, new RatingConnectionProvider(c), officeId, + ratingIdFinal, finalStartInstant.toEpochMilli(), + finalEndInstant.toEpochMilli(), false)); + } else { + connection(dsl, c -> retval[0] = + RatingJdbcFactory.ratingSet(finalMethod, new RatingConnectionProvider(c), officeId, + specificationId, start, end, false)); + } } catch (DataAccessException ex) { Throwable cause = ex.getCause(); @@ -151,7 +228,7 @@ public void store(String ratingSetXml, boolean includeTemplate) throws IOExcepti public void delete(String officeId, String specificationId, Instant start, Instant end) { Timestamp startDate = new Timestamp(start.toEpochMilli()); Timestamp endDate = new Timestamp(end.toEpochMilli()); - dsl.connection(c-> + dsl.connection(c -> CWMS_RATING_PACKAGE.call_DELETE_RATINGS( getDslContext(c,officeId).configuration(), specificationId, startDate, endDate, "UTC", officeId @@ -170,15 +247,15 @@ public String retrieveRatings(String format, String names, String unit, String d } private static final class RatingConnectionProvider implements ConnectionProvider { - private final Connection c; + private final Connection conn; - private RatingConnectionProvider(Connection c) { - this.c = c; + private RatingConnectionProvider(Connection conn) { + this.conn = conn; } @Override public Connection getConnection() { - return c; + return conn; } @Override diff --git a/cwms-data-api/src/test/java/cwms/cda/api/RatingsControllerTestIT.java b/cwms-data-api/src/test/java/cwms/cda/api/RatingsControllerTestIT.java index 2a55eb8c0..9d1f93f16 100644 --- a/cwms-data-api/src/test/java/cwms/cda/api/RatingsControllerTestIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/api/RatingsControllerTestIT.java @@ -7,14 +7,18 @@ package cwms.cda.api; +import cwms.cda.data.dao.JooqDao; import cwms.cda.formatters.Formats; import fixtures.TestAccounts; import hec.data.cwmsRating.io.RatingSetContainer; import hec.data.cwmsRating.io.RatingSpecContainer; import io.restassured.filter.log.LogDetail; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; import mil.army.usace.hec.cwms.rating.io.xml.RatingContainerXmlFactory; import mil.army.usace.hec.cwms.rating.io.xml.RatingSetContainerXmlFactory; import mil.army.usace.hec.cwms.rating.io.xml.RatingSpecXmlFactory; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.ParameterizedTest; @@ -22,19 +26,18 @@ import javax.servlet.http.HttpServletResponse; -import java.util.Arrays; - -import static cwms.cda.api.Controllers.FORMAT; -import static cwms.cda.api.Controllers.OFFICE; -import static cwms.cda.api.Controllers.STORE_TEMPLATE; +import static cwms.cda.api.Controllers.*; import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; @Tag("integration") -public class RatingsControllerTestIT extends DataApiTestIT +class RatingsControllerTestIT extends DataApiTestIT { private static final String EXISTING_LOC = "RatingsControllerTestIT"; private static final String EXISTING_SPEC = EXISTING_LOC + ".Stage;Flow.COE.Production"; + private static final String TEMPLATE = "Stage;Flow.COE"; private static final String SPK = "SPK"; @BeforeAll @@ -45,7 +48,9 @@ static void beforeAll() throws Exception String ratingXml = readResourceFile("cwms/cda/api/Zanesville_Stage_Flow_COE_Production.xml"); ratingXml = ratingXml.replaceAll("Zanesville", EXISTING_LOC); + String ratingXml2 = ratingXml.replaceAll("2002-04-09T13:53:01Z", "2016-06-06T00:00:00Z"); RatingSetContainer container = RatingSetContainerXmlFactory.ratingSetContainerFromXml(ratingXml); + RatingSetContainer container2 = RatingSetContainerXmlFactory.ratingSetContainerFromXml(ratingXml2); RatingSpecContainer specContainer = container.ratingSpecContainer; specContainer.officeId = SPK; specContainer.specOfficeId = SPK; @@ -53,6 +58,7 @@ static void beforeAll() throws Exception String specXml = RatingSpecXmlFactory.toXml(specContainer, "", 0, true); String templateXml = RatingSpecXmlFactory.toXml(specContainer, "", 0); String setXml = RatingContainerXmlFactory.toXml(container, "", 0, true, false); + String setXml2 = RatingContainerXmlFactory.toXml(container2, "", 0, true, false); TestAccounts.KeyUser user = TestAccounts.KeyUser.SPK_NORMAL; //Create Template @@ -103,6 +109,45 @@ static void beforeAll() throws Exception .assertThat() .log().ifValidationFails(LogDetail.ALL,true) .statusCode(is(HttpServletResponse.SC_OK)); + + //Create the second set + given() + .log().ifValidationFails(LogDetail.ALL,true) + .contentType(Formats.XMLV2) + .body(setXml2) + .header("Authorization", user.toHeaderValue()) + .queryParam(OFFICE, SPK) + .queryParam(STORE_TEMPLATE, false) + .when() + .redirects().follow(true) + .redirects().max(3) + .post("/ratings") + .then() + .log().ifValidationFails(LogDetail.ALL,true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)); + } + + @AfterAll + static void afterAll() + { + TestAccounts.KeyUser user = TestAccounts.KeyUser.SPK_NORMAL; + + // Delete Template + given() + .log().ifValidationFails(LogDetail.ALL,true) + .contentType(Formats.XMLV2) + .header("Authorization", user.toHeaderValue()) + .queryParam(OFFICE, SPK) + .queryParam(METHOD, JooqDao.DeleteMethod.DELETE_ALL) + .when() + .redirects().follow(true) + .redirects().max(3) + .delete("/ratings/template/" + TEMPLATE) + .then() + .log().ifValidationFails(LogDetail.ALL,true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_NO_CONTENT)); } @ParameterizedTest @@ -111,7 +156,7 @@ void test_getAll_legacy(GetAllLegacyTest test) { given() .log().ifValidationFails(LogDetail.ALL,true) - .queryParam(FORMAT, test._queryParam) + .queryParam(FORMAT, test.queryParam) .when() .redirects().follow(true) .redirects().max(3) @@ -120,7 +165,7 @@ void test_getAll_legacy(GetAllLegacyTest test) .assertThat() .log().ifValidationFails(LogDetail.ALL,true) .statusCode(is(HttpServletResponse.SC_OK)) - .contentType(is(test._expectedContentType)); + .contentType(is(test.expectedContentType)); } @ParameterizedTest @@ -129,7 +174,7 @@ void test_getAll(GetAllTest test) { given() .log().ifValidationFails(LogDetail.ALL,true) - .accept(test._accept) + .accept(test.accept) .when() .redirects().follow(true) .redirects().max(3) @@ -138,7 +183,7 @@ void test_getAll(GetAllTest test) .assertThat() .log().ifValidationFails(LogDetail.ALL,true) .statusCode(is(HttpServletResponse.SC_OK)) - .contentType(is(test._expectedContentType)); + .contentType(is(test.expectedContentType)); } @ParameterizedTest @@ -147,7 +192,7 @@ void test_getOne(GetOneTest test) { given() .log().ifValidationFails(LogDetail.ALL,true) - .accept(test._accept) + .accept(test.accept) .queryParam(OFFICE, SPK) .when() .redirects().follow(true) @@ -157,7 +202,86 @@ void test_getOne(GetOneTest test) .assertThat() .log().ifValidationFails(LogDetail.ALL,true) .statusCode(is(HttpServletResponse.SC_OK)) - .contentType(is(test._expectedContentType)); + .contentType(is(test.expectedContentType)); + } + + @ParameterizedTest + @EnumSource(GetOneTest.class) + void test_get_one_match_date(GetOneTest test) { + String enable = "enable"; + ExtractableResponse response = given() + .log().ifValidationFails(LogDetail.ALL,true) + .accept(test.accept) + .queryParam(OFFICE, SPK) + .queryParam(EFFECTIVE_DATE, "2002-01-01T00:00:00Z") + .queryParam(enable, true) + .when() + .redirects().follow(true) + .redirects().max(3) + .get("/ratings/" + EXISTING_SPEC) + .then() + .assertThat() + .log().ifValidationFails(LogDetail.ALL,true) + .statusCode(is(HttpServletResponse.SC_OK)) + .contentType(is(test.expectedContentType)) + .extract(); + + String effectiveDate = response.path("ratings.simple-rating[0].effective-date"); + if (effectiveDate == null) { + effectiveDate = response.path("simple-rating.effective-date"); + } + assertNotNull(effectiveDate); + assertEquals("2002-04-09T13:53:00Z", effectiveDate); + + response = given() + .log().ifValidationFails(LogDetail.ALL,true) + .accept(test.accept) + .queryParam(OFFICE, SPK) + .queryParam(enable, true) + .queryParam(EFFECTIVE_DATE, "2022-01-01T00:00:00Z") + .when() + .redirects().follow(true) + .redirects().max(3) + .get("/ratings/" + EXISTING_SPEC) + .then() + .assertThat() + .log().ifValidationFails(LogDetail.ALL,true) + .statusCode(is(HttpServletResponse.SC_OK)) + .contentType(is(test.expectedContentType)) + .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); + + response = given() + .log().ifValidationFails(LogDetail.ALL,true) + .accept(test.accept) + .queryParam(OFFICE, SPK) + .queryParam(enable, true) + .queryParam(EFFECTIVE_DATE, "2010-01-01T00:00:00-07:00") + .queryParam(START, "2000-01-01T00:00:00-07:00") // ignored parameter + .queryParam(END, "2020-01-01T00:00:00-07:00") // ignored parameter + .when() + .redirects().follow(true) + .redirects().max(3) + .get("/ratings/" + EXISTING_SPEC) + .then() + .log().ifValidationFails(LogDetail.ALL,true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + .contentType(is(test.expectedContentType)) + .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 @@ -169,13 +293,13 @@ enum GetOneTest JSONV2(Formats.JSONV2, Formats.JSONV2), ; - final String _accept; - final String _expectedContentType; + final String accept; + final String expectedContentType; GetOneTest(String accept, String expectedContentType) { - _accept = accept; - _expectedContentType = expectedContentType; + this.accept = accept; + this.expectedContentType = expectedContentType; } } @@ -185,13 +309,13 @@ enum GetAllLegacyTest XML(Formats.XML_LEGACY, Formats.XML), ; - final String _queryParam; - final String _expectedContentType; + final String queryParam; + final String expectedContentType; GetAllLegacyTest(String queryParam, String expectedContentType) { - _queryParam = queryParam; - _expectedContentType = expectedContentType; + this.queryParam = queryParam; + this.expectedContentType = expectedContentType; } } @@ -206,13 +330,13 @@ enum GetAllTest JSONV2(Formats.JSONV2, Formats.JSONV2), ; - final String _accept; - final String _expectedContentType; + final String accept; + final String expectedContentType; GetAllTest(String accept, String expectedContentType) { - _accept = accept; - _expectedContentType = expectedContentType; + this.accept = accept; + this.expectedContentType = expectedContentType; } } }