diff --git a/dbrepo-database-service/pom.xml b/dbrepo-database-service/pom.xml index dc1a4e444643c1aa0f41918c0852b2a3e096d7cf..ce51fd308c1a2268274b568a59309396750c0292 100644 --- a/dbrepo-database-service/pom.xml +++ b/dbrepo-database-service/pom.xml @@ -25,12 +25,13 @@ <java.version>17</java.version> <spring-cloud.version>4.0.2</spring-cloud.version> <mapstruct.version>1.5.5.Final</mapstruct.version> - <docker.version>3.3.0</docker.version> <jacoco.version>0.8.10</jacoco.version> <jwt.version>4.3.0</jwt.version> <c3p0.version>0.9.5.5</c3p0.version> <c3p0-hibernate.version>6.2.2.Final</c3p0-hibernate.version> <springdoc-openapi.version>2.1.0</springdoc-openapi.version> + <hsqldb.version>2.7.2</hsqldb.version> + <testcontainers.version>1.18.3</testcontainers.version> <opensearch-client.version>1.1.0</opensearch-client.version> </properties> @@ -163,8 +164,27 @@ </exclusions> </dependency> <dependency> - <groupId>com.h2database</groupId> - <artifactId>h2</artifactId> + <groupId>org.hsqldb</groupId> + <artifactId>hsqldb</artifactId> + <version>${hsqldb.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${testcontainers.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>mariadb</artifactId> + <version>${testcontainers.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>rabbitmq</artifactId> + <version>${testcontainers.version}</version> <scope>test</scope> </dependency> <dependency> @@ -183,23 +203,6 @@ <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> - <!-- Docker --> - <dependency> - <groupId>com.github.docker-java</groupId> - <artifactId>docker-java</artifactId> - <version>${docker.version}</version> - <exclusions> - <exclusion> - <groupId>javax.ws.rs</groupId> - <artifactId>jsr311-api</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>com.github.docker-java</groupId> - <artifactId>docker-java-transport-httpclient5</artifactId> - <version>${docker.version}</version> - </dependency> <!-- Mapping --> <dependency> <groupId>org.mapstruct</groupId> diff --git a/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java b/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java index 955f7e8816d1a25ba894b3bdf624a4e96c07862b..09d0db2a1ca2900d753e4a9765cae0b3bea22517 100644 --- a/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java +++ b/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java @@ -14,6 +14,9 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; @@ -21,15 +24,12 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import java.security.Principal; @Log4j2 @RestController @CrossOrigin(origins = "*") -@RequestMapping("/api/container/{id}/database/{databaseId}/access") +@RequestMapping("/api/database/{id}/access") public class AccessEndpoint { private final AccessService accessService; @@ -65,14 +65,12 @@ public class AccessEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<?> create(@NotBlank @PathVariable("id") Long containerId, - @NotBlank @PathVariable("databaseId") Long databaseId, + public ResponseEntity<?> create(@NotBlank @PathVariable("id") Long databaseId, @Valid @RequestBody DatabaseGiveAccessDto accessDto, @NotNull Principal principal) throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException, QueryMalformedException, DatabaseMalformedException { - log.debug("endpoint give access to database, containerId={}, databaseId={}, accessDto={}, principal={}", - containerId, databaseId, accessDto, principal); + log.debug("endpoint give access to database, databaseId={}, accessDto={}, principal={}", databaseId, accessDto, principal); try { accessService.find(databaseId, accessDto.getUsername()); log.error("Failed to give access to user with username {}, already has access", accessDto.getUsername()); @@ -80,7 +78,7 @@ public class AccessEndpoint { } catch (AccessDeniedException e) { /* ignore */ } - accessService.create(containerId, databaseId, accessDto); + accessService.create(databaseId, accessDto); return ResponseEntity.accepted() .build(); } @@ -109,17 +107,15 @@ public class AccessEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<?> update(@NotBlank @PathVariable("id") Long containerId, - @NotBlank @PathVariable("databaseId") Long databaseId, + public ResponseEntity<?> update(@NotBlank @PathVariable("id") Long databaseId, @NotBlank @PathVariable("username") String username, @Valid @RequestBody DatabaseModifyAccessDto accessDto, @NotNull Principal principal) throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException, AccessDeniedException, QueryMalformedException, DatabaseMalformedException { - log.debug("endpoint modify access to database, containerId={}, databaseId={}, username={}, accessDto={}, principal={}", - containerId, databaseId, username, accessDto, principal); + log.debug("endpoint modify access to database, databaseId={}, username={}, accessDto={}, principal={}", databaseId, username, accessDto, principal); accessService.find(databaseId, username); - accessService.update(containerId, databaseId, username, accessDto); + accessService.update(databaseId, username, accessDto); return ResponseEntity.accepted() .build(); } @@ -145,12 +141,10 @@ public class AccessEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<DatabaseAccessDto> find(@NotBlank @PathVariable("id") Long containerId, - @NotBlank @PathVariable("databaseId") Long databaseId, + public ResponseEntity<DatabaseAccessDto> find(@NotBlank @PathVariable("id") Long databaseId, @NotNull Principal principal) throws NotAllowedException, AccessDeniedException { - log.debug("endpoint check access to database, containerId={}, databaseId={}, principal={}", - containerId, databaseId, principal); + log.debug("endpoint check access to database, databaseId={}, principal={}", databaseId, principal); final DatabaseAccess access = accessService.find(databaseId, principal.getName()); final DatabaseAccessDto dto = databaseMapper.databaseAccessToDatabaseAccessDto(access); log.trace("check access resulted in dto {}", dto); @@ -186,16 +180,14 @@ public class AccessEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<?> revoke(@NotBlank @PathVariable("id") Long containerId, - @NotBlank @PathVariable("databaseId") Long databaseId, + public ResponseEntity<?> revoke(@NotBlank @PathVariable("id") Long databaseId, @NotBlank @PathVariable("username") String username, @NotNull Principal principal) throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException, AccessDeniedException, QueryMalformedException, DatabaseMalformedException { - log.debug("endpoint revoke access to database, containerId={}, databaseId={}, username={}, principal={}", - containerId, databaseId, username, principal); + log.debug("endpoint revoke access to database, databaseId={}, username={}, principal={}", databaseId, username, principal); accessService.find(databaseId, username); - accessService.delete(containerId, databaseId, username); + accessService.delete(databaseId, username); return ResponseEntity.accepted() .build(); } diff --git a/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java b/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java index d1e815abc1b709231c7685ebe7fb264478ba57b4..fd8f6d74a55494a89e02656de120f618e2e89262 100644 --- a/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java +++ b/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java @@ -1,9 +1,7 @@ package at.tuwien.endpoints; -import at.tuwien.api.container.ContainerDto; import at.tuwien.api.database.*; import at.tuwien.api.error.ApiErrorDto; -import at.tuwien.entities.container.Container; import at.tuwien.entities.database.Database; import at.tuwien.entities.database.DatabaseAccess; import at.tuwien.entities.user.User; @@ -20,6 +18,8 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; +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.HttpStatus; @@ -28,8 +28,6 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; import java.security.Principal; import java.util.List; import java.util.stream.Collectors; @@ -37,7 +35,7 @@ import java.util.stream.Collectors; @Log4j2 @RestController @CrossOrigin(origins = "*") -@RequestMapping("/api/container/{id}/database") +@RequestMapping("/api/database") public class DatabaseEndpoint { private final UserService userService; @@ -75,12 +73,12 @@ public class DatabaseEndpoint { mediaType = "application/json", array = @ArraySchema(schema = @Schema(implementation = DatabaseBriefDto.class)))}), }) - public ResponseEntity<List<DatabaseBriefDto>> list(@NotNull @PathVariable("id") Long containerId, - @NotNull Principal principal) { - log.debug("endpoint list databases, containerId={}, principal={}", containerId, principal); - final List<DatabaseBriefDto> databases = databaseService.findAll(containerId) + public ResponseEntity<List<DatabaseDto>> list(@NotNull Principal principal) { + log.debug("endpoint list databases, principal={}", principal); + List<DatabaseDto> databases; + databases = databaseService.findAll() .stream() - .map(databaseMapper::databaseToDatabaseBriefDto) + .map(databaseMapper::databaseToDatabaseDto) .collect(Collectors.toList()); log.trace("list databases resulted in databases {}", databases); return ResponseEntity.ok(databases); @@ -138,27 +136,21 @@ public class DatabaseEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<DatabaseBriefDto> create(@NotNull @PathVariable("id") Long containerId, - @Valid @RequestBody DatabaseCreateDto createDto, + public ResponseEntity<DatabaseBriefDto> create(@Valid @RequestBody DatabaseCreateDto createDto, @NotNull Principal principal) throws ImageNotSupportedException, ContainerNotFoundException, DatabaseMalformedException, AmqpException, ContainerConnectionException, UserNotFoundException, DatabaseNotFoundException, DatabaseNameExistsException, DatabaseConnectionException, QueryMalformedException, NotAllowedException, BrokerVirtualHostCreationException, QueryStoreException, BrokerVirtualHostGrantException { - log.debug("endpoint create database, containerId={}, createDto={}, principal={}", containerId, createDto, + log.debug("endpoint create database, createDto={}, principal={}", createDto, principal); - final Container container = containerService.find(containerId); final User user = userService.findByUsername(principal.getName()); - if (!container.getOwner().equals(user)) { - log.error("Failed to create database: not owner"); - throw new NotAllowedException(("Failed to create database: not owner")); - } - final Database database = databaseService.create(containerId, createDto, principal); + final Database database = databaseService.create(createDto, principal); messageQueueService.createUser(user); messageQueueService.createExchange(database, principal); messageQueueService.updatePermissions(principal); - queryStoreService.create(containerId, database.getId(), principal); + queryStoreService.create(database.getId(), principal); databaseAccessRepository.save(databaseMapper.defaultCreatorAccess(database, user)); final DatabaseBriefDto dto = databaseMapper.databaseToDatabaseBriefDto(database); log.trace("create database resulted in database {}", dto); @@ -166,7 +158,7 @@ public class DatabaseEndpoint { .body(dto); } - @PutMapping("/{databaseId}/visibility") + @PutMapping("/{id}/visibility") @Transactional @PreAuthorize("hasAuthority('modify-database-visibility')") @Timed(value = "database.visibility", description = "Time needed to modify a database visibility") @@ -188,26 +180,24 @@ public class DatabaseEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<DatabaseDto> visibility(@NotNull @PathVariable("id") Long containerId, - @NotNull @PathVariable Long databaseId, + public ResponseEntity<DatabaseDto> visibility(@NotNull @PathVariable Long id, @Valid @RequestBody DatabaseModifyVisibilityDto data, @NotNull Principal principal) throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException { - log.debug("endpoint update database, containerId={}, databaseId={}, data={}, principal={}", containerId, - databaseId, data, principal); - final Database database = databaseService.findById(containerId, databaseId); + log.debug("endpoint update database, id={}, data={}, principal={}", id, data, principal); + final Database database = databaseService.findById(id); final User user = userService.findByUsername(principal.getName()); if (!database.getOwner().equals(user)) { log.error("Failed to create database: not owner"); throw new NotAllowedException(("Failed to create database: not owner")); } - final DatabaseDto dto = databaseMapper.databaseToDatabaseDto(databaseService.visibility(containerId, databaseId, data)); + final DatabaseDto dto = databaseMapper.databaseToDatabaseDto(databaseService.visibility(id, data)); log.trace("update database resulted in database {}", dto); return ResponseEntity.accepted() .body(dto); } - @PutMapping("/{databaseId}/transfer") + @PutMapping("/{id}/transfer") @Transactional @PreAuthorize("hasAuthority('modify-database-owner')") @Timed(value = "database.transfer", description = "Time needed to transfer a database ownership") @@ -229,26 +219,24 @@ public class DatabaseEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<DatabaseDto> transfer(@NotNull @PathVariable("id") Long containerId, - @NotNull @PathVariable Long databaseId, + public ResponseEntity<DatabaseDto> transfer(@NotNull @PathVariable Long id, @Valid @RequestBody DatabaseTransferDto transferDto, @NotNull Principal principal) throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException { - log.debug("endpoint update database, containerId={}, databaseId={}, transferDto={}, principal={}", containerId, - databaseId, transferDto, principal); - final Database database = databaseService.findById(containerId, databaseId); + log.debug("endpoint update database, id={}, transferDto={}, principal={}", id, transferDto, principal); + final Database database = databaseService.findById(id); final User user = userService.findByUsername(principal.getName()); if (!database.getOwner().equals(user)) { log.error("Failed to create database: not owner"); throw new NotAllowedException(("Failed to create database: not owner")); } - final DatabaseDto dto = databaseMapper.databaseToDatabaseDto(databaseService.transfer(containerId, databaseId, transferDto)); + final DatabaseDto dto = databaseMapper.databaseToDatabaseDto(databaseService.transfer(id, transferDto)); log.trace("update database resulted in database {}", dto); return ResponseEntity.accepted() .body(dto); } - @GetMapping("/{databaseId}") + @GetMapping("/{id}") @Transactional(readOnly = true) @Timed(value = "database.find", description = "Time needed to find a database") @Operation(summary = "Find some database", security = @SecurityRequirement(name = "bearerAuth")) @@ -269,27 +257,24 @@ public class DatabaseEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<DatabaseDto> findById(@NotNull @PathVariable("id") Long containerId, - @NotNull @PathVariable Long databaseId, + public ResponseEntity<DatabaseDto> findById(@NotNull @PathVariable Long id, Principal principal) throws DatabaseNotFoundException, AccessDeniedException, ContainerNotFoundException { - log.debug("endpoint find database, containerId={}, databaseId={}", containerId, databaseId); - final Database database = databaseService.findById(containerId, databaseId); + log.debug("endpoint find database, id={}", id); + final Database database = databaseService.findById(id); final DatabaseDto dto = databaseMapper.databaseToDatabaseDto(database); if (principal != null && database.getOwner().equalsPrincipal(principal)) { /* only owner sees the access rights */ // TODO improve this by proper mapping - final List<DatabaseAccess> accesses = accessService.list(databaseId); + final List<DatabaseAccess> accesses = accessService.list(id); dto.setAccesses(accesses.stream() .map(databaseMapper::databaseAccessToDatabaseAccessDto) .collect(Collectors.toList())); } - final ContainerDto containerDto = containerService.inspect(containerId); - dto.setContainer(containerDto); log.trace("find database resulted in dto {}", dto); return ResponseEntity.ok(dto); } - @DeleteMapping("/{databaseId}") + @DeleteMapping("/{id}") @Transactional @PreAuthorize("hasAuthority('delete-database')") @Timed(value = "database.delete", description = "Time needed to delete a database") @@ -336,17 +321,16 @@ public class DatabaseEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<?> delete(@NotNull @PathVariable("id") Long containerId, - @NotNull @PathVariable Long databaseId, + public ResponseEntity<?> delete(@NotNull @PathVariable Long id, Principal principal) throws DatabaseNotFoundException, ImageNotSupportedException, DatabaseMalformedException, AmqpException, ContainerNotFoundException, QueryMalformedException, BrokerVirtualHostCreationException, UserNotFoundException, BrokerVirtualHostGrantException, DatabaseConnectionException { - log.debug("endpoint delete database, containerId={}, databaseId={}, principal={}", containerId, databaseId, + log.debug("endpoint delete database, id={}, principal={}", id, principal); - final Database database = databaseService.findById(containerId, databaseId); + final Database database = databaseService.findById(id); messageQueueService.deleteExchange(database); - databaseService.delete(containerId, databaseId, principal); + databaseService.delete(id, principal); messageQueueService.updatePermissions(principal); return ResponseEntity.accepted() .build(); diff --git a/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/LicenseEndpoint.java b/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/LicenseEndpoint.java index 14105173421f5d044a5ee89a8eee49f156d4e34c..6663d1e89f8f850f99e881159c857d9a8603e65a 100644 --- a/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/LicenseEndpoint.java +++ b/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/LicenseEndpoint.java @@ -1,9 +1,6 @@ package at.tuwien.endpoints; -import at.tuwien.api.container.ContainerBriefDto; -import at.tuwien.api.database.DatabaseBriefDto; import at.tuwien.api.database.LicenseDto; -import at.tuwien.api.error.ApiErrorDto; import at.tuwien.mapper.LicenseMapper; import at.tuwien.service.LicenseService; import io.micrometer.core.annotation.Timed; @@ -17,18 +14,19 @@ 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.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; -import jakarta.validation.constraints.NotBlank; import java.util.List; import java.util.stream.Collectors; @Log4j2 @RestController @CrossOrigin(origins = "*") -@RequestMapping("/api/container/{id}/database") +@RequestMapping("/api/database") public class LicenseEndpoint { private final LicenseMapper licenseMapper; @@ -51,8 +49,8 @@ public class LicenseEndpoint { mediaType = "application/json", array = @ArraySchema(schema = @Schema(implementation = LicenseDto.class)))}), }) - public ResponseEntity<List<LicenseDto>> list(@NotBlank @PathVariable("id") Long containerId) { - log.debug("endpoint list licenses, containerId={}", containerId); + public ResponseEntity<List<LicenseDto>> list() { + log.debug("endpoint list licenses"); final List<LicenseDto> licenses = licenseService.findAll() .stream() .map(licenseMapper::licenseToLicenseDto) diff --git a/dbrepo-database-service/rest-service/src/main/resources/init/querystore.sql b/dbrepo-database-service/rest-service/src/main/resources/init/querystore.sql index 26fc6e54370ec268fa2cfa683f37c825d7cfa81b..1bf8b26c5580b343a7e75864931f2f8584932843 100644 --- a/dbrepo-database-service/rest-service/src/main/resources/init/querystore.sql +++ b/dbrepo-database-service/rest-service/src/main/resources/init/querystore.sql @@ -1,4 +1,4 @@ -CREATE SEQUENCE `qs_queries_seq`; +CREATE SEQUENCE `qs_queries_seq`; CREATE TABLE `qs_queries` ( `id` bigint not null primary key default nextval(`qs_queries_seq`), `created` datetime not null default now(), `executed` datetime not null default now(), `created_by` varchar(255) not null, `query` text not null, `query_normalized` text not null, `is_persisted` boolean not null, `query_hash` varchar(255) not null, `result_hash` varchar(255), `result_number` bigint ); CREATE PROCEDURE hash_table(IN name VARCHAR(255), OUT hash VARCHAR(255), OUT count BIGINT) BEGIN DECLARE _sql TEXT; SELECT CONCAT('SELECT SHA2(GROUP_CONCAT(CONCAT_WS(\'\',', GROUP_CONCAT(CONCAT('`', column_name, '`') ORDER BY column_name), ') SEPARATOR \',\'), 256) AS hash, COUNT(*) AS count FROM `', name, '` INTO @hash, @count;') FROM `information_schema`.`columns` WHERE `table_schema` = DATABASE() AND `table_name` = name INTO _sql; PREPARE stmt FROM _sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SET hash = @hash; SET count = @count; END; CREATE PROCEDURE store_query(IN query TEXT, IN executed DATETIME, OUT queryId BIGINT) BEGIN DECLARE _queryhash varchar(255) DEFAULT SHA2(query, 256); DECLARE _username varchar(255) DEFAULT REGEXP_REPLACE(current_user(), '@.*', ''); DECLARE _query TEXT DEFAULT CONCAT('CREATE OR REPLACE TABLE _tmp AS (', query, ')'); PREPARE stmt FROM _query; EXECUTE stmt; DEALLOCATE PREPARE stmt; CALL hash_table('_tmp', @hash, @count); IF @hash IS NULL THEN INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); ELSE INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); END IF; END; diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java index 1a62502333d3cba17e7807c858a3f37104af7066..4cf40e356bc1cba8d5d880c8297064a6728bf662 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java @@ -2,6 +2,7 @@ package at.tuwien.config; import at.tuwien.api.database.AccessTypeDto; import at.tuwien.api.database.DatabaseGiveAccessDto; +import at.tuwien.entities.container.Container; import at.tuwien.entities.database.Database; import at.tuwien.entities.user.User; import at.tuwien.exception.QueryMalformedException; @@ -9,6 +10,8 @@ import at.tuwien.mapper.DatabaseMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import java.sql.*; import java.time.Instant; @@ -19,28 +22,23 @@ import java.util.List; @Configuration public class MariaDbConfig { - private final DatabaseMapper databaseMapper; - @Autowired - public MariaDbConfig(DatabaseMapper databaseMapper) { - this.databaseMapper = databaseMapper; - } + private DatabaseMapper databaseMapper; /** * Inserts a query into a created database with given hostname and database name. The method uses the JDBC in-out * notation <a href="#{@link}">{@link https://learn.microsoft.com/en-us/sql/connect/jdbc/using-sql-escape-sequences?view=sql-server-ver16#stored-procedure-calls}</a> * - * @param hostname The hostname. - * @param database The database name. + * @param database The database. * @param query The query. * @param username The connection username. * @param password The connection password. * @return The generated or retrieved query id. * @throws SQLException The procedure did not succeed. */ - public static Long mockSystemQueryInsert(String hostname, String database, String query, String username, String password) + public static Long mockSystemQueryInsert(Database database, String query, String username, String password) throws SQLException { - final String jdbc = "jdbc:mariadb://" + hostname + "/" + database; + final String jdbc = "jdbc:mariadb://" + database.getContainer().getHost() + ":" + database.getContainer().getPort() + "/" + database.getInternalName(); log.trace("connect to database {}", jdbc); try (Connection connection = DriverManager.getConnection(jdbc, username, password)) { final String call = "{call _store_query(?,?,?,?)}"; @@ -58,11 +56,58 @@ public class MariaDbConfig { } } - public static void dropDatabase(String hostname, String database, String username, String password) + public static void createDatabase(Container container, String database) throws SQLException { + final String jdbc = "jdbc:mariadb://" + container.getHost() + ":" + container.getPort(); + log.trace("connect to database {}", jdbc); + try (Connection connection = DriverManager.getConnection(jdbc, container.getPrivilegedUsername(), container.getPrivilegedPassword())) { + final String sql = "CREATE DATABASE `" + database + "`;"; + log.trace("prepare statement '{}'", sql); + final PreparedStatement statement = connection.prepareStatement(sql); + statement.executeUpdate(); + statement.close(); + } + } + + public static void createInitDatabase(Container container, Database database) throws SQLException { + final String jdbc = "jdbc:mariadb://" + container.getHost() + ":" + container.getPort(); + log.trace("connect to database {}", jdbc); + try (Connection connection = DriverManager.getConnection(jdbc, container.getPrivilegedUsername(), container.getPrivilegedPassword())) { + ResourceDatabasePopulator populator = new ResourceDatabasePopulator(new ClassPathResource("init/" + database.getInternalName() + ".sql"), new ClassPathResource("init/querystore.sql")); + populator.setSeparator(";\n"); + populator.populate(connection); + } + } + + public static void dropAllDatabases(Container container) { + final String jdbc = "jdbc:mariadb://" + container.getHost() + ":" + container.getPort(); + log.trace("connect to database {}", jdbc); + try (Connection connection = DriverManager.getConnection(jdbc, container.getPrivilegedUsername(), container.getPrivilegedPassword())) { + final String sql = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'mysql', 'performance_schema');"; + log.trace("prepare statement '{}'", sql); + final PreparedStatement statement = connection.prepareStatement(sql); + final ResultSet resultSet = statement.executeQuery(); + final List<String> databases = new LinkedList<>(); + while (resultSet.next()) { + databases.add(resultSet.getString(1)); + } + resultSet.close(); + statement.close(); + for (String database : databases) { + final String drop = "DROP DATABASE IF EXISTS `" + database + "`;"; + final PreparedStatement dropStatement = connection.prepareStatement(drop); + dropStatement.executeUpdate(); + dropStatement.close(); + } + } catch (SQLException e) { + log.error("could not drop all databases", e); + } + } + + public static void dropDatabase(Container container, String database) throws SQLException { - final String jdbc = "jdbc:mariadb://" + hostname + "/" + database; + final String jdbc = "jdbc:mariadb://" + container.getHost() + ":" + container.getPort(); log.trace("connect to database {}", jdbc); - try (Connection connection = DriverManager.getConnection(jdbc, username, password)) { + try (Connection connection = DriverManager.getConnection(jdbc, container.getPrivilegedUsername(), container.getPrivilegedPassword())) { final String sql = "DROP DATABASE IF EXISTS `" + database + "`;"; log.trace("prepare statement '{}'", sql); final PreparedStatement statement = connection.prepareStatement(sql); @@ -71,11 +116,11 @@ public class MariaDbConfig { } } - public void mockGrantUserPermissions(String hostname, Database database, User user) throws SQLException, + public void mockGrantUserPermissions(Container container, Database database, User user) throws SQLException, QueryMalformedException { - final String jdbc = "jdbc:mariadb://" + hostname + "/" + database.getInternalName(); + final String jdbc = "jdbc:mariadb://" + container.getHost() + ":" + container.getPort() + "/" + database.getInternalName(); log.trace("connect to database {}", jdbc); - try (Connection connection = DriverManager.getConnection(jdbc, "root", "mariadb")) { + try (Connection connection = DriverManager.getConnection(jdbc, container.getPrivilegedUsername(), container.getPrivilegedPassword())) { final DatabaseGiveAccessDto access = DatabaseGiveAccessDto.builder() .username(user.getUsername()) .type(AccessTypeDto.WRITE_ALL) @@ -141,17 +186,16 @@ public class MariaDbConfig { * Inserts a query into a created database with given hostname and database name. The method uses the JDBC in-out * notation <a href="#{@link}">{@link https://learn.microsoft.com/en-us/sql/connect/jdbc/using-sql-escape-sequences?view=sql-server-ver16#stored-procedure-calls}</a> * - * @param hostname The hostname. - * @param database The database name. + * @param database The database. * @param query The query. * @param username The connection username. * @param password The connection password. * @return The generated or retrieved query id. * @throws SQLException The procedure did not succeed. */ - public static Long mockUserQueryInsert(String hostname, String database, String query, String username, String password) + public static Long mockUserQueryInsert(Database database, String query, String username, String password) throws SQLException { - final String jdbc = "jdbc:mariadb://" + hostname + "/" + database; + final String jdbc = "jdbc:mariadb://" + database.getContainer().getHost() + ":" + database.getContainer().getPort() + "/" + database.getInternalName(); log.trace("connect to database {}", jdbc); try (Connection connection = DriverManager.getConnection(jdbc, username, password)) { final String call = "{call store_query(?,?,?)}"; @@ -172,13 +216,12 @@ public class MariaDbConfig { * Inserts a query into a created database with given hostname and database name. The method uses the JDBC in-out * notation <a href="#{@link}">{@link https://learn.microsoft.com/en-us/sql/connect/jdbc/using-sql-escape-sequences?view=sql-server-ver16#stored-procedure-calls}</a> * - * @param hostname The hostname. - * @param database The database name. + * @param database The database. * @param query The query. * @return The generated or retrieved query id. * @throws SQLException The procedure did not succeed. */ - public static Long mockSystemQueryInsert(String hostname, String database, String query) throws SQLException { - return mockSystemQueryInsert(hostname, database, query, "root", "mariadb"); + public static Long mockSystemQueryInsert(Database database, String query) throws SQLException { + return mockSystemQueryInsert(database, query, database.getContainer().getPrivilegedUsername(), database.getContainer().getPrivilegedPassword()); } } diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..587927a0703c0bc78a8dc41fb665ac5d02a1d3b4 --- /dev/null +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java @@ -0,0 +1,55 @@ +package at.tuwien.config; + +import at.tuwien.test.BaseTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.testcontainers.containers.MariaDBContainer; +import org.testcontainers.images.PullPolicy; + +/** + * This class configures the MariaDB container for the integration tests. + */ +@Configuration +public class MariaDbContainerConfig { + + @Bean + public CustomMariaDBContainer mariaDB() { + return CustomMariaDBContainer.getInstance(); + } + + /** + * This class represents the customized MariaDB container. It is a singleton to avoid the recreation of containers + * which can be very time-consuming. + */ + public static class CustomMariaDBContainer extends MariaDBContainer<CustomMariaDBContainer> { + + private static CustomMariaDBContainer instance; + + public static CustomMariaDBContainer getInstance() { + if(instance == null) { + instance = new CustomMariaDBContainer(BaseTest.IMAGE_1_NAME + ":" + BaseTest.IMAGE_1_VERSION); + instance.withImagePullPolicy(PullPolicy.alwaysPull()); + instance.addFixedExposedPort(BaseTest.CONTAINER_1_PORT, BaseTest.IMAGE_1_PORT); + instance.withUsername(BaseTest.CONTAINER_1_PRIVILEGED_USERNAME); + instance.withPassword(BaseTest.CONTAINER_1_PRIVILEGED_PASSWORD); + instance.withInitScript("init/users.sql"); + } + return instance; + } + + private CustomMariaDBContainer(String dockerImageName) { + super(dockerImageName); + } + + @Override + protected void configure() { + super.configure(); + this.addEnv("MYSQL_USER", "test"); // MariaDB does not allow this to be root + } + + @Override + public void stop() { + // do nothing, JVM handles shut down + } + } +} diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/endpoint/AccessEndpointUnitTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/endpoint/AccessEndpointUnitTest.java index df61f6197b64646980cf1fa585e62478c478ecdc..60092144ddc8a2b13ba884470b9f6e02ff6fe4f1 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/endpoint/AccessEndpointUnitTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/endpoint/AccessEndpointUnitTest.java @@ -75,7 +75,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - generic_create(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, null, USER_2_USERNAME, USER_2, null); + generic_create(DATABASE_1_ID, DATABASE_1, null, USER_2_USERNAME, USER_2, null); }); } @@ -85,7 +85,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - generic_create(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, null, USER_4_USERNAME, USER_4, USER_4_PRINCIPAL); + generic_create(DATABASE_1_ID, DATABASE_1, null, USER_4_USERNAME, USER_4, USER_4_PRINCIPAL); }); } @@ -97,10 +97,10 @@ public class AccessEndpointUnitTest extends BaseUnitTest { /* mock */ doNothing() .when(accessService) - .create(eq(CONTAINER_1_ID), eq(DATABASE_1_ID), any(DatabaseGiveAccessDto.class)); + .create(eq(DATABASE_1_ID), any(DatabaseGiveAccessDto.class)); /* test */ - generic_create(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, null, USER_2_USERNAME, USER_2, USER_1_PRINCIPAL); + generic_create(DATABASE_1_ID, DATABASE_1, null, USER_2_USERNAME, USER_2, USER_1_PRINCIPAL); } @Test @@ -109,7 +109,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - generic_find(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, null, USER_1_USERNAME, null, null); + generic_find(DATABASE_1_ID, DATABASE_1, null, USER_1_USERNAME, null, null); }); } @@ -119,7 +119,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(AccessDeniedException.class, () -> { - generic_find(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, null, USER_2_USERNAME, USER_2_ID, USER_2_PRINCIPAL); + generic_find(DATABASE_1_ID, DATABASE_1, null, USER_2_USERNAME, USER_2_ID, USER_2_PRINCIPAL); }); } @@ -128,7 +128,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { public void find_hasRoleHasAccess_succeeds() throws AccessDeniedException, NotAllowedException { /* test */ - generic_find(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, DATABASE_1_USER_1_READ_ACCESS, USER_1_USERNAME, USER_1_ID, USER_1_PRINCIPAL); + generic_find(DATABASE_1_ID, DATABASE_1, DATABASE_1_USER_1_READ_ACCESS, USER_1_USERNAME, USER_1_ID, USER_1_PRINCIPAL); } @Test @@ -141,7 +141,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - generic_update(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, null, USER_4_USERNAME, null); + generic_update(DATABASE_1_ID, DATABASE_1, null, USER_4_USERNAME, null); }); } @@ -155,7 +155,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(AccessDeniedException.class, () -> { - generic_update(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, null, USER_4_USERNAME, USER_1_PRINCIPAL); + generic_update(DATABASE_1_ID, DATABASE_1, null, USER_4_USERNAME, USER_1_PRINCIPAL); }); } @@ -169,7 +169,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - generic_update(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, null, USER_4_USERNAME, USER_4_PRINCIPAL); + generic_update(DATABASE_1_ID, DATABASE_1, null, USER_4_USERNAME, USER_4_PRINCIPAL); }); } @@ -183,10 +183,10 @@ public class AccessEndpointUnitTest extends BaseUnitTest { .thenReturn(Optional.of(USER_1)); doNothing() .when(accessService) - .update(eq(CONTAINER_1_ID), eq(DATABASE_1_ID), eq(USER_2_USERNAME), any(DatabaseModifyAccessDto.class)); + .update(eq(DATABASE_1_ID), eq(USER_2_USERNAME), any(DatabaseModifyAccessDto.class)); /* test */ - generic_update(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, DATABASE_1_USER_2_WRITE_OWN_ACCESS, USER_2_USERNAME, USER_1_PRINCIPAL); + generic_update(DATABASE_1_ID, DATABASE_1, DATABASE_1_USER_2_WRITE_OWN_ACCESS, USER_2_USERNAME, USER_1_PRINCIPAL); } @Test @@ -195,7 +195,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - generic_revoke(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1_USER_1_WRITE_ALL_ACCESS, USER_2_USERNAME, USER_1_PRINCIPAL); + generic_revoke(DATABASE_1_ID, DATABASE_1_USER_1_WRITE_ALL_ACCESS, USER_2_USERNAME, USER_1_PRINCIPAL); }); } @@ -205,7 +205,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - generic_revoke(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1_USER_1_WRITE_ALL_ACCESS, USER_2_USERNAME, USER_4_PRINCIPAL); + generic_revoke(DATABASE_1_ID, DATABASE_1_USER_1_WRITE_ALL_ACCESS, USER_2_USERNAME, USER_4_PRINCIPAL); }); } @@ -217,17 +217,17 @@ public class AccessEndpointUnitTest extends BaseUnitTest { /* mock */ doNothing() .when(accessService) - .delete(CONTAINER_1_ID, DATABASE_1_ID, USER_2_USERNAME); + .delete(DATABASE_1_ID, USER_2_USERNAME); /* test */ - generic_revoke(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1_USER_1_WRITE_ALL_ACCESS, USER_2_USERNAME, USER_1_PRINCIPAL); + generic_revoke(DATABASE_1_ID, DATABASE_1_USER_1_WRITE_ALL_ACCESS, USER_2_USERNAME, USER_1_PRINCIPAL); } /* ################################################################################################### */ /* ## GENERIC TEST CASES ## */ /* ################################################################################################### */ - protected void generic_create(Long containerId, Long databaseId, Database database, DatabaseAccess access, + protected void generic_create(Long databaseId, Database database, DatabaseAccess access, String username, User user, Principal principal) throws UserNotFoundException, NotAllowedException, QueryMalformedException, DatabaseNotFoundException, DatabaseMalformedException, AccessDeniedException { @@ -253,12 +253,12 @@ public class AccessEndpointUnitTest extends BaseUnitTest { } /* test */ - final ResponseEntity<?> response = accessEndpoint.create(containerId, databaseId, request, principal); + final ResponseEntity<?> response = accessEndpoint.create(databaseId, request, principal); assertEquals(HttpStatus.ACCEPTED, response.getStatusCode()); assertNull(response.getBody()); } - protected void generic_find(Long containerId, Long databaseId, Database database, DatabaseAccess access, + protected void generic_find(Long databaseId, Database database, DatabaseAccess access, String username, UUID userId, Principal principal) throws AccessDeniedException, NotAllowedException { @@ -277,7 +277,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { } /* test */ - final ResponseEntity<DatabaseAccessDto> response = accessEndpoint.find(containerId, databaseId, principal); + final ResponseEntity<DatabaseAccessDto> response = accessEndpoint.find(databaseId, principal); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody()); final DatabaseAccessDto dto = response.getBody(); @@ -286,7 +286,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { assertEquals(accessMapper.accessType(access.getType()), dto.getType()); } - protected void generic_update(Long containerId, Long databaseId, Database database, DatabaseAccess access, + protected void generic_update(Long databaseId, Database database, DatabaseAccess access, String username, Principal principal) throws AccessDeniedException, NotAllowedException, UserNotFoundException, QueryMalformedException, DatabaseNotFoundException, DatabaseMalformedException { final DatabaseModifyAccessDto request = DatabaseModifyAccessDto.builder() @@ -308,12 +308,12 @@ public class AccessEndpointUnitTest extends BaseUnitTest { } /* test */ - final ResponseEntity<?> response = accessEndpoint.update(containerId, databaseId, username, request, principal); + final ResponseEntity<?> response = accessEndpoint.update(databaseId, username, request, principal); assertEquals(HttpStatus.ACCEPTED, response.getStatusCode()); assertNull(response.getBody()); } - protected void generic_revoke(Long containerId, Long databaseId, DatabaseAccess access, String username, + protected void generic_revoke(Long databaseId, DatabaseAccess access, String username, Principal principal) throws AccessDeniedException, NotAllowedException, UserNotFoundException, QueryMalformedException, DatabaseNotFoundException, DatabaseMalformedException { @@ -330,7 +330,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { } /* test */ - final ResponseEntity<?> response = accessEndpoint.revoke(containerId, databaseId, username, principal); + final ResponseEntity<?> response = accessEndpoint.revoke(databaseId, username, principal); assertEquals(HttpStatus.ACCEPTED, response.getStatusCode()); assertNull(response.getBody()); } diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/endpoint/DatabaseEndpointUnitTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/endpoint/DatabaseEndpointUnitTest.java index 513d93fa263f4f2c8485c83b7d51c76bc0ff2044..d7a7685ff6ced7afc63c6cfb066236af0452064f 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/endpoint/DatabaseEndpointUnitTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/endpoint/DatabaseEndpointUnitTest.java @@ -9,13 +9,19 @@ import at.tuwien.entities.container.Container; import at.tuwien.entities.database.Database; import at.tuwien.entities.database.DatabaseAccess; import at.tuwien.exception.*; +import at.tuwien.repository.mdb.DatabaseAccessRepository; +import at.tuwien.repository.mdb.IdentifierRepository; +import at.tuwien.repository.mdb.UserRepository; import at.tuwien.repository.sdb.DatabaseIdxRepository; -import at.tuwien.repository.mdb.*; -import at.tuwien.service.*; +import at.tuwien.service.AccessService; +import at.tuwien.service.ContainerService; +import at.tuwien.service.MessageQueueService; +import at.tuwien.service.QueryStoreService; import at.tuwien.service.impl.MariaDbServiceImpl; import com.rabbitmq.client.Channel; import lombok.extern.log4j.Log4j2; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -82,13 +88,14 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { @WithAnonymousUser public void create_anonymous_fails() { final DatabaseCreateDto request = DatabaseCreateDto.builder() + .cid(CONTAINER_1_ID) .name(DATABASE_1_NAME) .isPublic(DATABASE_1_PUBLIC) .build(); /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - create_generic(CONTAINER_1_ID, CONTAINER_1, DATABASE_1_ID, null, request, null); + create_generic(DATABASE_1_ID, null, request, null); }); } @@ -96,6 +103,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { @WithMockUser(username = USER_4_USERNAME) public void create_noRole_fails() { final DatabaseCreateDto request = DatabaseCreateDto.builder() + .cid(CONTAINER_3_ID) .name(DATABASE_3_NAME) .isPublic(DATABASE_3_PUBLIC) .build(); @@ -106,27 +114,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - create_generic(CONTAINER_3_ID, CONTAINER_3, DATABASE_3_ID, null, request, USER_4_PRINCIPAL); - }); - } - - @Test - @WithMockUser(username = USER_2_USERNAME, authorities = {"create-database"}) - public void create_hasRoleForeign_fails() throws ContainerNotFoundException { - final DatabaseCreateDto request = DatabaseCreateDto.builder() - .name(DATABASE_1_NAME) - .isPublic(DATABASE_1_PUBLIC) - .build(); - - /* mock */ - when(containerService.find(CONTAINER_1_ID)) - .thenReturn(CONTAINER_1); - when(userRepository.findByUsername(USER_2_USERNAME)) - .thenReturn(Optional.of(USER_2)); - - /* test */ - assertThrows(NotAllowedException.class, () -> { - create_generic(CONTAINER_1_ID, CONTAINER_1, DATABASE_1_ID, null, request, USER_2_PRINCIPAL); + create_generic(DATABASE_3_ID, null, request, USER_4_PRINCIPAL); }); } @@ -137,6 +125,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { QueryStoreException, DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException, AmqpException, BrokerVirtualHostCreationException, ContainerNotFoundException { final DatabaseCreateDto request = DatabaseCreateDto.builder() + .cid(CONTAINER_1_ID) .name(DATABASE_1_NAME) .isPublic(DATABASE_1_PUBLIC) .build(); @@ -146,7 +135,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { .thenReturn(Optional.of(USER_1)); when(containerService.find(CONTAINER_1_ID)) .thenReturn(CONTAINER_1); - when(databaseService.create(CONTAINER_1_ID, request, USER_1_PRINCIPAL)) + when(databaseService.create(request, USER_1_PRINCIPAL)) .thenReturn(DATABASE_1); doNothing() .when(messageQueueService) @@ -159,12 +148,12 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { .updatePermissions(USER_1_PRINCIPAL); doNothing() .when(queryStoreService) - .create(CONTAINER_1_ID, DATABASE_1_ID, USER_1_PRINCIPAL); + .create(DATABASE_1_ID, USER_1_PRINCIPAL); when(databaseAccessRepository.save(any(DatabaseAccess.class))) .thenReturn(DATABASE_1_USER_1_WRITE_ALL_ACCESS); /* test */ - create_generic(CONTAINER_1_ID, CONTAINER_1, DATABASE_1_ID, null, request, USER_1_PRINCIPAL); + create_generic(DATABASE_1_ID, null, request, USER_1_PRINCIPAL); } @Test @@ -175,7 +164,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { assertFalse(DATABASE_1_PUBLIC); /* test */ - list_generic(CONTAINER_1_ID, DATABASE_1_ID, CONTAINER_1, List.of(DATABASE_1), null); + list_generic(DATABASE_1_ID, CONTAINER_1, List.of(DATABASE_1), null); } @Test @@ -190,7 +179,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { .thenReturn(Optional.of(USER_1)); /* test */ - list_generic(CONTAINER_3_ID, DATABASE_3_ID, CONTAINER_3, List.of(DATABASE_3), USER_1_PRINCIPAL); + list_generic(DATABASE_3_ID, CONTAINER_3, List.of(DATABASE_3), USER_1_PRINCIPAL); } @Test @@ -205,7 +194,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { .thenReturn(Optional.of(USER_1)); /* test */ - list_generic(CONTAINER_3_ID, DATABASE_3_ID, CONTAINER_3, List.of(DATABASE_3), USER_1_PRINCIPAL); + list_generic(DATABASE_3_ID, CONTAINER_3, List.of(DATABASE_3), USER_1_PRINCIPAL); } @Test @@ -217,7 +206,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - visibility_generic(CONTAINER_1_ID, CONTAINER_1, DATABASE_1_ID, DATABASE_1, DATABASE_1_DTO, request, null); + visibility_generic(DATABASE_1_ID, DATABASE_1, DATABASE_1_DTO, request, null); }); } @@ -233,7 +222,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { .thenReturn(Optional.of(USER_1)); /* test */ - visibility_generic(CONTAINER_1_ID, CONTAINER_1, DATABASE_1_ID, DATABASE_1, DATABASE_1_DTO, request, USER_1_PRINCIPAL); + visibility_generic(DATABASE_1_ID, DATABASE_1, DATABASE_1_DTO, request, USER_1_PRINCIPAL); } @Test @@ -245,7 +234,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - visibility_generic(CONTAINER_1_ID, CONTAINER_1, DATABASE_1_ID, DATABASE_1, DATABASE_1_DTO, request, USER_4_PRINCIPAL); + visibility_generic(DATABASE_1_ID, DATABASE_1, DATABASE_1_DTO, request, USER_4_PRINCIPAL); }); } @@ -262,7 +251,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(NotAllowedException.class, () -> { - visibility_generic(CONTAINER_1_ID, CONTAINER_1, DATABASE_1_ID, DATABASE_1, DATABASE_1_DTO, request, USER_2_PRINCIPAL); + visibility_generic(DATABASE_1_ID, DATABASE_1, DATABASE_1_DTO, request, USER_2_PRINCIPAL); }); } @@ -279,7 +268,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - databaseEndpoint.transfer(CONTAINER_3_ID, DATABASE_3_ID, request, USER_4_PRINCIPAL); + databaseEndpoint.transfer(DATABASE_3_ID, request, USER_4_PRINCIPAL); }); } @@ -293,12 +282,12 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* mock */ when(userRepository.findByUsername(USER_2_USERNAME)) .thenReturn(Optional.of(USER_2)); - when(databaseService.findById(CONTAINER_1_ID, DATABASE_1_ID)) + when(databaseService.findById(DATABASE_1_ID)) .thenReturn(DATABASE_1); /* test */ assertThrows(NotAllowedException.class, () -> { - databaseEndpoint.transfer(CONTAINER_1_ID, DATABASE_1_ID, request, USER_2_PRINCIPAL); + databaseEndpoint.transfer(DATABASE_1_ID, request, USER_2_PRINCIPAL); }); } @@ -314,11 +303,11 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { .thenReturn(Optional.of(USER_1)); when(userRepository.findByUsername(USER_4_USERNAME)) .thenReturn(Optional.of(USER_4)); - when(databaseService.findById(CONTAINER_1_ID, DATABASE_1_ID)) + when(databaseService.findById(DATABASE_1_ID)) .thenReturn(DATABASE_1); /* test */ - databaseEndpoint.transfer(CONTAINER_1_ID, DATABASE_1_ID, request, USER_1_PRINCIPAL); + databaseEndpoint.transfer(DATABASE_1_ID, request, USER_1_PRINCIPAL); } @Test @@ -331,15 +320,15 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* mock */ when(userRepository.findByUsername(USER_1_USERNAME)) .thenReturn(Optional.of(USER_1)); - when(databaseService.findById(CONTAINER_1_ID, DATABASE_1_ID)) + when(databaseService.findById(DATABASE_1_ID)) .thenReturn(DATABASE_1); doThrow(UserNotFoundException.class) .when(databaseService) - .transfer(CONTAINER_1_ID, DATABASE_1_ID, request); + .transfer(DATABASE_1_ID, request); /* test */ assertThrows(UserNotFoundException.class, () -> { - databaseEndpoint.transfer(CONTAINER_1_ID, DATABASE_1_ID, request, USER_1_PRINCIPAL); + databaseEndpoint.transfer(DATABASE_1_ID, request, USER_1_PRINCIPAL); }); } @@ -348,7 +337,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { public void findById_anonymous_succeeds() throws AccessDeniedException, DatabaseNotFoundException, ContainerNotFoundException { /* test */ - findById_generic(CONTAINER_1_ID, CONTAINER_1, DATABASE_1_ID, DATABASE_1, null); + findById_generic(DATABASE_1_ID, DATABASE_1, null); } @Test @@ -357,7 +346,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(DatabaseNotFoundException.class, () -> { - findById_generic(CONTAINER_1_ID, CONTAINER_1, DATABASE_1_ID, null, null); + findById_generic(DATABASE_1_ID, null, null); }); } @@ -369,7 +358,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { assertTrue(DATABASE_3_PUBLIC); /* test */ - findById_generic(CONTAINER_3_ID, CONTAINER_3, DATABASE_3_ID, DATABASE_3, USER_1_PRINCIPAL); + findById_generic(DATABASE_3_ID, DATABASE_3, USER_1_PRINCIPAL); } @Test @@ -381,7 +370,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { assertTrue(DATABASE_3_PUBLIC); /* test */ - findById_generic(CONTAINER_3_ID, CONTAINER_3, DATABASE_3_ID, DATABASE_3, USER_1_PRINCIPAL); + findById_generic(DATABASE_3_ID, DATABASE_3, USER_1_PRINCIPAL); } @Test @@ -394,7 +383,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { .thenReturn(List.of(DATABASE_1_USER_1_WRITE_ALL_ACCESS, DATABASE_1_USER_2_READ_ACCESS)); /* test */ - final DatabaseDto response = findById_generic(CONTAINER_1_ID, CONTAINER_1, DATABASE_1_ID, DATABASE_1, USER_1_PRINCIPAL); + final DatabaseDto response = findById_generic(DATABASE_1_ID, DATABASE_1, USER_1_PRINCIPAL); final List<DatabaseAccessDto> accessList = response.getAccesses(); assertNotNull(accessList); assertEquals(2, accessList.size()); @@ -406,7 +395,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - delete_generic(CONTAINER_1_ID, CONTAINER_1, DATABASE_1_ID, DATABASE_1, null, null); + delete_generic(DATABASE_1_ID, DATABASE_1, null, null); }); } @@ -416,7 +405,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - delete_generic(CONTAINER_1_ID, CONTAINER_1, DATABASE_1_ID, DATABASE_1, USER_1_USERNAME, USER_1_PRINCIPAL); + delete_generic(DATABASE_1_ID, DATABASE_1, USER_1_USERNAME, USER_1_PRINCIPAL); }); } @@ -428,30 +417,30 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { AmqpException, BrokerVirtualHostCreationException, ContainerNotFoundException, DatabaseMalformedException { /* test */ - delete_generic(CONTAINER_2_ID, CONTAINER_2, DATABASE_2_ID, DATABASE_2, USER_2_USERNAME, USER_2_PRINCIPAL); + delete_generic(DATABASE_2_ID, DATABASE_2, USER_2_USERNAME, USER_2_PRINCIPAL); } /* ################################################################################################### */ /* ## GENERIC TEST CASES ## */ /* ################################################################################################### */ - public void list_generic(Long containerId, Long databaseId, Container container, List<Database> databases, Principal principal) { + public void list_generic(Long databaseId, Container container, List<Database> databases, Principal principal) { /* mock */ when(identifierRepository.findByDatabaseId(databaseId)) .thenReturn(List.of()); - when(databaseService.findAll(containerId)) + when(databaseService.findAll()) .thenReturn(databases); /* test */ - final ResponseEntity<List<DatabaseBriefDto>> response = databaseEndpoint.list(containerId, principal); + final ResponseEntity<List<DatabaseDto>> response = databaseEndpoint.list(principal); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody()); - final List<DatabaseBriefDto> body = response.getBody(); + final List<DatabaseDto> body = response.getBody(); assertEquals(databases.size(), body.size()); } - public void create_generic(Long containerId, Container container, Long databaseId, Database database, + public void create_generic(Long databaseId, Database database, DatabaseCreateDto data, Principal principal) throws UserNotFoundException, DatabaseNameExistsException, NotAllowedException, ContainerConnectionException, DatabaseMalformedException, QueryStoreException, DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException, @@ -463,7 +452,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { .createExchange(database, principal); doNothing() .when(queryStoreService) - .create(containerId, databaseId, principal); + .create(databaseId, principal); doNothing() .when(messageQueueService) .updatePermissions(principal); @@ -471,73 +460,73 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { .thenReturn(DATABASE_1_USER_1_WRITE_ALL_ACCESS); /* test */ - final ResponseEntity<DatabaseBriefDto> response = databaseEndpoint.create(containerId, data, principal); + final ResponseEntity<DatabaseBriefDto> response = databaseEndpoint.create(data, principal); assertEquals(HttpStatus.CREATED, response.getStatusCode()); assertNotNull(response.getBody()); } - public void visibility_generic(Long containerId, Container container, Long databaseId, Database database, + public void visibility_generic(Long databaseId, Database database, DatabaseDto dto, DatabaseModifyVisibilityDto data, Principal principal) throws NotAllowedException, DatabaseNotFoundException, UserNotFoundException { /* mock */ if (database != null) { - when(databaseService.findById(containerId, databaseId)) + when(databaseService.findById(databaseId)) .thenReturn(database); - when(databaseService.visibility(containerId, databaseId, data)) + when(databaseService.visibility(databaseId, data)) .thenReturn(database); } else { doThrow(DatabaseNotFoundException.class) .when(databaseService) - .findById(containerId, databaseId); + .findById(databaseId); } when(databaseIdxRepository.save(any(DatabaseDto.class))) .thenReturn(dto); /* test */ - final ResponseEntity<DatabaseDto> response = databaseEndpoint.visibility(containerId, databaseId, data, principal); + final ResponseEntity<DatabaseDto> response = databaseEndpoint.visibility(databaseId, data, principal); assertEquals(HttpStatus.ACCEPTED, response.getStatusCode()); assertNotNull(response.getBody()); } - public DatabaseDto findById_generic(Long containerId, Container container, Long databaseId, Database database, + public DatabaseDto findById_generic(Long databaseId, Database database, Principal principal) throws DatabaseNotFoundException, AccessDeniedException, ContainerNotFoundException { /* mock */ if (database != null) { - when(databaseService.findById(containerId, databaseId)) + when(databaseService.findById(databaseId)) .thenReturn(database); } else { doThrow(DatabaseNotFoundException.class) .when(databaseService) - .findById(containerId, databaseId); + .findById(databaseId); } /* test */ - final ResponseEntity<DatabaseDto> response = databaseEndpoint.findById(containerId, databaseId, principal); + final ResponseEntity<DatabaseDto> response = databaseEndpoint.findById(databaseId, principal); assertEquals(HttpStatus.OK, response.getStatusCode()); final DatabaseDto body = response.getBody(); assertNotNull(body); return body; } - public void delete_generic(Long containerId, Container container, Long databaseId, Database database, + public void delete_generic(Long databaseId, Database database, String username, Principal principal) throws DatabaseNotFoundException, UserNotFoundException, DatabaseConnectionException, QueryMalformedException, ImageNotSupportedException, AmqpException, BrokerVirtualHostCreationException, ContainerNotFoundException, DatabaseMalformedException, BrokerVirtualHostGrantException { /* mock */ if (database != null) { - when(databaseService.findById(containerId, databaseId)) + when(databaseService.findById(databaseId)) .thenReturn(database); } else { doThrow(DatabaseNotFoundException.class) .when(databaseService) - .findById(containerId, databaseId); + .findById(databaseId); } /* test */ - final ResponseEntity<?> response = databaseEndpoint.delete(containerId, databaseId, principal); + final ResponseEntity<?> response = databaseEndpoint.delete(databaseId, principal); assertEquals(HttpStatus.ACCEPTED, response.getStatusCode()); assertNull(response.getBody()); } diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/endpoint/LicenseEndpointUnitTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/endpoint/LicenseEndpointUnitTest.java index 8d295059ec299c3bc8216a795f1a8927ce62fc53..5c9cd792e3f9af32dcc64904d843e8e4d7f7f14a 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/endpoint/LicenseEndpointUnitTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/endpoint/LicenseEndpointUnitTest.java @@ -1,7 +1,7 @@ package at.tuwien.endpoint; import at.tuwien.BaseUnitTest; -import at.tuwien.api.database.*; +import at.tuwien.api.database.LicenseDto; import at.tuwien.config.IndexConfig; import at.tuwien.config.ReadyConfig; import at.tuwien.endpoints.LicenseEndpoint; @@ -20,7 +20,8 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.Mockito.when; @Log4j2 @@ -54,7 +55,7 @@ public class LicenseEndpointUnitTest extends BaseUnitTest { .thenReturn(List.of(LICENSE_1)); /* test */ - final ResponseEntity<List<LicenseDto>> response = licenseEndpoint.list(CONTAINER_1_ID); + final ResponseEntity<List<LicenseDto>> response = licenseEndpoint.list(); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody()); final List<LicenseDto> body = response.getBody(); @@ -72,7 +73,7 @@ public class LicenseEndpointUnitTest extends BaseUnitTest { .thenReturn(List.of()); /* test */ - final ResponseEntity<List<LicenseDto>> response = licenseEndpoint.list(CONTAINER_1_ID); + final ResponseEntity<List<LicenseDto>> response = licenseEndpoint.list(); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody()); final List<LicenseDto> body = response.getBody(); diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayTest.java index db1c4a966ce040c514d82bc11db8a4621c8340c5..c38f91b1d521a1eb0a52f28f7916574bdee7a39d 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayTest.java @@ -6,7 +6,6 @@ import at.tuwien.config.ReadyConfig; import at.tuwien.exception.BrokerVirtualHostCreationException; import at.tuwien.exception.BrokerVirtualHostGrantException; import at.tuwien.repository.sdb.DatabaseIdxRepository; -import at.tuwien.test.BaseTest; import com.rabbitmq.client.Channel; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.Test; @@ -24,7 +23,7 @@ import org.springframework.web.client.RestTemplate; import java.net.URI; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/mapper/DatabaseMapperTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/mapper/DatabaseMapperTest.java index af5a088a39a82748b1d12211ef852e2271ef2a0f..3f50eda70386a28b1a6fb9ae3bc15f526f622216 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/mapper/DatabaseMapperTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/mapper/DatabaseMapperTest.java @@ -6,7 +6,6 @@ import at.tuwien.api.user.UserBriefDto; import at.tuwien.config.IndexConfig; import at.tuwien.config.ReadyConfig; import at.tuwien.repository.sdb.DatabaseIdxRepository; -import at.tuwien.test.BaseTest; import com.rabbitmq.client.Channel; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.Test; diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/AccessServiceIntegrationTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/AccessServiceIntegrationTest.java index 2a5de492d3518b01997b71fceb501d61a287fc62..4e0959880f4c405d1348633810813b4db6ccb0ab 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/AccessServiceIntegrationTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/AccessServiceIntegrationTest.java @@ -4,8 +4,8 @@ import at.tuwien.BaseUnitTest; import at.tuwien.api.database.AccessTypeDto; import at.tuwien.api.database.DatabaseGiveAccessDto; import at.tuwien.api.database.DatabaseModifyAccessDto; -import at.tuwien.config.DockerConfig; import at.tuwien.config.IndexConfig; +import at.tuwien.config.MariaDbConfig; import at.tuwien.config.ReadyConfig; import at.tuwien.entities.database.AccessType; import at.tuwien.entities.database.DatabaseAccess; @@ -14,7 +14,7 @@ import at.tuwien.repository.mdb.*; import at.tuwien.repository.sdb.DatabaseIdxRepository; import com.rabbitmq.client.Channel; import lombok.extern.log4j.Log4j2; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -24,8 +24,11 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.testcontainers.containers.MariaDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; -import java.io.File; +import java.sql.SQLException; import java.util.List; import java.util.UUID; import java.util.stream.Stream; @@ -34,6 +37,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @Log4j2 +@Testcontainers @SpringBootTest @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(SpringExtension.class) @@ -72,24 +76,12 @@ public class AccessServiceIntegrationTest extends BaseUnitTest { @Autowired private RealmRepository realmRepository; - private final static String BIND_WEATHER = new File("../../dbrepo-metadata-db/test/src/test/resources/weather").toPath().toAbsolutePath() + ":/docker-entrypoint-initdb.d"; - - @BeforeAll - public static void beforeAll() { - afterAll(); - DockerConfig.createAllNetworks(); - } - - @AfterAll - public static void afterAll() { - DockerConfig.removeAllContainers(); - DockerConfig.removeAllNetworks(); - } + @Container + @Autowired + private MariaDBContainer<?> mariaDBContainer; @BeforeEach - public void beforeEach() { - afterEach(); - DockerConfig.createAllNetworks(); + public void beforeEach() throws SQLException { /* metadata database */ realmRepository.save(REALM_DBREPO); imageRepository.save(IMAGE_1); @@ -98,12 +90,8 @@ public class AccessServiceIntegrationTest extends BaseUnitTest { userRepository.save(USER_3_SIMPLE); containerRepository.save(CONTAINER_1_SIMPLE); databaseRepository.save(DATABASE_1_SIMPLE); - } - - @AfterEach - public void afterEach() { - DockerConfig.removeAllContainers(); - DockerConfig.removeAllNetworks(); + MariaDbConfig.dropAllDatabases(CONTAINER_1); + MariaDbConfig.createInitDatabase(CONTAINER_1, DATABASE_1); } public static Stream<Arguments> create_succeeds_parameters() { @@ -120,20 +108,20 @@ public class AccessServiceIntegrationTest extends BaseUnitTest { public static Stream<Arguments> update_succeeds_parameters() { return Stream.of( - Arguments.arguments("same access", CONTAINER_1_ID, DATABASE_1_ID, AccessTypeDto.READ, AccessType.READ, + Arguments.arguments("same access", DATABASE_1_ID, AccessTypeDto.READ, AccessType.READ, USER_2_USERNAME, USER_2_ID), - Arguments.arguments("write own access", CONTAINER_1_ID, DATABASE_1_ID, AccessTypeDto.WRITE_OWN, + Arguments.arguments("write own access", DATABASE_1_ID, AccessTypeDto.WRITE_OWN, AccessType.WRITE_OWN, USER_2_USERNAME, USER_2_ID), - Arguments.arguments("write all access", CONTAINER_1_ID, DATABASE_1_ID, AccessTypeDto.WRITE_ALL, + Arguments.arguments("write all access", DATABASE_1_ID, AccessTypeDto.WRITE_ALL, AccessType.WRITE_ALL, USER_2_USERNAME, USER_2_ID) ); } public static Stream<Arguments> update_fails_parameters() { return Stream.of( - Arguments.arguments("user not found", UserNotFoundException.class, CONTAINER_1_ID, DATABASE_1_ID, + Arguments.arguments("user not found", UserNotFoundException.class, DATABASE_1_ID, AccessTypeDto.READ, "l33tsp34k"), - Arguments.arguments("database not found", DatabaseNotFoundException.class, CONTAINER_2_ID, DATABASE_2_ID, + Arguments.arguments("database not found", DatabaseNotFoundException.class, DATABASE_2_ID, AccessTypeDto.READ, USER_2_USERNAME) ); } @@ -169,7 +157,7 @@ public class AccessServiceIntegrationTest extends BaseUnitTest { /* test */ assertThrows(expectedException, () -> { - accessService.create(CONTAINER_1_ID, DATABASE_1_ID, request); + accessService.create(DATABASE_1_ID, request); }); } @@ -184,12 +172,8 @@ public class AccessServiceIntegrationTest extends BaseUnitTest { .username(username) .build(); - /* mock */ - DockerConfig.createContainer(BIND_WEATHER, CONTAINER_1_SIMPLE, CONTAINER_1_ENV); - DockerConfig.startContainer(CONTAINER_1_SIMPLE); - /* test */ - accessService.create(CONTAINER_1_ID, DATABASE_1_ID, request); + accessService.create(DATABASE_1_ID, request); final List<DatabaseAccess> response = databaseAccessRepository.findAll(); assertEquals(1, response.size()); assertEquals(access, response.get(0).getType()); @@ -199,7 +183,7 @@ public class AccessServiceIntegrationTest extends BaseUnitTest { @ParameterizedTest @MethodSource("update_succeeds_parameters") - protected void update_succeeds(String test, Long containerId, Long databaseId, AccessTypeDto accessTypeDto, AccessType access, + protected void update_succeeds(String test, Long databaseId, AccessTypeDto accessTypeDto, AccessType access, String username) throws UserNotFoundException, NotAllowedException, QueryMalformedException, DatabaseNotFoundException, DatabaseMalformedException, AccessDeniedException, InterruptedException { final DatabaseModifyAccessDto request = DatabaseModifyAccessDto.builder() @@ -208,11 +192,9 @@ public class AccessServiceIntegrationTest extends BaseUnitTest { /* mock */ databaseAccessRepository.save(DATABASE_1_USER_2_READ_ACCESS); - DockerConfig.createContainer(BIND_WEATHER, CONTAINER_1_SIMPLE, CONTAINER_1_ENV); - DockerConfig.startContainer(CONTAINER_1_SIMPLE); /* test */ - accessService.update(containerId, databaseId, username, request); + accessService.update(databaseId, username, request); final List<DatabaseAccess> response = databaseAccessRepository.findAll(); assertEquals(1, response.size()); assertEquals(access, response.get(0).getType()); @@ -221,7 +203,7 @@ public class AccessServiceIntegrationTest extends BaseUnitTest { @ParameterizedTest @MethodSource("update_fails_parameters") - protected <T extends Throwable> void update_fails(String name, Class<T> expectedException, Long containerId, + protected <T extends Throwable> void update_fails(String name, Class<T> expectedException, Long databaseId, AccessTypeDto accessTypeDto, String username) { final DatabaseModifyAccessDto request = DatabaseModifyAccessDto.builder() @@ -230,7 +212,7 @@ public class AccessServiceIntegrationTest extends BaseUnitTest { /* test */ assertThrows(expectedException, () -> { - accessService.update(containerId, databaseId, username, request); + accessService.update(databaseId, username, request); }); } @@ -240,7 +222,7 @@ public class AccessServiceIntegrationTest extends BaseUnitTest { /* test */ assertThrows(expectedException, () -> { - accessService.delete(CONTAINER_1_ID, DATABASE_1_ID, username); + accessService.delete(DATABASE_1_ID, username); }); } @@ -250,12 +232,8 @@ public class AccessServiceIntegrationTest extends BaseUnitTest { UserNotFoundException, NotAllowedException, QueryMalformedException, DatabaseNotFoundException, DatabaseMalformedException { - /* mock */ - DockerConfig.createContainer(BIND_WEATHER, CONTAINER_1_SIMPLE, CONTAINER_1_ENV); - DockerConfig.startContainer(CONTAINER_1_SIMPLE); - /* test */ - accessService.delete(CONTAINER_1_ID, DATABASE_1_ID, username); + accessService.delete(DATABASE_1_ID, username); } } diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/AccessServiceUnitTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/AccessServiceUnitTest.java index e7221b3642ae1433ccc698c13e5dc53db9c4628c..53073534439f1440f5d76304ac46b416f7139047 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/AccessServiceUnitTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/AccessServiceUnitTest.java @@ -9,7 +9,9 @@ import at.tuwien.entities.database.AccessType; import at.tuwien.entities.database.DatabaseAccess; import at.tuwien.exception.AccessDeniedException; import at.tuwien.exception.NotAllowedException; -import at.tuwien.repository.mdb.*; +import at.tuwien.repository.mdb.DatabaseAccessRepository; +import at.tuwien.repository.mdb.DatabaseRepository; +import at.tuwien.repository.mdb.UserRepository; import at.tuwien.repository.sdb.DatabaseIdxRepository; import com.rabbitmq.client.Channel; import lombok.extern.log4j.Log4j2; @@ -119,7 +121,7 @@ public class AccessServiceUnitTest extends BaseUnitTest { /* test */ assertThrows(NotAllowedException.class, () -> { - accessService.update(CONTAINER_1_ID, DATABASE_1_ID, USER_1_USERNAME, request); + accessService.update(DATABASE_1_ID, USER_1_USERNAME, request); }); } diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceComponentTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceComponentTest.java index eab873555a3b1413c95fa7aa441405f3a3f81644..72b0b423897401c46dc485fca6275179fb053579 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceComponentTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceComponentTest.java @@ -3,7 +3,9 @@ package at.tuwien.service; import at.tuwien.BaseUnitTest; import at.tuwien.api.database.DatabaseCreateDto; import at.tuwien.api.database.DatabaseDto; -import at.tuwien.config.*; +import at.tuwien.config.IndexConfig; +import at.tuwien.config.MariaDbConfig; +import at.tuwien.config.ReadyConfig; import at.tuwien.entities.database.Database; import at.tuwien.repository.sdb.DatabaseIdxRepository; import at.tuwien.repository.mdb.ContainerRepository; @@ -12,22 +14,26 @@ import at.tuwien.repository.mdb.UserRepository; import at.tuwien.service.impl.MariaDbServiceImpl; import com.rabbitmq.client.Channel; import lombok.extern.log4j.Log4j2; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; 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.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.testcontainers.containers.MariaDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; -import java.io.File; import java.util.Optional; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @Log4j2 +@Testcontainers @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(SpringExtension.class) @SpringBootTest @@ -57,65 +63,44 @@ public class DatabaseServiceComponentTest extends BaseUnitTest { @Autowired private MariaDbServiceImpl databaseService; - private final static String BIND_MUSICOLOGY = new File("../../dbrepo-metadata-db/test/src/test/resources/musicology").toPath().toAbsolutePath() + ":/docker-entrypoint-initdb.d"; - - @BeforeAll - public static void beforeAll() { - afterAll(); - DockerConfig.createAllNetworks(); - } - - @AfterAll - public static void afterAll() { - DockerConfig.removeAllContainers(); - DockerConfig.removeAllNetworks(); - } + @Container + @Autowired + public MariaDBContainer<?> mariaDBContainer; @BeforeEach public void beforeEach() { - afterEach(); - } - - @AfterEach - public void afterEach() { - DockerConfig.removeAllContainers(); + MariaDbConfig.dropAllDatabases(CONTAINER_1); } @Test public void create_elasticSearch_succeeds() throws Exception { /* mock */ - DockerConfig.createContainer(null, CONTAINER_ELASTIC, CONTAINER_ELASTIC_ENV); - DockerConfig.startContainer(CONTAINER_ELASTIC); - DockerConfig.createContainer(BIND_MUSICOLOGY, CONTAINER_3, CONTAINER_3_ENV); - DockerConfig.startContainer(CONTAINER_3); - MariaDbConfig.dropDatabase(CONTAINER_3_INTERNALNAME, DATABASE_3_INTERNALNAME, "root", "mariadb"); when(databaseIdxRepository.save(any(DatabaseDto.class))) .thenReturn(DATABASE_3_DTO); /* test */ - generic_create(CONTAINER_3_ID, DATABASE_3_CREATE, DATABASE_3); + generic_create(DATABASE_3_CREATE, DATABASE_3); } /* ################################################################################################### */ /* ## GENERIC TEST CASES ## */ /* ################################################################################################### */ - protected void generic_create(Long containerId, DatabaseCreateDto createDto, Database database) + protected void generic_create(DatabaseCreateDto createDto, Database database) throws Exception { /* mock */ when(userRepository.findByUsername(USER_1_USERNAME)) .thenReturn(Optional.of(USER_1)); - when(containerRepository.findById(CONTAINER_3_ID)) - .thenReturn(Optional.of(CONTAINER_3)); + when(containerRepository.findById(CONTAINER_1_ID)) + .thenReturn(Optional.of(CONTAINER_1)); when(databaseRepository.save(any(Database.class))) .thenReturn(DATABASE_3); /* test */ - final Database response = databaseService.create(containerId, createDto, USER_1_PRINCIPAL); + final Database response = databaseService.create(createDto, USER_1_PRINCIPAL); assertEquals(database.getName(), response.getName()); - assertEquals(containerId, database.getId()); } } diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java index 5afc03b3bdd9fbad3382ab37d32e62216f8be7f2..061e825d1e183ccb572281abc8146c169c0b25d3 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java @@ -5,26 +5,28 @@ import at.tuwien.api.database.DatabaseCreateDto; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.DatabaseModifyVisibilityDto; import at.tuwien.api.database.DatabaseTransferDto; -import at.tuwien.config.DockerConfig; import at.tuwien.config.IndexConfig; import at.tuwien.config.MariaDbConfig; import at.tuwien.config.ReadyConfig; import at.tuwien.entities.database.Database; import at.tuwien.exception.*; -import at.tuwien.repository.sdb.DatabaseIdxRepository; import at.tuwien.repository.mdb.*; +import at.tuwien.repository.sdb.DatabaseIdxRepository; import at.tuwien.service.impl.MariaDbServiceImpl; import com.rabbitmq.client.Channel; import lombok.extern.log4j.Log4j2; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; 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.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.testcontainers.containers.MariaDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; -import java.io.File; import java.sql.SQLException; import static org.junit.jupiter.api.Assertions.*; @@ -32,6 +34,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @Log4j2 +@Testcontainers @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(SpringExtension.class) @SpringBootTest @@ -70,125 +73,83 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest { @Autowired private MariaDbConfig mariaDbConfig; - private final static String BIND_WEATHER = new File("../../dbrepo-metadata-db/test/src/test/resources/weather").toPath().toAbsolutePath() + ":/docker-entrypoint-initdb.d"; - private final static String BIND_ZOO = new File("../../dbrepo-metadata-db/test/src/test/resources/zoo").toPath().toAbsolutePath() + ":/docker-entrypoint-initdb.d"; - private final static String BIND_MUSICOLOGY = new File("../../dbrepo-metadata-db/test/src/test/resources/musicology").toPath().toAbsolutePath() + ":/docker-entrypoint-initdb.d"; - - @BeforeAll - public static void beforeAll() { - afterAll(); - DockerConfig.createAllNetworks(); - } - - @AfterAll - public static void afterAll() { - DockerConfig.removeAllContainers(); - DockerConfig.removeAllNetworks(); - } + @Container + @Autowired + private MariaDBContainer<?> mariaDBContainer; @BeforeEach - public void beforeEach() { - afterEach(); - DockerConfig.createAllNetworks(); + public void beforeEach() throws SQLException { /* metadata database */ imageRepository.save(IMAGE_1); realmRepository.save(REALM_DBREPO); userRepository.save(USER_1); userRepository.save(USER_2); userRepository.save(USER_3); - } - - @AfterEach - public void afterEach() { - DockerConfig.removeAllContainers(); - DockerConfig.removeAllNetworks(); + containerRepository.save(CONTAINER_1_SIMPLE); + databaseRepository.save(DATABASE_3_SIMPLE); + MariaDbConfig.dropAllDatabases(CONTAINER_1); + MariaDbConfig.createInitDatabase(CONTAINER_1, DATABASE_3); } @Test public void create_succeeds() throws Exception { /* mock */ - DockerConfig.createContainer(BIND_MUSICOLOGY, CONTAINER_3_SIMPLE, CONTAINER_3_ENV); - DockerConfig.startContainer(CONTAINER_3_SIMPLE); - MariaDbConfig.dropDatabase(CONTAINER_3_INTERNALNAME, DATABASE_3_INTERNALNAME, "root", "mariadb"); + MariaDbConfig.dropDatabase(CONTAINER_1, DATABASE_1_INTERNALNAME); when(databaseIdxRepository.save(any(DatabaseDto.class))) - .thenReturn(DATABASE_3_DTO); - containerRepository.save(CONTAINER_1_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_2_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_3_SIMPLE); + .thenReturn(DATABASE_1_DTO); + when(databaseIdxRepository.save(any(DatabaseDto.class))) + .thenReturn(DATABASE_1_DTO); /* test */ - generic_create(CONTAINER_3_ID, DATABASE_3_CREATE, DATABASE_3); + generic_create(DATABASE_1_CREATE, DATABASE_1); } @Test public void create_inSequence_succeeds() throws Exception { /* mock */ - DockerConfig.createContainer(BIND_ZOO, CONTAINER_2_SIMPLE, CONTAINER_2_ENV); - DockerConfig.startContainer(CONTAINER_2_SIMPLE); - MariaDbConfig.dropDatabase(CONTAINER_2_INTERNALNAME, DATABASE_2_INTERNALNAME, "root", "mariadb"); - DockerConfig.createContainer(BIND_MUSICOLOGY, CONTAINER_3_SIMPLE, CONTAINER_3_ENV); - DockerConfig.startContainer(CONTAINER_3_SIMPLE); - MariaDbConfig.dropDatabase(CONTAINER_3_INTERNALNAME, DATABASE_3_INTERNALNAME, "root", "mariadb"); + MariaDbConfig.dropDatabase(CONTAINER_1, DATABASE_2_INTERNALNAME); + MariaDbConfig.dropDatabase(CONTAINER_1, DATABASE_3_INTERNALNAME); + databaseRepository.deleteAll(); when(databaseIdxRepository.save(any(DatabaseDto.class))) .thenReturn(DATABASE_2_DTO) .thenReturn(DATABASE_3_DTO); - containerRepository.save(CONTAINER_1_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_2_SIMPLE); - containerRepository.save(CONTAINER_3_SIMPLE); /* test */ - generic_create(CONTAINER_2_ID, DATABASE_2_CREATE, DATABASE_2); - generic_create(CONTAINER_3_ID, DATABASE_3_CREATE, DATABASE_3); + generic_create(DATABASE_2_CREATE, DATABASE_2); + generic_create(DATABASE_3_CREATE, DATABASE_3); } @Test public void create_outOfSequence_succeeds() throws Exception { /* mock */ - DockerConfig.createContainer(BIND_ZOO, CONTAINER_2_SIMPLE, CONTAINER_2_ENV); - DockerConfig.startContainer(CONTAINER_2_SIMPLE); - MariaDbConfig.dropDatabase(CONTAINER_2_INTERNALNAME, DATABASE_2_INTERNALNAME, "root", "mariadb"); - DockerConfig.createContainer(BIND_MUSICOLOGY, CONTAINER_3_SIMPLE, CONTAINER_3_ENV); - DockerConfig.startContainer(CONTAINER_3_SIMPLE); - MariaDbConfig.dropDatabase(CONTAINER_3_INTERNALNAME, DATABASE_3_INTERNALNAME, "root", "mariadb"); + MariaDbConfig.dropDatabase(CONTAINER_1, DATABASE_2_INTERNALNAME); + MariaDbConfig.dropDatabase(CONTAINER_1, DATABASE_3_INTERNALNAME); + databaseRepository.deleteAll(); when(databaseIdxRepository.save(any(DatabaseDto.class))) .thenReturn(DATABASE_3_DTO) .thenReturn(DATABASE_2_DTO); - containerRepository.save(CONTAINER_1_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_2_SIMPLE); - containerRepository.save(CONTAINER_3_SIMPLE); /* test */ - generic_create(CONTAINER_3_ID, DATABASE_3_CREATE, DATABASE_3); - generic_create(CONTAINER_2_ID, DATABASE_2_CREATE, DATABASE_2); + generic_create(DATABASE_3_CREATE, DATABASE_3); + generic_create(DATABASE_2_CREATE, DATABASE_2); } @Test - public void create_queryStore_succeeds() throws SQLException, InterruptedException, QueryMalformedException { + public void create_queryStore_succeeds() throws Exception { /* mock */ - DockerConfig.createContainer(BIND_MUSICOLOGY, CONTAINER_3_SIMPLE, CONTAINER_3_ENV); - DockerConfig.startContainer(CONTAINER_3_SIMPLE); - containerRepository.save(CONTAINER_1_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_2_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_3_SIMPLE); /* test */ generic_insert(QUERY_4_STATEMENT, 1L); } @Test - public void create_queryStoreSameQueryHash_succeeds() throws SQLException, InterruptedException, - QueryMalformedException { + public void create_queryStoreSameQueryHash_succeeds() throws Exception { /* mock */ - DockerConfig.createContainer(BIND_MUSICOLOGY, CONTAINER_3_SIMPLE, CONTAINER_3_ENV); - DockerConfig.startContainer(CONTAINER_3_SIMPLE); - containerRepository.save(CONTAINER_1_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_2_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_3_SIMPLE); /* test */ generic_insert(QUERY_4_STATEMENT, 1L); @@ -197,28 +158,18 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest { } @Test - public void create_systemProcedure_succeeds() throws SQLException, InterruptedException, QueryMalformedException { + public void create_systemProcedure_succeeds() throws Exception { /* mock */ - DockerConfig.createContainer(BIND_MUSICOLOGY, CONTAINER_3_SIMPLE, CONTAINER_3_ENV); - DockerConfig.startContainer(CONTAINER_3_SIMPLE); - containerRepository.save(CONTAINER_1_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_2_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_3_SIMPLE); /* test */ - generic_system_insert("root", "mariadb"); + generic_system_insert(CONTAINER_1_PRIVILEGED_USERNAME, CONTAINER_1_PRIVILEGED_PASSWORD); } @Test public void create_systemProcedure_fails() throws InterruptedException { /* mock */ - DockerConfig.createContainer(BIND_MUSICOLOGY, CONTAINER_3_SIMPLE, CONTAINER_3_ENV); - DockerConfig.startContainer(CONTAINER_3_SIMPLE); - containerRepository.save(CONTAINER_1_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_2_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_3_SIMPLE); /* test */ assertThrows(SQLException.class, () -> { @@ -230,25 +181,15 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest { public void create_userProcedureRoot_succeeds() throws SQLException, InterruptedException, QueryMalformedException { /* mock */ - DockerConfig.createContainer(BIND_MUSICOLOGY, CONTAINER_3_SIMPLE, CONTAINER_3_ENV); - DockerConfig.startContainer(CONTAINER_3_SIMPLE); - containerRepository.save(CONTAINER_1_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_2_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_3_SIMPLE); /* test */ - generic_user_insert("root", "mariadb"); + generic_user_insert(CONTAINER_1_PRIVILEGED_USERNAME, CONTAINER_1_PRIVILEGED_PASSWORD); } @Test public void create_userProcedureUser_succeeds() throws SQLException, InterruptedException, QueryMalformedException { /* mock */ - DockerConfig.createContainer(BIND_MUSICOLOGY, CONTAINER_3_SIMPLE, CONTAINER_3_ENV); - DockerConfig.startContainer(CONTAINER_3_SIMPLE); - containerRepository.save(CONTAINER_1_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_2_SIMPLE) /* increase id */; - containerRepository.save(CONTAINER_3_SIMPLE); /* test */ generic_user_insert("junit1", "junit1"); @@ -257,16 +198,14 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest { @Test public void delete_succeeds() throws InterruptedException, QueryMalformedException, UserNotFoundException, DatabaseConnectionException, DatabaseNotFoundException, ImageNotSupportedException, - ContainerNotFoundException, DatabaseMalformedException { + ContainerNotFoundException, DatabaseMalformedException, SQLException { /* mock */ - DockerConfig.createContainer(BIND_WEATHER, CONTAINER_1_SIMPLE, CONTAINER_1_ENV); - DockerConfig.startContainer(CONTAINER_1_SIMPLE); - containerRepository.save(CONTAINER_1); databaseRepository.save(DATABASE_1); + MariaDbConfig.createInitDatabase(CONTAINER_1, DATABASE_1); /* test */ - databaseService.delete(CONTAINER_1_ID, DATABASE_1_ID, USER_1_PRINCIPAL); + databaseService.delete(DATABASE_1_ID, USER_1_PRINCIPAL); } @Test @@ -276,26 +215,25 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest { .build(); /* mock */ - containerRepository.save(CONTAINER_1_SIMPLE); databaseRepository.save(DATABASE_1); /* test */ - final Database response = databaseService.visibility(CONTAINER_1_ID, DATABASE_1_ID, request); + final Database response = databaseService.visibility(DATABASE_1_ID, request); assertTrue(response.getIsPublic()); } @Test - public void transfer_succeeds() throws DatabaseNotFoundException, UserNotFoundException { + public void transfer_succeeds() throws DatabaseNotFoundException, UserNotFoundException, SQLException { final DatabaseTransferDto request = DatabaseTransferDto.builder() .username(USER_2_USERNAME) .build(); /* mock */ - containerRepository.save(CONTAINER_1_SIMPLE); + MariaDbConfig.createInitDatabase(CONTAINER_1, DATABASE_1); databaseRepository.save(DATABASE_1); /* test */ - final Database response = databaseService.transfer(CONTAINER_1_ID, DATABASE_1_ID, request); + final Database response = databaseService.transfer(DATABASE_1_ID, request); assertEquals(USER_2_ID, response.getOwnedBy()); } @@ -306,42 +244,39 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest { protected void generic_insert(String query, Long assertQueryId) throws SQLException, QueryMalformedException { /* mock */ - mariaDbConfig.mockGrantUserPermissions(CONTAINER_3_INTERNALNAME, DATABASE_3, USER_1); + mariaDbConfig.mockGrantUserPermissions(CONTAINER_1, DATABASE_3, USER_1); /* test */ - final Long response = MariaDbConfig.mockSystemQueryInsert(CONTAINER_3_INTERNALNAME, DATABASE_3_INTERNALNAME, query); + final Long response = MariaDbConfig.mockSystemQueryInsert(DATABASE_3, query); assertNotNull(response); assertEquals(assertQueryId, response); } - protected void generic_create(Long containerId, DatabaseCreateDto createDto, Database database) + protected void generic_create(DatabaseCreateDto createDto, Database database) throws Exception { /* test */ - final Database response = databaseService.create(containerId, createDto, USER_1_PRINCIPAL); + final Database response = databaseService.create(createDto, USER_1_PRINCIPAL); assertEquals(database.getName(), response.getName()); - assertEquals(containerId, database.getId()); } protected void generic_system_insert(String username, String password) throws SQLException, QueryMalformedException { /* mock */ - mariaDbConfig.mockGrantUserPermissions(CONTAINER_3_INTERNALNAME, DATABASE_3, USER_1); + mariaDbConfig.mockGrantUserPermissions(CONTAINER_1, DATABASE_3, USER_1); /* test */ - final Long queryId = MariaDbConfig.mockSystemQueryInsert(CONTAINER_3_INTERNALNAME, DATABASE_3_INTERNALNAME, - QUERY_4_STATEMENT, username, password); + final Long queryId = MariaDbConfig.mockSystemQueryInsert(DATABASE_3, QUERY_4_STATEMENT, username, password); assertEquals(1L, queryId); } protected void generic_user_insert(String username, String password) throws SQLException, QueryMalformedException { /* mock */ - mariaDbConfig.mockGrantUserPermissions(CONTAINER_3_INTERNALNAME, DATABASE_3, USER_1); + mariaDbConfig.mockGrantUserPermissions(CONTAINER_1, DATABASE_3, USER_1); /* test */ - final Long queryId = MariaDbConfig.mockUserQueryInsert(CONTAINER_3_INTERNALNAME, DATABASE_3_INTERNALNAME, - QUERY_4_STATEMENT, username, password); + final Long queryId = MariaDbConfig.mockUserQueryInsert(DATABASE_3, QUERY_4_STATEMENT, username, password); assertEquals(1L, queryId); } diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java index afd7ddcaf6ab04ce909121ba2b0486ac540d2dab..96581a5a561dd6d4f3326bb2cd258717880f1fe9 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java @@ -7,7 +7,10 @@ import at.tuwien.config.ReadyConfig; import at.tuwien.entities.container.Container; import at.tuwien.entities.container.image.ContainerImage; import at.tuwien.entities.database.Database; -import at.tuwien.exception.*; +import at.tuwien.exception.ContainerNotFoundException; +import at.tuwien.exception.DatabaseNotFoundException; +import at.tuwien.exception.ImageNotSupportedException; +import at.tuwien.exception.UserNotFoundException; import at.tuwien.repository.mdb.ContainerRepository; import at.tuwien.repository.mdb.DatabaseRepository; import at.tuwien.repository.sdb.DatabaseIdxRepository; @@ -25,8 +28,10 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import java.util.List; import java.util.Optional; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; @Log4j2 @SpringBootTest @@ -51,6 +56,9 @@ public class DatabaseServiceUnitTest extends BaseUnitTest { @Autowired private MariaDbServiceImpl databaseService; + @MockBean + private UserService userService; + @MockBean private DatabaseRepository databaseRepository; @@ -60,11 +68,11 @@ public class DatabaseServiceUnitTest extends BaseUnitTest { @Test public void findAll_succeeds() { /* mock */ - when(databaseRepository.findAll(CONTAINER_1_ID)) + when(databaseRepository.findAll()) .thenReturn(List.of(DATABASE_1)); /* test */ - final List<Database> response = databaseService.findAll(CONTAINER_1_ID); + final List<Database> response = databaseService.findAll(); assertEquals(1, response.size()); assertEquals(DATABASE_1, response.get(0)); } @@ -76,7 +84,7 @@ public class DatabaseServiceUnitTest extends BaseUnitTest { when(databaseRepository.findById(DATABASE_1_ID)) .thenReturn(Optional.of(DATABASE_1)); - final Database response = databaseService.findById(CONTAINER_1_ID, DATABASE_1_ID); + final Database response = databaseService.findById(DATABASE_1_ID); /* test */ assertEquals(DATABASE_1, response); @@ -91,7 +99,7 @@ public class DatabaseServiceUnitTest extends BaseUnitTest { /* test */ assertThrows(DatabaseNotFoundException.class, () -> { - databaseService.findById(CONTAINER_1_ID, DATABASE_1_ID); + databaseService.findById(DATABASE_1_ID); }); } @@ -106,30 +114,33 @@ public class DatabaseServiceUnitTest extends BaseUnitTest { /* test */ assertThrows(DatabaseNotFoundException.class, () -> { - databaseService.delete(CONTAINER_1_ID, DATABASE_1_ID, USER_1_PRINCIPAL); + databaseService.delete(DATABASE_1_ID, USER_1_PRINCIPAL); }); } @Test - public void create_notFound_fails() { + public void create_notFound_fails() throws UserNotFoundException { final DatabaseCreateDto request = DatabaseCreateDto.builder() + .cid(CONTAINER_1_ID) .name(DATABASE_1_NAME) .build(); /* mock */ + when(userService.findByUsername(USER_1_USERNAME)) + .thenReturn(USER_1); when(containerRepository.findById(CONTAINER_1_ID)) .thenReturn(Optional.empty()); /* test */ assertThrows(ContainerNotFoundException.class, () -> { - databaseService.create(CONTAINER_1_ID, request, USER_1_PRINCIPAL); + databaseService.create(request, USER_1_PRINCIPAL); }); } @Test public void delete_image_fails() { final ContainerImage image = ContainerImage.builder() - .repository("mysql") + .name("mysql") .build(); final Container container = Container.builder() .image(image) @@ -141,12 +152,12 @@ public class DatabaseServiceUnitTest extends BaseUnitTest { /* mock */ when(containerRepository.findById(CONTAINER_1_ID)) .thenReturn(Optional.of(CONTAINER_1)); - when(databaseRepository.findPublicOrMine(CONTAINER_1_ID, DATABASE_1_ID, USER_1_USERNAME)) + when(databaseRepository.findPublicOrMine(DATABASE_1_ID, USER_1_USERNAME)) .thenReturn(Optional.of(database)); /* test */ assertThrows(ImageNotSupportedException.class, () -> { - databaseService.delete(CONTAINER_1_ID, DATABASE_1_ID, USER_1_PRINCIPAL); + databaseService.delete(DATABASE_1_ID, USER_1_PRINCIPAL); }); } diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/IdentifierServiceIntegrationTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/IdentifierServiceIntegrationTest.java index b39fa1b5074899bf82a26e4fd8a659a39cfe573f..360900ecff68d5a85e2fac802d1111390e15a528 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/IdentifierServiceIntegrationTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/IdentifierServiceIntegrationTest.java @@ -19,7 +19,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; @Log4j2 @SpringBootTest diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/LicenseServiceIntegrationTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/LicenseServiceIntegrationTest.java index 3cf9f68def035e2218d96bbc8ae6ad39c9cd5137..7e7c680ee1def2b8d766e124f92cdacff72d2e28 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/LicenseServiceIntegrationTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/LicenseServiceIntegrationTest.java @@ -5,7 +5,7 @@ import at.tuwien.config.IndexConfig; import at.tuwien.config.ReadyConfig; import at.tuwien.entities.database.License; import at.tuwien.exception.LicenseNotFoundException; -import at.tuwien.repository.mdb.*; +import at.tuwien.repository.mdb.LicenseRepository; import at.tuwien.repository.sdb.DatabaseIdxRepository; import com.rabbitmq.client.Channel; import lombok.extern.log4j.Log4j2; @@ -16,6 +16,9 @@ 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.test.context.junit.jupiter.SpringExtension; +import org.testcontainers.containers.MariaDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; @@ -23,6 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @Log4j2 +@Testcontainers @SpringBootTest @ExtendWith(SpringExtension.class) public class LicenseServiceIntegrationTest extends BaseUnitTest { @@ -45,6 +49,10 @@ public class LicenseServiceIntegrationTest extends BaseUnitTest { @Autowired private LicenseService licenseService; + @Container + @Autowired + public MariaDBContainer<?> mariaDBContainer; + @BeforeEach public void beforeEach() { licenseRepository.save(LICENSE_1); diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java index 800da8a157faa805f81d1b7b2bf70e537974048a..cc6d8c65fa669e9e858ccf79ba777386d4af6a99 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java @@ -1,7 +1,6 @@ package at.tuwien.service; import at.tuwien.BaseUnitTest; -import at.tuwien.config.DockerConfig; import at.tuwien.config.IndexConfig; import at.tuwien.config.ReadyConfig; import at.tuwien.exception.AmqpException; @@ -14,23 +13,30 @@ import at.tuwien.service.impl.RabbitMqServiceImpl; import at.tuwien.utils.AmqpUtils; import com.rabbitmq.client.Channel; import lombok.extern.log4j.Log4j2; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; 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.test.annotation.DirtiesContext; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.testcontainers.containers.RabbitMQContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; @Log4j2 +@Testcontainers @SpringBootTest @ExtendWith(SpringExtension.class) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class MessageQueueServiceIntegrationTest extends BaseUnitTest { @MockBean @@ -57,19 +63,17 @@ public class MessageQueueServiceIntegrationTest extends BaseUnitTest { @Autowired private AmqpUtils amqpUtils; - @BeforeAll - public static void beforeAll() throws InterruptedException { - afterAll(); - DockerConfig.createAllNetworks(); - /* create amqp */ - DockerConfig.createContainer(null, CONTAINER_BROKER, CONTAINER_BROKER_ENV); - DockerConfig.startContainer(CONTAINER_BROKER); - } - - @AfterAll - public static void afterAll() { - DockerConfig.removeAllContainers(); - DockerConfig.removeAllNetworks(); + @Container + private static final RabbitMQContainer rabbitMQContainer = new RabbitMQContainer("rabbitmq:3-management-alpine") + .withVhost("/"); + + @DynamicPropertySource + static void rabbitMQProperties(DynamicPropertyRegistry registry) { + registry.add("fda.gateway.endpoint", () -> "http://" + rabbitMQContainer.getHost() + ":" + rabbitMQContainer.getHttpPort()); + registry.add("spring.rabbitmq.host", rabbitMQContainer::getHost); + registry.add("spring.rabbitmq.port", rabbitMQContainer::getAmqpPort); + registry.add("spring.rabbitmq.username", rabbitMQContainer::getAdminUsername); + registry.add("spring.rabbitmq.password", rabbitMQContainer::getAdminPassword); } @Test diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceUnitTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceUnitTest.java index eeaaf10655ce2f48c8c857086137773b4de4fabd..9e64183e46818a03f87c3efc1fb740c9f795684f 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceUnitTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceUnitTest.java @@ -20,7 +20,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.doThrow; @Log4j2 diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/QueryStoreServiceIntegrationTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/QueryStoreServiceIntegrationTest.java index 726405881c79d5b8876ad85c4d272d2e1b759f84..5c04c74fca704a8cf84eb7e0e366730026227bf0 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/QueryStoreServiceIntegrationTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/QueryStoreServiceIntegrationTest.java @@ -1,12 +1,10 @@ package at.tuwien.service; import at.tuwien.BaseUnitTest; -import at.tuwien.config.DockerConfig; import at.tuwien.config.IndexConfig; +import at.tuwien.config.MariaDbConfig; import at.tuwien.config.ReadyConfig; -import at.tuwien.entities.user.User; import at.tuwien.exception.*; -import at.tuwien.mapper.DatabaseMapper; import at.tuwien.repository.mdb.*; import at.tuwien.repository.sdb.DatabaseIdxRepository; import at.tuwien.service.impl.HibernateConnector; @@ -14,19 +12,23 @@ import at.tuwien.service.impl.QueryStoreServiceImpl; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.rabbitmq.client.Channel; import lombok.extern.log4j.Log4j2; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; 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.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.testcontainers.containers.MariaDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; -import java.io.File; import java.sql.Connection; import java.sql.SQLException; @Log4j2 +@Testcontainers @SpringBootTest @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(SpringExtension.class) @@ -62,50 +64,38 @@ public class QueryStoreServiceIntegrationTest extends BaseUnitTest { @Autowired private QueryStoreServiceImpl queryStoreService; + @Container @Autowired - private DatabaseMapper databaseMapper; - - private final static String BIND_WEATHER = new File("../../dbrepo-metadata-db/test/src/test/resources/weather").toPath().toAbsolutePath() + ":/docker-entrypoint-initdb.d"; + private MariaDBContainer<?> mariaDBContainer; @BeforeEach - public void beforeEach() { - afterEach(); - /* create network */ - DockerConfig.createAllNetworks(); + public void beforeEach() throws SQLException { /* metadata database */ realmRepository.save(REALM_DBREPO); userRepository.save(USER_1); imageRepository.save(IMAGE_1); containerRepository.save(CONTAINER_1_SIMPLE); databaseRepository.save(DATABASE_1_SIMPLE); - } - - @AfterEach - public void afterEach() { - DockerConfig.removeAllContainers(); - DockerConfig.removeAllNetworks(); + MariaDbConfig.dropAllDatabases(CONTAINER_1); } @Test public void create_succeeds() throws UserNotFoundException, QueryStoreException, DatabaseConnectionException, - DatabaseNotFoundException, DatabaseMalformedException, InterruptedException { + DatabaseNotFoundException, DatabaseMalformedException, SQLException { - /* mock */ - DockerConfig.createContainer(null, CONTAINER_1, CONTAINER_1_ENV); - DockerConfig.startContainer(CONTAINER_1); + /* setup */ + MariaDbConfig.createDatabase(CONTAINER_1, DATABASE_1_INTERNALNAME); /* test */ - queryStoreService.create(CONTAINER_1_ID, DATABASE_1_ID, USER_1_PRINCIPAL); + queryStoreService.create(DATABASE_1_ID, USER_1_PRINCIPAL); } @Test - public void executeQuery_succeeds() throws SQLException, InterruptedException { - final User root = databaseMapper.containerToPrivilegedUser(CONTAINER_1); - final ComboPooledDataSource dataSource = HibernateConnector.getDataSource(CONTAINER_1_IMAGE, CONTAINER_1, DATABASE_1, root); + public void executeQuery_succeeds() throws SQLException { + final ComboPooledDataSource dataSource = HibernateConnector.getPrivilegedDataSource(CONTAINER_1_IMAGE, CONTAINER_1, DATABASE_1); - /* mock */ - DockerConfig.createContainer(BIND_WEATHER, CONTAINER_1, CONTAINER_1_ENV); - DockerConfig.startContainer(CONTAINER_1); + /* setup */ + MariaDbConfig.createInitDatabase(CONTAINER_1, DATABASE_1); /* test */ try { diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/utils/FileUtilTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/utils/FileUtilTest.java index 026b0f429825689995129930aced2044d94d107c..9679a5ce5cec670a41ee3619c45d1156733e9404 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/utils/FileUtilTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/utils/FileUtilTest.java @@ -4,7 +4,6 @@ import at.tuwien.BaseUnitTest; import at.tuwien.config.IndexConfig; import at.tuwien.config.ReadyConfig; import at.tuwien.repository.sdb.DatabaseIdxRepository; -import at.tuwien.test.BaseTest; import com.rabbitmq.client.Channel; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.Disabled; diff --git a/dbrepo-database-service/rest-service/src/test/resources/application.properties b/dbrepo-database-service/rest-service/src/test/resources/application.properties index 2387763b3a8016a0151a2b563694b1608c50b8b8..e7b9d109d089456f88c6b54b64a7980a41ac2d8d 100644 --- a/dbrepo-database-service/rest-service/src/test/resources/application.properties +++ b/dbrepo-database-service/rest-service/src/test/resources/application.properties @@ -9,22 +9,22 @@ spring.cloud.config.discovery.enabled=false spring.cloud.config.enabled=false # disable datasource -# spring 6 fix https://github.com/h2database/h2database/issues/3363 -spring.datasource.url=jdbc:h2:mem:testdb;NON_KEYWORDS=VALUE,KEY;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS FDA -spring.datasource.driverClassName=org.h2.Driver -spring.datasource.username=sa -spring.datasource.password=password -spring.jpa.database-platform=org.hibernate.dialect.H2Dialect -spring.jpa.hibernate.ddl-auto=create-drop -spring.jpa.show-sql=false +spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver +spring.datasource.url=jdbc:hsqldb:mem:testdb;db_close_delay=-1;sql.syntax_mys=true +spring.jpa.database-platform=org.hibernate.dialect.HSQLDialect +spring.datasource.username=root +spring.datasource.password=dbrepo +spring.sql.init.mode=always +spring.sql.init.schema-locations=classpath*:init/schema.sql +spring.jpa.hibernate.ddl-auto=create # logging logging.level.root=error logging.level.at.tuwien.=trace # rabbitmq -fda.gateway.endpoint=http://dbrepo-broker-service:15672 -spring.rabbitmq.host=dbrepo-broker-service +fda.gateway.endpoint=http://localhost:15672 +spring.rabbitmq.host=localhost spring.rabbitmq.virtual-host=/ spring.rabbitmq.username=guest spring.rabbitmq.password=guest diff --git a/dbrepo-database-service/rest-service/src/test/resources/init/musicology.sql b/dbrepo-database-service/rest-service/src/test/resources/init/musicology.sql new file mode 100644 index 0000000000000000000000000000000000000000..4d2c8deb43ede5de84cd321a302e97ef84038508 --- /dev/null +++ b/dbrepo-database-service/rest-service/src/test/resources/init/musicology.sql @@ -0,0 +1,18 @@ +CREATE DATABASE musicology; +USE musicology; + +CREATE SEQUENCE seq_mfcc; + +CREATE TABLE mfcc +( + id BIGINT PRIMARY KEY NOT NULL DEFAULT nextval(`seq_mfcc`), + value DECIMAL NOT NULL +) WITH SYSTEM VERSIONING; + +INSERT INTO `mfcc` (`value`) +VALUES (11.2), + (11.3), + (11.4), + (11.9), + (12.3), + (23.1); \ No newline at end of file diff --git a/dbrepo-database-service/rest-service/src/test/resources/init/schema.sql b/dbrepo-database-service/rest-service/src/test/resources/init/schema.sql new file mode 100644 index 0000000000000000000000000000000000000000..f8482e47d5b0827e87537d940b54900a8f2d8f3b --- /dev/null +++ b/dbrepo-database-service/rest-service/src/test/resources/init/schema.sql @@ -0,0 +1 @@ +CREATE SCHEMA IF NOT EXISTS fda; \ No newline at end of file diff --git a/dbrepo-database-service/rest-service/src/test/resources/init/users.sql b/dbrepo-database-service/rest-service/src/test/resources/init/users.sql new file mode 100644 index 0000000000000000000000000000000000000000..45f7b53a0f602a780522da646d64da2a0bc36e53 --- /dev/null +++ b/dbrepo-database-service/rest-service/src/test/resources/init/users.sql @@ -0,0 +1,4 @@ +CREATE USER junit1 IDENTIFIED BY 'junit1'; +CREATE USER junit2 IDENTIFIED BY 'junit2'; +CREATE USER junit3 IDENTIFIED BY 'junit3'; +CREATE USER junit4 IDENTIFIED BY 'junit4'; \ No newline at end of file diff --git a/dbrepo-database-service/rest-service/src/test/resources/init/weather.sql b/dbrepo-database-service/rest-service/src/test/resources/init/weather.sql new file mode 100644 index 0000000000000000000000000000000000000000..05976e23e48dd83f763a0acbf841223e7e879d43 --- /dev/null +++ b/dbrepo-database-service/rest-service/src/test/resources/init/weather.sql @@ -0,0 +1,65 @@ +/* https://www.kaggle.com/jsphyg/weather-dataset-rattle-package */ +CREATE DATABASE weather; +USE weather; + +CREATE TABLE weather_location +( + location VARCHAR(255) PRIMARY KEY, + lat DOUBLE PRECISION NULL, + lng DOUBLE PRECISION NULL +) WITH SYSTEM VERSIONING; + +CREATE TABLE weather_aus +( + id BIGINT NOT NULL PRIMARY KEY, + `date` DATE NOT NULL, + location VARCHAR(255) NULL, + mintemp DOUBLE PRECISION NULL, + rainfall DOUBLE PRECISION NULL, + FOREIGN KEY (location) REFERENCES weather_location (location), + UNIQUE (`date`), + CHECK (`mintemp` > 0) +) WITH SYSTEM VERSIONING; + +CREATE TABLE sensor +( + `timestamp` TIMESTAMP NOT NULL PRIMARY KEY, + `value` DECIMAL +) WITH SYSTEM VERSIONING; + +INSERT INTO weather_location (location, lat, lng) +VALUES ('Albury', -36.0653583, 146.9112214), + ('Sydney', -33.847927, 150.6517942), + ('Vienna', null, null); + +INSERT INTO weather_aus (id, `date`, location, mintemp, rainfall) +VALUES (1, '2008-12-01', 'Albury', 13.4, 0.6), + (2, '2008-12-02', 'Albury', 7.4, 0), + (3, '2008-12-03', 'Albury', 12.9, 0); + +INSERT INTO sensor (`timestamp`, value) +VALUES ('2022-12-24 17:00:00', 10.0), + ('2022-12-24 18:00:00', 10.2), + ('2022-12-24 19:00:00', null), + ('2022-12-24 20:00:00', 10.3), + ('2022-12-24 21:00:00', 10.0), + ('2022-12-24 22:00:00', null); + +######################################################################################################################## +## TEST CASE PRE-REQUISITE ## +######################################################################################################################## + +CREATE VIEW junit2 AS +( +select `date`, `location`, `mintemp`, `rainfall` +from `weather_aus` +where `location` = 'Albury'); + +CREATE VIEW `hs_weather_aus` AS +SELECT * +FROM (SELECT `id`, ROW_START AS inserted_at, IF(ROW_END > NOW(), NULL, ROW_END) AS deleted_at, COUNT(*) as total + FROM `weather_aus` FOR SYSTEM_TIME ALL + GROUP BY inserted_at, deleted_at + ORDER BY deleted_at DESC + LIMIT 50) AS v +ORDER BY v.inserted_at, v.deleted_at ASC; diff --git a/dbrepo-database-service/rest-service/src/test/resources/init/zoo.sql b/dbrepo-database-service/rest-service/src/test/resources/init/zoo.sql new file mode 100644 index 0000000000000000000000000000000000000000..238978ac00ac8d9bc710348790a4a7d00155de60 --- /dev/null +++ b/dbrepo-database-service/rest-service/src/test/resources/init/zoo.sql @@ -0,0 +1,194 @@ +CREATE DATABASE zoo; +USE zoo; + +create sequence seq_zoo_id; +create sequence seq_names_id; +create table zoo +( + id bigint not null default nextval(`seq_zoo_id`), + animal_name varchar(255) null, + hair tinyint(1) null, + feathers tinyint(1) null, + eggs tinyint(1) null, + milk tinyint(1) null, + airborne tinyint(1) null, + aquatic tinyint(1) null, + predator tinyint(1) null, + toothed tinyint(1) null, + backbone tinyint(1) null, + breathes tinyint(1) null, + venomous tinyint(1) null, + fins tinyint(1) null, + legs bigint null, + tail tinyint(1) null, + domestic tinyint(1) null, + catsize tinyint(1) null, + class_type bigint null, + primary key (id) +) with system versioning; + +create table names +( + id bigint not null default nextval(`seq_names_id`), + firstname varchar(255), + lastname varchar(255), + primary key (id), + unique key (firstname, lastname) +) with system versioning; + +create table likes +( + name_id bigint not null, + zoo_id bigint not null, + primary key (name_id, zoo_id), + foreign key (name_id) references names (id), + foreign key (zoo_id) references zoo (id) +) with system versioning; + +INSERT INTO zoo (id, animal_name, hair, feathers, eggs, milk, airborne, aquatic, predator, toothed, backbone, breathes, + venomous, fins, legs, tail, domestic, catsize, class_type) +VALUES (1, 'aardvark', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 0, 0, 1, 1), + (2, 'antelope', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (3, 'bass', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (4, 'bear', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 0, 0, 1, 1), + (5, 'boar', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (6, 'buffalo', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (7, 'calf', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 1, 1, 1), + (8, 'carp', 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 4), + (9, 'catfish', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (10, 'cavy', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 0, 1, 0, 1), + (11, 'cheetah', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (12, 'chicken', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 1, 0, 2), + (13, 'chub', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (14, 'clam', 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7), + (15, 'crab', 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 7), + (16, 'crayfish', 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7), + (17, 'crow', 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (18, 'deer', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (19, 'dogfish', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 4), + (20, 'dolphin', 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1), + (21, 'dove', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 1, 0, 2), + (22, 'duck', 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (23, 'elephant', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (24, 'flamingo', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2), + (25, 'flea', 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 6, 0, 0, 0, 6), + (26, 'frog', 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 4, 0, 0, 0, 5), + (27, 'frog', 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 4, 0, 0, 0, 5), + (28, 'fruitbat', 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 2, 1, 0, 0, 1), + (29, 'giraffe', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (30, 'girl', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 2, 0, 1, 1, 1), + (31, 'gnat', 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 6, 0, 0, 0, 6), + (32, 'goat', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 1, 1, 1), + (33, 'gorilla', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 2, 0, 0, 1, 1), + (34, 'gull', 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (35, 'haddock', 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (36, 'hamster', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 1, 0, 1), + (37, 'hare', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 0, 1), + (38, 'hawk', 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (39, 'herring', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (40, 'honeybee', 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 6, 0, 1, 0, 6), + (41, 'housefly', 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 6, 0, 0, 0, 6), + (42, 'kiwi', 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (43, 'ladybird', 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 6, 0, 0, 0, 6), + (44, 'lark', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (45, 'leopard', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (46, 'lion', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (47, 'lobster', 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7), + (48, 'lynx', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (49, 'mink', 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (50, 'mole', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 0, 1), + (51, 'mongoose', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (52, 'moth', 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 6, 0, 0, 0, 6), + (53, 'newt', 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 4, 1, 0, 0, 5), + (54, 'octopus', 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 8, 0, 0, 1, 7), + (55, 'opossum', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 0, 1), + (56, 'oryx', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (57, 'ostrich', 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2), + (58, 'parakeet', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 1, 0, 2), + (59, 'penguin', 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2), + (60, 'pheasant', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (61, 'pike', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 4), + (62, 'piranha', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (63, 'pitviper', 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 3), + (64, 'platypus', 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (65, 'polecat', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (66, 'pony', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 1, 1, 1), + (67, 'porpoise', 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1), + (68, 'puma', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (69, 'pussycat', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 1, 1, 1), + (70, 'raccoon', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (71, 'reindeer', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 1, 1, 1), + (72, 'rhea', 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2), + (73, 'scorpion', 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 8, 1, 0, 0, 7), + (74, 'seahorse', 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (75, 'seal', 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1), + (76, 'sealion', 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 2, 1, 0, 1, 1), + (77, 'seasnake', 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 3), + (78, 'seawasp', 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 7), + (79, 'skimmer', 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (80, 'skua', 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (81, 'slowworm', 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 3), + (82, 'slug', 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 7), + (83, 'sole', 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (84, 'sparrow', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (85, 'squirrel', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 2, 1, 0, 0, 1), + (86, 'starfish', 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 7), + (87, 'stingray', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 4), + (88, 'swan', 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2), + (89, 'termite', 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 6, 0, 0, 0, 6), + (90, 'toad', 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 4, 0, 0, 0, 5), + (91, 'tortoise', 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 4, 1, 0, 1, 3), + (92, 'tuatara', 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 0, 3), + (93, 'tuna', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 4), + (94, 'vampire', 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 2, 1, 0, 0, 1), + (95, 'vole', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 0, 1), + (96, 'vulture', 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2), + (97, 'wallaby', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 2, 1, 0, 1, 1), + (98, 'wasp', 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 6, 0, 0, 0, 6), + (99, 'wolf', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (100, 'worm', 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 7), + (101, 'wren', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2); + +INSERT INTO names (firstname, lastname) +VALUES ('Moritz', 'Staudinger'), + ('Martin', 'Weise'), + ('Eva', 'Gergely'), + ('Cornelia', 'Michlits'), + ('Kirill', 'Stytsenko'); + +INSERT INTO likes (name_id, zoo_id) +VALUES (1, 5), + (1, 10), + (2, 3), + (2, 80), + (3, 4), + (4, 4), + (5, 100); + +######################################################################################################################## +## TEST CASE PRE-REQUISITE ## +######################################################################################################################## + +CREATE VIEW mock_view AS +( +SELECT `id`, + `animal_name`, + `hair`, + `feathers`, + `eggs`, + `milk`, + `airborne`, + `aquatic`, + `predator`, + `toothed`, + `backbone`, + `breathes`, + `venomous`, + `fins`, + `legs`, + `tail`, + `domestic`, + `catsize`, + `class_type` +FROM `zoo` +WHERE `class_type` = 1); diff --git a/dbrepo-database-service/rest-service/src/test/resources/weather/1_querystore.sql b/dbrepo-database-service/rest-service/src/test/resources/weather/1_querystore.sql deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/dbrepo-database-service/rest-service/src/test/resources/weather/2_weather.sql b/dbrepo-database-service/rest-service/src/test/resources/weather/2_weather.sql deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/dbrepo-database-service/rest-service/src/test/resources/weather/3_users.sql b/dbrepo-database-service/rest-service/src/test/resources/weather/3_users.sql deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/config/AmqpConfig.java b/dbrepo-database-service/services/src/main/java/at/tuwien/config/AmqpConfig.java index 1c493eb9ddc3a2d5e40ab5e44d5857ead3305ee5..4abaf6c398e94a2e272332ed2ed32f7802f3b35c 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/config/AmqpConfig.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/config/AmqpConfig.java @@ -18,6 +18,9 @@ public class AmqpConfig { @Value("${spring.rabbitmq.host}") private String ampqHost; + @Value("${spring.rabbitmq.port:5672}") + private int ampqPort; + @Value("${spring.rabbitmq.virtual-host}") private String virtualHost; @@ -31,6 +34,7 @@ public class AmqpConfig { public Channel getChannel() throws IOException, TimeoutException { final ConnectionFactory factory = new ConnectionFactory(); factory.setHost(ampqHost); + factory.setPort(ampqPort); factory.setVirtualHost(virtualHost); factory.setUsername(ampqUsername); factory.setPassword(ampqPassword); diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java b/dbrepo-database-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java index e0ff9189e5c4ab5009f4b4a65a80e33f1104bea0..70887d0e33bfd4919aa42b35b5e48aac0f7b2579 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java @@ -3,9 +3,9 @@ package at.tuwien.config; import at.tuwien.auth.AuthTokenFilter; import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; import io.swagger.v3.oas.annotations.security.SecurityScheme; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -18,8 +18,6 @@ import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; -import jakarta.servlet.http.HttpServletResponse; - @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) @@ -46,7 +44,7 @@ public class WebSecurityConfig { new AntPathRequestMatcher("/swagger-ui.html") ); final OrRequestMatcher publicEndpoints = new OrRequestMatcher( - new AntPathRequestMatcher("/api/container/**/database/**", "GET") + new AntPathRequestMatcher("/api/database/**", "GET") ); /* enable CORS and disable CSRF */ http = http.cors().and().csrf().disable(); diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/ContainerMapper.java b/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/ContainerMapper.java index 3056c030b40b625628bedadff001818f26e8540e..4c74ed486cefadb499d458aa305f25262193a0ca 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/ContainerMapper.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/ContainerMapper.java @@ -11,7 +11,6 @@ public interface ContainerMapper { @Mappings({ @Mapping(target = "id", source = "id"), - @Mapping(target = "database", source = "database", ignore = true), }) ContainerDto containerToContainerDto(Container data); diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/DatabaseMapper.java b/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/DatabaseMapper.java index 183e146a6c2ead0fdf9c76dd2f9e0675e4d678c2..178dce6b597b077130b4e21cb0d6426aed42bbb7 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/DatabaseMapper.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/DatabaseMapper.java @@ -2,10 +2,7 @@ package at.tuwien.mapper; import at.tuwien.api.database.*; import at.tuwien.api.user.UserDetailsDto; -import at.tuwien.entities.container.Container; import at.tuwien.entities.container.image.ContainerImage; -import at.tuwien.entities.container.image.ContainerImageEnvironmentItem; -import at.tuwien.entities.container.image.ContainerImageEnvironmentItemType; import at.tuwien.entities.database.AccessType; import at.tuwien.entities.database.Database; import at.tuwien.entities.database.DatabaseAccess; @@ -17,7 +14,6 @@ import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; import org.mapstruct.Named; -import org.springframework.transaction.annotation.Transactional; import java.security.Principal; import java.sql.Connection; @@ -26,7 +22,6 @@ import java.sql.SQLException; import java.text.Normalizer; import java.util.Locale; import java.util.regex.Pattern; -import java.util.stream.Collectors; @Mapper(componentModel = "spring", uses = {ContainerMapper.class, UserMapper.class, ImageMapper.class}) public interface DatabaseMapper { @@ -56,29 +51,7 @@ public interface DatabaseMapper { /* keep */ @Named("engineMapping") default String containerImageToEngine(ContainerImage data) { - return data.getRepository() + ":" + data.getTag(); - } - - @Transactional(readOnly = true) - default User containerToPrivilegedUser(Container container) { - final String username = container.getImage() - .getEnvironment() - .stream() - .filter(e -> e.getType().equals(ContainerImageEnvironmentItemType.PRIVILEGED_USERNAME)) - .map(ContainerImageEnvironmentItem::getValue) - .collect(Collectors.toList()) - .get(0); - final String password = container.getImage() - .getEnvironment() - .stream() - .filter(e -> e.getType().equals(ContainerImageEnvironmentItemType.PRIVILEGED_PASSWORD)) - .map(ContainerImageEnvironmentItem::getValue) - .collect(Collectors.toList()) - .get(0); - return User.builder() - .username(username) - .databasePassword(password) - .build(); + return data.getName() + ":" + data.getVersion(); } @Mappings({ diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/ImageMapper.java b/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/ImageMapper.java index 30d5ff02e7c001c1b95b4eb57021d32c9ef350a8..f8d8dc6763889c033acd866d559bd3f18aa8372c 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/ImageMapper.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/ImageMapper.java @@ -2,14 +2,8 @@ package at.tuwien.mapper; import at.tuwien.api.container.image.ImageDto; import at.tuwien.entities.container.image.ContainerImage; -import at.tuwien.entities.container.image.ContainerImageEnvironmentItem; -import at.tuwien.entities.container.image.ContainerImageEnvironmentItemType; -import at.tuwien.exception.ImageNotSupportedException; import org.mapstruct.Mapper; -import java.util.Optional; -import java.util.Properties; - @Mapper(componentModel = "spring") public interface ImageMapper { @@ -18,30 +12,4 @@ public interface ImageMapper { /* keep */ ImageDto containerImageToImageDto(ContainerImage data); - @Deprecated - default Properties containerImageToProperties(ContainerImage data) throws ImageNotSupportedException { - final Properties properties = new Properties(); - final Optional<ContainerImageEnvironmentItem> username = data.getEnvironment() - .stream() - .filter(i -> i.getType().equals(ContainerImageEnvironmentItemType.USERNAME)) - .findFirst(); - if (username.isEmpty()) { - log.error("Credentials error: no username found"); - throw new ImageNotSupportedException("Credentials error"); - } - final Optional<ContainerImageEnvironmentItem> password = data.getEnvironment() - .stream() - .filter(i -> i.getType().equals(ContainerImageEnvironmentItemType.PASSWORD)) - .findFirst(); - if (password.isEmpty()) { - log.error("Credentials error: no password found"); - throw new ImageNotSupportedException("Credentials error"); - } - properties.setProperty("user", username.get() - .getValue()); - properties.setProperty("password", password.get() - .getValue()); - return properties; - } - } diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/repository/mdb/DatabaseRepository.java b/dbrepo-database-service/services/src/main/java/at/tuwien/repository/mdb/DatabaseRepository.java index b70f0e0fb20ef5b6479805f7ed06e57c138aa907..1c75a69d4f7404e9ca577d533cb58b454397a7be 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/repository/mdb/DatabaseRepository.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/repository/mdb/DatabaseRepository.java @@ -15,16 +15,14 @@ public interface DatabaseRepository extends JpaRepository<Database, Long> { @Query("select d from Database d where d.owner.username = :username") List<Database> findAllByUsername(@Param("username") String username); - @Query("select d from Database d where d.container.id = :containerId") - List<Database> findAll(@Param("containerId") Long containerId); + List<Database> findAll(); - @Query("select d from Database d where d.container.id = :containerId and d.id = :databaseId and (d.isPublic = " + + @Query("select d from Database d where d.id = :databaseId and (d.isPublic = " + "true or d.owner.username = " + ":username)") - Optional<Database> findPublicOrMine(@Param("containerId") Long containerId, @Param("databaseId") Long databaseId, - @Param("username") String username); + Optional<Database> findPublicOrMine(@Param("databaseId") Long databaseId, @Param("username") String username); - @Query("select d from Database d where d.container.id = :containerId and d.isPublic = true and d.id = :databaseId") - Optional<Database> findPublic(@Param("containerId") Long containerId, @Param("databaseId") Long databaseId); + @Query("select d from Database d where d.isPublic = true and d.id = :databaseId") + Optional<Database> findPublic(@Param("databaseId") Long databaseId); } diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/service/AccessService.java b/dbrepo-database-service/services/src/main/java/at/tuwien/service/AccessService.java index 97eed76ada8e5b1ed01ac97ab6de9d6b2354680b..3747f33997091e82664e2b72af0ff485820b486b 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/service/AccessService.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/service/AccessService.java @@ -24,7 +24,6 @@ public interface AccessService { /** * Give somebody access to a database of container. * - * @param containerId The container id. * @param databaseId The database id. * @param accessDto The access. * @throws DatabaseNotFoundException The database was not found in the metadata database. @@ -33,13 +32,12 @@ public interface AccessService { * @throws QueryMalformedException The mapped access query is malformed. * @throws DatabaseMalformedException The database has an invalid state. */ - void create(Long containerId, Long databaseId, DatabaseGiveAccessDto accessDto) + void create(Long databaseId, DatabaseGiveAccessDto accessDto) throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException, QueryMalformedException, DatabaseMalformedException; /** * Update access to a database. * - * @param containerId The container id. * @param databaseId The database id. * @param username The username. * @param accessDto The updated access. @@ -49,13 +47,12 @@ public interface AccessService { * @throws QueryMalformedException The mapped access query is malformed. * @throws DatabaseMalformedException The database has an invalid state. */ - void update(Long containerId, Long databaseId, String username, DatabaseModifyAccessDto accessDto) + void update(Long databaseId, String username, DatabaseModifyAccessDto accessDto) throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException, QueryMalformedException, DatabaseMalformedException, AccessDeniedException; /** * Revokes access to a database of container. * - * @param containerId The container id. * @param databaseId The database id. * @param username The user name. * @throws DatabaseNotFoundException The database was not found in the metadata database. @@ -64,6 +61,6 @@ public interface AccessService { * @throws QueryMalformedException The mapped access query is malformed. * @throws DatabaseMalformedException The database has an invalid state. */ - void delete(Long containerId, Long databaseId, String username) + void delete(Long databaseId, String username) throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException, QueryMalformedException, DatabaseMalformedException; } diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/service/DatabaseService.java b/dbrepo-database-service/services/src/main/java/at/tuwien/service/DatabaseService.java index e10324b97ac79ec7c69e15cf0b401fde75a36a7c..3c4327ca0d5c7c711f1331c3d17e3113bb42fd95 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/service/DatabaseService.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/service/DatabaseService.java @@ -13,61 +13,50 @@ import java.util.List; @Service public interface DatabaseService { - /** - * Finds all databases in the metadata database for a given container id. - * - * @param containerId The container id. - * @return List of databases. - */ - List<Database> findAll(Long containerId); + List<Database> findAll(); /** * Finds a specific database for a given id in the metadata database. * - * @param containerId The container id. * @param databaseId The database id. * @param principal The principal. * @return The database, if successful. * @throws DatabaseNotFoundException The database was not found in the metadata database. */ - Database findPublicOrMineById(Long containerId, Long databaseId, Principal principal) + Database findPublicOrMineById(Long databaseId, Principal principal) throws DatabaseNotFoundException; /** * Find a database by id, only used in the authentication service * - * @param containerId the container id. * @param databaseId the database id. * @return The database, if successful. * @throws DatabaseNotFoundException The database was not found in the metadata database. */ - Database findById(Long containerId, Long databaseId) throws DatabaseNotFoundException; + Database findById(Long databaseId) throws DatabaseNotFoundException; /** * Deletes a database with given id in the metadata database. Side effects: does only mark the database as deleted, * does not actually delete it. * - * @param id The container id. * @param databaseId The database id. * @throws DatabaseNotFoundException The database was not found in the metadata database. * @throws ImageNotSupportedException The image is not supported. * @throws DatabaseMalformedException The query string is malformed. * @throws AmqpException The exchange could not be deleted. * @throws ContainerConnectionException The connection to the container could not be established. - * @throws ContainerNotFoundException The container was not found in the metadata database. * @throws DatabaseConnectionException The connection to the database could not be established by the database connector. * @throws QueryMalformedException The mapped deletion query resulted in an invalid query statement and thus was rejected by the database engine. * @throws UserNotFoundException The current user could not be loaded in the metadata database. */ - void delete(Long id, Long databaseId, Principal principal) + void delete(Long databaseId, Principal principal) throws DatabaseNotFoundException, ImageNotSupportedException, - DatabaseMalformedException, AmqpException, ContainerConnectionException, ContainerNotFoundException, + DatabaseMalformedException, AmqpException, ContainerConnectionException, DatabaseConnectionException, QueryMalformedException, UserNotFoundException; /** * Creates a new database with minimal metadata in the metadata database and creates a new database on the container. * - * @param id The container id. * @param createDto The metadata. * @return The database, if successful. * @throws ImageNotSupportedException The image is not supported. @@ -80,7 +69,7 @@ public interface DatabaseService { * @throws DatabaseConnectionException The connection to the database could not be established by the database connector. * @throws QueryMalformedException The mapped creation query resulted in an invalid query statement and thus was rejected by the database engine. */ - Database create(Long id, DatabaseCreateDto createDto, Principal principal) + Database create(DatabaseCreateDto createDto, Principal principal) throws ImageNotSupportedException, ContainerNotFoundException, DatabaseMalformedException, AmqpException, ContainerConnectionException, UserNotFoundException, DatabaseNameExistsException, DatabaseConnectionException, QueryMalformedException; @@ -88,25 +77,21 @@ public interface DatabaseService { /** * Updates the visibility of the database. * - * @param containerId The container id. * @param databaseId The database id. * @param data The visibility * @return The database, if successful. * @throws DatabaseNotFoundException The database was not found in the metadata database. */ - Database visibility(Long containerId, Long databaseId, DatabaseModifyVisibilityDto data) - throws DatabaseNotFoundException; + Database visibility(Long databaseId, DatabaseModifyVisibilityDto data) throws DatabaseNotFoundException; /** * Transfer ownership of a database * - * @param containerId The container id. * @param databaseId The database id. * @param transferDto The payload with the new owner. * @return The database, if successful. * @throws DatabaseNotFoundException The database was not found in the metadata database. * @throws UserNotFoundException The new user was not found in the metadata database. */ - Database transfer(Long containerId, Long databaseId, DatabaseTransferDto transferDto) - throws DatabaseNotFoundException, UserNotFoundException; + Database transfer(Long databaseId, DatabaseTransferDto transferDto) throws DatabaseNotFoundException, UserNotFoundException; } diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/service/IdentifierService.java b/dbrepo-database-service/services/src/main/java/at/tuwien/service/IdentifierService.java index 2059be0057c18c93df7843c7956ef3ff77abcffc..0238eca2c5b925cf14220dac1ac3b5b483349db9 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/service/IdentifierService.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/service/IdentifierService.java @@ -1,13 +1,9 @@ package at.tuwien.service; import at.tuwien.entities.identifier.Identifier; -import at.tuwien.entities.identifier.IdentifierType; -import at.tuwien.exception.IdentifierNotFoundException; -import org.jvnet.hk2.annotations.Service; import java.util.List; -@Service public interface IdentifierService { /** diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/service/QueryStoreService.java b/dbrepo-database-service/services/src/main/java/at/tuwien/service/QueryStoreService.java index 308ebfed90037615d126f118d6f0c80c4595da12..680f8322db35e2663c164d3306ede6d33ed6c1a0 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/service/QueryStoreService.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/service/QueryStoreService.java @@ -7,9 +7,8 @@ import java.security.Principal; public interface QueryStoreService { /** - * Creates the query store in the database with given container id. + * Creates the query store in the database. * - * @param containerId The container id. * @param databaseId The database id. * @param principal The principal of the user. * @throws DatabaseNotFoundException @@ -18,5 +17,5 @@ public interface QueryStoreService { * @throws UserNotFoundException * @throws QueryStoreException */ - void create(Long containerId, Long databaseId, Principal principal) throws DatabaseNotFoundException, DatabaseConnectionException, DatabaseMalformedException, UserNotFoundException, QueryStoreException; + void create(Long databaseId, Principal principal) throws DatabaseNotFoundException, DatabaseConnectionException, DatabaseMalformedException, UserNotFoundException, QueryStoreException; } diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java b/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java index 1a615abbe6105ba959f8002f42a4f4c7df6b41d2..ddb1e5c31171ba82bb486633ec5e439a0aa7e27a 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java @@ -60,11 +60,11 @@ public class AccessServiceImpl extends HibernateConnector implements AccessServi @Override @Transactional - public void create(Long containerId, Long databaseId, DatabaseGiveAccessDto accessDto) + public void create(Long databaseId, DatabaseGiveAccessDto accessDto) throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException, QueryMalformedException, DatabaseMalformedException { /* check */ - final Database database = databaseService.findById(containerId, databaseId); + final Database database = databaseService.findById(databaseId); final Container container = database.getContainer(); final User user = userService.findByUsername(accessDto.getUsername()); log.trace("give access to user with username {}", user.getUsername()); @@ -72,8 +72,7 @@ public class AccessServiceImpl extends HibernateConnector implements AccessServi log.error("Failed to give access to user with username {}, has already permission", accessDto.getUsername()); throw new NotAllowedException("Failed to give access"); } - final User root = databaseMapper.containerToPrivilegedUser(container); - final ComboPooledDataSource dataSource = getDataSource(container.getImage(), container, database, root); + final ComboPooledDataSource dataSource = getPrivilegedDataSource(container.getImage(), container, database); try { final Connection connection = dataSource.getConnection(); /* create user if not exists */ @@ -100,11 +99,11 @@ public class AccessServiceImpl extends HibernateConnector implements AccessServi @Override @Transactional - public void update(Long containerId, Long databaseId, String username, DatabaseModifyAccessDto accessDto) + public void update(Long databaseId, String username, DatabaseModifyAccessDto accessDto) throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException, QueryMalformedException, DatabaseMalformedException, AccessDeniedException { /* check */ - final Database database = databaseService.findById(containerId, databaseId); + final Database database = databaseService.findById(databaseId); final Container container = database.getContainer(); final User user = userService.findByUsername(username); if (database.getOwner().getUsername().equals(username)) { @@ -112,8 +111,7 @@ public class AccessServiceImpl extends HibernateConnector implements AccessServi throw new NotAllowedException("Failed modify access"); } find(databaseId, username); - final User root = databaseMapper.containerToPrivilegedUser(container); - final ComboPooledDataSource dataSource = getDataSource(container.getImage(), container, database, root); + final ComboPooledDataSource dataSource = getPrivilegedDataSource(container.getImage(), container, database); final DatabaseGiveAccessDto giveAccess = databaseMapper.databaseModifyAccessToDatabaseGiveAccessDto(username, accessDto); try { final Connection connection = dataSource.getConnection(); @@ -140,19 +138,18 @@ public class AccessServiceImpl extends HibernateConnector implements AccessServi @Override @Transactional - public void delete(Long containerId, Long databaseId, String username) + public void delete(Long databaseId, String username) throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException, QueryMalformedException, DatabaseMalformedException { /* check */ - final Database database = databaseService.findById(containerId, databaseId); + final Database database = databaseService.findById(databaseId); final Container container = database.getContainer(); final User user = userService.findByUsername(username); if (database.getOwner().getUsername().equals(username)) { log.error("Failed to revoke access of user with username {}, because it is the owner", username); throw new NotAllowedException("Failed revoke access"); } - final User root = databaseMapper.containerToPrivilegedUser(container); - final ComboPooledDataSource dataSource = getDataSource(container.getImage(), container, root); + final ComboPooledDataSource dataSource = getPrivilegedDataSource(container.getImage(), container); try { final Connection connection = dataSource.getConnection(); /* create user */ diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/HibernateConnector.java b/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/HibernateConnector.java index b5629aa17ab6d341161598ce1fb02ec7285fcc36..9bb5c149f7bfb197ff37b8eaaf4dcc95cf5d37d5 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/HibernateConnector.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/HibernateConnector.java @@ -13,15 +13,32 @@ import org.springframework.stereotype.Service; public abstract class HibernateConnector { public static ComboPooledDataSource getDataSource(ContainerImage image, Container container, User user) { - return getDataSource(image, container, null, user); + return getDataSource(image, container, null, user.getUsername(), user.getDatabasePassword()); } - public static ComboPooledDataSource getDataSource(ContainerImage image, Container container, Database database, - User user) { + public static ComboPooledDataSource getPrivilegedDataSource(ContainerImage image, Container container) { + return getPrivilegedDataSource(image, container, null); + } + + public static ComboPooledDataSource getPrivilegedDataSource(ContainerImage image, Container container, Database database) { + final ComboPooledDataSource dataSource = new ComboPooledDataSource(); + dataSource.setJdbcUrl(url(image, container, database)); + dataSource.setUser(container.getPrivilegedUsername()); + dataSource.setPassword(container.getPrivilegedPassword()); + dataSource.setInitialPoolSize(5); + dataSource.setMinPoolSize(5); + dataSource.setAcquireIncrement(5); + dataSource.setMaxPoolSize(20); + dataSource.setMaxStatements(100); + log.trace("created pooled data source {}", dataSource); + return dataSource; + } + + public static ComboPooledDataSource getDataSource(ContainerImage image, Container container, Database database, String username, String password) { final ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setJdbcUrl(url(image, container, database)); - dataSource.setUser(user.getUsername()); - dataSource.setPassword(user.getDatabasePassword()); + dataSource.setUser(username); + dataSource.setPassword(password); dataSource.setInitialPoolSize(5); dataSource.setMinPoolSize(5); dataSource.setAcquireIncrement(5); @@ -35,7 +52,9 @@ public abstract class HibernateConnector { final StringBuilder stringBuilder = new StringBuilder("jdbc:") .append(image.getJdbcMethod()) .append("://") - .append(container.getInternalName()) + .append(container.getHost()) + .append(":") + .append(container.getPort()) .append("/"); if (database != null) { stringBuilder.append(database.getInternalName()) diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java b/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java index 0725475a576d5db1a134aef6c6cbcde40ac9cdd1..b3d1d1fede9d9ff12475a8d06f16c0a4b8461e28 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java @@ -18,11 +18,12 @@ import com.mchange.v2.c3p0.ComboPooledDataSource; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; - import org.springframework.transaction.annotation.Transactional; import java.security.Principal; -import java.sql.*; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; import java.util.List; import java.util.Optional; @@ -48,21 +49,21 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe } @Override - public List<Database> findAll(Long containerId) { - return databaseRepository.findAll(containerId); + public List<Database> findAll() { + return databaseRepository.findAll(); } @Override @Transactional(readOnly = true) - public Database findPublicOrMineById(Long containerId, Long databaseId, Principal principal) + public Database findPublicOrMineById(Long databaseId, Principal principal) throws DatabaseNotFoundException { final Optional<Database> database; if (principal == null) { log.trace("principal is null, find public database"); - database = databaseRepository.findPublic(containerId, databaseId); + database = databaseRepository.findPublic(databaseId); } else { log.trace("principal is not null, find public or mine database"); - database = databaseRepository.findPublicOrMine(containerId, databaseId, principal.getName()); + database = databaseRepository.findPublicOrMine(databaseId, principal.getName()); } if (database.isEmpty()) { log.error("Failed to find database with id {}", databaseId); @@ -73,29 +74,27 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe @Override @Transactional(readOnly = true) - public Database findById(Long id, Long databaseId) throws DatabaseNotFoundException { - final Optional<Database> database = databaseRepository.findById(databaseId); + public Database findById(Long id) throws DatabaseNotFoundException { + final Optional<Database> database = databaseRepository.findById(id); if (database.isEmpty()) { - log.error("Failed to find database with id {}", databaseId); - throw new DatabaseNotFoundException("could not find database with id " + databaseId); + log.error("Failed to find database with id {}", id); + throw new DatabaseNotFoundException("could not find database with id " + id); } return database.get(); } @Override @Transactional - public void delete(Long containerId, Long databaseId, Principal principal) throws DatabaseNotFoundException, - ImageNotSupportedException, DatabaseMalformedException, ContainerNotFoundException, - DatabaseConnectionException, QueryMalformedException, UserNotFoundException { - final Container container = containerService.find(containerId); - final Database database = findPublicOrMineById(containerId, databaseId, principal); - if (!database.getContainer().getImage().getRepository().equals("mariadb")) { + public void delete(Long databaseId, Principal principal) throws DatabaseNotFoundException, + ImageNotSupportedException, DatabaseMalformedException, DatabaseConnectionException, + QueryMalformedException, UserNotFoundException { + final Database database = findPublicOrMineById(databaseId, principal); + if (!database.getContainer().getImage().getName().equals("mariadb")) { log.error("Currently only MariaDB is supported"); throw new ImageNotSupportedException("Currently only MariaDB is supported"); } - final User root = databaseMapper.containerToPrivilegedUser(container); /* run query */ - final ComboPooledDataSource dataSource = getDataSource(container.getImage(), container, database, root); + final ComboPooledDataSource dataSource = getPrivilegedDataSource(database.getContainer().getImage(), database.getContainer(), database); try { final Connection connection = dataSource.getConnection(); final PreparedStatement preparedStatement = databaseMapper.databaseToRawDeleteDatabaseQuery(connection, database); @@ -116,27 +115,21 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe @Override @Transactional - public Database create(Long containerId, DatabaseCreateDto createDto, Principal principal) + public Database create(DatabaseCreateDto createDto, Principal principal) throws ImageNotSupportedException, ContainerNotFoundException, DatabaseMalformedException, AmqpException, ContainerConnectionException, UserNotFoundException, DatabaseNameExistsException, DatabaseConnectionException, QueryMalformedException { - final Container container = containerService.find(containerId); - if (container.getDatabase() != null) { - log.error("Failed to create database {} in container with id {}, only one database per container", createDto.getName(), containerId); - throw new DatabaseMalformedException("Failed to create database " + createDto.getName() + " in container with id " + containerId + ", only one database per container"); - } - final User root = databaseMapper.containerToPrivilegedUser(container); final User user = userService.findByUsername(principal.getName()); /* start the object */ final Database database = databaseMapper.databaseCreateDtoToDatabase(createDto); - database.setId(containerId); - database.setContainer(container); + final Container container = containerService.find(database.getCid()); final User owner = userService.findByUsername(principal.getName()); + database.setContainer(container); database.setOwnedBy(owner.getId()); database.setCreatedBy(owner.getId()); database.setContactPerson(owner.getId()); database.setExchangeName("dbrepo." + database.getInternalName()); - final ComboPooledDataSource dataSource = getDataSource(container.getImage(), container, root); + final ComboPooledDataSource dataSource = getPrivilegedDataSource(container.getImage(), container); try { final Connection connection = dataSource.getConnection(); /* create database */ @@ -164,10 +157,9 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe @Override @Transactional - public Database visibility(Long containerId, Long databaseId, DatabaseModifyVisibilityDto data) - throws DatabaseNotFoundException { + public Database visibility(Long databaseId, DatabaseModifyVisibilityDto data) throws DatabaseNotFoundException { /* check */ - final Database database = findById(containerId, databaseId); + final Database database = findById(databaseId); /* map */ database.setIsPublic(data.getIsPublic()); /* update entity in metadata database */ @@ -181,10 +173,9 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe @Override @Transactional - public Database transfer(Long containerId, Long databaseId, DatabaseTransferDto transferDto) - throws DatabaseNotFoundException, UserNotFoundException { + public Database transfer(Long databaseId, DatabaseTransferDto transferDto) throws DatabaseNotFoundException, UserNotFoundException { /* check */ - final Database entity = findById(containerId, databaseId); + final Database entity = findById(databaseId); final User user = userService.findByUsername(transferDto.getUsername()); /* update in metadata database */ entity.setOwnedBy(user.getId()); diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/QueryStoreServiceImpl.java b/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/QueryStoreServiceImpl.java index 838efb1d95e1f553ab84de8dd970806adffb0a5c..4f65dca2afcd2138c3c04441db3317f2b0d14445 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/QueryStoreServiceImpl.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/QueryStoreServiceImpl.java @@ -1,12 +1,10 @@ package at.tuwien.service.impl; -import at.tuwien.utils.FileUtil; import at.tuwien.entities.database.Database; -import at.tuwien.entities.user.User; import at.tuwien.exception.*; -import at.tuwien.mapper.DatabaseMapper; import at.tuwien.service.DatabaseService; import at.tuwien.service.QueryStoreService; +import at.tuwien.utils.FileUtil; import com.mchange.v2.c3p0.ComboPooledDataSource; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; @@ -23,23 +21,20 @@ import java.sql.SQLException; @Service public class QueryStoreServiceImpl extends HibernateConnector implements QueryStoreService { - private final DatabaseMapper databaseMapper; private final DatabaseService databaseService; @Autowired - public QueryStoreServiceImpl(DatabaseMapper databaseMapper, DatabaseService databaseService) { - this.databaseMapper = databaseMapper; + public QueryStoreServiceImpl(DatabaseService databaseService) { this.databaseService = databaseService; } @Override @Transactional(rollbackFor = DatabaseMalformedException.class) - public void create(Long containerId, Long databaseId, Principal principal) throws DatabaseNotFoundException, + public void create(Long databaseId, Principal principal) throws DatabaseNotFoundException, DatabaseConnectionException, DatabaseMalformedException, UserNotFoundException, QueryStoreException { - final Database database = databaseService.findById(containerId, databaseId); - final User root = databaseMapper.containerToPrivilegedUser(database.getContainer()); + final Database database = databaseService.findById(databaseId); /* create */ - final ComboPooledDataSource dataSource = getDataSource(database.getContainer().getImage(), database.getContainer(), database, root); + final ComboPooledDataSource dataSource = getPrivilegedDataSource(database.getContainer().getImage(), database.getContainer(), database); try { final Connection connection = dataSource.getConnection(); for (String query : FileUtil.loadResource("/init/querystore.sql")) { diff --git a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..a469eadf815d07d9a2fbfbde175a74dd15202145 --- /dev/null +++ b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java @@ -0,0 +1,230 @@ +package at.tuwien.config; + +import at.tuwien.api.database.AccessTypeDto; +import at.tuwien.api.database.DatabaseGiveAccessDto; +import at.tuwien.entities.container.Container; +import at.tuwien.entities.database.Database; +import at.tuwien.entities.user.User; +import at.tuwien.exception.QueryMalformedException; +import at.tuwien.mapper.DatabaseMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; + +import java.sql.*; +import java.time.Instant; +import java.util.LinkedList; +import java.util.List; + +@Slf4j +@Configuration +public class MariaDbConfig { + + @Autowired + private DatabaseMapper databaseMapper; + + /** + * Inserts a query into a created database with given hostname and database name. The method uses the JDBC in-out + * notation <a href="#{@link}">{@link https://learn.microsoft.com/en-us/sql/connect/jdbc/using-sql-escape-sequences?view=sql-server-ver16#stored-procedure-calls}</a> + * + * @param hostname The hostname. + * @param database The database name. + * @param query The query. + * @param username The connection username. + * @param password The connection password. + * @return The generated or retrieved query id. + * @throws SQLException The procedure did not succeed. + */ + public static Long mockSystemQueryInsert(Database database, String query, String username, String password) + throws SQLException { + final String jdbc = "jdbc:mariadb://" + database.getContainer().getHost() + ":" + database.getContainer().getPort() + "/" + database.getInternalName(); + log.trace("connect to database {}", jdbc); + try (Connection connection = DriverManager.getConnection(jdbc, username, password)) { + final String call = "{call _store_query(?,?,?,?)}"; + log.trace("prepare procedure '{}'", call); + final CallableStatement statement = connection.prepareCall(call); + statement.setString(1, username); + statement.setString(2, query); + statement.setTimestamp(3, Timestamp.from(Instant.now())); + statement.registerOutParameter(4, Types.BIGINT); + statement.executeUpdate(); + final Long queryId = statement.getLong(4); + statement.close(); + log.debug("received queryId={}", queryId); + return queryId; + } + } + + public static void createDatabase(Container container, String database) throws SQLException { + final String jdbc = "jdbc:mariadb://" + container.getHost() + ":" + container.getPort(); + log.trace("connect to database {}", jdbc); + try (Connection connection = DriverManager.getConnection(jdbc, container.getPrivilegedUsername(), container.getPrivilegedPassword())) { + final String sql = "CREATE DATABASE `" + database + "`;"; + log.trace("prepare statement '{}'", sql); + final PreparedStatement statement = connection.prepareStatement(sql); + statement.executeUpdate(); + statement.close(); + } + } + + public static void createInitDatabase(Container container, Database database) throws SQLException { + final String jdbc = "jdbc:mariadb://" + container.getHost() + ":" + container.getPort(); + log.trace("connect to database {}", jdbc); + try (Connection connection = DriverManager.getConnection(jdbc, container.getPrivilegedUsername(), container.getPrivilegedPassword())) { + ResourceDatabasePopulator populator = new ResourceDatabasePopulator(new ClassPathResource("init/" + database.getInternalName() + ".sql"), new ClassPathResource("init/querystore.sql")); + populator.setSeparator(";\n"); + populator.populate(connection); + } + } + + public static void dropAllDatabases(Container container) { + final String jdbc = "jdbc:mariadb://" + container.getHost() + ":" + container.getPort(); + log.trace("connect to database {}", jdbc); + try (Connection connection = DriverManager.getConnection(jdbc, container.getPrivilegedUsername(), container.getPrivilegedPassword())) { + final String sql = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'mysql', 'performance_schema');"; + log.trace("prepare statement '{}'", sql); + final PreparedStatement statement = connection.prepareStatement(sql); + final ResultSet resultSet = statement.executeQuery(); + final List<String> databases = new LinkedList<>(); + while (resultSet.next()) { + databases.add(resultSet.getString(1)); + } + resultSet.close(); + statement.close(); + for (String database : databases) { + final String drop = "DROP DATABASE IF EXISTS `" + database + "`;"; + final PreparedStatement dropStatement = connection.prepareStatement(drop); + dropStatement.executeUpdate(); + dropStatement.close(); + } + } catch (SQLException e) { + log.error("could not drop all databases", e); + } + } + + public static void dropDatabase(Container container, String database) + throws SQLException { + final String jdbc = "jdbc:mariadb://" + container.getHost() + ":" + container.getPort(); + log.trace("connect to database {}", jdbc); + try (Connection connection = DriverManager.getConnection(jdbc, container.getPrivilegedUsername(), container.getPrivilegedPassword())) { + final String sql = "DROP DATABASE IF EXISTS `" + database + "`;"; + log.trace("prepare statement '{}'", sql); + final PreparedStatement statement = connection.prepareStatement(sql); + statement.executeUpdate(); + statement.close(); + } + } + + public void mockGrantUserPermissions(Container container, Database database, User user) throws SQLException, + QueryMalformedException { + final String jdbc = "jdbc:mariadb://" + container.getHost() + ":" + container.getPort() + "/" + database.getInternalName(); + log.trace("connect to database {}", jdbc); + try (Connection connection = DriverManager.getConnection(jdbc, container.getPrivilegedUsername(), container.getPrivilegedPassword())) { + final DatabaseGiveAccessDto access = DatabaseGiveAccessDto.builder() + .username(user.getUsername()) + .type(AccessTypeDto.WRITE_ALL) + .build(); + final PreparedStatement statement1 = databaseMapper.rawGrantUserAccessQuery(connection, access); + statement1.executeUpdate(); + final PreparedStatement statement2 = databaseMapper.rawGrantUserProcedure(connection, user); + statement2.executeUpdate(); + final PreparedStatement statement3 = databaseMapper.rawFlushPrivileges(connection); + statement3.executeUpdate(); + } + } + + public static List<String> getUsernames(String hostname, String database, String username, String password) + throws SQLException { + final String jdbc = "jdbc:mariadb://" + hostname + "/" + database; + log.trace("connect to database {}", jdbc); + final List<String> usernames = new LinkedList<>(); + try (Connection connection = DriverManager.getConnection(jdbc, username, password)) { + final String query = "SELECT User FROM mysql.user;"; + log.trace("prepare statement '{}'", query); + final PreparedStatement statement = connection.prepareStatement(query); + final ResultSet set = statement.executeQuery(); + statement.close(); + while (set.next()) { + usernames.add(set.getString("User")); + } + log.debug("received usernames={}", usernames); + return usernames; + } + } + + public static String getPrivileges(String hostname, String database, String user, String username, String password) + throws Exception { + final String jdbc = "jdbc:mariadb://" + hostname + "/" + database; + log.trace("connect to database {}", jdbc); + final List<String> usernames = new LinkedList<>(); + try (Connection connection = DriverManager.getConnection(jdbc, username, password)) { + final String query = "SHOW GRANTS FOR `" + user + "`;"; + log.trace("prepare statement '{}'", query); + final PreparedStatement statement = connection.prepareStatement(query); + final ResultSet set = statement.executeQuery(); + statement.close(); + if (set.next()) { + return set.getString(1); + } + } + throw new Exception("Failed to get privileges"); + } + + public static void mockQuery(String hostname, String query, String username, String password) + throws SQLException { + final String jdbc = "jdbc:mariadb://" + hostname; + log.trace("connect to database {}", jdbc); + try (Connection connection = DriverManager.getConnection(jdbc, username, password)) { + final PreparedStatement statement = connection.prepareStatement(query); + statement.executeUpdate(); + statement.close(); + } + } + + /** + * Inserts a query into a created database with given hostname and database name. The method uses the JDBC in-out + * notation <a href="#{@link}">{@link https://learn.microsoft.com/en-us/sql/connect/jdbc/using-sql-escape-sequences?view=sql-server-ver16#stored-procedure-calls}</a> + * + * @param hostname The hostname. + * @param database The database name. + * @param query The query. + * @param username The connection username. + * @param password The connection password. + * @return The generated or retrieved query id. + * @throws SQLException The procedure did not succeed. + */ + public static Long mockUserQueryInsert(Database database, String query, String username, String password) + throws SQLException { + final String jdbc = "jdbc:mariadb://" + database.getContainer().getHost() + ":" + database.getContainer().getPort() + "/" + database.getInternalName(); + log.trace("connect to database {}", jdbc); + try (Connection connection = DriverManager.getConnection(jdbc, username, password)) { + final String call = "{call store_query(?,?,?)}"; + log.trace("prepare procedure '{}'", call); + final CallableStatement statement = connection.prepareCall(call); + statement.setString(1, query); + statement.setTimestamp(2, Timestamp.from(Instant.now())); + statement.registerOutParameter(3, Types.BIGINT); + statement.executeUpdate(); + final Long queryId = statement.getLong(3); + statement.close(); + log.debug("received queryId={}", queryId); + return queryId; + } + } + + /** + * Inserts a query into a created database with given hostname and database name. The method uses the JDBC in-out + * notation <a href="#{@link}">{@link https://learn.microsoft.com/en-us/sql/connect/jdbc/using-sql-escape-sequences?view=sql-server-ver16#stored-procedure-calls}</a> + * + * @param hostname The hostname. + * @param database The database name. + * @param query The query. + * @return The generated or retrieved query id. + * @throws SQLException The procedure did not succeed. + */ + public static Long mockSystemQueryInsert(Database database, String query) throws SQLException { + return mockSystemQueryInsert(database, query, database.getContainer().getPrivilegedUsername(), database.getContainer().getPrivilegedPassword()); + } +} diff --git a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..587927a0703c0bc78a8dc41fb665ac5d02a1d3b4 --- /dev/null +++ b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java @@ -0,0 +1,55 @@ +package at.tuwien.config; + +import at.tuwien.test.BaseTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.testcontainers.containers.MariaDBContainer; +import org.testcontainers.images.PullPolicy; + +/** + * This class configures the MariaDB container for the integration tests. + */ +@Configuration +public class MariaDbContainerConfig { + + @Bean + public CustomMariaDBContainer mariaDB() { + return CustomMariaDBContainer.getInstance(); + } + + /** + * This class represents the customized MariaDB container. It is a singleton to avoid the recreation of containers + * which can be very time-consuming. + */ + public static class CustomMariaDBContainer extends MariaDBContainer<CustomMariaDBContainer> { + + private static CustomMariaDBContainer instance; + + public static CustomMariaDBContainer getInstance() { + if(instance == null) { + instance = new CustomMariaDBContainer(BaseTest.IMAGE_1_NAME + ":" + BaseTest.IMAGE_1_VERSION); + instance.withImagePullPolicy(PullPolicy.alwaysPull()); + instance.addFixedExposedPort(BaseTest.CONTAINER_1_PORT, BaseTest.IMAGE_1_PORT); + instance.withUsername(BaseTest.CONTAINER_1_PRIVILEGED_USERNAME); + instance.withPassword(BaseTest.CONTAINER_1_PRIVILEGED_PASSWORD); + instance.withInitScript("init/users.sql"); + } + return instance; + } + + private CustomMariaDBContainer(String dockerImageName) { + super(dockerImageName); + } + + @Override + protected void configure() { + super.configure(); + this.addEnv("MYSQL_USER", "test"); // MariaDB does not allow this to be root + } + + @Override + public void stop() { + // do nothing, JVM handles shut down + } + } +} diff --git a/dbrepo-table-service/rest-service/src/test/resources/init/musicology.sql b/dbrepo-table-service/rest-service/src/test/resources/init/musicology.sql new file mode 100644 index 0000000000000000000000000000000000000000..4d2c8deb43ede5de84cd321a302e97ef84038508 --- /dev/null +++ b/dbrepo-table-service/rest-service/src/test/resources/init/musicology.sql @@ -0,0 +1,18 @@ +CREATE DATABASE musicology; +USE musicology; + +CREATE SEQUENCE seq_mfcc; + +CREATE TABLE mfcc +( + id BIGINT PRIMARY KEY NOT NULL DEFAULT nextval(`seq_mfcc`), + value DECIMAL NOT NULL +) WITH SYSTEM VERSIONING; + +INSERT INTO `mfcc` (`value`) +VALUES (11.2), + (11.3), + (11.4), + (11.9), + (12.3), + (23.1); \ No newline at end of file diff --git a/dbrepo-table-service/rest-service/src/test/resources/init/schema.sql b/dbrepo-table-service/rest-service/src/test/resources/init/schema.sql new file mode 100644 index 0000000000000000000000000000000000000000..f8482e47d5b0827e87537d940b54900a8f2d8f3b --- /dev/null +++ b/dbrepo-table-service/rest-service/src/test/resources/init/schema.sql @@ -0,0 +1 @@ +CREATE SCHEMA IF NOT EXISTS fda; \ No newline at end of file diff --git a/dbrepo-table-service/rest-service/src/test/resources/init/users.sql b/dbrepo-table-service/rest-service/src/test/resources/init/users.sql new file mode 100644 index 0000000000000000000000000000000000000000..45f7b53a0f602a780522da646d64da2a0bc36e53 --- /dev/null +++ b/dbrepo-table-service/rest-service/src/test/resources/init/users.sql @@ -0,0 +1,4 @@ +CREATE USER junit1 IDENTIFIED BY 'junit1'; +CREATE USER junit2 IDENTIFIED BY 'junit2'; +CREATE USER junit3 IDENTIFIED BY 'junit3'; +CREATE USER junit4 IDENTIFIED BY 'junit4'; \ No newline at end of file diff --git a/dbrepo-table-service/rest-service/src/test/resources/init/weather.sql b/dbrepo-table-service/rest-service/src/test/resources/init/weather.sql new file mode 100644 index 0000000000000000000000000000000000000000..05976e23e48dd83f763a0acbf841223e7e879d43 --- /dev/null +++ b/dbrepo-table-service/rest-service/src/test/resources/init/weather.sql @@ -0,0 +1,65 @@ +/* https://www.kaggle.com/jsphyg/weather-dataset-rattle-package */ +CREATE DATABASE weather; +USE weather; + +CREATE TABLE weather_location +( + location VARCHAR(255) PRIMARY KEY, + lat DOUBLE PRECISION NULL, + lng DOUBLE PRECISION NULL +) WITH SYSTEM VERSIONING; + +CREATE TABLE weather_aus +( + id BIGINT NOT NULL PRIMARY KEY, + `date` DATE NOT NULL, + location VARCHAR(255) NULL, + mintemp DOUBLE PRECISION NULL, + rainfall DOUBLE PRECISION NULL, + FOREIGN KEY (location) REFERENCES weather_location (location), + UNIQUE (`date`), + CHECK (`mintemp` > 0) +) WITH SYSTEM VERSIONING; + +CREATE TABLE sensor +( + `timestamp` TIMESTAMP NOT NULL PRIMARY KEY, + `value` DECIMAL +) WITH SYSTEM VERSIONING; + +INSERT INTO weather_location (location, lat, lng) +VALUES ('Albury', -36.0653583, 146.9112214), + ('Sydney', -33.847927, 150.6517942), + ('Vienna', null, null); + +INSERT INTO weather_aus (id, `date`, location, mintemp, rainfall) +VALUES (1, '2008-12-01', 'Albury', 13.4, 0.6), + (2, '2008-12-02', 'Albury', 7.4, 0), + (3, '2008-12-03', 'Albury', 12.9, 0); + +INSERT INTO sensor (`timestamp`, value) +VALUES ('2022-12-24 17:00:00', 10.0), + ('2022-12-24 18:00:00', 10.2), + ('2022-12-24 19:00:00', null), + ('2022-12-24 20:00:00', 10.3), + ('2022-12-24 21:00:00', 10.0), + ('2022-12-24 22:00:00', null); + +######################################################################################################################## +## TEST CASE PRE-REQUISITE ## +######################################################################################################################## + +CREATE VIEW junit2 AS +( +select `date`, `location`, `mintemp`, `rainfall` +from `weather_aus` +where `location` = 'Albury'); + +CREATE VIEW `hs_weather_aus` AS +SELECT * +FROM (SELECT `id`, ROW_START AS inserted_at, IF(ROW_END > NOW(), NULL, ROW_END) AS deleted_at, COUNT(*) as total + FROM `weather_aus` FOR SYSTEM_TIME ALL + GROUP BY inserted_at, deleted_at + ORDER BY deleted_at DESC + LIMIT 50) AS v +ORDER BY v.inserted_at, v.deleted_at ASC; diff --git a/dbrepo-table-service/rest-service/src/test/resources/init/zoo.sql b/dbrepo-table-service/rest-service/src/test/resources/init/zoo.sql new file mode 100644 index 0000000000000000000000000000000000000000..238978ac00ac8d9bc710348790a4a7d00155de60 --- /dev/null +++ b/dbrepo-table-service/rest-service/src/test/resources/init/zoo.sql @@ -0,0 +1,194 @@ +CREATE DATABASE zoo; +USE zoo; + +create sequence seq_zoo_id; +create sequence seq_names_id; +create table zoo +( + id bigint not null default nextval(`seq_zoo_id`), + animal_name varchar(255) null, + hair tinyint(1) null, + feathers tinyint(1) null, + eggs tinyint(1) null, + milk tinyint(1) null, + airborne tinyint(1) null, + aquatic tinyint(1) null, + predator tinyint(1) null, + toothed tinyint(1) null, + backbone tinyint(1) null, + breathes tinyint(1) null, + venomous tinyint(1) null, + fins tinyint(1) null, + legs bigint null, + tail tinyint(1) null, + domestic tinyint(1) null, + catsize tinyint(1) null, + class_type bigint null, + primary key (id) +) with system versioning; + +create table names +( + id bigint not null default nextval(`seq_names_id`), + firstname varchar(255), + lastname varchar(255), + primary key (id), + unique key (firstname, lastname) +) with system versioning; + +create table likes +( + name_id bigint not null, + zoo_id bigint not null, + primary key (name_id, zoo_id), + foreign key (name_id) references names (id), + foreign key (zoo_id) references zoo (id) +) with system versioning; + +INSERT INTO zoo (id, animal_name, hair, feathers, eggs, milk, airborne, aquatic, predator, toothed, backbone, breathes, + venomous, fins, legs, tail, domestic, catsize, class_type) +VALUES (1, 'aardvark', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 0, 0, 1, 1), + (2, 'antelope', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (3, 'bass', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (4, 'bear', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 0, 0, 1, 1), + (5, 'boar', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (6, 'buffalo', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (7, 'calf', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 1, 1, 1), + (8, 'carp', 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 4), + (9, 'catfish', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (10, 'cavy', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 0, 1, 0, 1), + (11, 'cheetah', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (12, 'chicken', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 1, 0, 2), + (13, 'chub', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (14, 'clam', 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7), + (15, 'crab', 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 7), + (16, 'crayfish', 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7), + (17, 'crow', 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (18, 'deer', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (19, 'dogfish', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 4), + (20, 'dolphin', 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1), + (21, 'dove', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 1, 0, 2), + (22, 'duck', 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (23, 'elephant', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (24, 'flamingo', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2), + (25, 'flea', 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 6, 0, 0, 0, 6), + (26, 'frog', 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 4, 0, 0, 0, 5), + (27, 'frog', 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 4, 0, 0, 0, 5), + (28, 'fruitbat', 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 2, 1, 0, 0, 1), + (29, 'giraffe', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (30, 'girl', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 2, 0, 1, 1, 1), + (31, 'gnat', 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 6, 0, 0, 0, 6), + (32, 'goat', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 1, 1, 1), + (33, 'gorilla', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 2, 0, 0, 1, 1), + (34, 'gull', 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (35, 'haddock', 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (36, 'hamster', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 1, 0, 1), + (37, 'hare', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 0, 1), + (38, 'hawk', 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (39, 'herring', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (40, 'honeybee', 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 6, 0, 1, 0, 6), + (41, 'housefly', 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 6, 0, 0, 0, 6), + (42, 'kiwi', 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (43, 'ladybird', 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 6, 0, 0, 0, 6), + (44, 'lark', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (45, 'leopard', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (46, 'lion', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (47, 'lobster', 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7), + (48, 'lynx', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (49, 'mink', 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (50, 'mole', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 0, 1), + (51, 'mongoose', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (52, 'moth', 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 6, 0, 0, 0, 6), + (53, 'newt', 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 4, 1, 0, 0, 5), + (54, 'octopus', 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 8, 0, 0, 1, 7), + (55, 'opossum', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 0, 1), + (56, 'oryx', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (57, 'ostrich', 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2), + (58, 'parakeet', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 1, 0, 2), + (59, 'penguin', 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2), + (60, 'pheasant', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (61, 'pike', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 4), + (62, 'piranha', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (63, 'pitviper', 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 3), + (64, 'platypus', 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (65, 'polecat', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (66, 'pony', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 1, 1, 1), + (67, 'porpoise', 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1), + (68, 'puma', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (69, 'pussycat', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 1, 1, 1), + (70, 'raccoon', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (71, 'reindeer', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 1, 1, 1), + (72, 'rhea', 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2), + (73, 'scorpion', 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 8, 1, 0, 0, 7), + (74, 'seahorse', 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (75, 'seal', 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1), + (76, 'sealion', 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 2, 1, 0, 1, 1), + (77, 'seasnake', 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 3), + (78, 'seawasp', 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 7), + (79, 'skimmer', 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (80, 'skua', 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (81, 'slowworm', 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 3), + (82, 'slug', 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 7), + (83, 'sole', 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 4), + (84, 'sparrow', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2), + (85, 'squirrel', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 2, 1, 0, 0, 1), + (86, 'starfish', 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 7), + (87, 'stingray', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 4), + (88, 'swan', 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2), + (89, 'termite', 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 6, 0, 0, 0, 6), + (90, 'toad', 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 4, 0, 0, 0, 5), + (91, 'tortoise', 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 4, 1, 0, 1, 3), + (92, 'tuatara', 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 0, 3), + (93, 'tuna', 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 4), + (94, 'vampire', 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 2, 1, 0, 0, 1), + (95, 'vole', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 0, 1), + (96, 'vulture', 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2), + (97, 'wallaby', 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 2, 1, 0, 1, 1), + (98, 'wasp', 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 6, 0, 0, 0, 6), + (99, 'wolf', 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1), + (100, 'worm', 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 7), + (101, 'wren', 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2); + +INSERT INTO names (firstname, lastname) +VALUES ('Moritz', 'Staudinger'), + ('Martin', 'Weise'), + ('Eva', 'Gergely'), + ('Cornelia', 'Michlits'), + ('Kirill', 'Stytsenko'); + +INSERT INTO likes (name_id, zoo_id) +VALUES (1, 5), + (1, 10), + (2, 3), + (2, 80), + (3, 4), + (4, 4), + (5, 100); + +######################################################################################################################## +## TEST CASE PRE-REQUISITE ## +######################################################################################################################## + +CREATE VIEW mock_view AS +( +SELECT `id`, + `animal_name`, + `hair`, + `feathers`, + `eggs`, + `milk`, + `airborne`, + `aquatic`, + `predator`, + `toothed`, + `backbone`, + `breathes`, + `venomous`, + `fins`, + `legs`, + `tail`, + `domestic`, + `catsize`, + `class_type` +FROM `zoo` +WHERE `class_type` = 1);