From 3bdb3683dd8bd852a281e14fc3e4382c1779835f Mon Sep 17 00:00:00 2001 From: zack-rma Date: Wed, 18 Dec 2024 14:16:17 -0800 Subject: [PATCH 1/5] Implemented ConfigResources Controller refactor, ConfigSensor mapping IN PROGRESS --- .../opendcs/odcsapi/res/ConfigResources.java | 267 +++++++++++++--- .../odcsapi/res/ConfigResourcesTest.java | 196 ++++++++++++ .../odcsapi/res/it/ConfigResourcesIT.java | 302 ++++++++++++++++++ 3 files changed, 719 insertions(+), 46 deletions(-) create mode 100644 opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/ConfigResourcesTest.java create mode 100644 opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java diff --git a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java index 67cc53ff6..d6d714190 100644 --- a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java +++ b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java @@ -15,9 +15,13 @@ package org.opendcs.odcsapi.res; -import java.sql.SQLException; -import java.util.logging.Logger; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; + import javax.annotation.security.RolesAllowed; +import javax.servlet.http.HttpServletResponse; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -30,19 +34,31 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import decodes.db.ConfigSensor; +import decodes.db.DatabaseException; +import decodes.db.DatabaseIO; +import decodes.db.DecodesScript; +import decodes.db.DecodesScriptException; +import decodes.db.EngineeringUnit; +import decodes.db.PlatformConfig; +import decodes.db.PlatformConfigList; +import decodes.db.Poly5Converter; +import decodes.db.ScriptSensor; +import decodes.db.UnitConverter; +import decodes.sql.DbKey; +import org.opendcs.odcsapi.beans.ApiConfigRef; import org.opendcs.odcsapi.beans.ApiConfigScript; import org.opendcs.odcsapi.beans.ApiConfigScriptSensor; +import org.opendcs.odcsapi.beans.ApiConfigSensor; import org.opendcs.odcsapi.beans.ApiPlatformConfig; -import org.opendcs.odcsapi.dao.ApiConfigDAO; +import org.opendcs.odcsapi.beans.ApiUnitConverter; import org.opendcs.odcsapi.dao.DbException; import org.opendcs.odcsapi.errorhandling.ErrorCodes; import org.opendcs.odcsapi.errorhandling.WebAppException; -import org.opendcs.odcsapi.hydrojson.DbInterface; import org.opendcs.odcsapi.util.ApiConstants; -import org.opendcs.odcsapi.util.ApiHttpUtil; @Path("/") -public class ConfigResources +public class ConfigResources extends OpenDcsResource { @Context HttpHeaders httpHeaders; @@ -52,79 +68,238 @@ public class ConfigResources @RolesAllowed({ApiConstants.ODCS_API_GUEST}) public Response getConfigRefs() throws DbException { - Logger.getLogger(ApiConstants.loggerName).fine("geConfigRefs"); - try (DbInterface dbi = new DbInterface(); - ApiConfigDAO configDAO = new ApiConfigDAO(dbi)) + try + { + DatabaseIO dbIo = getLegacyDatabase(); + PlatformConfigList configList = new PlatformConfigList(); + dbIo.readConfigList(configList); + return Response.status(HttpServletResponse.SC_OK).entity(map(configList)).build(); + } + catch (DatabaseException ex) { - return ApiHttpUtil.createResponse(configDAO.getConfigRefs()); + throw new DbException("Error reading config list", ex); } } + static List map(PlatformConfigList configList) + { + List configRefs = new ArrayList<>(); + for (PlatformConfig config : configList.values()) + { + ApiConfigRef configRef = new ApiConfigRef(); + if (config.getId() != null) + { + configRef.setConfigId(config.getId().getValue()); + } + else + { + configRef.setConfigId(DbKey.NullKey.getValue()); + } + configRef.setName(config.getName()); + configRef.setNumPlatforms(config.numPlatformsUsing); + configRef.setDescription(config.description); + configRefs.add(configRef); + } + return configRefs; + } + @GET @Path("config") @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({ApiConstants.ODCS_API_GUEST}) - public Response getConfig(@QueryParam("configid") Long configId) throws WebAppException, DbException, SQLException + public Response getConfig(@QueryParam("configid") Long configId) throws WebAppException, DbException { if (configId == null) - throw new WebAppException(ErrorCodes.MISSING_ID, - "Missing required configid parameter."); - - Logger.getLogger(ApiConstants.loggerName).fine("getConfig id=" + configId); - try (DbInterface dbi = new DbInterface(); - ApiConfigDAO configDAO = new ApiConfigDAO(dbi)) { - return ApiHttpUtil.createResponse(configDAO.getConfig(configId)); + throw new WebAppException(ErrorCodes.MISSING_ID, + "Missing required configid parameter."); + } + + try + { + DatabaseIO dbIo = getLegacyDatabase(); + PlatformConfig config = new PlatformConfig(); + config.setId(DbKey.createDbKey(configId)); + dbIo.readConfig(config); + return Response.status(HttpServletResponse.SC_OK).entity(map(config)).build(); + } + catch (DatabaseException ex) + { + throw new DbException("Error reading config", ex); } } + static ApiPlatformConfig map(PlatformConfig config) + { + ApiPlatformConfig apiConfig = new ApiPlatformConfig(); + if (config.getId() != null) + { + apiConfig.setConfigId(config.getId().getValue()); + } + else + { + apiConfig.setConfigId(DbKey.NullKey.getValue()); + } + apiConfig.setName(config.getName()); + apiConfig.setNumPlatforms(config.numPlatformsUsing); + apiConfig.setDescription(config.description); + return apiConfig; + } + @POST @Path("config") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({ApiConstants.ODCS_API_ADMIN, ApiConstants.ODCS_API_USER}) - public Response postConfig(ApiPlatformConfig config) throws WebAppException, DbException, SQLException + public Response postConfig(ApiPlatformConfig config) throws DbException + { + try + { + DatabaseIO dbIo = getLegacyDatabase(); + PlatformConfig pc = map(config); + dbIo.writeConfig(pc); + return Response.status(HttpServletResponse.SC_OK) + .entity(map(pc)) + .build(); + } + catch (DatabaseException ex) + { + throw new DbException("Error saving config", ex); + } + } + + static PlatformConfig map(ApiPlatformConfig config) throws DbException { - Logger.getLogger(ApiConstants.loggerName).fine("post config received config " + config.getName() - + " with ID=" + config.getConfigId()); - - Logger.getLogger(ApiConstants.loggerName).fine("POST config script sensors: "); - for(ApiConfigScript acs : config.getScripts()) - { - Logger.getLogger(ApiConstants.loggerName).fine("\tscript " + acs.getName()); - for(ApiConfigScriptSensor acss : acs.getScriptSensors()) + try + { + PlatformConfig pc = new PlatformConfig(config.getName()); + if (config.getConfigId() != null) + { + pc.setId(DbKey.createDbKey(config.getConfigId())); + } + else + { + pc.setId(DbKey.NullKey); + } + pc.description = config.getDescription(); + pc.numPlatformsUsing = config.getNumPlatforms(); + + pc.configName = config.getName(); + pc.decodesScripts = map(config.getScripts(), pc); + for (ApiConfigSensor sensor : config.getConfigSensors()) { - Logger.getLogger(ApiConstants.loggerName).fine("\t\t" + acss.prettyPrint()); + ConfigSensor configSensor = new ConfigSensor(null, sensor.getSensorNumber()); + configSensor.sensorName = sensor.getSensorName(); + configSensor.platformConfig = pc; + pc.addSensor(configSensor); } + + return pc; + } + catch (DatabaseException ex) + { + throw new DbException("Error mapping platform config", ex); + } + } + + static Vector map(List scripts, PlatformConfig config) throws DbException + { + if (scripts == null) + { + return new Vector<>(); + } + + try + { + Vector decodesScripts = new Vector<>(); + for(ApiConfigScript script : scripts) + { + DecodesScript.DecodesScriptBuilder dsb = DecodesScript.empty(); + dsb.platformConfig(config); + dsb.scriptName(script.getName()); + DecodesScript ds = dsb.build(); + for (ApiConfigScriptSensor sensor : script.getScriptSensors()) + { + ds.addScriptSensor(map(sensor)); + } + decodesScripts.add(ds); + } + return decodesScripts; + } + catch(DecodesScriptException | IOException ex) + { + throw new DbException("Error mapping scripts", ex); + } + } + + static ScriptSensor map(ApiConfigScriptSensor sensor) + { + ScriptSensor scriptSensor = new ScriptSensor(null, sensor.getSensorNumber()); + scriptSensor.execConverter = map(sensor.getUnitConverter()); + if (sensor.getUnitConverter().getUcId() != null) + { + scriptSensor.setUnitConverterId(DbKey.createDbKey(sensor.getUnitConverter().getUcId())); } - try (DbInterface dbi = new DbInterface(); - ApiConfigDAO configDAO = new ApiConfigDAO(dbi)) + else { - configDAO.writeConfig(config); - return ApiHttpUtil.createResponse(config); + scriptSensor.setUnitConverterId(DbKey.NullKey); } + return scriptSensor; + } + + static UnitConverter map(ApiUnitConverter unitConverter) + { + EngineeringUnit from = EngineeringUnit.getEngineeringUnit(unitConverter.getFromAbbr()); + EngineeringUnit to = EngineeringUnit.getEngineeringUnit(unitConverter.getToAbbr()); + Poly5Converter pc = new Poly5Converter(from, to); + double[] coeffs = new double[6]; + coeffs[0] = unitConverter.getA() != null ? unitConverter.getA() : 0.0; + coeffs[1] = unitConverter.getB() != null ? unitConverter.getB() : 0.0; + coeffs[2] = unitConverter.getC() != null ? unitConverter.getC() : 0.0; + coeffs[3] = unitConverter.getD() != null ? unitConverter.getD() : 0.0; + coeffs[4] = unitConverter.getE() != null ? unitConverter.getE() : 0.0; + coeffs[5] = unitConverter.getF() != null ? unitConverter.getF() : 0.0; + pc.setCoefficients(coeffs); + return pc; } - + + @DELETE @Path("config") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({ApiConstants.ODCS_API_ADMIN, ApiConstants.ODCS_API_USER}) - public Response deleteConfig(@QueryParam("configid") Long configId) throws WebAppException, DbException, SQLException + public Response deleteConfig(@QueryParam("configid") Long configId) throws DbException, WebAppException { - Logger.getLogger(ApiConstants.loggerName).fine("DELETE config received configid=" + configId); - - // Use username and password to attempt to connect to the database - try (DbInterface dbi = new DbInterface(); - ApiConfigDAO cfgDao = new ApiConfigDAO(dbi)) - { - if (cfgDao.numPlatformsUsing(configId) > 0) - return ApiHttpUtil.createResponse(" Cannot delete config with ID " + configId + " because it is used by one or more platforms.", ErrorCodes.NOT_ALLOWED); - - cfgDao.deleteConfig(configId); - return ApiHttpUtil.createResponse("Config with ID " + configId + " deleted"); + if (configId == null) + { + throw new WebAppException(HttpServletResponse.SC_BAD_REQUEST, + "Missing required configid parameter."); } - } + try + { + DatabaseIO dbIo = getLegacyDatabase(); + PlatformConfig pc = new PlatformConfig(); + pc.setId(DbKey.createDbKey(configId)); + dbIo.readConfig(pc); + + if (pc.numPlatformsUsing > 0) + { + return Response.status(HttpServletResponse.SC_METHOD_NOT_ALLOWED) + .entity(" Cannot delete config with ID " + + configId + " because it is used by one or more platforms.") + .build(); + } + dbIo.deleteConfig(pc); + return Response.status(HttpServletResponse.SC_OK) + .entity("Config with ID " + configId + " deleted") + .build(); + } + catch (DatabaseException ex) + { + throw new DbException("Error deleting config", ex); + } + } } diff --git a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/ConfigResourcesTest.java b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/ConfigResourcesTest.java new file mode 100644 index 000000000..ae0e31bc1 --- /dev/null +++ b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/ConfigResourcesTest.java @@ -0,0 +1,196 @@ +package org.opendcs.odcsapi.res; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Vector; + +import decodes.db.DecodesScript; +import decodes.db.PlatformConfig; +import decodes.db.PlatformConfigList; +import decodes.db.Poly5Converter; +import decodes.db.ScriptSensor; +import decodes.db.UnitConverter; +import decodes.sql.DbKey; +import org.junit.jupiter.api.Test; +import org.opendcs.odcsapi.beans.ApiConfigRef; +import org.opendcs.odcsapi.beans.ApiConfigScript; +import org.opendcs.odcsapi.beans.ApiConfigScriptSensor; +import org.opendcs.odcsapi.beans.ApiPlatformConfig; +import org.opendcs.odcsapi.beans.ApiUnitConverter; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.opendcs.odcsapi.res.ConfigResources.map; + +final class ConfigResourcesTest +{ + @Test + void testPlatformConfigListMap() throws Exception + { + PlatformConfigList pcl = new PlatformConfigList(); + PlatformConfig config = new PlatformConfig(); + config.numPlatformsUsing = 11; + config.configName = "Test config"; + config.description = "Platform description"; + config.setId(DbKey.createDbKey(5899L)); + pcl.add(config); + + List configRefs = map(pcl); + + assertNotNull(configRefs); + assertEquals(config.numPlatformsUsing, configRefs.get(0).getNumPlatforms()); + assertEquals(config.configName, configRefs.get(0).getName()); + assertEquals(config.description, configRefs.get(0).getDescription()); + assertEquals(config.getId().getValue(), configRefs.get(0).getConfigId()); + } + + @Test + void testPlatformConfigMap() throws Exception + { + PlatformConfig config = new PlatformConfig(); + config.numPlatformsUsing = 11; + config.configName = "Test config"; + config.description = "Platform description"; + config.setId(DbKey.createDbKey(5899L)); + + ApiPlatformConfig apiConfig = map(config); + + assertNotNull(apiConfig); + assertEquals(config.numPlatformsUsing, apiConfig.getNumPlatforms()); + assertEquals(config.configName, apiConfig.getName()); + assertEquals(config.description, apiConfig.getDescription()); + assertEquals(config.getId().getValue(), apiConfig.getConfigId()); + } + + @Test + void testApiPlatformConfigMap() throws Exception + { + ApiPlatformConfig apiConfig = new ApiPlatformConfig(); + apiConfig.setNumPlatforms(11); + apiConfig.setName("Test config"); + apiConfig.setDescription("Platform description"); + apiConfig.setScripts(scriptListBuilder()); + apiConfig.setConfigId(5899L); + + PlatformConfig config = map(apiConfig); + assertNotNull(config); + assertEquals(apiConfig.getNumPlatforms(), config.numPlatformsUsing); + assertEquals(apiConfig.getName(), config.configName); + assertEquals(apiConfig.getDescription(), config.description); + assertEquals(apiConfig.getConfigId(), config.getId().getValue()); + for (Iterator scriptName = config.getScripts(); scriptName.hasNext(); ) + { + DecodesScript script = scriptName.next(); + assertEquals(apiConfig.getScripts().get(0).getName(), script.scriptName); + for (ScriptSensor sensor : script.scriptSensors) + { + assertEquals(apiConfig.getScripts().get(0).getScriptSensors().get(0).getSensorNumber(), sensor.sensorNumber); + assertMatch(apiConfig.getScripts().get(0).getScriptSensors().get(0).getUnitConverter(), (Poly5Converter) sensor.execConverter); + } + } + } + + @Test + void testApiConfigScriptMap() throws Exception + { + List scripts = scriptListBuilder(); + + Vector decodesScripts = map(scripts, new PlatformConfig()); + + assertNotNull(decodesScripts); + assertEquals(scripts.size(), decodesScripts.size()); + assertEquals(scripts.get(0).getName(), decodesScripts.get(0).scriptName); + for (ScriptSensor sensor : decodesScripts.get(0).scriptSensors) + { + assertEquals(scripts.get(0).getScriptSensors().get(0).getSensorNumber(), sensor.sensorNumber); + assertMatch(scripts.get(0).getScriptSensors().get(0).getUnitConverter(), (Poly5Converter) sensor.execConverter); + } + } + + @Test + void testApiConfigScriptSensorMap() + { + ApiConfigScriptSensor sensor = new ApiConfigScriptSensor(); + sensor.setSensorNumber(1); + ApiUnitConverter unitConverter = new ApiUnitConverter(); + unitConverter.setUcId(1234L); + unitConverter.setAlgorithm("None"); + unitConverter.setFromAbbr("ft"); + unitConverter.setToAbbr("m"); + unitConverter.setA(1.0); + unitConverter.setB(2.0); + unitConverter.setC(3.0); + unitConverter.setD(4.0); + unitConverter.setE(5.0); + unitConverter.setF(6.0); + sensor.setUnitConverter(unitConverter); + + ScriptSensor decodesSensor = map(sensor); + + assertNotNull(decodesSensor); + assertEquals(sensor.getSensorNumber(), decodesSensor.sensorNumber); + assertMatch(sensor.getUnitConverter(), (Poly5Converter) decodesSensor.execConverter); + } + + @Test + void testApiUnitConverterMap() throws Exception + { + ApiUnitConverter unitConverter = new ApiUnitConverter(); + unitConverter.setUcId(1234L); + unitConverter.setAlgorithm("None"); + unitConverter.setFromAbbr("ft"); + unitConverter.setToAbbr("m"); + unitConverter.setA(1.0); + unitConverter.setB(2.0); + unitConverter.setC(3.0); + unitConverter.setD(4.0); + unitConverter.setE(5.0); + unitConverter.setF(6.0); + + UnitConverter decodesUc = map(unitConverter); + + assertNotNull(decodesUc); + assertEquals(unitConverter.getFromAbbr(), decodesUc.getFromAbbr()); + assertEquals(unitConverter.getToAbbr(), decodesUc.getToAbbr()); + assertEquals(3545706.0, decodesUc.convert(20.0)); + } + + private static void assertMatch(ApiUnitConverter apiUc, Poly5Converter decodesUc) + { + assertEquals(apiUc.getFromAbbr(), decodesUc.getFromAbbr()); + assertEquals(apiUc.getToAbbr(), decodesUc.getToAbbr()); + assertEquals(123456.0, decodesUc.convert(10.0)); + } + + private static ArrayList scriptListBuilder() + { + ArrayList configScriptList = new ArrayList<>(); + ApiConfigScript script = new ApiConfigScript(); + script.setName("Test script"); + script.setScriptSensors(buildScriptSensorList()); + configScriptList.add(script); + return configScriptList; + } + + private static ArrayList buildScriptSensorList() + { + ArrayList scriptSensorList = new ArrayList<>(); + ApiConfigScriptSensor scriptSensor = new ApiConfigScriptSensor(); + scriptSensor.setSensorNumber(1); + ApiUnitConverter unitConverter = new ApiUnitConverter(); + unitConverter.setUcId(1234L); + unitConverter.setAlgorithm("None"); + unitConverter.setFromAbbr("ft"); + unitConverter.setToAbbr("m"); + unitConverter.setA(1.0); + unitConverter.setB(2.0); + unitConverter.setC(3.0); + unitConverter.setD(4.0); + unitConverter.setE(5.0); + unitConverter.setF(6.0); + scriptSensor.setUnitConverter(unitConverter); + scriptSensorList.add(scriptSensor); + return scriptSensorList; + } +} diff --git a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java new file mode 100644 index 000000000..f1d8dea4f --- /dev/null +++ b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java @@ -0,0 +1,302 @@ +package org.opendcs.odcsapi.res.it; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Properties; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.core.MediaType; + +import com.fasterxml.jackson.databind.ObjectMapper; +import decodes.sql.DbKey; +import io.restassured.filter.log.LogDetail; +import io.restassured.filter.session.SessionFilter; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.TestTemplate; +import org.junit.jupiter.api.extension.ExtendWith; +import org.opendcs.odcsapi.beans.ApiConfigScript; +import org.opendcs.odcsapi.beans.ApiConfigScriptSensor; +import org.opendcs.odcsapi.beans.ApiConfigSensor; +import org.opendcs.odcsapi.beans.ApiPlatformConfig; +import org.opendcs.odcsapi.beans.ApiUnitConverter; +import org.opendcs.odcsapi.fixtures.DatabaseContextProvider; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +@Tag("integration") +@ExtendWith(DatabaseContextProvider.class) +final class ConfigResourcesIT extends BaseIT +{ + private static SessionFilter sessionFilter; + private static Long configId; + private static final ObjectMapper mapper = new ObjectMapper(); + + @BeforeEach + void setUp() throws Exception + { + setUpCreds(); + sessionFilter = new SessionFilter(); + + authenticate(sessionFilter); + + ApiPlatformConfig config = new ApiPlatformConfig(); + config.setDescription("Test Platform"); + config.setNumPlatforms(1); + config.setName("Test Platform"); + ArrayList sensors = new ArrayList<>(); + ApiConfigSensor sensor = new ApiConfigSensor(); + sensor.setSensorName("Test Sensor"); + sensor.setAbsoluteMax(100.0); + sensor.setAbsoluteMin(0.0); + sensor.setRecordingInterval(900); + sensor.setTimeOfFirstSample(0); + Properties properties = new Properties(); + properties.setProperty("site", "Test Site"); + sensor.setProperties(properties); + HashMap dataTypes = new HashMap<>(); + dataTypes.put("Test Type", "Test Units"); + sensor.setDataTypes(dataTypes); + sensors.add(sensor); + config.setConfigSensors(sensors); + ArrayList scripts = new ArrayList<>(); + ApiConfigScript script = new ApiConfigScript(); + script.setName("Test Script"); + ArrayList scriptSensors = new ArrayList<>(); + ApiConfigScriptSensor scriptSensor = new ApiConfigScriptSensor(); + // TODO: Tie this into the unit converter endpoint. Causes NPE if converter with ID is not in DB + ApiUnitConverter unitConverter = new ApiUnitConverter(); + unitConverter.setAlgorithm("x * 100 + 32"); + unitConverter.setFromAbbr("C"); + unitConverter.setToAbbr("F"); + unitConverter.setA(100.0); + unitConverter.setB(32.0); + Long convId = storeConverter(unitConverter); + unitConverter.setUcId(convId); + scriptSensor.setUnitConverter(unitConverter); + scriptSensors.add(scriptSensor); + script.setScriptSensors(scriptSensors); + scripts.add(script); + config.setScripts(scripts); + + String configJson = mapper.writeValueAsString(config); + + ExtractableResponse response = given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .body(configJson) + .when() + .redirects().follow(true) + .redirects().max(3) + .post("config") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + .extract() + ; + + configId = response.body().jsonPath().getLong("configId"); + } + + @AfterEach + void tearDown() + { + given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .queryParam("configid", configId) + .when() + .redirects().follow(true) + .redirects().max(3) + .delete("config") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + ; + + logout(sessionFilter); + } + + @TestTemplate + void testGetConfigRefs() + { + given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .when() + .redirects().follow(true) + .redirects().max(3) + .get("configrefs") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + ; + } + + @TestTemplate + void testGetConfig() + { + given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .queryParam("configid", configId) + .when() + .redirects().follow(true) + .redirects().max(3) + .get("config") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + ; + } + + @TestTemplate + void testPostAndDeleteConfig() throws Exception + { + ApiPlatformConfig config = new ApiPlatformConfig(); + config.setDescription("Test Platform 1"); + config.setNumPlatforms(1); + config.setName("Test Platform 2"); + ArrayList sensors = new ArrayList<>(); + ApiConfigSensor sensor = new ApiConfigSensor(); + sensor.setSensorName("Test Sensor 1"); + sensor.setAbsoluteMax(120.0); + sensor.setAbsoluteMin(2.0); + sensor.setRecordingInterval(90); + sensor.setTimeOfFirstSample(10000000); + Properties properties = new Properties(); + properties.setProperty("site", "Test Site 1"); + sensor.setProperties(properties); + HashMap dataTypes = new HashMap<>(); + dataTypes.put("Test Type", "Test Units 1"); + sensor.setDataTypes(dataTypes); + sensors.add(sensor); + config.setConfigSensors(sensors); + ArrayList scripts = new ArrayList<>(); + ApiConfigScript script = new ApiConfigScript(); + script.setName("Test Script"); + ArrayList scriptSensors = new ArrayList<>(); + // TODO: Tie this into the unit converter endpoint. Causes NPE if converter with ID is not in DB + ApiConfigScriptSensor scriptSensor = new ApiConfigScriptSensor(); + ApiUnitConverter unitConverter = new ApiUnitConverter(); + unitConverter.setAlgorithm("x * A"); + unitConverter.setFromAbbr("m"); + unitConverter.setToAbbr("ft"); + unitConverter.setA(3.28084); + Long convId = storeConverter(unitConverter); + unitConverter.setUcId(convId); + scriptSensor.setUnitConverter(unitConverter); + scriptSensor.setSensorNumber(convId.intValue()); + scriptSensors.add(scriptSensor); + script.setScriptSensors(scriptSensors); + scripts.add(script); + config.setScripts(scripts); + + String configJson = mapper.writeValueAsString(config); + + ExtractableResponse response = given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .body(configJson) + .when() + .redirects().follow(true) + .redirects().max(3) + .post("config") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + .extract() + ; + + Long newConfigId = response.body().jsonPath().getLong("configId"); + + given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .queryParam("configid", newConfigId) + .when() + .redirects().follow(true) + .redirects().max(3) + .delete("config") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + ; + } + + private Long storeConverter(ApiUnitConverter unitConverter) throws Exception + { + String converterJson = mapper.writeValueAsString(unitConverter); + + given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .body(converterJson) + .when() + .redirects().follow(true) + .redirects().max(3) + .post("euconv") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + ; + + ExtractableResponse response = given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .when() + .redirects().follow(true) + .redirects().max(3) + .get("euconvlist") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + .extract() + ; + + for (int i = 0; i < response.body().jsonPath().getList("").size(); i++) + { + if (response.body().jsonPath().getString("[" + i + "].fromAbbr").equals(unitConverter.getFromAbbr()) + && response.body().jsonPath().getString("[" + i + "].toAbbr").equals(unitConverter.getToAbbr())) + { + return response.body().jsonPath().getLong("[" + i + "].ucId"); + } + } + + return DbKey.NullKey.getValue(); + } +} From 4d9aaea9da55ebe18068c9b7a165fa98281431d3 Mon Sep 17 00:00:00 2001 From: zack-rma Date: Mon, 30 Dec 2024 16:41:12 -0800 Subject: [PATCH 2/5] Updated IT, fixed mapping bugs --- .../opendcs/odcsapi/res/ConfigResources.java | 28 +++++++-- .../odcsapi/res/ConfigResourcesTest.java | 34 ++++++++++- .../odcsapi/res/it/ConfigResourcesIT.java | 57 ------------------- 3 files changed, 57 insertions(+), 62 deletions(-) diff --git a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java index d6d714190..384fae72e 100644 --- a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java +++ b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java @@ -45,6 +45,7 @@ import decodes.db.Poly5Converter; import decodes.db.ScriptSensor; import decodes.db.UnitConverter; +import decodes.db.UnitConverterDb; import decodes.sql.DbKey; import org.opendcs.odcsapi.beans.ApiConfigRef; import org.opendcs.odcsapi.beans.ApiConfigScript; @@ -226,16 +227,30 @@ static Vector map(List scripts, PlatformConfig c } return decodesScripts; } - catch(DecodesScriptException | IOException ex) + catch(DecodesScriptException | IOException | DatabaseException ex) { throw new DbException("Error mapping scripts", ex); } } - static ScriptSensor map(ApiConfigScriptSensor sensor) + static ScriptSensor map(ApiConfigScriptSensor sensor) throws DatabaseException { ScriptSensor scriptSensor = new ScriptSensor(null, sensor.getSensorNumber()); scriptSensor.execConverter = map(sensor.getUnitConverter()); + UnitConverterDb rawConv = new UnitConverterDb(sensor.getUnitConverter().getFromAbbr(), + sensor.getUnitConverter().getToAbbr()); + rawConv.algorithm = sensor.getUnitConverter().getAlgorithm(); + if (sensor.getUnitConverter().getUcId() != null) + { + rawConv.setId(DbKey.createDbKey(sensor.getUnitConverter().getUcId())); + } + else + { + rawConv.setId(DbKey.NullKey); + } + ApiUnitConverter uc = sensor.getUnitConverter(); + rawConv.coefficients = coefficientMap(uc); + scriptSensor.rawConverter = rawConv; if (sensor.getUnitConverter().getUcId() != null) { scriptSensor.setUnitConverterId(DbKey.createDbKey(sensor.getUnitConverter().getUcId())); @@ -252,6 +267,12 @@ static UnitConverter map(ApiUnitConverter unitConverter) EngineeringUnit from = EngineeringUnit.getEngineeringUnit(unitConverter.getFromAbbr()); EngineeringUnit to = EngineeringUnit.getEngineeringUnit(unitConverter.getToAbbr()); Poly5Converter pc = new Poly5Converter(from, to); + pc.setCoefficients(coefficientMap(unitConverter)); + return pc; + } + + static double[] coefficientMap(ApiUnitConverter unitConverter) + { double[] coeffs = new double[6]; coeffs[0] = unitConverter.getA() != null ? unitConverter.getA() : 0.0; coeffs[1] = unitConverter.getB() != null ? unitConverter.getB() : 0.0; @@ -259,8 +280,7 @@ static UnitConverter map(ApiUnitConverter unitConverter) coeffs[3] = unitConverter.getD() != null ? unitConverter.getD() : 0.0; coeffs[4] = unitConverter.getE() != null ? unitConverter.getE() : 0.0; coeffs[5] = unitConverter.getF() != null ? unitConverter.getF() : 0.0; - pc.setCoefficients(coeffs); - return pc; + return coeffs; } diff --git a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/ConfigResourcesTest.java b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/ConfigResourcesTest.java index ae0e31bc1..59507194c 100644 --- a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/ConfigResourcesTest.java +++ b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/ConfigResourcesTest.java @@ -21,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.opendcs.odcsapi.res.ConfigResources.coefficientMap; import static org.opendcs.odcsapi.res.ConfigResources.map; final class ConfigResourcesTest @@ -109,7 +110,7 @@ void testApiConfigScriptMap() throws Exception } @Test - void testApiConfigScriptSensorMap() + void testApiConfigScriptSensorMap() throws Exception { ApiConfigScriptSensor sensor = new ApiConfigScriptSensor(); sensor.setSensorNumber(1); @@ -131,6 +132,16 @@ void testApiConfigScriptSensorMap() assertNotNull(decodesSensor); assertEquals(sensor.getSensorNumber(), decodesSensor.sensorNumber); assertMatch(sensor.getUnitConverter(), (Poly5Converter) decodesSensor.execConverter); + assertEquals(sensor.getUnitConverter().getFromAbbr(), decodesSensor.rawConverter.fromAbbr); + assertEquals(sensor.getUnitConverter().getToAbbr(), decodesSensor.rawConverter.toAbbr); + assertEquals(sensor.getUnitConverter().getA(), decodesSensor.rawConverter.coefficients[0]); + assertEquals(sensor.getUnitConverter().getB(), decodesSensor.rawConverter.coefficients[1]); + assertEquals(sensor.getUnitConverter().getC(), decodesSensor.rawConverter.coefficients[2]); + assertEquals(sensor.getUnitConverter().getD(), decodesSensor.rawConverter.coefficients[3]); + assertEquals(sensor.getUnitConverter().getE(), decodesSensor.rawConverter.coefficients[4]); + assertEquals(sensor.getUnitConverter().getF(), decodesSensor.rawConverter.coefficients[5]); + assertEquals(sensor.getUnitConverter().getUcId(), decodesSensor.rawConverter.getId().getValue()); + assertEquals(sensor.getUnitConverter().getAlgorithm(), decodesSensor.rawConverter.algorithm); } @Test @@ -156,6 +167,27 @@ void testApiUnitConverterMap() throws Exception assertEquals(3545706.0, decodesUc.convert(20.0)); } + @Test + void testCoefficientMap() + { + ApiUnitConverter unitConverter = new ApiUnitConverter(); + unitConverter.setA(1.0); + unitConverter.setB(2.0); + unitConverter.setC(3.0); + unitConverter.setD(4.0); + unitConverter.setE(5.0); + unitConverter.setF(6.0); + + double[] coefficients = coefficientMap(unitConverter); + + assertEquals(unitConverter.getA(), coefficients[0]); + assertEquals(unitConverter.getB(), coefficients[1]); + assertEquals(unitConverter.getC(), coefficients[2]); + assertEquals(unitConverter.getD(), coefficients[3]); + assertEquals(unitConverter.getE(), coefficients[4]); + assertEquals(unitConverter.getF(), coefficients[5]); + } + private static void assertMatch(ApiUnitConverter apiUc, Poly5Converter decodesUc) { assertEquals(apiUc.getFromAbbr(), decodesUc.getFromAbbr()); diff --git a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java index f1d8dea4f..0bc765413 100644 --- a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java +++ b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java @@ -7,7 +7,6 @@ import javax.ws.rs.core.MediaType; import com.fasterxml.jackson.databind.ObjectMapper; -import decodes.sql.DbKey; import io.restassured.filter.log.LogDetail; import io.restassured.filter.session.SessionFilter; import io.restassured.response.ExtractableResponse; @@ -67,15 +66,12 @@ void setUp() throws Exception script.setName("Test Script"); ArrayList scriptSensors = new ArrayList<>(); ApiConfigScriptSensor scriptSensor = new ApiConfigScriptSensor(); - // TODO: Tie this into the unit converter endpoint. Causes NPE if converter with ID is not in DB ApiUnitConverter unitConverter = new ApiUnitConverter(); unitConverter.setAlgorithm("x * 100 + 32"); unitConverter.setFromAbbr("C"); unitConverter.setToAbbr("F"); unitConverter.setA(100.0); unitConverter.setB(32.0); - Long convId = storeConverter(unitConverter); - unitConverter.setUcId(convId); scriptSensor.setUnitConverter(unitConverter); scriptSensors.add(scriptSensor); script.setScriptSensors(scriptSensors); @@ -195,17 +191,13 @@ void testPostAndDeleteConfig() throws Exception ApiConfigScript script = new ApiConfigScript(); script.setName("Test Script"); ArrayList scriptSensors = new ArrayList<>(); - // TODO: Tie this into the unit converter endpoint. Causes NPE if converter with ID is not in DB ApiConfigScriptSensor scriptSensor = new ApiConfigScriptSensor(); ApiUnitConverter unitConverter = new ApiUnitConverter(); unitConverter.setAlgorithm("x * A"); unitConverter.setFromAbbr("m"); unitConverter.setToAbbr("ft"); unitConverter.setA(3.28084); - Long convId = storeConverter(unitConverter); - unitConverter.setUcId(convId); scriptSensor.setUnitConverter(unitConverter); - scriptSensor.setSensorNumber(convId.intValue()); scriptSensors.add(scriptSensor); script.setScriptSensors(scriptSensors); scripts.add(script); @@ -250,53 +242,4 @@ void testPostAndDeleteConfig() throws Exception .statusCode(is(HttpServletResponse.SC_OK)) ; } - - private Long storeConverter(ApiUnitConverter unitConverter) throws Exception - { - String converterJson = mapper.writeValueAsString(unitConverter); - - given() - .log().ifValidationFails(LogDetail.ALL, true) - .accept(MediaType.APPLICATION_JSON) - .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", authHeader) - .filter(sessionFilter) - .body(converterJson) - .when() - .redirects().follow(true) - .redirects().max(3) - .post("euconv") - .then() - .log().ifValidationFails(LogDetail.ALL, true) - .assertThat() - .statusCode(is(HttpServletResponse.SC_OK)) - ; - - ExtractableResponse response = given() - .log().ifValidationFails(LogDetail.ALL, true) - .accept(MediaType.APPLICATION_JSON) - .header("Authorization", authHeader) - .filter(sessionFilter) - .when() - .redirects().follow(true) - .redirects().max(3) - .get("euconvlist") - .then() - .log().ifValidationFails(LogDetail.ALL, true) - .assertThat() - .statusCode(is(HttpServletResponse.SC_OK)) - .extract() - ; - - for (int i = 0; i < response.body().jsonPath().getList("").size(); i++) - { - if (response.body().jsonPath().getString("[" + i + "].fromAbbr").equals(unitConverter.getFromAbbr()) - && response.body().jsonPath().getString("[" + i + "].toAbbr").equals(unitConverter.getToAbbr())) - { - return response.body().jsonPath().getLong("[" + i + "].ucId"); - } - } - - return DbKey.NullKey.getValue(); - } } From 71c1bcc92f6891d2e59144b4e8a0334ba37464c4 Mon Sep 17 00:00:00 2001 From: zack-rma Date: Tue, 31 Dec 2024 16:23:43 -0800 Subject: [PATCH 3/5] Added TODO item for broken method implementation --- .../src/main/java/org/opendcs/odcsapi/res/ConfigResources.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java index 384fae72e..3f838b459 100644 --- a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java +++ b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java @@ -121,7 +121,7 @@ public Response getConfig(@QueryParam("configid") Long configId) throws WebAppEx DatabaseIO dbIo = getLegacyDatabase(); PlatformConfig config = new PlatformConfig(); config.setId(DbKey.createDbKey(configId)); - dbIo.readConfig(config); + dbIo.readConfig(config); // TODO: This method does not return any data. Investigate why. return Response.status(HttpServletResponse.SC_OK).entity(map(config)).build(); } catch (DatabaseException ex) From f64939117ace8d0ee153b6b4b73a6e2e53055661 Mon Sep 17 00:00:00 2001 From: zack-rma Date: Tue, 31 Dec 2024 16:24:50 -0800 Subject: [PATCH 4/5] Initial IT, bug in retrieval discovered - IN PROGRESS --- .../odcsapi/res/it/ConfigResourcesIT.java | 126 ++++++------------ .../res/it/OPEN_TSDB/config_get_expected.json | 48 +++++++ .../res/it/OPEN_TSDB/config_input_data.json | 47 +++++++ .../config_post_delete_expected.json | 49 +++++++ .../config_post_delete_input_data.json | 49 +++++++ .../it/OPEN_TSDB/config_refs_expected.json | 8 ++ 6 files changed, 244 insertions(+), 83 deletions(-) create mode 100644 opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_get_expected.json create mode 100644 opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_input_data.json create mode 100644 opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_expected.json create mode 100644 opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_input_data.json create mode 100644 opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_refs_expected.json diff --git a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java index 0bc765413..93c0a2bb9 100644 --- a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java +++ b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java @@ -1,14 +1,11 @@ package org.opendcs.odcsapi.res.it; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Properties; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.core.MediaType; -import com.fasterxml.jackson.databind.ObjectMapper; import io.restassured.filter.log.LogDetail; import io.restassured.filter.session.SessionFilter; +import io.restassured.path.json.JsonPath; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; import org.junit.jupiter.api.AfterEach; @@ -16,14 +13,10 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; -import org.opendcs.odcsapi.beans.ApiConfigScript; -import org.opendcs.odcsapi.beans.ApiConfigScriptSensor; -import org.opendcs.odcsapi.beans.ApiConfigSensor; -import org.opendcs.odcsapi.beans.ApiPlatformConfig; -import org.opendcs.odcsapi.beans.ApiUnitConverter; import org.opendcs.odcsapi.fixtures.DatabaseContextProvider; import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; @Tag("integration") @@ -32,7 +25,6 @@ final class ConfigResourcesIT extends BaseIT { private static SessionFilter sessionFilter; private static Long configId; - private static final ObjectMapper mapper = new ObjectMapper(); @BeforeEach void setUp() throws Exception @@ -42,43 +34,7 @@ void setUp() throws Exception authenticate(sessionFilter); - ApiPlatformConfig config = new ApiPlatformConfig(); - config.setDescription("Test Platform"); - config.setNumPlatforms(1); - config.setName("Test Platform"); - ArrayList sensors = new ArrayList<>(); - ApiConfigSensor sensor = new ApiConfigSensor(); - sensor.setSensorName("Test Sensor"); - sensor.setAbsoluteMax(100.0); - sensor.setAbsoluteMin(0.0); - sensor.setRecordingInterval(900); - sensor.setTimeOfFirstSample(0); - Properties properties = new Properties(); - properties.setProperty("site", "Test Site"); - sensor.setProperties(properties); - HashMap dataTypes = new HashMap<>(); - dataTypes.put("Test Type", "Test Units"); - sensor.setDataTypes(dataTypes); - sensors.add(sensor); - config.setConfigSensors(sensors); - ArrayList scripts = new ArrayList<>(); - ApiConfigScript script = new ApiConfigScript(); - script.setName("Test Script"); - ArrayList scriptSensors = new ArrayList<>(); - ApiConfigScriptSensor scriptSensor = new ApiConfigScriptSensor(); - ApiUnitConverter unitConverter = new ApiUnitConverter(); - unitConverter.setAlgorithm("x * 100 + 32"); - unitConverter.setFromAbbr("C"); - unitConverter.setToAbbr("F"); - unitConverter.setA(100.0); - unitConverter.setB(32.0); - scriptSensor.setUnitConverter(unitConverter); - scriptSensors.add(scriptSensor); - script.setScriptSensors(scriptSensors); - scripts.add(script); - config.setScripts(scripts); - - String configJson = mapper.writeValueAsString(config); + String configJson = getJsonFromResource("config_input_data.json"); ExtractableResponse response = given() .log().ifValidationFails(LogDetail.ALL, true) @@ -127,6 +83,8 @@ void tearDown() @TestTemplate void testGetConfigRefs() { + JsonPath expected = getJsonPathFromResource("config_refs_expected.json"); + given() .log().ifValidationFails(LogDetail.ALL, true) .accept(MediaType.APPLICATION_JSON) @@ -141,12 +99,17 @@ void testGetConfigRefs() .log().ifValidationFails(LogDetail.ALL, true) .assertThat() .statusCode(is(HttpServletResponse.SC_OK)) + .body("[0].name", equalTo(expected.getString("[0].name"))) + .body("[0].description", equalTo(expected.getString("[0].description"))) + .body("[0].numPlatforms", equalTo(expected.getInt("[0].numPlatforms"))) ; } @TestTemplate void testGetConfig() { + JsonPath expected = getJsonPathFromResource("config_get_expected.json"); + given() .log().ifValidationFails(LogDetail.ALL, true) .accept(MediaType.APPLICATION_JSON) @@ -162,48 +125,19 @@ void testGetConfig() .log().ifValidationFails(LogDetail.ALL, true) .assertThat() .statusCode(is(HttpServletResponse.SC_OK)) + .body("name", equalTo(expected.getString("name"))) + .body("description", equalTo(expected.getString("description"))) + .body("numPlatforms", equalTo(expected.getLong("numPlatforms"))) + .body("scripts.size()", equalTo(expected.getString("scripts.size()"))) + .body("configSensors.size()", equalTo(expected.getString("configSensors.size()"))) + // TODO: Add script and configSensor assertions ; } @TestTemplate void testPostAndDeleteConfig() throws Exception { - ApiPlatformConfig config = new ApiPlatformConfig(); - config.setDescription("Test Platform 1"); - config.setNumPlatforms(1); - config.setName("Test Platform 2"); - ArrayList sensors = new ArrayList<>(); - ApiConfigSensor sensor = new ApiConfigSensor(); - sensor.setSensorName("Test Sensor 1"); - sensor.setAbsoluteMax(120.0); - sensor.setAbsoluteMin(2.0); - sensor.setRecordingInterval(90); - sensor.setTimeOfFirstSample(10000000); - Properties properties = new Properties(); - properties.setProperty("site", "Test Site 1"); - sensor.setProperties(properties); - HashMap dataTypes = new HashMap<>(); - dataTypes.put("Test Type", "Test Units 1"); - sensor.setDataTypes(dataTypes); - sensors.add(sensor); - config.setConfigSensors(sensors); - ArrayList scripts = new ArrayList<>(); - ApiConfigScript script = new ApiConfigScript(); - script.setName("Test Script"); - ArrayList scriptSensors = new ArrayList<>(); - ApiConfigScriptSensor scriptSensor = new ApiConfigScriptSensor(); - ApiUnitConverter unitConverter = new ApiUnitConverter(); - unitConverter.setAlgorithm("x * A"); - unitConverter.setFromAbbr("m"); - unitConverter.setToAbbr("ft"); - unitConverter.setA(3.28084); - scriptSensor.setUnitConverter(unitConverter); - scriptSensors.add(scriptSensor); - script.setScriptSensors(scriptSensors); - scripts.add(script); - config.setScripts(scripts); - - String configJson = mapper.writeValueAsString(config); + String configJson = getJsonFromResource("config_post_delete_input_data.json"); ExtractableResponse response = given() .log().ifValidationFails(LogDetail.ALL, true) @@ -225,6 +159,32 @@ void testPostAndDeleteConfig() throws Exception Long newConfigId = response.body().jsonPath().getLong("configId"); + JsonPath expected = getJsonPathFromResource("config_post_delete_expected.json"); + + // Get the config and assert it matches expected JSON + given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .queryParam("configid", newConfigId) + .when() + .redirects().follow(true) + .redirects().max(3) + .get("config") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + .body("name", equalTo(expected.getString("name"))) + .body("description", equalTo(expected.getString("description"))) + .body("numPlatforms", equalTo(expected.getLong("numPlatforms"))) + .body("scripts.size()", equalTo(expected.getString("scripts.size()"))) + .body("configSensors.size()", equalTo(expected.getString("configSensors.size()"))) + // TODO: Add script and configSensor assertions + ; + given() .log().ifValidationFails(LogDetail.ALL, true) .accept(MediaType.APPLICATION_JSON) diff --git a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_get_expected.json b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_get_expected.json new file mode 100644 index 000000000..846cff23a --- /dev/null +++ b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_get_expected.json @@ -0,0 +1,48 @@ +{ + "configId": 4, + "name": "Test Platform", + "numPlatforms": 1, + "description": "Test Platform", + "configSensors": [ + { + "sensorNumber" : 0, + "sensorName" : "Test Sensor", + "recordingMode" : "U", + "recordingInterval" : 900, + "timeOfFirstSample" : 0, + "absoluteMin" : 0.0, + "absoluteMax" : 100.0, + "properties" : { + "site" : "Test Site" + }, + "dataTypes" : { + "Test Type" : "Test Units" + }, + "usgsStatCode" : null + } + ], + "scripts": [ + { + "name" : "Test Script", + "dataOrder" : "U", + "headerType" : null, + "scriptSensors" : [ { + "sensorNumber" : 0, + "unitConverter" : { + "ucId" : null, + "fromAbbr" : "C", + "toAbbr" : "F", + "algorithm" : "x * 100 + 32", + "a" : 100.0, + "b" : 32.0, + "c" : null, + "d" : null, + "e" : null, + "f" : null + } + } + ], + "formatStatements" : [ ] + } + ] +} \ No newline at end of file diff --git a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_input_data.json b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_input_data.json new file mode 100644 index 000000000..5beadca60 --- /dev/null +++ b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_input_data.json @@ -0,0 +1,47 @@ +{ + "configId" : null, + "name" : "Test Platform", + "numPlatforms" : 1, + "description" : "Test Platform", + "configSensors" : [ + { + "sensorNumber" : 0, + "sensorName" : "Test Sensor", + "recordingMode" : "U", + "recordingInterval" : 900, + "timeOfFirstSample" : 0, + "absoluteMin" : 0.0, + "absoluteMax" : 100.0, + "properties" : { + "site" : "Test Site" + }, + "dataTypes" : { + "Test Type" : "Test Units" + }, + "usgsStatCode" : null + } + ], + "scripts" : [ + { + "name" : "Test Script", + "dataOrder" : "U", + "headerType" : null, + "scriptSensors" : [ { + "sensorNumber" : 0, + "unitConverter" : { + "ucId" : null, + "fromAbbr" : "C", + "toAbbr" : "F", + "algorithm" : "x * 100 + 32", + "a" : 100.0, + "b" : 32.0, + "c" : null, + "d" : null, + "e" : null, + "f" : null + } + } + ], + "formatStatements" : [ ] + } ] +} \ No newline at end of file diff --git a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_expected.json b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_expected.json new file mode 100644 index 000000000..c3d6acfe4 --- /dev/null +++ b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_expected.json @@ -0,0 +1,49 @@ +{ + "configId": 3, + "name": "Test Platform 2", + "numPlatforms": 1, + "description": "Test Platform 1", + "configSensors": [ + { + "sensorNumber" : 0, + "sensorName" : "Test Sensor 1", + "recordingMode" : "U", + "recordingInterval" : 90, + "timeOfFirstSample" : 10000000, + "absoluteMin" : 2.0, + "absoluteMax" : 120.0, + "properties" : { + "site" : "Test Site 1" + }, + "dataTypes" : { + "Test Type" : "Test Units 1" + }, + "usgsStatCode" : null + } + ], + "scripts": [ + { + "name" : "Test Script", + "dataOrder" : "U", + "headerType" : null, + "scriptSensors" : [ + { + "sensorNumber" : 0, + "unitConverter" : { + "ucId" : null, + "fromAbbr" : "m", + "toAbbr" : "ft", + "algorithm" : "x * A", + "a" : 3.28084, + "b" : null, + "c" : null, + "d" : null, + "e" : null, + "f" : null + } + } + ], + "formatStatements" : [ ] + } + ] +} \ No newline at end of file diff --git a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_input_data.json b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_input_data.json new file mode 100644 index 000000000..de174b932 --- /dev/null +++ b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_input_data.json @@ -0,0 +1,49 @@ +{ + "configId" : null, + "name" : "Test Platform 2", + "numPlatforms" : 1, + "description" : "Test Platform 1", + "configSensors" : [ + { + "sensorNumber" : 0, + "sensorName" : "Test Sensor 1", + "recordingMode" : "U", + "recordingInterval" : 90, + "timeOfFirstSample" : 10000000, + "absoluteMin" : 2.0, + "absoluteMax" : 120.0, + "properties" : { + "site" : "Test Site 1" + }, + "dataTypes" : { + "Test Type" : "Test Units 1" + }, + "usgsStatCode" : null + } + ], + "scripts" : [ + { + "name" : "Test Script", + "dataOrder" : "U", + "headerType" : null, + "scriptSensors" : [ + { + "sensorNumber" : 0, + "unitConverter" : { + "ucId" : null, + "fromAbbr" : "m", + "toAbbr" : "ft", + "algorithm" : "x * A", + "a" : 3.28084, + "b" : null, + "c" : null, + "d" : null, + "e" : null, + "f" : null + } + } + ], + "formatStatements" : [ ] + } + ] +} \ No newline at end of file diff --git a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_refs_expected.json b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_refs_expected.json new file mode 100644 index 000000000..e370146e7 --- /dev/null +++ b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_refs_expected.json @@ -0,0 +1,8 @@ +[ + { + "configId": 1, + "name": "Test Platform", + "numPlatforms": 0, + "description":"Test Platform" + } +] \ No newline at end of file From 3d6554333ca59e778e0a913440015d8e350b5a7a Mon Sep 17 00:00:00 2001 From: zack-rma Date: Thu, 16 Jan 2025 14:31:54 -0800 Subject: [PATCH 5/5] Fixed bugs, updated Toolkit method usage --- .../DatabaseItemNotFoundException.java | 41 +++++ .../MissingParameterException.java | 41 +++++ .../opendcs/odcsapi/res/ConfigResources.java | 143 ++++++++++++++++-- .../odcsapi/res/ConfigResourcesTest.java | 98 +++++++++++- .../odcsapi/res/it/ConfigResourcesIT.java | 78 ++++++++-- .../res/it/OPEN_TSDB/config_get_expected.json | 10 +- .../res/it/OPEN_TSDB/config_input_data.json | 10 +- .../config_post_delete_expected.json | 4 +- .../config_post_delete_input_data.json | 2 +- 9 files changed, 377 insertions(+), 50 deletions(-) create mode 100644 opendcs-rest-api/src/main/java/org/opendcs/odcsapi/errorhandling/DatabaseItemNotFoundException.java create mode 100644 opendcs-rest-api/src/main/java/org/opendcs/odcsapi/errorhandling/MissingParameterException.java diff --git a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/errorhandling/DatabaseItemNotFoundException.java b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/errorhandling/DatabaseItemNotFoundException.java new file mode 100644 index 000000000..a22e21cd8 --- /dev/null +++ b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/errorhandling/DatabaseItemNotFoundException.java @@ -0,0 +1,41 @@ +package org.opendcs.odcsapi.errorhandling; + +import javax.servlet.http.HttpServletResponse; + +public class DatabaseItemNotFoundException extends WebAppException +{ + /** detailed error msg */ + private String errMessage = ""; + + public DatabaseItemNotFoundException(String errMessage) + { + super(HttpServletResponse.SC_NOT_FOUND, errMessage); + this.errMessage = errMessage; + } + + public DatabaseItemNotFoundException(String errMessage, Throwable throwable) + { + super(HttpServletResponse.SC_NOT_FOUND, errMessage, throwable); + this.errMessage = errMessage; + } + + public DatabaseItemNotFoundException() { } + + @Override + public int getStatus() + { + return HttpServletResponse.SC_NOT_FOUND; + } + + @Override + public String getErrMessage() + { + return errMessage; + } + + @Override + public void setErrMessage(String errMessage) + { + this.errMessage = errMessage; + } +} \ No newline at end of file diff --git a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/errorhandling/MissingParameterException.java b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/errorhandling/MissingParameterException.java new file mode 100644 index 000000000..57f6ef4c9 --- /dev/null +++ b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/errorhandling/MissingParameterException.java @@ -0,0 +1,41 @@ +package org.opendcs.odcsapi.errorhandling; + +import javax.servlet.http.HttpServletResponse; + +public class MissingParameterException extends WebAppException +{ + /** detailed error msg */ + private String errMessage = ""; + + public MissingParameterException(String errMessage) + { + super(HttpServletResponse.SC_BAD_REQUEST, errMessage); + this.errMessage = errMessage; + } + + public MissingParameterException(String errMessage, Throwable throwable) + { + super(HttpServletResponse.SC_BAD_REQUEST, errMessage, throwable); + this.errMessage = errMessage; + } + + public MissingParameterException() { } + + @Override + public int getStatus() + { + return HttpServletResponse.SC_BAD_REQUEST; + } + + @Override + public String getErrMessage() + { + return errMessage; + } + + @Override + public void setErrMessage(String errMessage) + { + this.errMessage = errMessage; + } +} \ No newline at end of file diff --git a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java index 3f838b459..348d78048 100644 --- a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java +++ b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/ConfigResources.java @@ -17,7 +17,9 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Vector; import javax.annotation.security.RolesAllowed; @@ -35,17 +37,23 @@ import javax.ws.rs.core.Response; import decodes.db.ConfigSensor; +import decodes.db.Constants; +import decodes.db.DataType; import decodes.db.DatabaseException; import decodes.db.DatabaseIO; import decodes.db.DecodesScript; import decodes.db.DecodesScriptException; import decodes.db.EngineeringUnit; +import decodes.db.LinearConverter; +import decodes.db.NullConverter; import decodes.db.PlatformConfig; import decodes.db.PlatformConfigList; import decodes.db.Poly5Converter; import decodes.db.ScriptSensor; import decodes.db.UnitConverter; import decodes.db.UnitConverterDb; +import decodes.db.UsgsStdConverter; +import decodes.db.ValueNotFoundException; import decodes.sql.DbKey; import org.opendcs.odcsapi.beans.ApiConfigRef; import org.opendcs.odcsapi.beans.ApiConfigScript; @@ -54,7 +62,8 @@ import org.opendcs.odcsapi.beans.ApiPlatformConfig; import org.opendcs.odcsapi.beans.ApiUnitConverter; import org.opendcs.odcsapi.dao.DbException; -import org.opendcs.odcsapi.errorhandling.ErrorCodes; +import org.opendcs.odcsapi.errorhandling.DatabaseItemNotFoundException; +import org.opendcs.odcsapi.errorhandling.MissingParameterException; import org.opendcs.odcsapi.errorhandling.WebAppException; import org.opendcs.odcsapi.util.ApiConstants; @@ -69,9 +78,9 @@ public class ConfigResources extends OpenDcsResource @RolesAllowed({ApiConstants.ODCS_API_GUEST}) public Response getConfigRefs() throws DbException { + DatabaseIO dbIo = getLegacyDatabase(); try { - DatabaseIO dbIo = getLegacyDatabase(); PlatformConfigList configList = new PlatformConfigList(); dbIo.readConfigList(configList); return Response.status(HttpServletResponse.SC_OK).entity(map(configList)).build(); @@ -80,6 +89,10 @@ public Response getConfigRefs() throws DbException { throw new DbException("Error reading config list", ex); } + finally + { + dbIo.close(); + } } static List map(PlatformConfigList configList) @@ -112,22 +125,29 @@ public Response getConfig(@QueryParam("configid") Long configId) throws WebAppEx { if (configId == null) { - throw new WebAppException(ErrorCodes.MISSING_ID, - "Missing required configid parameter."); + throw new MissingParameterException("Missing required configid parameter."); } + DatabaseIO dbIo = getLegacyDatabase(); try { - DatabaseIO dbIo = getLegacyDatabase(); PlatformConfig config = new PlatformConfig(); config.setId(DbKey.createDbKey(configId)); - dbIo.readConfig(config); // TODO: This method does not return any data. Investigate why. + config = dbIo.readConfig(config); return Response.status(HttpServletResponse.SC_OK).entity(map(config)).build(); } catch (DatabaseException ex) { + if (ex.getCause() instanceof ValueNotFoundException) + { + throw new DatabaseItemNotFoundException("Config with ID " + configId + " not found"); + } throw new DbException("Error reading config", ex); } + finally + { + dbIo.close(); + } } static ApiPlatformConfig map(PlatformConfig config) @@ -144,6 +164,51 @@ static ApiPlatformConfig map(PlatformConfig config) apiConfig.setName(config.getName()); apiConfig.setNumPlatforms(config.numPlatformsUsing); apiConfig.setDescription(config.description); + List sensors = new ArrayList<>(); + config.getSensors().forEachRemaining(sensor -> { + ApiConfigSensor apiSensor = new ApiConfigSensor(); + apiSensor.setSensorNumber(sensor.sensorNumber); + apiSensor.setSensorName(sensor.sensorName); + apiSensor.setProperties(sensor.getProperties()); + apiSensor.setAbsoluteMax(sensor.absoluteMax); + apiSensor.setAbsoluteMin(sensor.absoluteMin); + apiSensor.setRecordingInterval(sensor.recordingInterval); + apiSensor.setTimeOfFirstSample(sensor.timeOfFirstSample); + apiSensor.setRecordingMode(sensor.recordingMode); + Map dataTypes = new HashMap<>(); + sensor.getDataTypes() + .forEachRemaining(entry -> + dataTypes.put(entry.getStandard(), entry.getCode())); + apiSensor.setDataTypes(dataTypes); + sensors.add(apiSensor); + }); + apiConfig.setConfigSensors(sensors); + List scripts = new ArrayList<>(); + config.getScripts().forEachRemaining(script -> { + ApiConfigScript apiScript = new ApiConfigScript(); + apiScript.setName(script.scriptName); + List scriptSensors = new ArrayList<>(); + script.scriptSensors.forEach(sensor -> { + ApiConfigScriptSensor apiSensor = new ApiConfigScriptSensor(); + apiSensor.setSensorNumber(sensor.sensorNumber); + ApiUnitConverter uc = new ApiUnitConverter(); + uc.setFromAbbr(sensor.rawConverter.fromAbbr); + uc.setToAbbr(sensor.rawConverter.toAbbr); + uc.setAlgorithm(sensor.rawConverter.algorithm); + uc.setA(sensor.rawConverter.coefficients[0]); + uc.setB(sensor.rawConverter.coefficients[1]); + uc.setC(sensor.rawConverter.coefficients[2]); + uc.setD(sensor.rawConverter.coefficients[3]); + uc.setE(sensor.rawConverter.coefficients[4]); + uc.setF(sensor.rawConverter.coefficients[5]); + uc.setUcId(sensor.getUnitConverterId().getValue()); + apiSensor.setUnitConverter(uc); + scriptSensors.add(apiSensor); + }); + apiScript.setScriptSensors(scriptSensors); + scripts.add(apiScript); + }); + apiConfig.setScripts(scripts); return apiConfig; } @@ -154,12 +219,12 @@ static ApiPlatformConfig map(PlatformConfig config) @RolesAllowed({ApiConstants.ODCS_API_ADMIN, ApiConstants.ODCS_API_USER}) public Response postConfig(ApiPlatformConfig config) throws DbException { + DatabaseIO dbIo = getLegacyDatabase(); try { - DatabaseIO dbIo = getLegacyDatabase(); PlatformConfig pc = map(config); dbIo.writeConfig(pc); - return Response.status(HttpServletResponse.SC_OK) + return Response.status(HttpServletResponse.SC_CREATED) .entity(map(pc)) .build(); } @@ -167,6 +232,10 @@ public Response postConfig(ApiPlatformConfig config) throws DbException { throw new DbException("Error saving config", ex); } + finally + { + dbIo.close(); + } } static PlatformConfig map(ApiPlatformConfig config) throws DbException @@ -192,6 +261,20 @@ static PlatformConfig map(ApiPlatformConfig config) throws DbException ConfigSensor configSensor = new ConfigSensor(null, sensor.getSensorNumber()); configSensor.sensorName = sensor.getSensorName(); configSensor.platformConfig = pc; + configSensor.absoluteMax = sensor.getAbsoluteMax(); + configSensor.absoluteMin = sensor.getAbsoluteMin(); + configSensor.recordingInterval = sensor.getRecordingInterval(); + configSensor.timeOfFirstSample = sensor.getTimeOfFirstSample(); + configSensor.recordingMode = sensor.getRecordingMode(); + for (Map.Entry entry : sensor.getDataTypes().entrySet()) + { + DataType dt = new DataType(entry.getKey(), entry.getValue()); + configSensor.addDataType(dt); + } + for (String name : sensor.getProperties().stringPropertyNames()) + { + configSensor.setProperty(name, sensor.getProperties().getProperty(name)); + } pc.addSensor(configSensor); } @@ -266,9 +349,36 @@ static UnitConverter map(ApiUnitConverter unitConverter) { EngineeringUnit from = EngineeringUnit.getEngineeringUnit(unitConverter.getFromAbbr()); EngineeringUnit to = EngineeringUnit.getEngineeringUnit(unitConverter.getToAbbr()); - Poly5Converter pc = new Poly5Converter(from, to); - pc.setCoefficients(coefficientMap(unitConverter)); - return pc; + double[] coeffs = coefficientMap(unitConverter); + if (unitConverter.getAlgorithm().equalsIgnoreCase("None")) + { + NullConverter nc = new NullConverter(from, to); + nc.setCoefficients(coeffs); + return nc; + } + else if (unitConverter.getAlgorithm().equalsIgnoreCase(Constants.eucvt_poly5)) + { + Poly5Converter pc = new Poly5Converter(from, to); + pc.setCoefficients(coeffs); + return pc; + } + + else if (unitConverter.getAlgorithm().equalsIgnoreCase(Constants.eucvt_linear)) + { + LinearConverter lc = new LinearConverter(from, to); + lc.setCoefficients(coeffs); + return lc; + } + else if (unitConverter.getAlgorithm().equalsIgnoreCase(Constants.eucvt_usgsstd)) + { + UsgsStdConverter uc = new UsgsStdConverter(from, to); + uc.setCoefficients(coeffs); + return uc; + } + else + { + throw new IllegalArgumentException("Unsupported algorithm: " + unitConverter.getAlgorithm()); + } } static double[] coefficientMap(ApiUnitConverter unitConverter) @@ -293,13 +403,12 @@ public Response deleteConfig(@QueryParam("configid") Long configId) throws DbExc { if (configId == null) { - throw new WebAppException(HttpServletResponse.SC_BAD_REQUEST, - "Missing required configid parameter."); + throw new MissingParameterException("Missing required configid parameter."); } + DatabaseIO dbIo = getLegacyDatabase(); try { - DatabaseIO dbIo = getLegacyDatabase(); PlatformConfig pc = new PlatformConfig(); pc.setId(DbKey.createDbKey(configId)); dbIo.readConfig(pc); @@ -313,7 +422,7 @@ public Response deleteConfig(@QueryParam("configid") Long configId) throws DbExc } dbIo.deleteConfig(pc); - return Response.status(HttpServletResponse.SC_OK) + return Response.status(HttpServletResponse.SC_NO_CONTENT) .entity("Config with ID " + configId + " deleted") .build(); } @@ -321,5 +430,9 @@ public Response deleteConfig(@QueryParam("configid") Long configId) throws DbExc { throw new DbException("Error deleting config", ex); } + finally + { + dbIo.close(); + } } } diff --git a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/ConfigResourcesTest.java b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/ConfigResourcesTest.java index 59507194c..b3ca88d73 100644 --- a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/ConfigResourcesTest.java +++ b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/ConfigResourcesTest.java @@ -5,13 +5,14 @@ import java.util.List; import java.util.Vector; +import decodes.db.ConfigSensor; import decodes.db.DecodesScript; import decodes.db.PlatformConfig; import decodes.db.PlatformConfigList; -import decodes.db.Poly5Converter; import decodes.db.ScriptSensor; import decodes.db.UnitConverter; import decodes.sql.DbKey; +import decodes.xml.DecodesScriptParser; import org.junit.jupiter.api.Test; import org.opendcs.odcsapi.beans.ApiConfigRef; import org.opendcs.odcsapi.beans.ApiConfigScript; @@ -21,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.opendcs.odcsapi.res.ConfigResources.coefficientMap; import static org.opendcs.odcsapi.res.ConfigResources.map; @@ -54,6 +56,30 @@ void testPlatformConfigMap() throws Exception config.configName = "Test config"; config.description = "Platform description"; config.setId(DbKey.createDbKey(5899L)); + Vector scripts = new Vector<>(); + PlatformConfig scriptConfig = new PlatformConfig(); + scriptConfig.numPlatformsUsing = 1; + scriptConfig.configName = "Test script config"; + scriptConfig.description = "Script config description"; + DecodesScript.DecodesScriptBuilder builder = new DecodesScript.DecodesScriptBuilder(new DecodesScriptParser()); + builder.platformConfig(scriptConfig); + DecodesScript script = builder.build(); + script.scriptName = "Test script"; + script.scriptType = "Test"; + scripts.add(script); + config.decodesScripts = scripts; + PlatformConfig sensor = new PlatformConfig(); + sensor.numPlatformsUsing = 1; + sensor.configName = "Test sensor"; + sensor.description = "Sensor description"; + ConfigSensor sensorConfig = new ConfigSensor(sensor, 12); + sensorConfig.absoluteMax = 100.0; + sensorConfig.absoluteMin = 0.0; + sensorConfig.recordingInterval = 15; + sensorConfig.recordingMode = 'C'; + sensorConfig.sensorName = "Test sensor"; + sensorConfig.setUsgsStatCode("00000"); + config.addSensor(sensorConfig); ApiPlatformConfig apiConfig = map(config); @@ -62,6 +88,13 @@ void testPlatformConfigMap() throws Exception assertEquals(config.configName, apiConfig.getName()); assertEquals(config.description, apiConfig.getDescription()); assertEquals(config.getId().getValue(), apiConfig.getConfigId()); + assertEquals(config.decodesScripts.size(), apiConfig.getScripts().size()); + assertEquals(config.decodesScripts.get(0).scriptName, apiConfig.getScripts().get(0).getName()); + assertEquals(config.getSensorVec().get(0).absoluteMax, apiConfig.getConfigSensors().get(0).getAbsoluteMax()); + assertEquals(config.getSensorVec().get(0).absoluteMin, apiConfig.getConfigSensors().get(0).getAbsoluteMin()); + assertEquals(config.getSensorVec().get(0).recordingInterval, apiConfig.getConfigSensors().get(0).getRecordingInterval()); + assertEquals(config.getSensorVec().get(0).recordingMode, apiConfig.getConfigSensors().get(0).getRecordingMode()); + assertEquals(config.getSensorVec().get(0).sensorName, apiConfig.getConfigSensors().get(0).getSensorName()); } @Test @@ -75,6 +108,7 @@ void testApiPlatformConfigMap() throws Exception apiConfig.setConfigId(5899L); PlatformConfig config = map(apiConfig); + assertNotNull(config); assertEquals(apiConfig.getNumPlatforms(), config.numPlatformsUsing); assertEquals(apiConfig.getName(), config.configName); @@ -87,9 +121,22 @@ void testApiPlatformConfigMap() throws Exception for (ScriptSensor sensor : script.scriptSensors) { assertEquals(apiConfig.getScripts().get(0).getScriptSensors().get(0).getSensorNumber(), sensor.sensorNumber); - assertMatch(apiConfig.getScripts().get(0).getScriptSensors().get(0).getUnitConverter(), (Poly5Converter) sensor.execConverter); + assertMatch(apiConfig.getScripts().get(0).getScriptSensors().get(0).getUnitConverter(), sensor.execConverter); } } + for (Iterator sensor = config.getSensors(); sensor.hasNext(); ) + { + ConfigSensor sensorConfig = sensor.next(); + assertEquals(apiConfig.getConfigSensors().get(0).getAbsoluteMax(), sensorConfig.absoluteMax); + assertEquals(apiConfig.getConfigSensors().get(0).getAbsoluteMin(), sensorConfig.absoluteMin); + assertEquals(apiConfig.getConfigSensors().get(0).getRecordingInterval(), sensorConfig.recordingInterval); + assertEquals(apiConfig.getConfigSensors().get(0).getRecordingMode(), sensorConfig.recordingMode); + assertEquals(apiConfig.getConfigSensors().get(0).getSensorName(), sensorConfig.sensorName); + assertEquals(apiConfig.getConfigSensors().get(0).getSensorNumber(), sensorConfig.sensorNumber); + assertEquals(apiConfig.getConfigSensors().get(0).getUsgsStatCode(), sensorConfig.getUsgsStatCode()); + assertEquals(apiConfig.getConfigSensors().get(0).getDataTypes(), sensorConfig.getDataType()); + assertEquals(apiConfig.getConfigSensors().get(0).getProperties(), sensorConfig.getProperties()); + } } @Test @@ -105,7 +152,7 @@ void testApiConfigScriptMap() throws Exception for (ScriptSensor sensor : decodesScripts.get(0).scriptSensors) { assertEquals(scripts.get(0).getScriptSensors().get(0).getSensorNumber(), sensor.sensorNumber); - assertMatch(scripts.get(0).getScriptSensors().get(0).getUnitConverter(), (Poly5Converter) sensor.execConverter); + assertMatch(scripts.get(0).getScriptSensors().get(0).getUnitConverter(), sensor.execConverter); } } @@ -116,7 +163,7 @@ void testApiConfigScriptSensorMap() throws Exception sensor.setSensorNumber(1); ApiUnitConverter unitConverter = new ApiUnitConverter(); unitConverter.setUcId(1234L); - unitConverter.setAlgorithm("None"); + unitConverter.setAlgorithm("Poly-5"); unitConverter.setFromAbbr("ft"); unitConverter.setToAbbr("m"); unitConverter.setA(1.0); @@ -131,7 +178,7 @@ void testApiConfigScriptSensorMap() throws Exception assertNotNull(decodesSensor); assertEquals(sensor.getSensorNumber(), decodesSensor.sensorNumber); - assertMatch(sensor.getUnitConverter(), (Poly5Converter) decodesSensor.execConverter); + assertMatch(sensor.getUnitConverter(), decodesSensor.execConverter); assertEquals(sensor.getUnitConverter().getFromAbbr(), decodesSensor.rawConverter.fromAbbr); assertEquals(sensor.getUnitConverter().getToAbbr(), decodesSensor.rawConverter.toAbbr); assertEquals(sensor.getUnitConverter().getA(), decodesSensor.rawConverter.coefficients[0]); @@ -147,6 +194,7 @@ void testApiConfigScriptSensorMap() throws Exception @Test void testApiUnitConverterMap() throws Exception { + // Test with NullConverter ApiUnitConverter unitConverter = new ApiUnitConverter(); unitConverter.setUcId(1234L); unitConverter.setAlgorithm("None"); @@ -161,10 +209,46 @@ void testApiUnitConverterMap() throws Exception UnitConverter decodesUc = map(unitConverter); + assertNotNull(decodesUc); + assertEquals(unitConverter.getFromAbbr(), decodesUc.getFromAbbr()); + assertEquals(unitConverter.getToAbbr(), decodesUc.getToAbbr()); + assertEquals(20.0, decodesUc.convert(20.0)); + + // Test with Poly5Converter + unitConverter.setAlgorithm("Poly-5"); + + decodesUc = map(unitConverter); + assertNotNull(decodesUc); assertEquals(unitConverter.getFromAbbr(), decodesUc.getFromAbbr()); assertEquals(unitConverter.getToAbbr(), decodesUc.getToAbbr()); assertEquals(3545706.0, decodesUc.convert(20.0)); + + // Test with CompositeConverter + unitConverter.setAlgorithm("Composite"); + unitConverter.setFromAbbr("in"); + + assertThrows(IllegalArgumentException.class, () -> map(unitConverter)); + + // Test with LinearConverter + unitConverter.setAlgorithm("Linear"); + unitConverter.setFromAbbr("ft"); + + decodesUc = map(unitConverter); + + assertNotNull(decodesUc); + assertEquals(unitConverter.getFromAbbr(), decodesUc.getFromAbbr()); + assertEquals(unitConverter.getToAbbr(), decodesUc.getToAbbr()); + assertEquals(22.0, decodesUc.convert(20.0)); + + // Test with USGSStandardConverter + unitConverter.setAlgorithm("USGS-Standard"); + decodesUc = map(unitConverter); + + assertNotNull(decodesUc); + assertEquals(unitConverter.getFromAbbr(), decodesUc.getFromAbbr()); + assertEquals(unitConverter.getToAbbr(), decodesUc.getToAbbr()); + assertEquals(10652.0, decodesUc.convert(20.0)); } @Test @@ -188,7 +272,7 @@ void testCoefficientMap() assertEquals(unitConverter.getF(), coefficients[5]); } - private static void assertMatch(ApiUnitConverter apiUc, Poly5Converter decodesUc) + private static void assertMatch(ApiUnitConverter apiUc, UnitConverter decodesUc) throws Exception { assertEquals(apiUc.getFromAbbr(), decodesUc.getFromAbbr()); assertEquals(apiUc.getToAbbr(), decodesUc.getToAbbr()); @@ -212,7 +296,7 @@ private static ArrayList buildScriptSensorList() scriptSensor.setSensorNumber(1); ApiUnitConverter unitConverter = new ApiUnitConverter(); unitConverter.setUcId(1234L); - unitConverter.setAlgorithm("None"); + unitConverter.setAlgorithm("Poly-5"); unitConverter.setFromAbbr("ft"); unitConverter.setToAbbr("m"); unitConverter.setA(1.0); diff --git a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java index 93c0a2bb9..b0d116f6d 100644 --- a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java +++ b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/ConfigResourcesIT.java @@ -19,7 +19,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -@Tag("integration") +@Tag("integration-opentsdb-only") @ExtendWith(DatabaseContextProvider.class) final class ConfigResourcesIT extends BaseIT { @@ -50,7 +50,7 @@ void setUp() throws Exception .then() .log().ifValidationFails(LogDetail.ALL, true) .assertThat() - .statusCode(is(HttpServletResponse.SC_OK)) + .statusCode(is(HttpServletResponse.SC_CREATED)) .extract() ; @@ -74,7 +74,7 @@ void tearDown() .then() .log().ifValidationFails(LogDetail.ALL, true) .assertThat() - .statusCode(is(HttpServletResponse.SC_OK)) + .statusCode(is(HttpServletResponse.SC_NO_CONTENT)) ; logout(sessionFilter); @@ -127,10 +127,28 @@ void testGetConfig() .statusCode(is(HttpServletResponse.SC_OK)) .body("name", equalTo(expected.getString("name"))) .body("description", equalTo(expected.getString("description"))) - .body("numPlatforms", equalTo(expected.getLong("numPlatforms"))) - .body("scripts.size()", equalTo(expected.getString("scripts.size()"))) - .body("configSensors.size()", equalTo(expected.getString("configSensors.size()"))) - // TODO: Add script and configSensor assertions + .body("numPlatforms", equalTo(expected.get("numPlatforms"))) + .body("scripts.size()", equalTo(expected.get("scripts.size()"))) + .body("configSensors.size()", equalTo(expected.get("configSensors.size()"))) + .body("configSensors[0].sensorNumber", equalTo(expected.get("configSensors[0].sensorNumber"))) + .body("configSensors[0].sensorName", equalTo(expected.get("configSensors[0].sensorName"))) + .body("configSensors[0].recordingMode", equalTo(expected.get("configSensors[0].recordingMode"))) + .body("configSensors[0].recordingInterval", equalTo(expected.get("configSensors[0].recordingInterval"))) + .body("configSensors[0].timeOfFirstSample", equalTo(expected.get("configSensors[0].timeOfFirstSample"))) + .body("configSensors[0].absoluteMin", equalTo(expected.get("configSensors[0].absoluteMin"))) + .body("configSensors[0].absoluteMax", equalTo(expected.get("configSensors[0].absoluteMax"))) + .body("configSensors[0].properties", equalTo(expected.get("configSensors[0].properties"))) + .body("configSensors[0].usgsStatCode", equalTo(expected.get("configSensors[0].usgsStatCode"))) + .body("configSensors[0].datatypes", equalTo(expected.get("configSensors[0].datatypes"))) + .body("scripts[0].name", equalTo(expected.getString("scripts[0].name"))) + .body("scripts[0].dataOrder", equalTo(expected.getString("scripts[0].dataOrder"))) + .body("scripts[0].headerType", equalTo(expected.getString("scripts[0].headerType"))) + .body("scripts[0].scriptSensors[0].sensorNumber", equalTo(expected.get("scripts[0].scriptSensors[0].sensorNumber"))) + .body("scripts[0].scriptSensors[0].unitConverter.fromAbbr", equalTo(expected.getString("scripts[0].scriptSensors[0].unitConverter.fromAbbr"))) + .body("scripts[0].scriptSensors[0].unitConverter.toAbbr", equalTo(expected.getString("scripts[0].scriptSensors[0].unitConverter.toAbbr"))) + .body("scripts[0].scriptSensors[0].unitConverter.algorithm", equalTo(expected.getString("scripts[0].scriptSensors[0].unitConverter.algorithm"))) + .body("scripts[0].scriptSensors[0].unitConverter.a", equalTo(expected.getFloat("scripts[0].scriptSensors[0].unitConverter.a"))) + .body("scripts[0].scriptSensors[0].unitConverter.b", equalTo(expected.getFloat("scripts[0].scriptSensors[0].unitConverter.b"))) ; } @@ -153,7 +171,7 @@ void testPostAndDeleteConfig() throws Exception .then() .log().ifValidationFails(LogDetail.ALL, true) .assertThat() - .statusCode(is(HttpServletResponse.SC_OK)) + .statusCode(is(HttpServletResponse.SC_CREATED)) .extract() ; @@ -179,10 +197,27 @@ void testPostAndDeleteConfig() throws Exception .statusCode(is(HttpServletResponse.SC_OK)) .body("name", equalTo(expected.getString("name"))) .body("description", equalTo(expected.getString("description"))) - .body("numPlatforms", equalTo(expected.getLong("numPlatforms"))) - .body("scripts.size()", equalTo(expected.getString("scripts.size()"))) - .body("configSensors.size()", equalTo(expected.getString("configSensors.size()"))) - // TODO: Add script and configSensor assertions + .body("numPlatforms", equalTo(expected.get("numPlatforms"))) + .body("scripts.size()", equalTo(expected.get("scripts.size()"))) + .body("configSensors.size()", equalTo(expected.get("configSensors.size()"))) + .body("configSensors[0].sensorNumber", equalTo(expected.get("configSensors[0].sensorNumber"))) + .body("configSensors[0].sensorName", equalTo(expected.get("configSensors[0].sensorName"))) + .body("configSensors[0].recordingMode", equalTo(expected.get("configSensors[0].recordingMode"))) + .body("configSensors[0].recordingInterval", equalTo(expected.get("configSensors[0].recordingInterval"))) + .body("configSensors[0].timeOfFirstSample", equalTo(expected.get("configSensors[0].timeOfFirstSample"))) + .body("configSensors[0].absoluteMin", equalTo(expected.get("configSensors[0].absoluteMin"))) + .body("configSensors[0].absoluteMax", equalTo(expected.get("configSensors[0].absoluteMax"))) + .body("configSensors[0].properties", equalTo(expected.get("configSensors[0].properties"))) + .body("configSensors[0].usgsStatCode", equalTo(expected.get("configSensors[0].usgsStatCode"))) + .body("configSensors[0].datatypes", equalTo(expected.get("configSensors[0].datatypes"))) + .body("scripts[0].name", equalTo(expected.getString("scripts[0].name"))) + .body("scripts[0].dataOrder", equalTo(expected.getString("scripts[0].dataOrder"))) + .body("scripts[0].headerType", equalTo(expected.getString("scripts[0].headerType"))) + .body("scripts[0].scriptSensors[0].sensorNumber", equalTo(expected.get("scripts[0].scriptSensors[0].sensorNumber"))) + .body("scripts[0].scriptSensors[0].unitConverter.fromAbbr", equalTo(expected.getString("scripts[0].scriptSensors[0].unitConverter.fromAbbr"))) + .body("scripts[0].scriptSensors[0].unitConverter.toAbbr", equalTo(expected.getString("scripts[0].scriptSensors[0].unitConverter.toAbbr"))) + .body("scripts[0].scriptSensors[0].unitConverter.algorithm", equalTo(expected.getString("scripts[0].scriptSensors[0].unitConverter.algorithm"))) + .body("scripts[0].scriptSensors[0].unitConverter.a", equalTo(expected.getFloat("scripts[0].scriptSensors[0].unitConverter.a"))) ; given() @@ -199,7 +234,24 @@ void testPostAndDeleteConfig() throws Exception .then() .log().ifValidationFails(LogDetail.ALL, true) .assertThat() - .statusCode(is(HttpServletResponse.SC_OK)) + .statusCode(is(HttpServletResponse.SC_NO_CONTENT)) ; + + // Retrieve and assert that the config is no longer there + given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .queryParam("configid", newConfigId) + .when() + .redirects().follow(true) + .redirects().max(3) + .get("config") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_NOT_FOUND)); } } diff --git a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_get_expected.json b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_get_expected.json index 846cff23a..6be80173c 100644 --- a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_get_expected.json +++ b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_get_expected.json @@ -1,23 +1,21 @@ { "configId": 4, "name": "Test Platform", - "numPlatforms": 1, + "numPlatforms": 0, "description": "Test Platform", "configSensors": [ { "sensorNumber" : 0, "sensorName" : "Test Sensor", "recordingMode" : "U", - "recordingInterval" : 900, + "recordingInterval" : 1500, "timeOfFirstSample" : 0, "absoluteMin" : 0.0, "absoluteMax" : 100.0, "properties" : { "site" : "Test Site" }, - "dataTypes" : { - "Test Type" : "Test Units" - }, + "dataTypes" : {}, "usgsStatCode" : null } ], @@ -32,7 +30,7 @@ "ucId" : null, "fromAbbr" : "C", "toAbbr" : "F", - "algorithm" : "x * 100 + 32", + "algorithm" : "Linear", "a" : 100.0, "b" : 32.0, "c" : null, diff --git a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_input_data.json b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_input_data.json index 5beadca60..16c8c55d6 100644 --- a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_input_data.json +++ b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_input_data.json @@ -1,23 +1,21 @@ { "configId" : null, "name" : "Test Platform", - "numPlatforms" : 1, + "numPlatforms" : 0, "description" : "Test Platform", "configSensors" : [ { "sensorNumber" : 0, "sensorName" : "Test Sensor", "recordingMode" : "U", - "recordingInterval" : 900, + "recordingInterval" : 1500, "timeOfFirstSample" : 0, "absoluteMin" : 0.0, "absoluteMax" : 100.0, "properties" : { "site" : "Test Site" }, - "dataTypes" : { - "Test Type" : "Test Units" - }, + "dataTypes" : {}, "usgsStatCode" : null } ], @@ -32,7 +30,7 @@ "ucId" : null, "fromAbbr" : "C", "toAbbr" : "F", - "algorithm" : "x * 100 + 32", + "algorithm" : "Linear", "a" : 100.0, "b" : 32.0, "c" : null, diff --git a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_expected.json b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_expected.json index c3d6acfe4..aa5f0b32e 100644 --- a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_expected.json +++ b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_expected.json @@ -1,7 +1,7 @@ { "configId": 3, "name": "Test Platform 2", - "numPlatforms": 1, + "numPlatforms": 0, "description": "Test Platform 1", "configSensors": [ { @@ -33,7 +33,7 @@ "ucId" : null, "fromAbbr" : "m", "toAbbr" : "ft", - "algorithm" : "x * A", + "algorithm" : "None", "a" : 3.28084, "b" : null, "c" : null, diff --git a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_input_data.json b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_input_data.json index de174b932..5efc80105 100644 --- a/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_input_data.json +++ b/opendcs-rest-api/src/test/resources/org/opendcs/odcsapi/res/it/OPEN_TSDB/config_post_delete_input_data.json @@ -33,7 +33,7 @@ "ucId" : null, "fromAbbr" : "m", "toAbbr" : "ft", - "algorithm" : "x * A", + "algorithm" : "None", "a" : 3.28084, "b" : null, "c" : null,