diff --git a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/dao/DbException.java b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/dao/DbException.java index 398f14eba..46e35c379 100644 --- a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/dao/DbException.java +++ b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/dao/DbException.java @@ -32,4 +32,9 @@ public DbException(String message, Exception cause) { super(message, cause); } + + public DbException(String message) + { + super(message); + } } diff --git a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/DataSourceResources.java b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/DataSourceResources.java index adfee7703..e0e64d26a 100644 --- a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/DataSourceResources.java +++ b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/DataSourceResources.java @@ -15,10 +15,14 @@ package org.opendcs.odcsapi.res; -import java.sql.SQLException; -import java.util.logging.Logger; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.Vector; +import java.util.regex.Pattern; 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; @@ -31,19 +35,25 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import decodes.db.DataSource; +import decodes.db.DataSourceList; +import decodes.db.DatabaseException; +import decodes.db.DatabaseIO; +import decodes.sql.DbKey; import org.opendcs.odcsapi.beans.ApiDataSource; -import org.opendcs.odcsapi.dao.ApiDataSourceDAO; +import org.opendcs.odcsapi.beans.ApiDataSourceGroupMember; +import org.opendcs.odcsapi.beans.ApiDataSourceRef; 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.sec.AuthorizationCheck; -import org.opendcs.odcsapi.util.ApiConstants; -import org.opendcs.odcsapi.util.ApiHttpUtil; @Path("/") -public class DataSourceResources +public class DataSourceResources extends OpenDcsResource { + private DatabaseIO dbIo; + private static final Pattern COMMA = Pattern.compile(","); + private static final Pattern EQUAL = Pattern.compile("="); + @Context HttpHeaders httpHeaders; @GET @@ -52,35 +62,159 @@ public class DataSourceResources @RolesAllowed({AuthorizationCheck.ODCS_API_GUEST}) public Response getDataSourceRefs() throws DbException { - Logger.getLogger(ApiConstants.loggerName).fine("getDataSourceRefs"); - try (DbInterface dbi = new DbInterface(); - ApiDataSourceDAO dao = new ApiDataSourceDAO(dbi)) + try + { + dbIo = getLegacyDatabase(); + DataSourceList dsl = new DataSourceList(); + dbIo.readDataSourceList(dsl); + return Response.status(HttpServletResponse.SC_OK).entity(map(dsl)).build(); + } + catch (DatabaseException ex) + { + throw new DbException("Error reading data source list: " + ex); + } + finally + { + dbIo.close(); + } + } + + static ArrayList map(DataSourceList dsl) + { + ArrayList ret = new ArrayList<>(); + for(DataSource ds : dsl.getList()) { - return ApiHttpUtil.createResponse(dao.readDataSourceRefs()); + ApiDataSourceRef adr = new ApiDataSourceRef(); + if (ds.getId() != null) + { + adr.setDataSourceId(ds.getId().getValue()); + } + else + { + adr.setDataSourceId(DbKey.NullKey.getValue()); + } + adr.setName(ds.getName()); + adr.setType(ds.dataSourceType); + adr.setUsedBy(ds.numUsedBy); + if (ds.getArguments() != null) + { + adr.setArguments(propsToString(ds.getArguments())); + } + else + { + adr.setArguments(ds.getDataSourceArg()); + } + ret.add(adr); } + return ret; + } + + static String propsToString(Properties props) + { + if (props == null || props.isEmpty()) + return ""; + + StringBuilder retVal = new StringBuilder(); + for (Object key : props.keySet()) + { + retVal.append(key).append("=").append(props.getProperty((String) key)).append(","); + } + return retVal.substring(0, retVal.length() - 1); } @GET @Path("datasource") @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({AuthorizationCheck.ODCS_API_GUEST}) - public Response geDataSource(@QueryParam("datasourceid") Long dataSourceId) - throws WebAppException, DbException, SQLException + public Response getDataSource(@QueryParam("datasourceid") Long dataSourceId) + throws WebAppException, DbException { + String notFound = "No such DECODES data source with id="; if (dataSourceId == null) - throw new WebAppException(ErrorCodes.MISSING_ID, - "Missing required datasourceid parameter."); - - Logger.getLogger(ApiConstants.loggerName).fine("getDataSource id=" + dataSourceId); - try (DbInterface dbi = new DbInterface(); - ApiDataSourceDAO dao = new ApiDataSourceDAO(dbi)) - { - ApiDataSource ret = dao.readDataSource(dataSourceId); - if (ret == null) - throw new WebAppException(ErrorCodes.NO_SUCH_OBJECT, - "No such DECODES data source with id=" + dataSourceId + "."); - return ApiHttpUtil.createResponse(ret); + { + throw new WebAppException(HttpServletResponse.SC_BAD_REQUEST, + "Missing required datasourceid parameter."); + } + + try + { + dbIo = getLegacyDatabase(); + DataSource ds = new DataSource(DbKey.createDbKey(dataSourceId)); + dbIo.readDataSource(ds); + + if (ds.getName() == null) + { + throw new WebAppException(HttpServletResponse.SC_NOT_FOUND, + notFound + dataSourceId + "."); + } + ApiDataSource ret = map(ds); + return Response.status(HttpServletResponse.SC_OK).entity(ret).build(); + } + catch (DatabaseException ex) + { + if (ex.getMessage().contains("No DataSource found with id")) + { + return Response.status(HttpServletResponse.SC_NOT_FOUND) + .entity(notFound + dataSourceId + ".").build(); + } + throw new DbException("Error reading data source: " + ex); + } + finally + { + dbIo.close(); + } + } + + static ApiDataSource map(DataSource ds) + { + if (ds == null) + return null; + ApiDataSource ads = new ApiDataSource(); + if (ds.getId() != null) + { + ads.setDataSourceId(ds.getId().getValue()); } + else + { + ads.setDataSourceId(DbKey.NullKey.getValue()); + } + ads.setName(ds.getName()); + ads.setType(ds.dataSourceType); + if (ds.getArguments() != null) + { + ads.setProps(ds.getArguments()); + } + else + { + ads.setProps(parseProps(ds.getDataSourceArg())); + } + ads.setGroupMembers(map(ds.groupMembers)); + ads.setUsedBy(ds.numUsedBy); + return ads; + } + + static List map(Vector groupMembers) + { + if (groupMembers == null) + { + return new ArrayList<>(); + } + List ret = new ArrayList<>(); + for(DataSource ds : groupMembers) + { + ApiDataSourceGroupMember ads = new ApiDataSourceGroupMember(); + if (ds.getId() != null) + { + ads.setDataSourceId(ds.getId().getValue()); + } + else + { + ads.setDataSourceId(DbKey.NullKey.getValue()); + } + ads.setDataSourceName(ds.getName()); + ret.add(ads); + } + return ret; } @POST @@ -88,18 +222,66 @@ public Response geDataSource(@QueryParam("datasourceid") Long dataSourceId) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({AuthorizationCheck.ODCS_API_ADMIN, AuthorizationCheck.ODCS_API_USER}) - public Response postDatasource(ApiDataSource datasource) throws WebAppException, DbException, SQLException + public Response postDatasource(ApiDataSource datasource) throws DbException, WebAppException + { + if (datasource == null) + { + throw new WebAppException(HttpServletResponse.SC_BAD_REQUEST, + "Missing required data source object."); + } + try + { + dbIo = getLegacyDatabase(); + DataSource source = map(datasource); + dbIo.writeDataSource(source); + return Response.status(HttpServletResponse.SC_OK) + .entity(map(source)) + .build(); + } + catch (DatabaseException ex) + { + throw new DbException("Error writing data source: " + ex); + } + finally + { + dbIo.close(); + } + } + + static DataSource map(ApiDataSource ads) throws DatabaseException { - Logger.getLogger(ApiConstants.loggerName).fine( - "post datasource received datasource " + datasource.getName() - + " with ID=" + datasource.getDataSourceId()); - - try (DbInterface dbi = new DbInterface(); - ApiDataSourceDAO dsDao = new ApiDataSourceDAO(dbi)) + DataSource ds = new DataSource(); + if (ads.getDataSourceId() != null) + { + ds.setId(DbKey.createDbKey(ads.getDataSourceId())); + } + else { - dsDao.writedDataSource(datasource); - return ApiHttpUtil.createResponse(datasource); + ds.setId(DbKey.NullKey); } + ds.setName(ads.getName()); + ds.dataSourceType = ads.getType(); + ds.arguments = ads.getProps(); + ds.setDataSourceArg(propsToString(ads.getProps())); + ds.numUsedBy = ads.getUsedBy(); + ds.groupMembers = map(ads.getGroupMembers()); + return ds; + } + + static Vector map(List groupMembers) + { + Vector ret = new Vector<>(); + if (groupMembers == null) + { + return ret; + } + for(ApiDataSourceGroupMember ads : groupMembers) + { + DataSource ds = new DataSource(DbKey.createDbKey(ads.getDataSourceId())); + ds.setName(ads.getDataSourceName()); + ret.add(ds); + } + return ret; } @DELETE @@ -107,25 +289,58 @@ public Response postDatasource(ApiDataSource datasource) throws WebAppException, @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({AuthorizationCheck.ODCS_API_ADMIN, AuthorizationCheck.ODCS_API_USER}) - public Response deleteDatasource(@QueryParam("datasourceid") Long datasourceId) throws DbException + public Response deleteDatasource(@QueryParam("datasourceid") Long datasourceId) throws DbException, WebAppException { - Logger.getLogger(ApiConstants.loggerName).fine( - "DELETE datasource received datasourceid=" + datasourceId); - - // Use username and password to attempt to connect to the database - try (DbInterface dbi = new DbInterface(); - ApiDataSourceDAO dsDao = new ApiDataSourceDAO(dbi)) - { - String errmsg = dsDao.datasourceUsedByRs(datasourceId); - if (errmsg != null) - return ApiHttpUtil.createResponse(" Cannot delete datasource with ID " + datasourceId - + " because it is used by the following routing specs: " - + errmsg, ErrorCodes.NOT_ALLOWED); - - dsDao.deleteDatasource(datasourceId); - return ApiHttpUtil.createResponse("Datasource with ID " + datasourceId + " deleted"); + if (datasourceId == null) + { + throw new WebAppException(HttpServletResponse.SC_BAD_REQUEST, "Missing required datasourceid parameter."); } - } + try + { + dbIo = getLegacyDatabase(); + DataSource ds = new DataSource(DbKey.createDbKey(datasourceId)); + dbIo.readDataSource(ds); + if (ds.getName() == null) + { + return Response.status(HttpServletResponse.SC_NOT_FOUND) + .entity("No such data source with ID " + datasourceId).build(); + } + if (ds.numUsedBy > 0) + { + return Response.status(HttpServletResponse.SC_METHOD_NOT_ALLOWED) + .entity(" Cannot delete datasource with ID " + datasourceId + + " because it is used by the following number of routing specs: " + + ds.numUsedBy).build(); + } + dbIo.deleteDataSource(ds); + return Response.status(HttpServletResponse.SC_OK) + .entity("Datasource with ID " + datasourceId + " deleted").build(); + } + catch (DatabaseException ex) + { + throw new DbException("Error deleting data source: " + ex); + } + finally + { + dbIo.close(); + } + } + + static Properties parseProps(String properties) + { + if (properties == null || properties.isEmpty()) + { + return new Properties(); + } + Properties props = new Properties(); + String[] pairs = properties.split(COMMA.pattern()); + for (String pair : pairs) + { + String[] keyValue = pair.split(EQUAL.pattern()); + props.setProperty(keyValue[0], keyValue[1]); + } + return props; + } } diff --git a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/DataSourceResourcesTest.java b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/DataSourceResourcesTest.java new file mode 100644 index 000000000..637449b2b --- /dev/null +++ b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/DataSourceResourcesTest.java @@ -0,0 +1,191 @@ +package org.opendcs.odcsapi.res; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + +import decodes.db.DataSource; +import decodes.db.DataSourceList; +import decodes.sql.DbKey; +import org.junit.jupiter.api.Test; +import org.opendcs.odcsapi.beans.ApiDataSource; +import org.opendcs.odcsapi.beans.ApiDataSourceGroupMember; +import org.opendcs.odcsapi.beans.ApiDataSourceRef; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; +import static org.opendcs.odcsapi.res.DataSourceResources.map; +import static org.opendcs.odcsapi.res.DataSourceResources.parseProps; +import static org.opendcs.odcsapi.res.DataSourceResources.propsToString; + +final class DataSourceResourcesTest +{ + @Test + void testDataSourceMap() throws Exception + { + DataSource ds = new DataSource(); + ds.numUsedBy = 12; + ds.setName("Parent"); + ds.setId(DbKey.createDbKey(57391L)); + Properties properties = new Properties(); + properties.setProperty("key", "value"); + ds.arguments = properties; + ds.dataSourceType = "Test type"; + ds.setDataSourceArg("This is a data source arg"); + Vector groupMembers = new Vector<>(); + DataSource member = new DataSource(); + member.setName("This is a group member"); + groupMembers.add(member); + ds.groupMembers = groupMembers; + + ApiDataSource apiData = map(ds); + + assertNotNull(apiData); + assertEquals(apiData.getDataSourceId(), ds.getId().getValue()); + assertEquals(apiData.getName(), ds.getName()); + assertMatch(apiData.getGroupMembers(), ds.groupMembers); + assertEquals(apiData.getUsedBy(), ds.numUsedBy); + assertEquals(apiData.getType(), ds.dataSourceType); + assertEquals(apiData.getProps(), ds.arguments); + } + + private static void assertMatch(List groupMembers, Vector groupMemVector) + { + for (ApiDataSourceGroupMember member : groupMembers) + { + boolean found = false; + for (DataSource source : groupMemVector) + { + if (member.getDataSourceId().equals(source.getId().getValue())) + { + found = true; + assertEquals(member.getDataSourceName(), source.getName()); + } + } + if (!found) + { + fail("Unable to find matching group member in list"); + } + } + } + + @Test + void testDataSourceListMap() + { + Vector groupMembers = new Vector<>(); + + List members = map(groupMembers); + assertNotNull(members); + assertMatch(members, groupMembers); + } + + @Test + void testApiDataSourceMap() throws Exception + { + ApiDataSource dataSource = new ApiDataSource(); + dataSource.setDataSourceId(58559642L); + dataSource.setName("data source name"); + dataSource.setType("Test type"); + dataSource.setUsedBy(12); + Properties props = new Properties(); + props.setProperty("Key", "Value"); + dataSource.setProps(props); + ArrayList memberList = new ArrayList<>(); + ApiDataSourceGroupMember member = new ApiDataSourceGroupMember(); + member.setDataSourceName("Child data source"); + member.setDataSourceId(8675309L); + memberList.add(member); + dataSource.setGroupMembers(memberList); + + DataSource result = map(dataSource); + + assertNotNull(result); + assertEquals(dataSource.getName(), result.getName()); + assertEquals(dataSource.getDataSourceId(), result.getId().getValue()); + assertEquals(dataSource.getUsedBy(), result.numUsedBy); + assertEquals(dataSource.getType(), result.dataSourceType); + assertEquals(dataSource.getProps(), result.arguments); + assertEquals(dataSource.getGroupMembers().size(), result.groupMembers.size()); + for (int i = 0; i < dataSource.getGroupMembers().size(); i++) + { + assertEquals(dataSource.getGroupMembers().get(i).getDataSourceName(), result.groupMembers.get(i).getName()); + assertEquals(dataSource.getGroupMembers().get(i).getDataSourceId(), result.groupMembers.get(i).getId().getValue()); + } + } + + @Test + void testDataSourceGroupMemberMap() + { + ArrayList groupMembers = new ArrayList<>(); + ApiDataSourceGroupMember member = new ApiDataSourceGroupMember(); + member.setDataSourceId(123456789L); + member.setDataSourceName("Test data source"); + groupMembers.add(member); + + Vector result = DataSourceResources.map(groupMembers); + + assertNotNull(result); + assertEquals(groupMembers.size(), result.size()); + for (int i = 0; i < groupMembers.size(); i++) + { + assertEquals(groupMembers.get(i).getDataSourceName(), result.get(i).getName()); + assertEquals(groupMembers.get(i).getDataSourceId(), result.get(i).getId().getValue()); + } + } + + @Test + void testSourceListToApiRefMap() throws Exception + { + DataSourceList list = new DataSourceList(); + DataSource ds = new DataSource(); + ds.setName("Test"); + ds.setDataSourceArg("test=true"); + ds.setId(DbKey.createDbKey(12345L)); + list.add(ds); + + List result = map(list); + + assertNotNull(result); + ApiDataSourceRef ref = result.get(0); + assertNotNull(ref); + assertEquals(ds.getName(), ref.getName()); + assertEquals(ds.getId().getValue(), ref.getDataSourceId()); + assertEquals(ds.getDataSourceArg(), ref.getArguments()); + } + + @Test + void testPropertyMap() + { + Properties props = new Properties(); + props.setProperty("key", "value"); + props.setProperty("key2", "value2"); + + ApiDataSource apiData = new ApiDataSource(); + apiData.setProps(props); + + String result = propsToString(apiData.getProps()); + + assertNotNull(result); + assertEquals("key=value,key2=value2", result); + + props = new Properties(); + result = propsToString(props); + assertEquals("", result); + } + + @Test + void testPropertyStringParser() + { + String propString = "key=value,key2=value2"; + Properties result = parseProps(propString); + assertEquals(2, result.size()); + assertEquals("value", result.getProperty("key")); + assertEquals("value2", result.getProperty("key2")); + + propString = ""; + result = parseProps(propString); + assertEquals(0, result.size()); + } +} diff --git a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/BaseIT.java b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/BaseIT.java index 999509a9f..c1b57e797 100644 --- a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/BaseIT.java +++ b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/BaseIT.java @@ -128,7 +128,7 @@ void authenticate(SessionFilter sessionFilter) void logout(SessionFilter sessionFilter) { - if(DatabaseSetupExtension.getCurrentDbType() == DbType.OPEN_TSDB) + if (DatabaseSetupExtension.getCurrentDbType() == DbType.OPEN_TSDB) { given() .log().ifValidationFails(LogDetail.ALL, true) diff --git a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/DataSourceResourcesIT.java b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/DataSourceResourcesIT.java new file mode 100644 index 000000000..ee4bbae21 --- /dev/null +++ b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/it/DataSourceResourcesIT.java @@ -0,0 +1,261 @@ +package org.opendcs.odcsapi.res.it; + + +import java.util.ArrayList; +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.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.ApiDataSource; +import org.opendcs.odcsapi.beans.ApiDataSourceGroupMember; +import org.opendcs.odcsapi.fixtures.DatabaseContextProvider; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.greaterThan; + +@Tag("integration-opentsdb-only") +@ExtendWith(DatabaseContextProvider.class) +final class DataSourceResourcesIT extends BaseIT +{ + private static SessionFilter sessionFilter; + private static Long sourceId; + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + @BeforeEach + void setUp() throws Exception + { + setUpCreds(); + sessionFilter = new SessionFilter(); + + authenticate(sessionFilter); + + ApiDataSource dsGroupMem = new ApiDataSource(); + dsGroupMem.setName("Sensor Data Value"); + dsGroupMem.setUsedBy(2); + dsGroupMem.setType("Sensor"); + Properties props = new Properties(); + props.setProperty("country", "USA"); + dsGroupMem.setProps(props); + + String dsJson = OBJECT_MAPPER.writeValueAsString(dsGroupMem); + + ExtractableResponse response = given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .body(dsJson) + .when() + .redirects().follow(true) + .redirects().max(3) + .post("datasource") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + .extract() + ; + + Long memberSourceId = response.body().jsonPath().getLong("dataSourceId"); + + ApiDataSource ds = new ApiDataSource(); + ds.setName("Sensor Data"); + ds.setUsedBy(12); + ds.setType("Sensor"); + Properties properties = new Properties(); + properties.setProperty("country", "USA"); + ds.setProps(properties); + ArrayList groupMembers = new ArrayList<>(); + ApiDataSourceGroupMember groupMember = new ApiDataSourceGroupMember(); + groupMember.setDataSourceName(dsGroupMem.getName()); + groupMember.setDataSourceId(memberSourceId); + groupMembers.add(groupMember); + ds.setGroupMembers(groupMembers); + + dsJson = OBJECT_MAPPER.writeValueAsString(ds); + + response = given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .body(dsJson) + .when() + .redirects().follow(true) + .redirects().max(3) + .post("datasource") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + .extract() + ; + + sourceId = response.body().jsonPath().getLong("dataSourceId"); + } + + @AfterEach + void tearDown() + { + given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .queryParam("datasourceid", sourceId) + .filter(sessionFilter) + .when() + .redirects().follow(true) + .redirects().max(3) + .delete("datasource") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + ; + + logout(sessionFilter); + } + + @TestTemplate + void testDataSourceRefs() + { + 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("datasourcerefs") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + .body("size()", greaterThan(0)) + ; + } + + @TestTemplate + void testGetDataSource() + { + given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .queryParam("datasourceid", sourceId) + .when() + .redirects().follow(true) + .redirects().max(3) + .get("datasource") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + ; + } + + @TestTemplate + void testPostAndDeleteDataSource() throws Exception + { + ApiDataSource dsGroupMem = new ApiDataSource(); + dsGroupMem.setName("Satellite Data Value"); + dsGroupMem.setUsedBy(2); + dsGroupMem.setType("Satellite"); + Properties props = new Properties(); + props.setProperty("country", "USA"); + dsGroupMem.setProps(props); + + String dsJson = OBJECT_MAPPER.writeValueAsString(dsGroupMem); + + ExtractableResponse response = given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .body(dsJson) + .when() + .redirects().follow(true) + .redirects().max(3) + .post("datasource") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + .extract() + ; + + Long memberSourceId = response.body().jsonPath().getLong("dataSourceId"); + + ApiDataSource ds = new ApiDataSource(); + ds.setName("Satellite Data"); + ds.setUsedBy(12); + ds.setType("Satellite"); + Properties properties = new Properties(); + properties.setProperty("location", "low Earth orbit"); + ds.setProps(properties); + ArrayList groupMembers = new ArrayList<>(); + ApiDataSourceGroupMember groupMember = new ApiDataSourceGroupMember(); + groupMember.setDataSourceName(dsGroupMem.getName()); + groupMember.setDataSourceId(memberSourceId); + groupMembers.add(groupMember); + ds.setGroupMembers(groupMembers); + + dsJson = OBJECT_MAPPER.writeValueAsString(ds); + + response = given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .filter(sessionFilter) + .body(dsJson) + .when() + .redirects().follow(true) + .redirects().max(3) + .post("datasource") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + .extract() + ; + + Long newSourceId = response.body().jsonPath().getLong("dataSourceId"); + + given() + .log().ifValidationFails(LogDetail.ALL, true) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", authHeader) + .queryParam("datasourceid", newSourceId) + .filter(sessionFilter) + .when() + .redirects().follow(true) + .redirects().max(3) + .delete("datasource") + .then() + .log().ifValidationFails(LogDetail.ALL, true) + .assertThat() + .statusCode(is(HttpServletResponse.SC_OK)) + ; + } +}