From b9188440af799aa9ce7328480ff7aec525ca51f1 Mon Sep 17 00:00:00 2001 From: Martin Weise <martin.weise@tuwien.ac.at> Date: Fri, 4 Oct 2024 17:38:24 +0200 Subject: [PATCH] Fixed access-related errors, ref #453 --- .../at/tuwien/endpoints/AccessEndpoint.java | 3 +- .../at/tuwien/endpoints/TableEndpoint.java | 10 +- .../java/at/tuwien/config/MariaDbConfig.java | 2 - .../endpoint/AccessEndpointUnitTest.java | 16 +- .../endpoint/TableEndpointUnitTest.java | 28 ++-- .../tuwien/mvc/PrometheusEndpointMvcTest.java | 4 +- .../service/SchemaServiceIntegrationTest.java | 56 +++---- .../service/TableServiceIntegrationTest.java | 68 +++------ .../service/ViewServiceIntegrationTest.java | 8 +- .../impl/MetadataServiceGatewayImpl.java | 36 ++++- .../java/at/tuwien/mapper/DataMapper.java | 36 ----- .../java/at/tuwien/mapper/MariaDbMapper.java | 137 +----------------- .../java/at/tuwien/service/TableService.java | 4 +- .../service/impl/TableServiceMariaDbImpl.java | 4 +- dbrepo-metadata-db/1_setup-schema.sql | 21 --- .../api/container/image/ImageDateDto.java | 48 ------ .../tuwien/api/container/image/ImageDto.java | 5 - .../internal/PrivilegedContainerDto.java | 1 - .../at/tuwien/api/database/ViewColumnDto.java | 4 - .../api/database/query/ImportCsvDto.java | 49 ------- .../tuwien/api/database/query/ImportDto.java | 10 -- .../api/database/table/columns/ColumnDto.java | 4 - .../at/tuwien/endpoints/AccessEndpoint.java | 39 ++--- .../at/tuwien/endpoints/TableEndpoint.java | 9 -- .../at/tuwien/endpoints/UserEndpoint.java | 14 +- .../tuwien/validation/EndpointValidator.java | 49 ++----- .../gateway/BrokerServiceGatewayUnitTest.java | 32 ++-- .../service/BrokerServiceIntegrationTest.java | 17 ++- .../service/DatabaseServiceUnitTest.java | 6 +- .../service/impl/AccessServiceImpl.java | 3 +- .../service/impl/DatabaseServiceImpl.java | 3 + .../main/java/at/tuwien/test/BaseTest.java | 87 ----------- dbrepo-ui/components/dialogs/EditAccess.vue | 36 +++-- dbrepo-ui/composables/access-service.ts | 2 +- dbrepo-ui/locales/en-US.json | 14 +- .../pages/database/[database_id]/settings.vue | 11 +- 36 files changed, 236 insertions(+), 640 deletions(-) delete mode 100644 dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/image/ImageDateDto.java delete mode 100644 dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/ImportCsvDto.java diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java index 133bee769c..4059a37a92 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java @@ -18,6 +18,7 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -88,7 +89,7 @@ public class AccessEndpoint { } try { accessService.create(database, user, data.getType()); - return ResponseEntity.accepted() + return ResponseEntity.status(HttpStatus.CREATED) .build(); } catch (SQLException e) { log.error("Failed to establish connection to database: {}", e.getMessage()); diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java index 4af577bed5..674ed4ec4c 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java @@ -4,8 +4,7 @@ import at.tuwien.ExportResourceDto; import at.tuwien.api.database.DatabaseAccessDto; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.internal.PrivilegedDatabaseDto; -import at.tuwien.api.database.query.ImportCsvDto; -import at.tuwien.api.database.query.QueryDto; +import at.tuwien.api.database.query.ImportDto; import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.api.database.table.*; import at.tuwien.api.database.table.internal.PrivilegedTableDto; @@ -33,7 +32,6 @@ import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.InputStreamResource; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -614,7 +612,7 @@ public class TableEndpoint { }) public ResponseEntity<Void> importDataset(@NotBlank @PathVariable("databaseId") Long databaseId, @NotBlank @PathVariable("tableId") Long tableId, - @Valid @RequestBody ImportCsvDto data, + @Valid @RequestBody ImportDto data, @NotNull Principal principal) throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, QueryMalformedException, StorageNotFoundException, SidecarImportException, NotAllowedException, @@ -623,10 +621,6 @@ public class TableEndpoint { final PrivilegedTableDto table = metadataServiceGateway.getTableById(databaseId, tableId); final DatabaseAccessDto access = metadataServiceGateway.getAccess(databaseId, UserUtil.getId(principal)); endpointValidator.validateOnlyWriteOwnOrWriteAllAccess(access.getType(), table.getOwner().getId(), UserUtil.getId(principal)); - if (data.getNullElement() == null) { - data.setNullElement(""); - log.debug("null element not present, default to empty string"); - } if (data.getLineTermination() == null) { data.setLineTermination("\\r\\n"); log.debug("line termination not present, default to {}", data.getLineTermination()); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java index b0c332a63b..691d96006b 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java @@ -6,13 +6,11 @@ import at.tuwien.api.database.internal.PrivilegedDatabaseDto; import at.tuwien.api.database.query.QueryDto; import at.tuwien.api.database.table.columns.ColumnTypeDto; import at.tuwien.api.database.table.internal.PrivilegedTableDto; -import at.tuwien.querystore.Query; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; -import java.io.IOException; import java.sql.*; import java.time.Instant; import java.util.*; diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/AccessEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/AccessEndpointUnitTest.java index 3beb5626b3..a2cbae3ea8 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/AccessEndpointUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/AccessEndpointUnitTest.java @@ -15,12 +15,14 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.junit.jupiter.SpringExtension; import java.sql.SQLException; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @Log4j2 @@ -54,7 +56,9 @@ public class AccessEndpointUnitTest extends AbstractUnitTest { .thenReturn(USER_4_PRIVILEGED_DTO); /* test */ - accessEndpoint.create(DATABASE_1_ID, USER_4_ID, UPDATE_DATABASE_ACCESS_READ_DTO); + final ResponseEntity<Void> response = accessEndpoint.create(DATABASE_1_ID, USER_4_ID, UPDATE_DATABASE_ACCESS_READ_DTO); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNull(response.getBody()); } @Test @@ -150,7 +154,9 @@ public class AccessEndpointUnitTest extends AbstractUnitTest { .thenReturn(USER_1_DTO); /* test */ - accessEndpoint.update(DATABASE_1_ID, USER_1_ID, UPDATE_DATABASE_ACCESS_READ_DTO); + final ResponseEntity<Void> response = accessEndpoint.update(DATABASE_1_ID, USER_1_ID, UPDATE_DATABASE_ACCESS_READ_DTO); + assertEquals(HttpStatus.ACCEPTED, response.getStatusCode()); + assertNull(response.getBody()); } @Test @@ -250,7 +256,9 @@ public class AccessEndpointUnitTest extends AbstractUnitTest { .delete(any(PrivilegedDatabaseDto.class), any(UserDto.class)); /* test */ - accessEndpoint.revoke(DATABASE_1_ID, USER_1_ID); + final ResponseEntity<Void> response = accessEndpoint.revoke(DATABASE_1_ID, USER_1_ID); + assertEquals(HttpStatus.ACCEPTED, response.getStatusCode()); + assertNull(response.getBody()); } @Test diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java index f03f4c3f18..e9356fc39f 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java @@ -2,7 +2,7 @@ package at.tuwien.endpoint; import at.tuwien.ExportResourceDto; import at.tuwien.api.database.DatabaseAccessDto; -import at.tuwien.api.database.query.ImportCsvDto; +import at.tuwien.api.database.query.ImportDto; import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.api.database.table.*; import at.tuwien.api.database.table.internal.PrivilegedTableDto; @@ -1261,7 +1261,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { public void importDataset_succeeds() throws DatabaseUnavailableException, TableNotFoundException, SidecarImportException, NotAllowedException, QueryMalformedException, RemoteUnavailableException, StorageNotFoundException, SQLException, MetadataServiceException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination(null) .location("deadbeef") @@ -1287,7 +1287,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_4_USERNAME) public void importDataset_noRole_fails() { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination("\\n") .location("deadbeef") @@ -1303,7 +1303,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void importDataset_tableNotFound_fails() throws TableNotFoundException, RemoteUnavailableException, MetadataServiceException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination("\\n") .location("deadbeef") @@ -1325,7 +1325,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { public void importDataset_unavailable_fails() throws RemoteUnavailableException, SidecarImportException, SQLException, QueryMalformedException, StorageNotFoundException, TableNotFoundException, MetadataServiceException, NotAllowedException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination("\\n") .location("deadbeef") @@ -1351,7 +1351,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { public void importDataset_writeOwnAccess_fails() throws RemoteUnavailableException, SidecarImportException, SQLException, QueryMalformedException, StorageNotFoundException, TableNotFoundException, MetadataServiceException, NotAllowedException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination("\\n") .location("deadbeef") @@ -1376,7 +1376,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void importDataset_readAccess_fails() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination("\\n") .location("deadbeef") @@ -1399,7 +1399,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { public void importDataset_writeOwnAccess_succeeds() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, DatabaseUnavailableException, SidecarImportException, QueryMalformedException, StorageNotFoundException, MetadataServiceException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination("\\n") .location("deadbeef") @@ -1419,7 +1419,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void importDataset_writeOwnAccessForeign_fails() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination("\\n") .location("deadbeef") @@ -1442,7 +1442,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { public void importDataset_writeAllAccessForeign_succeeds() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, DatabaseUnavailableException, SidecarImportException, QueryMalformedException, StorageNotFoundException, MetadataServiceException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination("\\n") .location("deadbeef") @@ -1463,7 +1463,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { public void importDataset_privateForeign_succeeds() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, DatabaseUnavailableException, SidecarImportException, QueryMalformedException, StorageNotFoundException, MetadataServiceException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination("\\n") .location("deadbeef") @@ -1484,7 +1484,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { public void importDataset_private_succeeds() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, DatabaseUnavailableException, SidecarImportException, QueryMalformedException, StorageNotFoundException, MetadataServiceException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination("\\n") .location("deadbeef") @@ -1504,7 +1504,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_2_USERNAME, authorities = {"insert-table-data"}) public void importDataset_privateForeign_fails() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination("\\n") .location("deadbeef") @@ -1526,7 +1526,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_2_USERNAME, authorities = {"insert-table-data"}) public void importDataset_privateReadAccess_fails() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .skipLines(1L) .lineTermination("\\n") .location("deadbeef") diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java index b331a03fa6..f4bd429a90 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java @@ -1,7 +1,7 @@ package at.tuwien.mvc; import at.tuwien.api.database.query.ExecuteStatementDto; -import at.tuwien.api.database.query.ImportCsvDto; +import at.tuwien.api.database.query.ImportDto; import at.tuwien.api.database.query.QueryPersistDto; import at.tuwien.api.database.table.TupleDeleteDto; import at.tuwien.api.database.table.TupleDto; @@ -201,7 +201,7 @@ public class PrometheusEndpointMvcTest extends AbstractUnitTest { /* ignore */ } try { - tableEndpoint.importDataset(DATABASE_1_ID, TABLE_1_ID, ImportCsvDto.builder().build(), USER_1_PRINCIPAL); + tableEndpoint.importDataset(DATABASE_1_ID, TABLE_1_ID, ImportDto.builder().build(), USER_1_PRINCIPAL); } catch (Exception e) { /* ignore */ } diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SchemaServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SchemaServiceIntegrationTest.java index d69ea86e68..85e2b80711 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SchemaServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SchemaServiceIntegrationTest.java @@ -1,6 +1,5 @@ package at.tuwien.service; -import at.tuwien.api.container.image.ImageDateDto; import at.tuwien.api.database.ViewColumnDto; import at.tuwien.api.database.ViewDto; import at.tuwien.api.database.table.TableBriefDto; @@ -16,7 +15,8 @@ import at.tuwien.api.database.table.constraints.unique.UniqueDto; import at.tuwien.api.identifier.IdentifierDto; import at.tuwien.config.MariaDbConfig; import at.tuwien.config.MariaDbContainerConfig; -import at.tuwien.exception.*; +import at.tuwien.exception.TableNotFoundException; +import at.tuwien.exception.ViewNotFoundException; import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.BeforeEach; @@ -74,11 +74,11 @@ public class SchemaServiceIntegrationTest extends AbstractUnitTest { final List<ColumnDto> columns = response.getColumns(); assertNotNull(columns); assertEquals(5, columns.size()); - assertColumn(columns.get(0), null, null, DATABASE_1_ID, "id", "id", ColumnTypeDto.BIGINT, 19L, 0L, false, null, null); - assertColumn(columns.get(1), null, null, DATABASE_1_ID, "given_name", "given_name", ColumnTypeDto.VARCHAR, 255L, null, false, null, null); - assertColumn(columns.get(2), null, null, DATABASE_1_ID, "middle_name", "middle_name", ColumnTypeDto.VARCHAR, 255L, null, true, null, null); - assertColumn(columns.get(3), null, null, DATABASE_1_ID, "family_name", "family_name", ColumnTypeDto.VARCHAR, 255L, null, false, null, null); - assertColumn(columns.get(4), null, null, DATABASE_1_ID, "age", "age", ColumnTypeDto.INT, 10L, 0L, false, null, null); + assertColumn(columns.get(0), null, null, DATABASE_1_ID, "id", "id", ColumnTypeDto.BIGINT, 19L, 0L, false, null); + assertColumn(columns.get(1), null, null, DATABASE_1_ID, "given_name", "given_name", ColumnTypeDto.VARCHAR, 255L, null, false, null); + assertColumn(columns.get(2), null, null, DATABASE_1_ID, "middle_name", "middle_name", ColumnTypeDto.VARCHAR, 255L, null, true, null); + assertColumn(columns.get(3), null, null, DATABASE_1_ID, "family_name", "family_name", ColumnTypeDto.VARCHAR, 255L, null, false, null); + assertColumn(columns.get(4), null, null, DATABASE_1_ID, "age", "age", ColumnTypeDto.INT, 10L, 0L, false, null); final ConstraintsDto constraints = response.getConstraints(); assertNotNull(constraints); final Set<PrimaryKeyDto> primaryKey = constraints.getPrimaryKey(); @@ -127,11 +127,11 @@ public class SchemaServiceIntegrationTest extends AbstractUnitTest { final List<ColumnDto> columns = response.getColumns(); assertNotNull(columns); assertEquals(3, columns.size()); - assertColumn(columns.get(0), null, null, DATABASE_2_ID, "id", "id", ColumnTypeDto.BIGINT, 19L, 0L, false, null, null); - assertColumn(columns.get(1), null, null, DATABASE_2_ID, "mode", "mode", ColumnTypeDto.ENUM, 3L, null, false, null, null); + assertColumn(columns.get(0), null, null, DATABASE_2_ID, "id", "id", ColumnTypeDto.BIGINT, 19L, 0L, false, null); + assertColumn(columns.get(1), null, null, DATABASE_2_ID, "mode", "mode", ColumnTypeDto.ENUM, 3L, null, false, null); assertEquals(2, columns.get(1).getEnums().size()); assertEquals(List.of("ABC", "DEF"), columns.get(1).getEnums()); - assertColumn(columns.get(2), null, null, DATABASE_2_ID, "seq", "seq", ColumnTypeDto.SET, 5L, null, true, null, null); + assertColumn(columns.get(2), null, null, DATABASE_2_ID, "seq", "seq", ColumnTypeDto.SET, 5L, null, true, null); assertEquals(3, columns.get(2).getSets().size()); assertEquals(List.of("1", "2", "3"), columns.get(2).getSets()); /* ignore rest (constraints) */ @@ -167,11 +167,11 @@ public class SchemaServiceIntegrationTest extends AbstractUnitTest { final List<ColumnDto> columns = response.getColumns(); assertNotNull(columns); assertEquals(5, columns.size()); - assertColumn(columns.get(0), null, null, DATABASE_1_ID, "id", "id", ColumnTypeDto.BIGINT, 19L, 0L, false, null, null); - assertColumn(columns.get(1), null, null, DATABASE_1_ID, "date", "date", ColumnTypeDto.DATE, null, null, false, IMAGE_DATE_1_ID, null); - assertColumn(columns.get(2), null, null, DATABASE_1_ID, "location", "location", ColumnTypeDto.VARCHAR, 255L, null, true, null, "Closest city"); - assertColumn(columns.get(3), null, null, DATABASE_1_ID, "mintemp", "mintemp", ColumnTypeDto.DOUBLE, 22L, null, true, null, null); - assertColumn(columns.get(4), null, null, DATABASE_1_ID, "rainfall", "rainfall", ColumnTypeDto.DOUBLE, 22L, null, true, null, null); + assertColumn(columns.get(0), null, null, DATABASE_1_ID, "id", "id", ColumnTypeDto.BIGINT, 19L, 0L, false, null); + assertColumn(columns.get(1), null, null, DATABASE_1_ID, "date", "date", ColumnTypeDto.DATE, null, null, false, null); + assertColumn(columns.get(2), null, null, DATABASE_1_ID, "location", "location", ColumnTypeDto.VARCHAR, 255L, null, true, "Closest city"); + assertColumn(columns.get(3), null, null, DATABASE_1_ID, "mintemp", "mintemp", ColumnTypeDto.DOUBLE, 22L, null, true, null); + assertColumn(columns.get(4), null, null, DATABASE_1_ID, "rainfall", "rainfall", ColumnTypeDto.DOUBLE, 22L, null, true, null); final ConstraintsDto constraints = response.getConstraints(); final List<PrimaryKeyDto> primaryKey = new LinkedList<>(constraints.getPrimaryKey()); assertEquals(1, primaryKey.size()); @@ -359,9 +359,9 @@ public class SchemaServiceIntegrationTest extends AbstractUnitTest { assertEquals(ColumnTypeDto.BOOL, pk0.getColumn().getColumnType()); final List<ColumnDto> columns = response.getColumns(); assertEquals(3, columns.size()); - assertColumn(columns.get(0), null, null, DATABASE_1_ID, "bool_default", "bool_default", ColumnTypeDto.BOOL, null, 0L, false, null, null); - assertColumn(columns.get(1), null, null, DATABASE_1_ID, "bool_tinyint", "bool_tinyint", ColumnTypeDto.BOOL, null, 0L, false, null, null); - assertColumn(columns.get(2), null, null, DATABASE_1_ID, "bool_tinyint_unsigned", "bool_tinyint_unsigned", ColumnTypeDto.BOOL, null, 0L, false, null, null); + assertColumn(columns.get(0), null, null, DATABASE_1_ID, "bool_default", "bool_default", ColumnTypeDto.BOOL, null, 0L, false, null); + assertColumn(columns.get(1), null, null, DATABASE_1_ID, "bool_tinyint", "bool_tinyint", ColumnTypeDto.BOOL, null, 0L, false, null); + assertColumn(columns.get(2), null, null, DATABASE_1_ID, "bool_tinyint_unsigned", "bool_tinyint_unsigned", ColumnTypeDto.BOOL, null, 0L, false, null); } @Test @@ -398,9 +398,9 @@ public class SchemaServiceIntegrationTest extends AbstractUnitTest { assertEquals(DATABASE_1_ID, column3.getDatabaseId()); } - protected static void assertViewColumn(ViewColumnDto column, Long id, Long databaseId, String name, String internalName, - ColumnTypeDto type, Long size, Long d, Boolean nullAllowed, - ImageDateDto dateFormat, String description) { + protected static void assertViewColumn(ViewColumnDto column, Long id, Long databaseId, String name, + String internalName, ColumnTypeDto type, Long size, Long d, + Boolean nullAllowed, String description) { log.trace("assert column: {}", internalName); assertNotNull(column); assertEquals(id, column.getId()); @@ -412,17 +412,11 @@ public class SchemaServiceIntegrationTest extends AbstractUnitTest { assertEquals(d, column.getD()); assertEquals(nullAllowed, column.getIsNullAllowed()); assertEquals(description, column.getDescription()); - if (dateFormat != null) { - assertNotNull(column.getDateFormat()); - assertEquals(dateFormat.getId(), column.getDateFormat().getId()); - } else { - assertNull(column.getDateFormat()); - } } protected static void assertColumn(ColumnDto column, Long id, Long tableId, Long databaseId, String name, String internalName, ColumnTypeDto type, Long size, Long d, Boolean nullAllowed, - Long dfid, String description) { + String description) { log.trace("assert column: {}", internalName); assertNotNull(column); assertEquals(id, column.getId()); @@ -437,12 +431,6 @@ public class SchemaServiceIntegrationTest extends AbstractUnitTest { assertEquals(d, column.getD()); assertEquals(nullAllowed, column.getIsNullAllowed()); assertEquals(description, column.getDescription()); - if (dfid != null) { - assertNotNull(column.getDateFormat()); - assertEquals(dfid, column.getDateFormat().getId()); - } else { - assertNull(column.getDateFormat()); - } } } diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationTest.java index 4ebaba4931..26251caa62 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationTest.java @@ -1,7 +1,7 @@ package at.tuwien.service; import at.tuwien.ExportResourceDto; -import at.tuwien.api.database.query.ImportCsvDto; +import at.tuwien.api.database.query.ImportDto; import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.api.database.table.*; import at.tuwien.api.database.table.columns.ColumnCreateDto; @@ -19,7 +19,6 @@ import at.tuwien.api.database.table.internal.TableCreateDto; import at.tuwien.config.MariaDbConfig; import at.tuwien.config.MariaDbContainerConfig; import at.tuwien.config.QueryConfig; -import at.tuwien.config.S3Config; import at.tuwien.exception.*; import at.tuwien.gateway.DataDatabaseSidecarGateway; import at.tuwien.gateway.MetadataServiceGateway; @@ -45,15 +44,11 @@ import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.math.BigInteger; -import java.nio.charset.Charset; -import java.nio.file.attribute.FileAttribute; -import java.nio.file.attribute.PosixFilePermissions; import java.sql.SQLException; import java.time.Instant; import java.util.*; import static at.tuwien.service.SchemaServiceIntegrationTest.assertColumn; -import static at.tuwien.service.SchemaServiceIntegrationTest.assertViewColumn; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.doNothing; @@ -383,9 +378,9 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { final List<ColumnDto> columns0 = table0.getColumns(); assertNotNull(columns0); Assertions.assertEquals(3, columns0.size()); - assertColumn(columns0.get(0), null, null, DATABASE_1_ID, "id", "id", ColumnTypeDto.BIGINT, 19L, 0L, false, null, null); - assertColumn(columns0.get(1), null, null, DATABASE_1_ID, "weather_id", "weather_id", ColumnTypeDto.BIGINT, 19L, 0L, false, null, null); - assertColumn(columns0.get(2), null, null, DATABASE_1_ID, "other_id", "other_id", ColumnTypeDto.BIGINT, 19L, 0L, false, null, null); + assertColumn(columns0.get(0), null, null, DATABASE_1_ID, "id", "id", ColumnTypeDto.BIGINT, 19L, 0L, false, null); + assertColumn(columns0.get(1), null, null, DATABASE_1_ID, "weather_id", "weather_id", ColumnTypeDto.BIGINT, 19L, 0L, false, null); + assertColumn(columns0.get(2), null, null, DATABASE_1_ID, "other_id", "other_id", ColumnTypeDto.BIGINT, 19L, 0L, false, null); final ConstraintsDto constraints0 = table0.getConstraints(); assertNotNull(constraints0); assertEquals(1, constraints0.getPrimaryKey().size()); @@ -430,8 +425,8 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { final List<ColumnDto> columns1 = table1.getColumns(); assertNotNull(columns1); Assertions.assertEquals(2, columns1.size()); - assertColumn(columns1.get(0), null, null, DATABASE_1_ID, "id", "id", ColumnTypeDto.BIGINT, 19L, 0L, false, null, null); - assertColumn(columns1.get(1), null, null, DATABASE_1_ID, "other_id", "other_id", ColumnTypeDto.BIGINT, 19L, 0L, false, null, null); + assertColumn(columns1.get(0), null, null, DATABASE_1_ID, "id", "id", ColumnTypeDto.BIGINT, 19L, 0L, false, null); + assertColumn(columns1.get(1), null, null, DATABASE_1_ID, "other_id", "other_id", ColumnTypeDto.BIGINT, 19L, 0L, false, null); final ConstraintsDto constraints1 = table1.getConstraints(); assertNotNull(constraints1); assertEquals(2, constraints1.getPrimaryKey().size()); @@ -458,9 +453,9 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { final List<ColumnDto> columns2 = table2.getColumns(); assertNotNull(columns2); Assertions.assertEquals(3, columns2.size()); - assertColumn(columns2.get(0), null, null, DATABASE_1_ID, "bool_default", "bool_default", ColumnTypeDto.BOOL, null, 0L, false, null, null); - assertColumn(columns2.get(1), null, null, DATABASE_1_ID, "bool_tinyint", "bool_tinyint", ColumnTypeDto.BOOL, null, 0L, false, null, null); - assertColumn(columns2.get(2), null, null, DATABASE_1_ID, "bool_tinyint_unsigned", "bool_tinyint_unsigned", ColumnTypeDto.BOOL, null, 0L, false, null, null); + assertColumn(columns2.get(0), null, null, DATABASE_1_ID, "bool_default", "bool_default", ColumnTypeDto.BOOL, null, 0L, false, null); + assertColumn(columns2.get(1), null, null, DATABASE_1_ID, "bool_tinyint", "bool_tinyint", ColumnTypeDto.BOOL, null, 0L, false, null); + assertColumn(columns2.get(2), null, null, DATABASE_1_ID, "bool_tinyint_unsigned", "bool_tinyint_unsigned", ColumnTypeDto.BOOL, null, 0L, false, null); final ConstraintsDto constraints2 = table2.getConstraints(); assertNotNull(constraints2); final Set<PrimaryKeyDto> primaryKey2 = constraints2.getPrimaryKey(); @@ -479,11 +474,11 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { final List<ColumnDto> columns3 = table3.getColumns(); assertNotNull(columns3); Assertions.assertEquals(5, columns3.size()); - assertColumn(columns3.get(0), null, null, DATABASE_1_ID, "id", "id", ColumnTypeDto.BIGINT, 19L, 0L, false, null, null); - assertColumn(columns3.get(1), null, null, DATABASE_1_ID, "given_name", "given_name", ColumnTypeDto.VARCHAR, 255L, null, false, null, null); - assertColumn(columns3.get(2), null, null, DATABASE_1_ID, "middle_name", "middle_name", ColumnTypeDto.VARCHAR, 255L, null, true, null, null); - assertColumn(columns3.get(3), null, null, DATABASE_1_ID, "family_name", "family_name", ColumnTypeDto.VARCHAR, 255L, null, false, null, null); - assertColumn(columns3.get(4), null, null, DATABASE_1_ID, "age", "age", ColumnTypeDto.INT, 10L, 0L, false, null, null); + assertColumn(columns3.get(0), null, null, DATABASE_1_ID, "id", "id", ColumnTypeDto.BIGINT, 19L, 0L, false, null); + assertColumn(columns3.get(1), null, null, DATABASE_1_ID, "given_name", "given_name", ColumnTypeDto.VARCHAR, 255L, null, false, null); + assertColumn(columns3.get(2), null, null, DATABASE_1_ID, "middle_name", "middle_name", ColumnTypeDto.VARCHAR, 255L, null, true, null); + assertColumn(columns3.get(3), null, null, DATABASE_1_ID, "family_name", "family_name", ColumnTypeDto.VARCHAR, 255L, null, false, null); + assertColumn(columns3.get(4), null, null, DATABASE_1_ID, "age", "age", ColumnTypeDto.INT, 10L, 0L, false, null); final ConstraintsDto constraints3 = table3.getConstraints(); assertNotNull(constraints3); final Set<PrimaryKeyDto> primaryKey3 = constraints3.getPrimaryKey(); @@ -509,8 +504,8 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { assertEquals(TABLE_4_INTERNALNAME, response.getInternalName()); final List<ColumnDto> columns = response.getColumns(); assertEquals(TABLE_4_COLUMNS.size(), columns.size()); - assertColumn(columns.get(0), null, null, DATABASE_1_ID, "timestamp", "timestamp", ColumnTypeDto.TIMESTAMP, null, null, false, queryConfig.getDefaultTimestampFormatId(), null); - assertColumn(columns.get(1), null, null, DATABASE_1_ID, "value", "value", ColumnTypeDto.DECIMAL, 10L, 10L, true, null, null); + assertColumn(columns.get(0), null, null, DATABASE_1_ID, "timestamp", "timestamp", ColumnTypeDto.TIMESTAMP, null, null, false, null); + assertColumn(columns.get(1), null, null, DATABASE_1_ID, "value", "value", ColumnTypeDto.DECIMAL, 10L, 10L, true, null); final ConstraintsDto constraints = response.getConstraints(); assertNotNull(constraints); final Set<PrimaryKeyDto> primaryKey = constraints.getPrimaryKey(); @@ -619,9 +614,9 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { assertEquals("composite_primary_key", response.getInternalName()); final List<ColumnDto> columns = response.getColumns(); assertEquals(3, columns.size()); - assertColumn(columns.get(0), null, null, DATABASE_1_ID, "name", "name", ColumnTypeDto.VARCHAR, 255L, null, false, null, null); - assertColumn(columns.get(1), null, null, DATABASE_1_ID, "lat", "lat", ColumnTypeDto.DECIMAL, 10L, 10L, false, null, null); - assertColumn(columns.get(2), null, null, DATABASE_1_ID, "lng", "lng", ColumnTypeDto.DECIMAL, 10L, 10L, false, null, null); + assertColumn(columns.get(0), null, null, DATABASE_1_ID, "name", "name", ColumnTypeDto.VARCHAR, 255L, null, false, null); + assertColumn(columns.get(1), null, null, DATABASE_1_ID, "lat", "lat", ColumnTypeDto.DECIMAL, 10L, 10L, false, null); + assertColumn(columns.get(2), null, null, DATABASE_1_ID, "lng", "lng", ColumnTypeDto.DECIMAL, 10L, 10L, false, null); final ConstraintsDto constraints = response.getConstraints(); assertNotNull(constraints); final Set<String> checks = constraints.getChecks(); @@ -768,33 +763,10 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { }); } - @Test - public void importDataset_withSeparatorAndQuoteAndNullElement_succeeds() throws SidecarImportException, - SQLException, QueryMalformedException, RemoteUnavailableException, StorageNotFoundException, IOException { - final ImportCsvDto request = ImportCsvDto.builder() - .location("weather_aus.csv") - .separator(';') - .quote('"') - .nullElement("NA") - .build(); - - /* mock */ - final File source = new File("src/test/resources/csv/weather_aus.csv"); - final File target = new File("/tmp/weather_aus.csv") /* must be /tmp */; - log.trace("copy dataset from {} to {}", source.toPath().toAbsolutePath(), target.toPath().toAbsolutePath()); - FileUtils.copyFile(source, target); - doNothing() - .when(dataDatabaseSidecarGateway) - .importFile(anyString(), anyInt(), eq("weather_aus.csv")); - - /* test */ - tableService.importDataset(TABLE_1_PRIVILEGED_DTO, request); - } - @Test public void importDataset_malformedData_fails() throws RemoteUnavailableException, StorageNotFoundException, IOException, SidecarImportException { - final ImportCsvDto request = ImportCsvDto.builder() + final ImportDto request = ImportDto.builder() .location("weather_aus.csv") .separator(';') .quote('"') diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java index 20a769f8ce..5f20464eb9 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java @@ -3,7 +3,6 @@ package at.tuwien.service; import at.tuwien.api.database.ViewColumnDto; import at.tuwien.api.database.ViewDto; import at.tuwien.api.database.query.QueryResultDto; -import at.tuwien.api.database.table.columns.ColumnDto; import at.tuwien.config.MariaDbConfig; import at.tuwien.config.MariaDbContainerConfig; import at.tuwien.exception.*; @@ -24,7 +23,6 @@ import java.time.Instant; import java.util.List; import java.util.Map; -import static at.tuwien.service.SchemaServiceIntegrationTest.assertViewColumn; import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -68,11 +66,11 @@ public class ViewServiceIntegrationTest extends AbstractUnitTest { final List<ViewColumnDto> columns = response.getColumns(); assertEquals(VIEW_1_COLUMNS.size(), columns.size()); ViewColumnDto ref = VIEW_1_COLUMNS_DTO.get(0); - SchemaServiceIntegrationTest.assertViewColumn(columns.get(0), null, ref.getDatabaseId(), ref.getName(), ref.getInternalName(), ref.getColumnType(), ref.getSize(), ref.getD(), ref.getIsNullAllowed(), ref.getDateFormat(), ref.getDescription()); + SchemaServiceIntegrationTest.assertViewColumn(columns.get(0), null, ref.getDatabaseId(), ref.getName(), ref.getInternalName(), ref.getColumnType(), ref.getSize(), ref.getD(), ref.getIsNullAllowed(), ref.getDescription()); ref = VIEW_1_COLUMNS_DTO.get(1); - SchemaServiceIntegrationTest.assertViewColumn(columns.get(1), null, ref.getDatabaseId(), ref.getName(), ref.getInternalName(), ref.getColumnType(), ref.getSize(), ref.getD(), ref.getIsNullAllowed(), ref.getDateFormat(), ref.getDescription()); + SchemaServiceIntegrationTest.assertViewColumn(columns.get(1), null, ref.getDatabaseId(), ref.getName(), ref.getInternalName(), ref.getColumnType(), ref.getSize(), ref.getD(), ref.getIsNullAllowed(), ref.getDescription()); ref = VIEW_1_COLUMNS_DTO.get(2); - SchemaServiceIntegrationTest.assertViewColumn(columns.get(2), null, ref.getDatabaseId(), ref.getName(), ref.getInternalName(), ref.getColumnType(), ref.getSize(), ref.getD(), ref.getIsNullAllowed(), ref.getDateFormat(), ref.getDescription()); + SchemaServiceIntegrationTest.assertViewColumn(columns.get(2), null, ref.getDatabaseId(), ref.getName(), ref.getInternalName(), ref.getColumnType(), ref.getSize(), ref.getD(), ref.getIsNullAllowed(), ref.getDescription()); } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java index 640ef7172a..771b8cbc7e 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java @@ -66,8 +66,11 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find container with id {}: service responded unsuccessful: {}", containerId, response.getStatusCode()); throw new MetadataServiceException("Failed to find container: service responded unsuccessful: " + response.getStatusCode()); } - if (!response.getHeaders().keySet().containsAll(List.of("X-Username", "X-Password"))) { + final List<String> expectedHeaders = List.of("X-Username", "X-Password"); + if (!response.getHeaders().keySet().containsAll(expectedHeaders)) { log.error("Failed to find all privileged container headers"); + log.debug("expected headers: {}", expectedHeaders); + log.debug("found headers: {}", response.getHeaders().keySet()); throw new MetadataServiceException("Failed to find all privileged container headers"); } if (response.getBody() == null) { @@ -98,8 +101,11 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find database with id {}: service responded unsuccessful: {}", id, response.getStatusCode()); throw new MetadataServiceException("Failed to find database: service responded unsuccessful: " + response.getStatusCode()); } - if (!response.getHeaders().keySet().containsAll(List.of("X-Username", "X-Password"))) { + final List<String> expectedHeaders = List.of("X-Username", "X-Password"); + if (!response.getHeaders().keySet().containsAll(expectedHeaders)) { log.error("Failed to find all privileged database headers"); + log.debug("expected headers: {}", expectedHeaders); + log.debug("found headers: {}", response.getHeaders().keySet()); throw new MetadataServiceException("Failed to find all privileged database headers"); } if (response.getBody() == null) { @@ -123,11 +129,18 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find database with internal name {}: {}", internalName, e.getMessage()); throw new RemoteUnavailableException("Failed to find database: " + e.getMessage(), e); } - if (!response.getStatusCode().equals(HttpStatus.OK) || response.getBody() == null) { + if (!response.getStatusCode().equals(HttpStatus.OK)) { log.error("Failed to find database with internal name {}: service responded unsuccessful: {}", internalName, response.getStatusCode()); throw new MetadataServiceException("Failed to find database: service responded unsuccessful: " + response.getStatusCode()); } - if (response.getBody().length != 1) { + final List<String> expectedHeaders = List.of("X-Username", "X-Password"); + if (!response.getHeaders().keySet().containsAll(expectedHeaders)) { + log.error("Failed to find all privileged database headers"); + log.debug("expected headers: {}", expectedHeaders); + log.debug("found headers: {}", response.getHeaders().keySet()); + throw new MetadataServiceException("Failed to find all privileged database headers"); + } + if (response.getBody() == null || response.getBody().length != 1) { log.error("Failed to find database with internal name {}: body is empty", internalName); throw new DatabaseNotFoundException("Failed to find database: body is empty"); } @@ -151,8 +164,11 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find table with id {}: service responded unsuccessful: {}", id, response.getStatusCode()); throw new MetadataServiceException("Failed to find table: service responded unsuccessful: " + response.getStatusCode()); } - if (!response.getHeaders().keySet().containsAll(List.of("X-Type", "X-Host", "X-Port", "X-Username", "X-Password", "X-Database", "X-Sidecar-Host", "X-Sidecar-Port"))) { + final List<String> expectedHeaders = List.of("X-Type", "X-Host", "X-Port", "X-Username", "X-Password", "X-Database", "X-Sidecar-Host", "X-Sidecar-Port"); + if (!response.getHeaders().keySet().containsAll(expectedHeaders)) { log.error("Failed to find all privileged table headers"); + log.debug("expected headers: {}", expectedHeaders); + log.debug("found headers: {}", response.getHeaders().keySet()); throw new MetadataServiceException("Failed to find all privileged table headers"); } if (response.getBody() == null) { @@ -189,8 +205,11 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find view with id {}: service responded unsuccessful: {}", id, response.getStatusCode()); throw new MetadataServiceException("Failed to find view: service responded unsuccessful: " + response.getStatusCode()); } - if (!response.getHeaders().keySet().containsAll(List.of("X-Type", "X-Host", "X-Port", "X-Username", "X-Password", "X-Database"))) { + final List<String> expectedHeaders = List.of("X-Type", "X-Host", "X-Port", "X-Username", "X-Password", "X-Database"); + if (!response.getHeaders().keySet().containsAll(expectedHeaders)) { log.error("Failed to find all privileged view headers"); + log.debug("expected headers: {}", expectedHeaders); + log.debug("found headers: {}", response.getHeaders().keySet()); throw new MetadataServiceException("Failed to find all privileged view headers"); } if (response.getBody() == null) { @@ -276,8 +295,11 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find user with id {}: service responded unsuccessful: {}", userId, response.getStatusCode()); throw new MetadataServiceException("Failed to find user: service responded unsuccessful: " + response.getStatusCode()); } - if (!response.getHeaders().keySet().containsAll(List.of("X-Username", "X-Password"))) { + final List<String> expectedHeaders = List.of("X-Username", "X-Password"); + if (!response.getHeaders().keySet().containsAll(expectedHeaders)) { log.error("Failed to find all privileged user headers"); + log.debug("expected headers: {}", expectedHeaders); + log.debug("found headers: {}", response.getHeaders().keySet()); throw new MetadataServiceException("Failed to find all privileged user headers"); } if (response.getBody() == null) { diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java index 5b4f1b2625..01854e0cb7 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java @@ -1,6 +1,5 @@ package at.tuwien.mapper; -import at.tuwien.api.container.image.ImageDateDto; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.ViewColumnDto; import at.tuwien.api.database.ViewDto; @@ -45,7 +44,6 @@ import java.io.StringReader; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.sql.*; -import java.sql.Date; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; @@ -176,19 +174,6 @@ public interface DataMapper { } else if (resultSet.getString(6) != null) { column.setSize(resultSet.getLong(6)); } - if (column.getColumnType().equals(ColumnTypeDto.TIMESTAMP) || column.getColumnType().equals(ColumnTypeDto.DATETIME)) { - column.setDateFormat(ImageDateDto.builder() - .id(queryConfig.getDefaultTimestampFormatId()) - .build()); - } else if (column.getColumnType().equals(ColumnTypeDto.DATE)) { - column.setDateFormat(ImageDateDto.builder() - .id(queryConfig.getDefaultDateFormatId()) - .build()); - } else if (column.getColumnType().equals(ColumnTypeDto.TIME)) { - column.setDateFormat(ImageDateDto.builder() - .id(queryConfig.getDefaultTimeFormatId()) - .build()); - } /* constraints */ if (resultSet.getString(9) != null && resultSet.getString(9).equals("PRI")) { table.getConstraints().getPrimaryKey().add(PrimaryKeyDto.builder() @@ -220,19 +205,6 @@ public interface DataMapper { } else if (resultSet.getString(6) != null) { column.setSize(resultSet.getLong(6)); } - if (column.getColumnType().equals(ColumnTypeDto.TIMESTAMP) || column.getColumnType().equals(ColumnTypeDto.DATETIME)) { - column.setDateFormat(ImageDateDto.builder() - .id(queryConfig.getDefaultTimestampFormatId()) - .build()); - } else if (column.getColumnType().equals(ColumnTypeDto.DATE)) { - column.setDateFormat(ImageDateDto.builder() - .id(queryConfig.getDefaultDateFormatId()) - .build()); - } else if (column.getColumnType().equals(ColumnTypeDto.TIME)) { - column.setDateFormat(ImageDateDto.builder() - .id(queryConfig.getDefaultTimeFormatId()) - .build()); - } view.getColumns() .add(column); log.trace("parsed view {}.{} column: {}", view.getDatabase().getInternalName(), view.getInternalName(), column.getInternalName()); @@ -561,10 +533,6 @@ public interface DataMapper { } switch (column.getColumnType()) { case DATE -> { - if (column.getDateFormat() == null) { - log.error("Missing date format for column {}", column.getId()); - throw new IllegalArgumentException("Missing date format"); - } final DateTimeFormatter formatter = new DateTimeFormatterBuilder() .parseCaseInsensitive() /* case insensitive to parse JAN and FEB */ .appendPattern("yyyy-MM-dd") @@ -574,10 +542,6 @@ public interface DataMapper { .toInstant(); } case TIMESTAMP, DATETIME -> { - if (column.getDateFormat() == null) { - log.error("Missing date format for column {}", column.getId()); - throw new IllegalArgumentException("Missing date format"); - } return Timestamp.valueOf(data.toString()) .toInstant(); } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java index d870215771..607ada8d04 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java @@ -1,6 +1,6 @@ package at.tuwien.mapper; -import at.tuwien.api.database.query.ImportCsvDto; +import at.tuwien.api.database.query.ImportDto; import at.tuwien.api.database.table.*; import at.tuwien.api.database.table.columns.*; import at.tuwien.api.database.table.internal.PrivilegedTableDto; @@ -10,13 +10,11 @@ import org.mapstruct.Mapper; import org.mapstruct.Named; import java.io.*; -import java.math.BigInteger; import java.sql.*; import java.sql.Date; import java.text.Normalizer; import java.time.*; import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeFormatterBuilder; import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -548,7 +546,7 @@ public interface MariaDbMapper { return statement.toString(); } - default String datasetToRawInsertQuery(String databaseName, PrivilegedTableDto table, ImportCsvDto data) { + default String datasetToRawInsertQuery(String databaseName, PrivilegedTableDto table, ImportDto data) { final StringBuilder statement = new StringBuilder("LOAD DATA INFILE '") .append(data.getLocation()) .append("' REPLACE INTO TABLE `") @@ -580,20 +578,10 @@ public interface MariaDbMapper { /* format as variable */ statement.append("@") .append(column.getInternalName()); - if (column.getDateFormat() != null) { - /* reformat dates */ - columnToDateSet(data, column, set); - } else if (column.getColumnType().equals(ColumnTypeDto.BOOL)) { - /* reformat booleans */ - columnToBoolSet(data, column, set); - } else { - /* reformat others */ - columnToTextSet(data, column, set); - } idx[0]++; }); statement.append(")") - .append(set.length() != 0 ? (" SET " + set) : "") + .append(!set.isEmpty() ? (" SET " + set) : "") .append(";"); log.trace("mapped insert statement: {}", statement); return statement.toString(); @@ -710,125 +698,6 @@ public interface MariaDbMapper { return statement.toString(); } - default void columnToDateSet(ImportCsvDto data, ColumnDto column, StringBuilder set) { - log.trace("import column has date format, need to format it: {}", column.getDateFormat().getUnixFormat()); - set.append(!set.isEmpty() ? ", " : "") - .append("`") - .append(column.getInternalName()) - .append("` = STR_TO_DATE("); - if (data.getNullElement() != null) { - set.append("IF(STRCMP(@") - .append(column.getInternalName()) - .append(",'") - .append(data.getNullElement()) - .append("'), @") - .append(column.getInternalName()) - .append(", NULL), '") - .append(column.getDateFormat() - .getDatabaseFormat() - .replace('\'', '\\')) - .append("')"); - return; - } - set.append("@") - .append(column.getInternalName()) - .append(", '") - .append(column.getDateFormat() - .getDatabaseFormat() - .replace('\'', '\\')) - .append("')"); - } - - default void columnToBoolSet(ImportCsvDto data, ColumnDto column, StringBuilder set) { - set.append(!set.isEmpty() ? ", " : "") - .append("`") - .append(column.getInternalName()) - .append("` = "); - if (data.getNullElement() != null) { - set.append("IF(!STRCMP(@") - .append(column.getInternalName()) - .append(",'") - .append(data.getNullElement()) - .append("'),NULL,"); - columnToBoolSet2(data, column, set); - set.append(")"); - return; - } - columnToBoolSet2(data, column, set); - } - - default void columnToBoolSet2(ImportCsvDto data, ColumnDto column, StringBuilder set) { - if (data.getTrueElement() != null) { - set.append("IF(!STRCMP(@") - .append(column.getInternalName()) - .append(",'") - .append(data.getTrueElement()) - .append("'),TRUE,"); - if (data.getFalseElement() != null) { - log.trace("import has false element present (both true and false)"); - /* can map both true/false */ - set.append("IF(!STRCMP(@") - .append(column.getInternalName()) - .append(",'") - .append(data.getFalseElement()) - .append("'),FALSE,@") - .append(column.getInternalName()) - .append("))"); - } else { - /* can only map true */ - set.append("@") - .append(column.getInternalName()) - .append(")"); - } - return; - } - if (data.getFalseElement() != null) { - set.append("IF(!STRCMP(@") - .append(column.getInternalName()) - .append(",'") - .append(data.getFalseElement()) - .append("'),FALSE,"); - if (data.getTrueElement() != null) { - log.trace("import has true element present (both true and false)"); - /* can map both true/false */ - set.append("IF(!STRCMP(@") - .append(column.getInternalName()) - .append(",'") - .append(data.getTrueElement()) - .append("'),TRUE,@") - .append(column.getInternalName()) - .append("))"); - } else { - /* can only map true */ - set.append("@") - .append(column.getInternalName()) - .append(")"); - } - return; - } - set.append("@") - .append(column.getInternalName()); - } - - default void columnToTextSet(ImportCsvDto data, ColumnDto column, StringBuilder set) { - set.append(!set.isEmpty() ? ", " : "") - .append("`") - .append(column.getInternalName()) - .append("` = "); - if (data.getNullElement() != null) { - set.append("IF(STRCMP(@") - .append(column.getInternalName()) - .append(",'") - .append(data.getNullElement()) - .append("'), @") - .append(column.getInternalName()) - .append(", NULL)"); - return; - } - set.append("@") - .append(column.getInternalName()); - } - default void prepareStatementWithColumnTypeObject(PreparedStatement statement, ColumnTypeDto columnType, int idx, String columnName, Object value) throws SQLException { switch (columnType) { diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java index 765a3b7e2e..33ef0026a8 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java @@ -2,7 +2,7 @@ package at.tuwien.service; import at.tuwien.ExportResourceDto; import at.tuwien.api.database.internal.PrivilegedDatabaseDto; -import at.tuwien.api.database.query.ImportCsvDto; +import at.tuwien.api.database.query.ImportDto; import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.api.database.table.*; import at.tuwien.api.database.table.internal.PrivilegedTableDto; @@ -104,7 +104,7 @@ public interface TableService { Long getCount(PrivilegedTableDto table, Instant timestamp) throws SQLException, QueryMalformedException; - void importDataset(PrivilegedTableDto table, ImportCsvDto data) throws SidecarImportException, + void importDataset(PrivilegedTableDto table, ImportDto data) throws SidecarImportException, StorageNotFoundException, SQLException, QueryMalformedException, RemoteUnavailableException; void deleteTuple(PrivilegedTableDto table, TupleDeleteDto data) throws SQLException, diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java index cdcde4f2c2..3ab02bbb01 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java @@ -2,7 +2,7 @@ package at.tuwien.service.impl; import at.tuwien.ExportResourceDto; import at.tuwien.api.database.internal.PrivilegedDatabaseDto; -import at.tuwien.api.database.query.ImportCsvDto; +import at.tuwien.api.database.query.ImportDto; import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.api.database.table.*; import at.tuwien.api.database.table.columns.ColumnDto; @@ -273,7 +273,7 @@ public class TableServiceMariaDbImpl extends HibernateConnector implements Table } @Override - public void importDataset(PrivilegedTableDto table, ImportCsvDto data) throws StorageNotFoundException, + public void importDataset(PrivilegedTableDto table, ImportDto data) throws StorageNotFoundException, SQLException, QueryMalformedException, RemoteUnavailableException, SidecarImportException { /* import .csv from blob storage to sidecar */ dataDatabaseSidecarGateway.importFile(table.getDatabase().getContainer().getSidecarHost(), table.getDatabase().getContainer().getSidecarPort(), data.getLocation()); diff --git a/dbrepo-metadata-db/1_setup-schema.sql b/dbrepo-metadata-db/1_setup-schema.sql index 9c21d44c0e..090cc81739 100644 --- a/dbrepo-metadata-db/1_setup-schema.sql +++ b/dbrepo-metadata-db/1_setup-schema.sql @@ -35,20 +35,6 @@ CREATE TABLE IF NOT EXISTS `mdb_images` UNIQUE (is_default) ) WITH SYSTEM VERSIONING; -CREATE TABLE IF NOT EXISTS `mdb_images_date` -( - id bigint NOT NULL AUTO_INCREMENT, - iid bigint NOT NULL, - database_format character varying(255) NOT NULL, - unix_format character varying(255) NOT NULL, - example character varying(255) NOT NULL, - has_time boolean NOT NULL, - created_at timestamp NOT NULL DEFAULT NOW(), - PRIMARY KEY (id), - FOREIGN KEY (iid) REFERENCES mdb_images (id), - UNIQUE (database_format, unix_format, example) -) WITH SYSTEM VERSIONING; - CREATE TABLE IF NOT EXISTS `mdb_containers` ( id bigint NOT NULL AUTO_INCREMENT, @@ -539,13 +525,6 @@ INSERT INTO `mdb_images` (name, registry, version, default_port, dialect, driver VALUES ('mariadb', 'docker.io', '11.1.3', 3306, 'org.hibernate.dialect.MariaDBDialect', 'org.mariadb.jdbc.Driver', 'mariadb'); -INSERT INTO `mdb_images_date` (iid, database_format, unix_format, example, has_time) -VALUES (1, '%Y-%c-%d %H:%i:%S.%f', 'yyyy-MM-dd HH:mm:ss.SSSSSS', '2022-01-30 13:44:25.499', true), - (1, '%Y-%c-%d %H:%i:%S', 'yyyy-MM-dd HH:mm:ss', '2022-01-30 13:44:25', true), - (1, '%Y-%c-%d', 'yyyy-MM-dd', '2022-01-30', false), - (1, '%H:%i:%S', 'HH:mm:ss', '13:44:25', true), - (1, '%d.%c.%Y', 'dd.MM.yyyy', '30.01.2022', false); - INSERT INTO `mdb_ontologies` (prefix, uri, uri_pattern, sparql_endpoint, rdf_path) VALUES ('om', 'http://www.ontology-of-units-of-measure.org/resource/om-2/', 'http://www.ontology-of-units-of-measure.org/resource/om-2/.*', null, 'rdf/om-2.0.rdf'), diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/image/ImageDateDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/image/ImageDateDto.java deleted file mode 100644 index 6fc25ad3cb..0000000000 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/image/ImageDateDto.java +++ /dev/null @@ -1,48 +0,0 @@ -package at.tuwien.api.container.image; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import lombok.extern.jackson.Jacksonized; - -import java.time.Instant; - -@Getter -@Setter -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Jacksonized -@ToString -public class ImageDateDto { - - @NotNull - private Long id; - - @NotBlank - @JsonProperty("database_format") - @Schema(example = "%d.%c.%Y") - private String databaseFormat; - - @NotBlank - @JsonProperty("unix_format") - @Schema(example = "dd.MM.YYYY") - private String unixFormat; - - @NotNull - @JsonProperty("has_time") - @Schema(example = "false") - private Boolean hasTime; - - - @NotNull - @Schema(example = "2021-03-12T15:26:21Z") - @JsonProperty("created_at") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "UTC") - private Instant createdAt; - -} diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/image/ImageDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/image/ImageDto.java index c0cf7f3bce..2806bf071f 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/image/ImageDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/image/ImageDto.java @@ -7,8 +7,6 @@ import jakarta.validation.constraints.NotNull; import lombok.*; import lombok.extern.jackson.Jacksonized; -import java.util.List; - @Getter @Setter @Builder @@ -38,9 +36,6 @@ public class ImageDto { @Schema(example = "org.mariadb.jdbc.Driver") private String driverClass; - @JsonProperty("date_formats") - private List<ImageDateDto> dateFormats; - @NotBlank @Schema(example = "org.hibernate.dialect.MariaDBDialect") private String dialect; diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/internal/PrivilegedContainerDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/internal/PrivilegedContainerDto.java index 8de17a48f3..8bda16bf41 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/internal/PrivilegedContainerDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/internal/PrivilegedContainerDto.java @@ -1,6 +1,5 @@ package at.tuwien.api.container.internal; -import at.tuwien.api.container.image.ImageDateDto; import at.tuwien.api.container.image.ImageDto; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/ViewColumnDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/ViewColumnDto.java index 337a61a637..75b0a3d684 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/ViewColumnDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/ViewColumnDto.java @@ -1,6 +1,5 @@ package at.tuwien.api.database; -import at.tuwien.api.container.image.ImageDateDto; import at.tuwien.api.database.table.columns.ColumnTypeDto; import at.tuwien.api.database.table.columns.concepts.ConceptDto; import at.tuwien.api.database.table.columns.concepts.UnitDto; @@ -47,9 +46,6 @@ public class ViewColumnDto { @Schema private String alias; - @JsonProperty("date_format") - private ImageDateDto dateFormat; - @NotNull @JsonProperty("auto_generated") @Schema(example = "false") diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/ImportCsvDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/ImportCsvDto.java deleted file mode 100644 index eac536143e..0000000000 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/ImportCsvDto.java +++ /dev/null @@ -1,49 +0,0 @@ -package at.tuwien.api.database.query; - -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import lombok.extern.jackson.Jacksonized; - -@Getter -@Setter -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Jacksonized -@ToString -public class ImportCsvDto { - - @NotBlank - @Schema(example = "file.csv") - private String location; - - @Min(value = 0L) - @JsonProperty("skip_lines") - private Long skipLines; - - @JsonProperty("false_element") - private String falseElement; - - @JsonProperty("true_element") - private String trueElement; - - @JsonProperty("null_element") - @Schema(example = "NA") - private String nullElement; - - @NotNull - @Schema(example = ",") - private Character separator; - - @Schema(example = "\"") - private Character quote; - - @JsonProperty("line_termination") - @Schema(example = "\\r\\n") - private String lineTermination; -} diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/ImportDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/ImportDto.java index b865f7892c..043e3bc3ee 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/ImportDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/ImportDto.java @@ -27,16 +27,6 @@ public class ImportDto { @JsonProperty("skip_lines") private Long skipLines; - @JsonProperty("false_element") - private String falseElement; - - @JsonProperty("true_element") - private String trueElement; - - @JsonProperty("null_element") - @Schema(example = "NA") - private String nullElement; - @NotNull @Schema(example = ",") private Character separator; diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java index a506dbca82..4e95fefc3e 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java @@ -1,6 +1,5 @@ package at.tuwien.api.database.table.columns; -import at.tuwien.api.container.image.ImageDateDto; import at.tuwien.api.database.ViewDto; import at.tuwien.api.database.table.TableDto; import at.tuwien.api.database.table.columns.concepts.ConceptDto; @@ -59,9 +58,6 @@ public class ColumnDto { @Schema private String alias; - @JsonProperty("date_format") - private ImageDateDto dateFormat; - @NotNull @JsonProperty("auto_generated") @Schema(example = "false") diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java index 9cdcfdedf9..f50f916ac4 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java @@ -101,18 +101,19 @@ public class AccessEndpoint { data.getType()); final Database database = databaseService.findById(databaseId); final User user = userService.findByUsername(principal.getName()); - if (database.getOwner().equals(user)) { - log.error("Failed to give access to user with id {}: not owner", userId); - throw new NotAllowedException("Failed to give access to user with id " + userId + ": not owner"); + if (!database.getOwner().equals(user)) { + log.error("Failed to create access: not owner"); + throw new NotAllowedException("Failed to create access: not owner"); } + final User otherUser = userService.findById(userId); try { - accessService.find(database, user); - log.error("Failed to give access to user with id {}: already has access", userId); - throw new NotAllowedException("Failed to give access to user with id " + userId + ": already has access"); + accessService.find(database, otherUser); + log.error("Failed to create access to user with id {}: already has access", userId); + throw new NotAllowedException("Failed to create access to user with id " + userId + ": already has access"); } catch (AccessNotFoundException e) { /* ignore */ } - accessService.create(database, user, data.getType()); + accessService.create(database, otherUser, data.getType()); return ResponseEntity.accepted() .build(); } @@ -163,12 +164,13 @@ public class AccessEndpoint { data.getType()); final Database database = databaseService.findById(databaseId); final User user = userService.findByUsername(principal.getName()); - if (database.getOwner().equals(user)) { - log.error("Failed to give access to user with id {}: not owner", userId); - throw new NotAllowedException("Failed to give access to user with id " + userId + ": not owner"); + if (!database.getOwner().equals(user)) { + log.error("Failed to update access: not owner"); + throw new NotAllowedException("Failed to update access: not owner"); } - accessService.find(database, user); - accessService.update(database, user, data.getType()); + final User otherUser = userService.findById(userId); + accessService.find(database, otherUser); + accessService.update(database, otherUser, data.getType()); return ResponseEntity.accepted() .build(); } @@ -211,8 +213,8 @@ public class AccessEndpoint { log.trace("principal is allowed to check foreign user access"); } final Database database = databaseService.findById(databaseId); - final User user = userService.findById(userId); - final DatabaseAccess access = accessService.find(database, user); + final User otherUser = userService.findById(userId); + final DatabaseAccess access = accessService.find(database, otherUser); final DatabaseAccessDto dto = databaseMapper.databaseAccessToDatabaseAccessDto(access); log.trace("check access resulted in dto {}", dto); return ResponseEntity.ok(dto); @@ -263,11 +265,12 @@ public class AccessEndpoint { final Database database = databaseService.findById(databaseId); final User user = userService.findByUsername(principal.getName()); if (!database.getOwner().equals(user)) { - log.error("Failed to revoke access to user with id {}: not owner", user.getId()); - throw new NotAllowedException("Failed to revoke access to user with id " + user.getId() + ": not owner"); + log.error("Failed to revoke access: not owner"); + throw new NotAllowedException("Failed to revoke access: not owner"); } - accessService.find(database, user); - accessService.delete(database, user); + final User otherUser = userService.findById(userId); + accessService.find(database, otherUser); + accessService.delete(database, otherUser); return ResponseEntity.accepted() .build(); } diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java index 4fb8240b1d..a3c0383118 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java @@ -349,15 +349,6 @@ public class TableEndpoint { final Database database = databaseService.findById(databaseId); endpointValidator.validateOnlyAccess(database, principal, true); endpointValidator.validateColumnCreateConstraints(data); - final List<ColumnCreateDto> failedDateColumns = data.getColumns() - .stream() - .filter(column -> List.of(ColumnTypeDto.DATE, ColumnTypeDto.DATETIME, ColumnTypeDto.TIME, ColumnTypeDto.TIMESTAMP).contains(column.getType())) - .filter(column -> Objects.isNull(column.getDfid())) - .toList(); - if (!failedDateColumns.isEmpty()) { - log.error("Failed to create table: date column(s) {} do not contain date format id", failedDateColumns.stream().map(ColumnCreateDto::getName).toList()); - throw new MalformedException("Failed to create table: date column(s) " + failedDateColumns.stream().map(ColumnCreateDto::getName).toList() + " do not contain date format id"); - } final Table table = tableService.createTable(database, data, principal); final TableDto dto = metadataMapper.customTableToTableDto(table); log.info("Created table with id {}", dto.getId()); diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java index b81a8142f7..34082d18c1 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java @@ -5,7 +5,10 @@ import at.tuwien.api.auth.RefreshTokenRequestDto; import at.tuwien.api.auth.SignupRequestDto; import at.tuwien.api.error.ApiErrorDto; import at.tuwien.api.keycloak.TokenDto; -import at.tuwien.api.user.*; +import at.tuwien.api.user.UserBriefDto; +import at.tuwien.api.user.UserDto; +import at.tuwien.api.user.UserPasswordDto; +import at.tuwien.api.user.UserUpdateDto; import at.tuwien.entities.database.Database; import at.tuwien.entities.user.User; import at.tuwien.exception.*; @@ -26,6 +29,7 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -284,7 +288,13 @@ public class UserEndpoint { } } final UserDto dto = userMapper.userToUserDto(user); - return ResponseEntity.ok() + final HttpHeaders headers = new HttpHeaders(); + if (UserUtil.isSystem(principal)) { + headers.set("X-Username", user.getUsername()); + headers.set("X-Password", user.getMariadbPassword()); + } + return ResponseEntity.status(HttpStatus.OK) + .headers(headers) .body(dto); } diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java index 92b1bbd164..31ab0b765d 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java @@ -68,46 +68,27 @@ public class EndpointValidator { if (data == null) { throw new MalformedException("Validation failed: table data is null"); } - final List<ColumnTypeDto> needSize = List.of(ColumnTypeDto.CHAR, ColumnTypeDto.VARCHAR); - final List<ColumnTypeDto> needSizeAndD = List.of(ColumnTypeDto.DOUBLE, ColumnTypeDto.DECIMAL); - final List<ColumnTypeDto> needDateFormat = List.of(ColumnTypeDto.DATETIME, ColumnTypeDto.TIMESTAMP, ColumnTypeDto.TIME); + final List<ColumnTypeDto> canHaveSize = List.of(ColumnTypeDto.CHAR, ColumnTypeDto.VARCHAR, ColumnTypeDto.BINARY, ColumnTypeDto.VARBINARY, ColumnTypeDto.BIT, ColumnTypeDto.TINYINT, ColumnTypeDto.SMALLINT, ColumnTypeDto.MEDIUMINT, ColumnTypeDto.INT); + final List<ColumnTypeDto> canHaveSizeAndD = List.of(ColumnTypeDto.DOUBLE, ColumnTypeDto.DECIMAL); /* check size */ final Optional<ColumnCreateDto> optional0 = data.getColumns() .stream() - .filter(c -> Objects.isNull(c.getSize())) - .filter(c -> needSize.contains(c.getType())) + .filter(c -> !Objects.isNull(c.getSize())) + .filter(c -> !canHaveSize.contains(c.getType())) .findFirst(); if (optional0.isPresent()) { - log.error("Validation failed: column {} needs size parameter", optional0.get().getName()); - throw new MalformedException("Validation failed: column " + optional0.get().getName() + " needs size parameter"); + log.error("Validation failed: column {} cannot have size parameter", optional0.get().getName()); + throw new MalformedException("Validation failed: column " + optional0.get().getName() + " cannot have size parameter"); } /* check size and d */ final Optional<ColumnCreateDto> optional1 = data.getColumns() .stream() - .filter(c -> needSizeAndD.contains(c.getType())) - .filter(c -> Objects.isNull(c.getSize()) || Objects.isNull(c.getD())) + .filter(c -> Objects.isNull(c.getSize()) ^ Objects.isNull(c.getD())) + .filter(c -> canHaveSizeAndD.contains(c.getType())) .findFirst(); if (optional1.isPresent()) { - log.error("Validation failed: column {} needs size and d parameter", optional1.get().getName()); - throw new MalformedException("Validation failed: column " + optional1.get().getName() + " needs size and d parameter"); - } - final Optional<ColumnCreateDto> optional1a = data.getColumns() - .stream() - .filter(c -> needSizeAndD.contains(c.getType())) - .filter(c -> c.getSize() > 65 || c.getD() > 38) - .findFirst(); - if (optional1a.isPresent()) { - log.error("Validation failed: column {} needs size (max 65) and d (max 30)", optional1a.get().getName()); - throw new MalformedException("Validation failed: column " + optional1a.get().getName() + " needs size (max 65) and d (max 30)"); - } - final Optional<ColumnCreateDto> optional1b = data.getColumns() - .stream() - .filter(c -> needSizeAndD.contains(c.getType())) - .filter(c -> c.getSize() < c.getD()) - .findFirst(); - if (optional1b.isPresent()) { - log.error("Validation failed: column {} needs size >= d", optional1b.get().getName()); - throw new MalformedException("Validation failed: column " + optional1b.get().getName() + " needs size >= d"); + log.error("Validation failed: column {} either needs both size and d parameter or none (use default)", optional1.get().getName()); + throw new MalformedException("Validation failed: column " + optional1.get().getName() + " either needs both size and d parameter or none (use default)"); } /* check enum */ final Optional<ColumnCreateDto> optional2 = data.getColumns() @@ -129,16 +110,6 @@ public class EndpointValidator { log.error("Validation failed: column {} needs at least 1 allowed set value", optional3.get().getName()); throw new MalformedException("Validation failed: column " + optional3.get().getName() + " needs at least 1 allowed set value"); } - /* check date */ - final Optional<ColumnCreateDto> optional4 = data.getColumns() - .stream() - .filter(c -> needDateFormat.contains(c.getType())) - .filter(c -> Objects.isNull(c.getDfid())) - .findFirst(); - if (optional4.isPresent()) { - log.error("Validation failed: column {} needs a format", optional4.get().getName()); - throw new MalformedException("Validation failed: column " + optional4.get().getName() + " needs a format"); - } } public boolean validateOnlyMineOrWriteAccessOrHasRole(User owner, Principal principal, DatabaseAccess access, String role) { diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayUnitTest.java index a812bd5de4..fc2a9c2c22 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayUnitTest.java @@ -1,5 +1,6 @@ package at.tuwien.gateway; +import at.tuwien.api.amqp.GrantExchangePermissionsDto; import at.tuwien.test.AbstractUnitTest; import at.tuwien.exception.*; import lombok.extern.log4j.Log4j2; @@ -33,6 +34,12 @@ public class BrokerServiceGatewayUnitTest extends AbstractUnitTest { @Autowired private BrokerServiceGateway brokerServiceGateway; + private final GrantExchangePermissionsDto WRITE_ALL_PERMISSIONS = GrantExchangePermissionsDto.builder() + .exchange("dbrepo") + .read("^(dbrepo\\.1\\..*)$") /* WRITE_ALL */ + .write("^(dbrepo\\.1\\..*)$") + .build(); + @Test public void grantTopicPermission_exchangeNoRightsBefore_succeeds() throws BrokerServiceException, BrokerServiceConnectionException { @@ -178,43 +185,40 @@ public class BrokerServiceGatewayUnitTest extends AbstractUnitTest { @Test public void grantExchangePermission_succeeds() throws BrokerServiceException, BrokerServiceConnectionException { - final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.CREATED) - .build(); /* mock */ when(restTemplate.exchange(anyString(), eq(HttpMethod.PUT), any(HttpEntity.class), eq(Void.class))) - .thenReturn(mock); + .thenReturn(ResponseEntity.status(HttpStatus.CREATED) + .build()); /* test */ - brokerServiceGateway.grantExchangePermission(USER_1_USERNAME, USER_1_RABBITMQ_GRANT_TOPIC_DTO); + brokerServiceGateway.grantExchangePermission(USER_1_USERNAME, WRITE_ALL_PERMISSIONS); } @Test public void grantExchangePermission_exists_succeeds() throws BrokerServiceException, BrokerServiceConnectionException { - final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.NO_CONTENT) - .build(); /* mock */ when(restTemplate.exchange(anyString(), eq(HttpMethod.PUT), any(HttpEntity.class), eq(Void.class))) - .thenReturn(mock); + .thenReturn(ResponseEntity.status(HttpStatus.NO_CONTENT) + .build()); /* test */ - brokerServiceGateway.grantExchangePermission(USER_1_USERNAME, USER_1_RABBITMQ_GRANT_TOPIC_DTO); + brokerServiceGateway.grantExchangePermission(USER_1_USERNAME, WRITE_ALL_PERMISSIONS); } @Test public void grantExchangePermission_unexpected2_fails() { - final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.BAD_GATEWAY) - .build(); /* mock */ when(restTemplate.exchange(anyString(), eq(HttpMethod.PUT), any(HttpEntity.class), eq(Void.class))) - .thenReturn(mock); + .thenReturn(ResponseEntity.status(HttpStatus.BAD_GATEWAY) + .build()); /* test */ assertThrows(BrokerServiceException.class, () -> { - brokerServiceGateway.grantExchangePermission(USER_1_USERNAME, USER_1_RABBITMQ_GRANT_TOPIC_DTO); + brokerServiceGateway.grantExchangePermission(USER_1_USERNAME, WRITE_ALL_PERMISSIONS); }); } @@ -228,7 +232,7 @@ public class BrokerServiceGatewayUnitTest extends AbstractUnitTest { /* test */ assertThrows(BrokerServiceConnectionException.class, () -> { - brokerServiceGateway.grantExchangePermission(USER_1_USERNAME, USER_1_RABBITMQ_GRANT_TOPIC_DTO); + brokerServiceGateway.grantExchangePermission(USER_1_USERNAME, WRITE_ALL_PERMISSIONS); }); } @@ -242,7 +246,7 @@ public class BrokerServiceGatewayUnitTest extends AbstractUnitTest { /* test */ assertThrows(BrokerServiceException.class, () -> { - brokerServiceGateway.grantExchangePermission(USER_1_USERNAME, USER_1_RABBITMQ_GRANT_TOPIC_DTO); + brokerServiceGateway.grantExchangePermission(USER_1_USERNAME, WRITE_ALL_PERMISSIONS); }); } diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/BrokerServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/BrokerServiceIntegrationTest.java index c9a2ad62b6..d04409c87b 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/BrokerServiceIntegrationTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/BrokerServiceIntegrationTest.java @@ -1,13 +1,15 @@ package at.tuwien.service; -import at.tuwien.config.RabbitConfig; -import at.tuwien.exception.*; -import at.tuwien.test.AbstractUnitTest; import at.tuwien.api.amqp.GrantExchangePermissionsDto; +import at.tuwien.api.amqp.GrantVirtualHostPermissionsDto; import at.tuwien.api.amqp.TopicPermissionDto; import at.tuwien.api.amqp.VirtualHostPermissionDto; +import at.tuwien.config.RabbitConfig; import at.tuwien.entities.database.DatabaseAccess; import at.tuwien.entities.user.User; +import at.tuwien.exception.BrokerServiceConnectionException; +import at.tuwien.exception.BrokerServiceException; +import at.tuwien.test.AbstractUnitTest; import at.tuwien.utils.AmqpUtils; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.BeforeEach; @@ -27,7 +29,7 @@ import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; import java.util.Set; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; @Log4j2 @Testcontainers @@ -167,10 +169,15 @@ public class BrokerServiceIntegrationTest extends AbstractUnitTest { protected VirtualHostPermissionDto setVirtualHostPermissions_generic() throws BrokerServiceException, BrokerServiceConnectionException { + final GrantVirtualHostPermissionsDto permissions = GrantVirtualHostPermissionsDto.builder() + .configure("") + .read("") + .write("") + .build(); final AmqpUtils amqpUtils = new AmqpUtils(rabbitContainer.getHttpUrl()); /* mock */ - amqpUtils.setVirtualHostPermissions(REALM_DBREPO_NAME, USER_1_USERNAME, USER_1_RABBITMQ_GRANT_DTO); + amqpUtils.setVirtualHostPermissions(REALM_DBREPO_NAME, USER_1_USERNAME, permissions); /* test */ brokerService.setVirtualHostPermissions(USER_1); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java index 68d6e1a93d..cb104542aa 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java @@ -212,7 +212,11 @@ public class DatabaseServiceUnitTest extends AbstractUnitTest { SearchServiceConnectionException { /* test */ - generic_modifyOwner(DATABASE_1, USER_1); + final Database response = generic_modifyOwner(DATABASE_1, USER_2); + assertEquals(USER_2, response.getOwner()); + assertEquals(USER_2_ID, response.getOwnedBy()); + assertEquals(USER_2, response.getContact()); + assertEquals(USER_2_ID, response.getContactPerson()); } @Test diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java index aaa50251c3..b6af901811 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java @@ -73,6 +73,7 @@ public class AccessServiceImpl implements AccessService { .database(database) .huserid(user.getId()) .type(metadataMapper.accessTypeDtoToAccessType(type)) + .user(user) .build(); database.getAccesses() .add(access); @@ -95,8 +96,8 @@ public class AccessServiceImpl implements AccessService { .hdbid(database.getId()) .database(database) .huserid(user.getId()) - .user(user) .type(metadataMapper.accessTypeDtoToAccessType(access)) + .user(user) .build(); final int idx = database.getAccesses().indexOf(entity); if (idx == -1) { diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceImpl.java index 986993ec78..330d4518de 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceImpl.java @@ -167,7 +167,10 @@ public class DatabaseServiceImpl implements DatabaseService { public Database modifyOwner(Database database, User user) throws DatabaseNotFoundException, SearchServiceException, SearchServiceConnectionException { /* update in metadata database */ + database.setOwner(user); database.setOwnedBy(user.getId()); + database.setContact(user); + database.setContactPerson(user.getId()); database = databaseRepository.save(database); /* save in search service */ searchServiceGateway.update(database); diff --git a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java index 6ade19c1ec..adff51d164 100644 --- a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java +++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java @@ -422,17 +422,6 @@ public abstract class BaseTest { public final static Instant USER_1_LAST_MODIFIED = USER_1_CREATED; public final static UUID USER_1_REALM_ID = REALM_DBREPO_ID; - public final static CreateUserDto USER_1_RABBITMQ_CREATE_DTO = CreateUserDto.builder() - .password("") - .tags("") - .build(); - - public final static GrantVirtualHostPermissionsDto USER_1_RABBITMQ_GRANT_DTO = GrantVirtualHostPermissionsDto.builder() - .configure("") - .read("") - .write("") - .build(); - public final static UpdateUserPasswordDto USER_1_UPDATE_PASSWORD_DTO = UpdateUserPasswordDto.builder() .username(USER_1_USERNAME) .password(USER_1_PASSWORD) @@ -924,13 +913,6 @@ public abstract class BaseTest { .hasTime(IMAGE_DATE_1_HAS_TIME) .build(); - public final static ImageDateDto IMAGE_DATE_1_DTO = ImageDateDto.builder() - .id(IMAGE_DATE_1_ID) - .unixFormat(IMAGE_DATE_1_UNIX_FORMAT) - .databaseFormat(IMAGE_DATE_1_DATABASE_FORMAT) - .hasTime(IMAGE_DATE_1_HAS_TIME) - .build(); - public final static ImageCreateDto IMAGE_1_CREATE_DTO = ImageCreateDto.builder() .registry(IMAGE_1_REGISTRY) .name(IMAGE_1_NAME) @@ -965,13 +947,6 @@ public abstract class BaseTest { .hasTime(IMAGE_DATE_2_HAS_TIME) .build(); - public final static ImageDateDto IMAGE_DATE_2_DTO = ImageDateDto.builder() - .id(IMAGE_DATE_2_ID) - .unixFormat(IMAGE_DATE_2_UNIX_FORMAT) - .databaseFormat(IMAGE_DATE_2_DATABASE_FORMAT) - .hasTime(IMAGE_DATE_2_HAS_TIME) - .build(); - public final static Long IMAGE_DATE_3_ID = 3L; public final static Long IMAGE_DATE_3_IMAGE_ID = IMAGE_1_ID; public final static String IMAGE_DATE_3_UNIX_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS"; @@ -988,13 +963,6 @@ public abstract class BaseTest { .hasTime(IMAGE_DATE_3_HAS_TIME) .build(); - public final static ImageDateDto IMAGE_DATE_3_DTO = ImageDateDto.builder() - .id(IMAGE_DATE_3_ID) - .unixFormat(IMAGE_DATE_3_UNIX_FORMAT) - .databaseFormat(IMAGE_DATE_3_DATABASE_FORMAT) - .hasTime(IMAGE_DATE_3_HAS_TIME) - .build(); - public final static Long IMAGE_DATE_4_ID = 4L; public final static Long IMAGE_DATE_4_IMAGE_ID = IMAGE_1_ID; public final static String IMAGE_DATE_4_UNIX_FORMAT = "HH:mm:ss"; @@ -1011,13 +979,6 @@ public abstract class BaseTest { .hasTime(IMAGE_DATE_4_HAS_TIME) .build(); - public final static ImageDateDto IMAGE_DATE_4_DTO = ImageDateDto.builder() - .id(IMAGE_DATE_4_ID) - .unixFormat(IMAGE_DATE_4_UNIX_FORMAT) - .databaseFormat(IMAGE_DATE_4_DATABASE_FORMAT) - .hasTime(IMAGE_DATE_4_HAS_TIME) - .build(); - public final static ContainerImage IMAGE_1 = ContainerImage.builder() .id(IMAGE_1_ID) .name(IMAGE_1_NAME) @@ -1041,7 +1002,6 @@ public abstract class BaseTest { .driverClass(IMAGE_1_DRIVER) .defaultPort(IMAGE_1_PORT) .isDefault(IMAGE_1_IS_DEFAULT) - .dateFormats(List.of(IMAGE_DATE_1_DTO, IMAGE_DATE_2_DTO, IMAGE_DATE_3_DTO)) .build(); public final static ImageBriefDto IMAGE_1_BRIEF_DTO = ImageBriefDto.builder() @@ -1253,12 +1213,6 @@ public abstract class BaseTest { public final static UserDto DATABASE_1_CREATOR_DTO = USER_1_DTO; public final static UserDto DATABASE_1_OWNER_DTO = USER_1_DTO; - public final static GrantExchangePermissionsDto USER_1_RABBITMQ_GRANT_TOPIC_DTO = GrantExchangePermissionsDto.builder() - .exchange("dbrepo") - .read("^(dbrepo\\." + DATABASE_1_INTERNALNAME + "\\..)$") - .write("^(dbrepo\\." + DATABASE_1_INTERNALNAME + "\\..)$") - .build(); - public final static DatabaseCreateDto DATABASE_1_CREATE = DatabaseCreateDto.builder() .name(DATABASE_1_NAME) .isPublic(DATABASE_1_PUBLIC) @@ -1632,7 +1586,6 @@ public abstract class BaseTest { .internalName("date") .ordinalPosition(1) .columnType(ColumnTypeDto.DATE) - .dateFormat(IMAGE_DATE_1_DTO) .isNullAllowed(true) .autoGenerated(false) .enums(null) @@ -2253,7 +2206,6 @@ public abstract class BaseTest { .name("Timestamp") .internalName("timestamp") .columnType(ColumnTypeDto.TIMESTAMP) - .dateFormat(IMAGE_DATE_3_DTO) .isNullAllowed(false) .autoGenerated(false) .build(), @@ -2264,7 +2216,6 @@ public abstract class BaseTest { .name("Value") .internalName("value") .columnType(ColumnTypeDto.DECIMAL) - .dateFormat(null) .isNullAllowed(true) .autoGenerated(false) .build()); @@ -3660,7 +3611,6 @@ public abstract class BaseTest { .name("id") .internalName("id") .isNullAllowed(false) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3674,7 +3624,6 @@ public abstract class BaseTest { .name("linie") .internalName("linie") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3688,7 +3637,6 @@ public abstract class BaseTest { .name("richtung") .internalName("richtung") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3702,7 +3650,6 @@ public abstract class BaseTest { .name("betriebsdatum") .internalName("betriebsdatum") .isNullAllowed(true) - .dateFormat(IMAGE_DATE_2_DTO) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3716,7 +3663,6 @@ public abstract class BaseTest { .name("fahrzeug") .internalName("fahrzeug") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3730,7 +3676,6 @@ public abstract class BaseTest { .name("kurs") .internalName("kurs") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3744,7 +3689,6 @@ public abstract class BaseTest { .name("seq_von") .internalName("seq_von") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3758,7 +3702,6 @@ public abstract class BaseTest { .name("halt_diva_von") .internalName("halt_diva_von") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3772,7 +3715,6 @@ public abstract class BaseTest { .name("halt_punkt_diva_von") .internalName("halt_punkt_diva_von") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3786,7 +3728,6 @@ public abstract class BaseTest { .name("halt_kurz_von1") .internalName("halt_kurz_von1") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3800,7 +3741,6 @@ public abstract class BaseTest { .name("datum_von") .internalName("datum_von") .isNullAllowed(true) - .dateFormat(IMAGE_DATE_2_DTO) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3814,7 +3754,6 @@ public abstract class BaseTest { .name("soll_an_von") .internalName("soll_an_von") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3828,7 +3767,6 @@ public abstract class BaseTest { .name("ist_an_von") .internalName("ist_an_von") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3842,7 +3780,6 @@ public abstract class BaseTest { .name("soll_ab_von") .internalName("soll_ab_von") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3856,7 +3793,6 @@ public abstract class BaseTest { .name("ist_ab_von") .internalName("ist_ab_von") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3870,7 +3806,6 @@ public abstract class BaseTest { .name("seq_nach") .internalName("seq_nach") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3884,7 +3819,6 @@ public abstract class BaseTest { .name("halt_diva_nach") .internalName("halt_diva_nach") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3898,7 +3832,6 @@ public abstract class BaseTest { .name("halt_punkt_diva_nach") .internalName("halt_punkt_diva_nach") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3912,7 +3845,6 @@ public abstract class BaseTest { .name("halt_kurz_nach1") .internalName("halt_kurz_nach1") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3926,7 +3858,6 @@ public abstract class BaseTest { .name("datum_nach") .internalName("datum_nach") .isNullAllowed(true) - .dateFormat(IMAGE_DATE_2_DTO) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3940,7 +3871,6 @@ public abstract class BaseTest { .name("soll_an_nach") .internalName("soll_an_nach") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3954,7 +3884,6 @@ public abstract class BaseTest { .name("ist_an_nach1") .internalName("ist_an_nach1") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3968,7 +3897,6 @@ public abstract class BaseTest { .name("soll_ab_nach") .internalName("soll_ab_nach") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3982,7 +3910,6 @@ public abstract class BaseTest { .name("ist_ab_nach") .internalName("ist_ab_nach") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -3996,7 +3923,6 @@ public abstract class BaseTest { .name("fahrt_id") .internalName("fahrt_id") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -4010,7 +3936,6 @@ public abstract class BaseTest { .name("fahrweg_id") .internalName("fahrweg_id") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -4024,7 +3949,6 @@ public abstract class BaseTest { .name("fw_no") .internalName("fw_no") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -4038,7 +3962,6 @@ public abstract class BaseTest { .name("fw_typ") .internalName("fw_typ") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -4052,7 +3975,6 @@ public abstract class BaseTest { .name("fw_kurz") .internalName("fw_kurz") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -4066,7 +3988,6 @@ public abstract class BaseTest { .name("fw_lang") .internalName("fw_lang") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -4080,7 +4001,6 @@ public abstract class BaseTest { .name("umlauf_von") .internalName("umlauf_von") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -4094,7 +4014,6 @@ public abstract class BaseTest { .name("halt_id_von") .internalName("halt_id_von") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -4108,7 +4027,6 @@ public abstract class BaseTest { .name("halt_id_nach") .internalName("halt_id_nach") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -4122,7 +4040,6 @@ public abstract class BaseTest { .name("halt_punkt_id_von") .internalName("halt_punkt_id_von") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build(), @@ -4136,7 +4053,6 @@ public abstract class BaseTest { .name("halt_punkt_id_nach") .internalName("halt_punkt_id_nach") .isNullAllowed(true) - .dateFormat(null) .enums(new LinkedList<>()) .sets(new LinkedList<>()) .build()); @@ -4891,7 +4807,6 @@ public abstract class BaseTest { .name("reminder") .internalName("reminder") .columnType(ColumnTypeDto.TIME) - .dateFormat(IMAGE_DATE_4_DTO) .isNullAllowed(false) .autoGenerated(false) .build(), @@ -5195,7 +5110,6 @@ public abstract class BaseTest { .internalName("date") .ordinalPosition(1) .columnType(ColumnTypeDto.DATE) - .dateFormat(IMAGE_DATE_1_DTO) .isNullAllowed(true) .autoGenerated(false) .build(), @@ -5388,7 +5302,6 @@ public abstract class BaseTest { .internalName("date") .ordinalPosition(3) .columnType(ColumnTypeDto.DATE) - .dateFormat(IMAGE_DATE_1_DTO) .isNullAllowed(true) .autoGenerated(false) .build() diff --git a/dbrepo-ui/components/dialogs/EditAccess.vue b/dbrepo-ui/components/dialogs/EditAccess.vue index 8132adddf5..039b1c40e8 100644 --- a/dbrepo-ui/components/dialogs/EditAccess.vue +++ b/dbrepo-ui/components/dialogs/EditAccess.vue @@ -12,14 +12,13 @@ <v-col> <v-autocomplete v-if="!isModification" - v-model="modify.userId" + v-model="localUserId" :items="eligibleUsers" :disabled="loadingUsers" :loading="loadingUsers" :rules="[v => !!v || $t('validation.required')]" required :variant="inputVariant" - hide-no-data hide-selected hide-details item-value="id" @@ -56,7 +55,7 @@ :disabled="!valid || loading || accessType === modify.type" :color="buttonColor" type="submit" - :text="$t('pages.database.subpages.access.submit.text')" + :text="$t('navigation.modify')" :loading="loading" @click="updateAccess" /> </v-card-actions> @@ -90,6 +89,7 @@ export default { loadingUsers: false, users: [], error: false, + localUserId: null, types: [ { title: this.$t('pages.database.subpages.access.read'), value: 'read' }, { title: this.$t('pages.database.subpages.access.write-own'), value: 'write_own' }, @@ -169,36 +169,48 @@ export default { }, revokeAccess () { const accessService = useAccessService() - accessService.remove(this.$route.params.database_id, this.userId) + accessService.remove(this.$route.params.database_id, this.localUserId) .then(() => { const toast = useToastInstance() - toast.success(this.$t('notifications.access.revoked')) + toast.success(this.$t('success.access.revoked')) this.$emit('close-dialog', { success: true }) }) + .catch(({code, message}) => { + const toast = useToastInstance() + toast.error(message) + }) .finally(() => { this.loading = false }) }, modifyAccess () { const accessService = useAccessService() - accessService.modify(this.$route.params.database_id, this.userId, this.modify) + accessService.modify(this.$route.params.database_id, this.localUserId, this.modify) .then(() => { const toast = useToastInstance() - toast.success(this.$t('notifications.access.modified')) + toast.success(this.$t('success.access.modified')) this.$emit('close-dialog', { success: true }) }) + .catch(({code, message}) => { + const toast = useToastInstance() + toast.error(message) + }) .finally(() => { this.loading = false }) }, giveAccess () { const accessService = useAccessService() - accessService.create(this.$route.params.database_id, this.userId, this.modify) + accessService.create(this.$route.params.database_id, this.localUserId, this.modify) .then(() => { const toast = useToastInstance() - toast.success(this.$t('notifications.access.created')) + toast.success(this.$t('success.access.created')) this.$emit('close-dialog', { success: true }) }) + .catch(({code, message}) => { + const toast = useToastInstance() + toast.error(message) + }) .finally(() => { this.loading = false }) @@ -210,6 +222,10 @@ export default { .then((users) => { this.users = users.filter(u => u.username !== this.database.creator.username) }) + .catch(({code}) => { + const toast = useToastInstance() + toast.error(this.$t(code)) + }) .finally(() => { this.loadingUsers = false }) @@ -217,6 +233,8 @@ export default { init () { if (!this.userId) { this.loadUsers() + } else { + this.localUserId = this.userId } if (!this.accessType) { this.modify.type = null diff --git a/dbrepo-ui/composables/access-service.ts b/dbrepo-ui/composables/access-service.ts index c08e5d0b9f..056efec117 100644 --- a/dbrepo-ui/composables/access-service.ts +++ b/dbrepo-ui/composables/access-service.ts @@ -21,7 +21,7 @@ export const useAccessService = (): any => { const axios = useAxiosInstance() console.debug('create access for user with id', userId, 'of database with id', databaseId) return new Promise<DatabaseAccessDto>((resolve, reject) => { - axios.post<DatabaseAccessDto>(`/api/database/${databaseId}/access`, payload) + axios.post<DatabaseAccessDto>(`/api/database/${databaseId}/access/${userId}`, payload) .then((response) => { console.info('Created access for user with id', userId, 'of database with id', databaseId) resolve(response.data) diff --git a/dbrepo-ui/locales/en-US.json b/dbrepo-ui/locales/en-US.json index 6abf715bc0..4eb7316617 100644 --- a/dbrepo-ui/locales/en-US.json +++ b/dbrepo-ui/locales/en-US.json @@ -32,7 +32,8 @@ "no": "No", "mine": "(mine)", "loading": "Loading", - "view": "View" + "view": "View", + "modify": "Modify" }, "pages": { "identifier": { @@ -611,10 +612,10 @@ "access": { "title": "Database Access", "subtitle": "Overview on users with their access to the database", - "read": "You can read all contents", - "write-own": "You can write own tables and read all contents", - "write-all": "You can write own tables and read all contents", - "revoke": "Revoke", + "read": "Read all contents", + "write-own": "Read all contents & write own tables", + "write-all": "Read all contents & write all tables", + "revoke": "No access", "action": "Action", "username": { "label": "Username", @@ -623,9 +624,6 @@ "type": { "label": "Access Type", "hint": "Required" - }, - "submit": { - "text": "Modify" } }, "create": { diff --git a/dbrepo-ui/pages/database/[database_id]/settings.vue b/dbrepo-ui/pages/database/[database_id]/settings.vue index 09c3d8263b..1d2d9dca0c 100644 --- a/dbrepo-ui/pages/database/[database_id]/settings.vue +++ b/dbrepo-ui/pages/database/[database_id]/settings.vue @@ -96,8 +96,9 @@ v-if="item && item.user && item.user.username !== user.username" size="x-small" variant="flat" + color="warning" :disabled="!canModifyAccess" - :text="$t('pages.database.subpages.access.submit.text')" + :text="$t('navigation.modify')" @click="modifyAccess(item)" /> </template> </v-data-table> @@ -107,7 +108,7 @@ variant="flat" :disabled="!canCreateAccess" color="warning" - :text="$t('pages.database.subpages.access.submit.text')" + :text="$t('navigation.create')" @click="giveAccess" /> </v-card-text> </v-card> @@ -422,7 +423,7 @@ export default { this.$refs.form.validate() }, closeDialog () { - this.reloadDatabase() + this.cacheStore.reloadDatabase() this.editAccessDialog = false }, updateDatabaseVisibility () { @@ -510,11 +511,11 @@ export default { updateDatabaseOwner () { this.loading = true const databaseService = useDatabaseService() - databaseService.updateOwner(this.$route.params.database_id, this.modifyOwner.id) + databaseService.updateOwner(this.$route.params.database_id, { id: this.modifyOwner.id }) .then(() => { const toast = useToastInstance() toast.success(this.$t('success.database.transfer')) - location.reload() + this.$router.push(`/database/${this.$route.params.database_id}/info`) }) .catch(() => { this.loading = false -- GitLab