From 4dfab5334361e7924281f48586d95562d7425a35 Mon Sep 17 00:00:00 2001 From: Martin Weise <martin.weise@tuwien.ac.at> Date: Sun, 7 May 2023 16:11:30 +0200 Subject: [PATCH] Fixed some database service --- dbrepo-database-service/pom.xml | 3 +- .../endpoint/AccessEndpointUnitTest.java | 144 ++++++++++++--- .../endpoint/DatabaseEndpointUnitTest.java | 167 +++++++++++------- .../gateway/BrokerServiceGatewayTest.java | 58 ++++++ .../DatabaseServiceIntegrationTest.java | 57 +++++- .../IdentifierServiceIntegrationTest.java | 98 ++++++++++ .../LicenseServiceIntegrationTest.java | 76 ++++++++ ...> MessageQueueServiceIntegrationTest.java} | 30 +++- .../service/MessageQueueServiceUnitTest.java | 82 +++++++++ .../QueryStoreServiceIntegrationTest.java | 111 ++++++++++++ .../service/UserServiceIntegrationTest.java | 92 ++++++++++ .../at/tuwien/service/DatabaseService.java | 2 + .../at/tuwien/service/IdentifierService.java | 9 +- .../at/tuwien/service/QueryStoreService.java | 12 ++ .../service/impl/HibernateConnector.java | 4 +- .../service/impl/IdentifierServiceImpl.java | 9 - .../service/impl/MariaDbServiceImpl.java | 7 +- .../service/impl/QueryStoreServiceImpl.java | 13 +- .../tuwien/entities/container/Container.java | 6 +- .../at/tuwien/entities/database/Database.java | 14 +- .../main/java/at/tuwien/test/BaseTest.java | 2 +- 21 files changed, 859 insertions(+), 137 deletions(-) create mode 100644 dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/IdentifierServiceIntegrationTest.java create mode 100644 dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/LicenseServiceIntegrationTest.java rename dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/{AmqpServiceIntegrationTest.java => MessageQueueServiceIntegrationTest.java} (75%) create mode 100644 dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceUnitTest.java create mode 100644 dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/QueryStoreServiceIntegrationTest.java create mode 100644 dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java diff --git a/dbrepo-database-service/pom.xml b/dbrepo-database-service/pom.xml index c86fd24642..49aac1bc36 100644 --- a/dbrepo-database-service/pom.xml +++ b/dbrepo-database-service/pom.xml @@ -226,8 +226,9 @@ <exclude>at/tuwien/utils/**/*</exclude> <exclude>at/tuwien/handlers/**/*</exclude> <exclude>at/tuwien/seeder/**/*</exclude> + <exclude>at/tuwien/auth/**/*</exclude> <exclude>**/HibernateConnector.class</exclude> - <exclude>**/FdaDatabaseManagingApplication.class</exclude> + <exclude>**/DbrepoDatabaseManagingApplication.class</exclude> </excludes> </configuration> <executions> 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 bf74ff488b..68b5a0c1c2 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 @@ -14,6 +14,7 @@ import at.tuwien.entities.user.User; import at.tuwien.exception.*; import at.tuwien.mapper.AccessMapper; import at.tuwien.repository.jpa.*; +import at.tuwien.service.AccessService; import com.rabbitmq.client.Channel; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.Disabled; @@ -33,7 +34,8 @@ import java.util.Optional; import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.when; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; @Log4j2 @SpringBootTest @@ -50,7 +52,7 @@ public class AccessEndpointUnitTest extends BaseUnitTest { private Channel channel; @MockBean - private DatabaseAccessRepository databaseAccessRepository; + private AccessService accessService; @MockBean private DatabaseRepository databaseRepository; @@ -84,6 +86,20 @@ public class AccessEndpointUnitTest extends BaseUnitTest { }); } + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"create-database-access"}) + public void create_succeeds() throws UserNotFoundException, NotAllowedException, QueryMalformedException, + DatabaseNotFoundException, DatabaseMalformedException, AccessDeniedException { + + /* mock */ + doNothing() + .when(accessService) + .create(eq(CONTAINER_1_ID), 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); + } + @Test @WithAnonymousUser public void find_anonymous_fails() { @@ -100,16 +116,16 @@ 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_1_PRINCIPAL); + generic_find(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, null, USER_2_USERNAME, USER_2_ID, USER_2_PRINCIPAL); }); } @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"check-database-access"}) - public void find_hasRoleHasAccess_fails() throws AccessDeniedException, NotAllowedException { + 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_2_USERNAME, USER_2_ID, USER_1_PRINCIPAL); + 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); } @Test @@ -154,13 +170,64 @@ public class AccessEndpointUnitTest extends BaseUnitTest { }); } + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"update-database-access"}) + public void update_succeeds() throws UserNotFoundException, AccessDeniedException, NotAllowedException, + QueryMalformedException, DatabaseNotFoundException, DatabaseMalformedException { + + /* mock */ + when(userRepository.findByUsername(USER_1_USERNAME)) + .thenReturn(Optional.of(USER_1)); + doNothing() + .when(accessService) + .update(eq(CONTAINER_1_ID), 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); + } + + @Test + @WithAnonymousUser + public void revoke_anonymous_fails() { + + /* 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); + }); + } + + @Test + @WithMockUser(username = USER_4_USERNAME) + public void revoke_noRoleNoAccess_fails() { + + /* 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); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"delete-database-access"}) + public void revoke_succeeds() throws UserNotFoundException, NotAllowedException, + QueryMalformedException, DatabaseNotFoundException, DatabaseMalformedException, AccessDeniedException { + + /* mock */ + doNothing() + .when(accessService) + .delete(CONTAINER_1_ID, 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 TEST CASES ## */ /* ################################################################################################### */ protected void generic_create(Long containerId, Long databaseId, Database database, DatabaseAccess access, String username, User user, Principal principal) throws UserNotFoundException, - NotAllowedException, QueryMalformedException, DatabaseNotFoundException, DatabaseMalformedException { + NotAllowedException, QueryMalformedException, DatabaseNotFoundException, DatabaseMalformedException, + AccessDeniedException { final DatabaseGiveAccessDto request = DatabaseGiveAccessDto.builder() .username(username) .type(AccessTypeDto.READ) @@ -171,12 +238,15 @@ public class AccessEndpointUnitTest extends BaseUnitTest { .thenReturn(Optional.of(database)); when(userRepository.findByUsername(username)) .thenReturn(Optional.of(user)); - if (access == null) { - when(databaseAccessRepository.findByDatabaseIdAndUsername(databaseId, username)) - .thenReturn(Optional.empty()); + if (access != null) { + log.trace("mock access {} for user with username {} for database with id {}", access.getType(), username, databaseId); + when(accessService.find(databaseId, username)) + .thenReturn(access); } else { - when(databaseAccessRepository.findByDatabaseIdAndUsername(databaseId, username)) - .thenReturn(Optional.of(access)); + log.trace("mock no access for user with username {} for database with id {}", username, databaseId); + doThrow(AccessDeniedException.class) + .when(accessService) + .find(databaseId, username); } /* test */ @@ -193,17 +263,14 @@ public class AccessEndpointUnitTest extends BaseUnitTest { when(databaseRepository.findById(databaseId)) .thenReturn(Optional.of(database)); if (access != null) { - when(databaseAccessRepository.findByDatabaseIdAndUsername(databaseId, username)) - .thenReturn(Optional.of(access)); - when(databaseAccessRepository.findByDatabaseIdAndUsername(databaseId, principal.getName())) - .thenReturn(Optional.of(DatabaseAccess.builder() - .type(access.getType()) - .hdbid(databaseId) - .huserid(username.equals(USER_1_USERNAME) ? USER_1_ID : USER_2_ID) - .build())); + log.trace("mock access {} for user with username {} for database with id {}", access.getType(), username, databaseId); + when(accessService.find(databaseId, username)) + .thenReturn(access); } else { - when(databaseAccessRepository.findByDatabaseIdAndUsername(databaseId, username)) - .thenReturn(Optional.empty()); + log.trace("mock no access for user with username {} for database with id {}", username, databaseId); + doThrow(AccessDeniedException.class) + .when(accessService) + .find(databaseId, username); } /* test */ @@ -226,12 +293,15 @@ public class AccessEndpointUnitTest extends BaseUnitTest { /* mock */ when(databaseRepository.findById(databaseId)) .thenReturn(Optional.of(database)); - if (access == null) { - when(databaseAccessRepository.findByDatabaseIdAndUsername(databaseId, username)) - .thenReturn(Optional.empty()); + if (access != null) { + log.trace("mock access {} for user with username {} for database with id {}", access.getType(), username, databaseId); + when(accessService.find(databaseId, username)) + .thenReturn(access); } else { - when(databaseAccessRepository.findByDatabaseIdAndUsername(databaseId, username)) - .thenReturn(Optional.of(access)); + log.trace("mock no access for user with username {} for database with id {}", username, databaseId); + doThrow(AccessDeniedException.class) + .when(accessService) + .find(databaseId, username); } /* test */ @@ -240,4 +310,26 @@ public class AccessEndpointUnitTest extends BaseUnitTest { assertNull(response.getBody()); } + protected void generic_revoke(Long containerId, Long databaseId, DatabaseAccess access, String username, + Principal principal) throws AccessDeniedException, NotAllowedException, + UserNotFoundException, QueryMalformedException, DatabaseNotFoundException, DatabaseMalformedException { + + /* mock */ + if (access != null) { + log.trace("mock access {} for user with username {} for database with id {}", access.getType(), username, databaseId); + when(accessService.find(databaseId, username)) + .thenReturn(access); + } else { + log.trace("mock no access for user with username {} for database with id {}", username, databaseId); + doThrow(AccessDeniedException.class) + .when(accessService) + .find(databaseId, username); + } + + /* test */ + final ResponseEntity<?> response = accessEndpoint.revoke(containerId, 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 6b8259fa0f..d73873ade4 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 @@ -11,8 +11,8 @@ import at.tuwien.entities.database.DatabaseAccess; import at.tuwien.exception.*; import at.tuwien.repository.elastic.DatabaseIdxRepository; import at.tuwien.repository.jpa.*; -import at.tuwien.service.MessageQueueService; -import at.tuwien.service.QueryStoreService; +import at.tuwien.service.*; +import at.tuwien.service.impl.MariaDbServiceImpl; import at.tuwien.test.BaseTest; import com.rabbitmq.client.Channel; import lombok.With; @@ -35,8 +35,7 @@ import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; @Log4j2 @SpringBootTest @@ -59,19 +58,22 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { private MessageQueueService messageQueueService; @MockBean - private DatabaseIdxRepository databaseIdxRepository; + private AccessService accessService; @MockBean - private DatabaseAccessRepository databaseAccessRepository; + private ContainerService containerService; + + @MockBean + private MariaDbServiceImpl databaseService; @MockBean private QueryStoreService queryStoreService; @MockBean - private ContainerRepository containerRepository; + private DatabaseIdxRepository databaseIdxRepository; @MockBean - private DatabaseRepository databaseRepository; + private DatabaseAccessRepository databaseAccessRepository; @MockBean private IdentifierRepository identifierRepository; @@ -113,13 +115,15 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { @Test @WithMockUser(username = USER_2_USERNAME, authorities = {"create-database"}) - public void create_hasRoleForeign_fails() { + 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)); @@ -129,6 +133,43 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { }); } + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"create-database"}) + public void create_succeeds() throws UserNotFoundException, BrokerVirtualHostGrantException, + DatabaseNameExistsException, NotAllowedException, ContainerConnectionException, DatabaseMalformedException, + QueryStoreException, DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException, + ImageNotSupportedException, AmqpException, BrokerVirtualHostCreationException, ContainerNotFoundException { + final DatabaseCreateDto request = DatabaseCreateDto.builder() + .name(DATABASE_1_NAME) + .isPublic(DATABASE_1_PUBLIC) + .build(); + + /* mock */ + when(userRepository.findByUsername(USER_1_USERNAME)) + .thenReturn(Optional.of(USER_1)); + when(containerService.find(CONTAINER_1_ID)) + .thenReturn(CONTAINER_1); + when(databaseService.create(CONTAINER_1_ID, request, USER_1_PRINCIPAL)) + .thenReturn(DATABASE_1); + doNothing() + .when(messageQueueService) + .createUser(USER_1); + doNothing() + .when(messageQueueService) + .createExchange(DATABASE_1, USER_1_PRINCIPAL); + doNothing() + .when(messageQueueService) + .updatePermissions(USER_1_PRINCIPAL); + doNothing() + .when(queryStoreService) + .create(CONTAINER_1_ID, 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); + } + @Test @WithAnonymousUser public void list_anonymous_succeeds() { @@ -247,7 +288,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { @Test @WithMockUser(username = USER_2_USERNAME, authorities = {"modify-database-owner"}) - public void transfer_hasRoleForeign_fails() { + public void transfer_hasRoleForeign_fails() throws DatabaseNotFoundException { final DatabaseTransferDto request = DatabaseTransferDto.builder() .username(USER_4_USERNAME) .build(); @@ -255,8 +296,8 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* mock */ when(userRepository.findByUsername(USER_2_USERNAME)) .thenReturn(Optional.of(USER_2)); - when(databaseRepository.findById(DATABASE_1_ID)) - .thenReturn(Optional.of(DATABASE_1)); + when(databaseService.findById(CONTAINER_1_ID, DATABASE_1_ID)) + .thenReturn(DATABASE_1); /* test */ assertThrows(NotAllowedException.class, () -> { @@ -276,8 +317,8 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { .thenReturn(Optional.of(USER_1)); when(userRepository.findByUsername(USER_4_USERNAME)) .thenReturn(Optional.of(USER_4)); - when(databaseRepository.findById(DATABASE_1_ID)) - .thenReturn(Optional.of(DATABASE_1)); + when(databaseService.findById(CONTAINER_1_ID, DATABASE_1_ID)) + .thenReturn(DATABASE_1); /* test */ databaseEndpoint.transfer(CONTAINER_1_ID, DATABASE_1_ID, request, USER_1_PRINCIPAL); @@ -285,7 +326,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"modify-database-owner"}) - public void transfer_hasRoleUserNotExists_succeeds() { + public void transfer_hasRoleUserNotExists_succeeds() throws DatabaseNotFoundException, UserNotFoundException { final DatabaseTransferDto request = DatabaseTransferDto.builder() .username("foobar") .build(); @@ -293,8 +334,11 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* mock */ when(userRepository.findByUsername(USER_1_USERNAME)) .thenReturn(Optional.of(USER_1)); - when(databaseRepository.findById(DATABASE_1_ID)) - .thenReturn(Optional.of(DATABASE_1)); + when(databaseService.findById(CONTAINER_1_ID, DATABASE_1_ID)) + .thenReturn(DATABASE_1); + doThrow(UserNotFoundException.class) + .when(databaseService) + .transfer(CONTAINER_1_ID, DATABASE_1_ID, request); /* test */ assertThrows(UserNotFoundException.class, () -> { @@ -343,6 +387,22 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { findById_generic(CONTAINER_3_ID, CONTAINER_3, DATABASE_3_ID, DATABASE_3, USER_1_PRINCIPAL); } + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"find-database"}) + public void findById_ownerSeesAccessRights_succeeds() throws AccessDeniedException, + DatabaseNotFoundException { + + /* mock */ + when(accessService.list(DATABASE_1_ID)) + .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 List<DatabaseAccessDto> accessList = response.getAccesses(); + assertNotNull(accessList); + assertEquals(2, accessList.size()); + } + @Test @WithAnonymousUser public void delete_anonymous_fails() { @@ -381,12 +441,10 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { public void list_generic(Long containerId, Long databaseId, Container container, List<Database> databases, Principal principal) { /* mock */ - when(containerRepository.findById(containerId)) - .thenReturn(Optional.of(container)); - when(databaseRepository.findAll(containerId)) - .thenReturn(databases); when(identifierRepository.findByDatabaseId(databaseId)) .thenReturn(List.of()); + when(databaseService.findAll(containerId)) + .thenReturn(databases); /* test */ final ResponseEntity<List<DatabaseBriefDto>> response = databaseEndpoint.list(containerId, principal); @@ -403,17 +461,6 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { ImageNotSupportedException, AmqpException, BrokerVirtualHostCreationException, ContainerNotFoundException, BrokerVirtualHostGrantException { /* mock */ - when(containerRepository.findById(containerId)) - .thenReturn(Optional.of(container)); - if (database != null) { - when(databaseRepository.findById(databaseId)) - .thenReturn(Optional.of(database)); - } else { - when(databaseRepository.findById(databaseId)) - .thenReturn(Optional.empty()); - } - when(databaseRepository.save(any(Database.class))) - .thenReturn(database); doNothing() .when(messageQueueService) .createExchange(database, principal); @@ -428,7 +475,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { /* test */ final ResponseEntity<DatabaseBriefDto> response = databaseEndpoint.create(containerId, data, principal); - assertEquals(HttpStatus.ACCEPTED, response.getStatusCode()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); assertNotNull(response.getBody()); } @@ -437,12 +484,16 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { throws NotAllowedException, DatabaseNotFoundException, UserNotFoundException { /* mock */ - when(containerRepository.findById(containerId)) - .thenReturn(Optional.of(container)); - when(databaseRepository.findById(databaseId)) - .thenReturn(Optional.of(database)); - when(databaseRepository.save(any(Database.class))) - .thenReturn(database); + if (database != null) { + when(databaseService.findById(containerId, databaseId)) + .thenReturn(database); + when(databaseService.visibility(containerId, databaseId, data)) + .thenReturn(database); + } else { + doThrow(DatabaseNotFoundException.class) + .when(databaseService) + .findById(containerId, databaseId); + } when(databaseIdxRepository.save(any(DatabaseDto.class))) .thenReturn(dto); @@ -452,29 +503,25 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { assertNotNull(response.getBody()); } - public void findById_generic(Long containerId, Container container, Long databaseId, Database database, - Principal principal) throws DatabaseNotFoundException, AccessDeniedException { + public DatabaseDto findById_generic(Long containerId, Container container, Long databaseId, Database database, + Principal principal) throws DatabaseNotFoundException, AccessDeniedException { /* mock */ - if (container != null) { - when(containerRepository.findById(containerId)) - .thenReturn(Optional.of(container)); - } else { - when(containerRepository.findById(containerId)) - .thenReturn(Optional.empty()); - } if (database != null) { - when(databaseRepository.findById(databaseId)) - .thenReturn(Optional.of(database)); + when(databaseService.findById(containerId, databaseId)) + .thenReturn(database); } else { - when(databaseRepository.findById(databaseId)) - .thenReturn(Optional.empty()); + doThrow(DatabaseNotFoundException.class) + .when(databaseService) + .findById(containerId, databaseId); } /* test */ final ResponseEntity<DatabaseDto> response = databaseEndpoint.findById(containerId, databaseId, principal); assertEquals(HttpStatus.OK, response.getStatusCode()); - assertNotNull(response.getBody()); + final DatabaseDto body = response.getBody(); + assertNotNull(body); + return body; } public void delete_generic(Long containerId, Container container, Long databaseId, Database database, @@ -483,13 +530,13 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { AmqpException, BrokerVirtualHostCreationException, ContainerNotFoundException, DatabaseMalformedException, BrokerVirtualHostGrantException { /* mock */ - when(containerRepository.findById(containerId)) - .thenReturn(Optional.of(container)); - when(databaseRepository.findById(databaseId)) - .thenReturn(Optional.of(database)); - if (username != null) { - when(databaseRepository.findPublicOrMine(containerId, databaseId, username)) - .thenReturn(Optional.of(database)); + if (database != null) { + when(databaseService.findById(containerId, databaseId)) + .thenReturn(database); + } else { + doThrow(DatabaseNotFoundException.class) + .when(databaseService) + .findById(containerId, databaseId); } /* test */ 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 866ae4ae48..4d920fbbbe 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 @@ -102,6 +102,21 @@ public class BrokerServiceGatewayTest extends BaseUnitTest { brokerServiceGateway.grantPermission(USER_1_USERNAME, VIRTUAL_HOST_EXCHANGE_UPDATE_DTO); } + @Test + public void grantPermission_invalidResponseCode_fails() { + final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .build(); + + /* mock */ + when(restTemplate.exchange(any(URI.class), eq(HttpMethod.PUT), any(HttpEntity.class), eq(Void.class))) + .thenReturn(mock); + + /* test */ + assertThrows(BrokerVirtualHostGrantException.class, () -> { + brokerServiceGateway.grantPermission(USER_1_USERNAME, VIRTUAL_HOST_EXCHANGE_UPDATE_DTO); + }); + } + @Test public void grantPermission_virtualHostNoRightsBefore_succeeds() throws BrokerVirtualHostGrantException { final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.CREATED) @@ -128,4 +143,47 @@ public class BrokerServiceGatewayTest extends BaseUnitTest { brokerServiceGateway.grantPermission(USER_1_USERNAME, VIRTUAL_HOST_GRANT_DTO); } + @Test + public void grantPermission_invalidResponseCode2_fails() { + final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.ACCEPTED) + .build(); + + /* mock */ + when(restTemplate.exchange(any(URI.class), eq(HttpMethod.PUT), any(HttpEntity.class), eq(Void.class))) + .thenReturn(mock); + + /* test */ + assertThrows(BrokerVirtualHostGrantException.class, () -> { + brokerServiceGateway.grantPermission(USER_1_USERNAME, VIRTUAL_HOST_GRANT_DTO); + }); + } + + @Test + public void createUser_succeeds() throws BrokerVirtualHostCreationException { + final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.NO_CONTENT) + .build(); + + /* mock */ + when(restTemplate.exchange(anyString(), eq(HttpMethod.PUT), any(HttpEntity.class), eq(Void.class))) + .thenReturn(mock); + + /* test */ + brokerServiceGateway.createUser(USER_1_USERNAME); + } + + @Test + public void createUser_invalidResponseCode_fails() { + final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.ACCEPTED) + .build(); + + /* mock */ + when(restTemplate.exchange(anyString(), eq(HttpMethod.PUT), any(HttpEntity.class), eq(Void.class))) + .thenReturn(mock); + + /* test */ + assertThrows(BrokerVirtualHostCreationException.class, () -> { + brokerServiceGateway.createUser(USER_1_USERNAME); + }); + } + } 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 85c0e90563..dde3a3f802 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 @@ -3,13 +3,15 @@ package at.tuwien.service; import at.tuwien.BaseUnitTest; 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.entities.user.User; -import at.tuwien.exception.QueryMalformedException; +import at.tuwien.exception.*; import at.tuwien.repository.elastic.DatabaseIdxRepository; import at.tuwien.repository.jpa.*; import at.tuwien.service.impl.MariaDbServiceImpl; @@ -73,8 +75,8 @@ 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 @@ -96,9 +98,9 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest { /* metadata database */ imageRepository.save(IMAGE_1); realmRepository.save(REALM_DBREPO); - userRepository.save(USER_1_SIMPLE); - userRepository.save(USER_2_SIMPLE); - userRepository.save(USER_3_SIMPLE); + userRepository.save(USER_1); + userRepository.save(USER_2); + userRepository.save(USER_3); } @AfterEach @@ -257,6 +259,51 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest { generic_user_insert("junit1", "junit1"); } + @Test + public void delete_succeeds() throws InterruptedException, QueryMalformedException, UserNotFoundException, + DatabaseConnectionException, DatabaseNotFoundException, ImageNotSupportedException, + ContainerNotFoundException, DatabaseMalformedException { + + /* mock */ + DockerConfig.createContainer(BIND_WEATHER, CONTAINER_1_SIMPLE, CONTAINER_1_ENV); + DockerConfig.startContainer(CONTAINER_1_SIMPLE); + containerRepository.save(CONTAINER_1); + databaseRepository.save(DATABASE_1); + + /* test */ + databaseService.delete(CONTAINER_1_ID, DATABASE_1_ID, USER_1_PRINCIPAL); + } + + @Test + public void visibility_succeeds() throws DatabaseNotFoundException { + final DatabaseModifyVisibilityDto request = DatabaseModifyVisibilityDto.builder() + .isPublic(true) + .build(); + + /* mock */ + containerRepository.save(CONTAINER_1_SIMPLE); + databaseRepository.save(DATABASE_1); + + /* test */ + final Database response = databaseService.visibility(CONTAINER_1_ID, DATABASE_1_ID, request); + assertTrue(response.getIsPublic()); + } + + @Test + public void transfer_succeeds() throws DatabaseNotFoundException, UserNotFoundException { + final DatabaseTransferDto request = DatabaseTransferDto.builder() + .username(USER_2_USERNAME) + .build(); + + /* mock */ + containerRepository.save(CONTAINER_1_SIMPLE); + databaseRepository.save(DATABASE_1); + + /* test */ + final Database response = databaseService.transfer(CONTAINER_1_ID, DATABASE_1_ID, request); + assertEquals(USER_2_ID, response.getOwnedBy()); + } + /* ################################################################################################### */ /* ## GENERIC TEST CASES ## */ /* ################################################################################################### */ 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 new file mode 100644 index 0000000000..d442fccb1b --- /dev/null +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/IdentifierServiceIntegrationTest.java @@ -0,0 +1,98 @@ +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.entities.identifier.Identifier; +import at.tuwien.entities.identifier.IdentifierType; +import at.tuwien.exception.AmqpException; +import at.tuwien.exception.IdentifierNotFoundException; +import at.tuwien.gateway.BrokerServiceGateway; +import at.tuwien.repository.jpa.*; +import at.tuwien.service.impl.RabbitMqServiceImpl; +import at.tuwien.utils.AmqpUtils; +import com.rabbitmq.client.Channel; +import lombok.extern.log4j.Log4j2; +import org.apache.http.auth.BasicUserPrincipal; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +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 java.security.Principal; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.when; + +@Log4j2 +@SpringBootTest +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@ExtendWith(SpringExtension.class) +public class IdentifierServiceIntegrationTest extends BaseUnitTest { + + @MockBean + private ReadyConfig readyConfig; + + @MockBean + private IndexConfig indexConfig; + + @MockBean + private Channel channel; + + @Autowired + private RealmRepository realmRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private ContainerRepository containerRepository; + + @Autowired + private ImageRepository imageRepository; + + @Autowired + private DatabaseRepository databaseRepository; + + @Autowired + private IdentifierRepository identifierRepository; + + @Autowired + private IdentifierService identifierService; + + @BeforeEach + public void beforeEach() { + realmRepository.save(REALM_DBREPO); + userRepository.save(USER_1); + imageRepository.save(IMAGE_1); + containerRepository.save(CONTAINER_1_SIMPLE); + databaseRepository.save(DATABASE_1_SIMPLE); + identifierRepository.save(IDENTIFIER_1); + } + + @Test + public void findAll_succeeds() { + + /* test */ + final List<Identifier> response = identifierService.findAll(DATABASE_1_ID); + assertEquals(1, response.size()); + } + + @Test + public void find_notFound_fails() { + + /* test */ + final List<Identifier> response = identifierService.findAll(DATABASE_2_ID); + assertEquals(0, response.size()); + } + + +} 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 new file mode 100644 index 0000000000..98ae89f241 --- /dev/null +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/LicenseServiceIntegrationTest.java @@ -0,0 +1,76 @@ +package at.tuwien.service; + +import at.tuwien.BaseUnitTest; +import at.tuwien.config.IndexConfig; +import at.tuwien.config.ReadyConfig; +import at.tuwien.entities.database.License; +import at.tuwien.entities.identifier.Identifier; +import at.tuwien.exception.LicenseNotFoundException; +import at.tuwien.repository.jpa.*; +import com.rabbitmq.client.Channel; +import lombok.extern.log4j.Log4j2; +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 java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@Log4j2 +@SpringBootTest +@ExtendWith(SpringExtension.class) +public class LicenseServiceIntegrationTest extends BaseUnitTest { + + @MockBean + private ReadyConfig readyConfig; + + @MockBean + private IndexConfig indexConfig; + + @MockBean + private Channel channel; + + @Autowired + private LicenseRepository licenseRepository; + + @Autowired + private LicenseService licenseService; + + @BeforeEach + public void beforeEach() { + licenseRepository.save(LICENSE_1); + } + + @Test + public void findAll_succeeds() { + + /* test */ + final List<License> response = licenseService.findAll(); + assertEquals(1, response.size()); + } + + @Test + public void find_succeeds() throws LicenseNotFoundException { + + /* test */ + final License response = licenseService.find(LICENSE_1_IDENTIFIER); + assertEquals(LICENSE_1_IDENTIFIER, response.getIdentifier()); + } + + @Test + public void find_fails() { + + /* test */ + assertThrows(LicenseNotFoundException.class, () -> { + licenseService.find("CC0"); + }); + } + +} diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/AmqpServiceIntegrationTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java similarity index 75% rename from dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/AmqpServiceIntegrationTest.java rename to dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java index 5912c4ea9d..17e63a0882 100644 --- a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/AmqpServiceIntegrationTest.java +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java @@ -5,6 +5,8 @@ import at.tuwien.config.DockerConfig; import at.tuwien.config.IndexConfig; import at.tuwien.config.ReadyConfig; import at.tuwien.exception.AmqpException; +import at.tuwien.exception.BrokerVirtualHostCreationException; +import at.tuwien.exception.BrokerVirtualHostGrantException; import at.tuwien.gateway.BrokerServiceGateway; import at.tuwien.repository.jpa.DatabaseRepository; import at.tuwien.service.impl.RabbitMqServiceImpl; @@ -24,14 +26,13 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import java.security.Principal; import java.util.List; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.when; @Log4j2 @SpringBootTest @ExtendWith(SpringExtension.class) -public class AmqpServiceIntegrationTest extends BaseUnitTest { +public class MessageQueueServiceIntegrationTest extends BaseUnitTest { @MockBean private ReadyConfig readyConfig; @@ -49,7 +50,7 @@ public class AmqpServiceIntegrationTest extends BaseUnitTest { private Channel channel; @Autowired - private RabbitMqServiceImpl amqpService; + private RabbitMqServiceImpl messageQueueService; @Autowired private AmqpUtils amqpUtils; @@ -71,10 +72,9 @@ public class AmqpServiceIntegrationTest extends BaseUnitTest { @Test public void createExchange_succeeds() throws AmqpException { - final Principal principal = new BasicUserPrincipal(USER_1_USERNAME); /* test */ - amqpService.createExchange(DATABASE_1, principal); + messageQueueService.createExchange(DATABASE_1, USER_1_PRINCIPAL); assertTrue(amqpUtils.exchangeExists(DATABASE_1_EXCHANGE)); } @@ -82,10 +82,24 @@ public class AmqpServiceIntegrationTest extends BaseUnitTest { public void deleteExchange_succeeds() throws AmqpException { /* test */ - amqpService.deleteExchange(DATABASE_1); + messageQueueService.deleteExchange(DATABASE_1); assertFalse(amqpUtils.exchangeExists(DATABASE_1_EXCHANGE)); } + @Test + public void createUser_succeeds() throws BrokerVirtualHostCreationException { + + /* test */ + messageQueueService.createUser(USER_1); + } + + @Test + public void updatePermissions_succeeds() throws BrokerVirtualHostGrantException { + + /* test */ + messageQueueService.updatePermissions(USER_1_PRINCIPAL); + } + @Test public void init_succeeds() throws AmqpException { @@ -95,7 +109,7 @@ public class AmqpServiceIntegrationTest extends BaseUnitTest { /* test */ assertFalse(amqpUtils.exchangeExists(DATABASE_1_EXCHANGE)); - amqpService.init(); + messageQueueService.init(); assertTrue(amqpUtils.exchangeExists(DATABASE_1_EXCHANGE)); } 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 new file mode 100644 index 0000000000..b01dcfbd68 --- /dev/null +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceUnitTest.java @@ -0,0 +1,82 @@ +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; +import at.tuwien.gateway.BrokerServiceGateway; +import at.tuwien.repository.jpa.DatabaseRepository; +import at.tuwien.service.impl.RabbitMqServiceImpl; +import at.tuwien.utils.AmqpUtils; +import com.rabbitmq.client.BuiltinExchangeType; +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.context.junit.jupiter.SpringExtension; + +import java.io.IOException; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.when; + +@Log4j2 +@SpringBootTest +@ExtendWith(SpringExtension.class) +public class MessageQueueServiceUnitTest extends BaseUnitTest { + + @MockBean + private ReadyConfig readyConfig; + + @MockBean + private IndexConfig indexConfig; + + @MockBean + private DatabaseRepository databaseRepository; + + @MockBean + private BrokerServiceGateway brokerServiceGateway; + + @MockBean + private Channel channel; + + @Autowired + private RabbitMqServiceImpl messageQueueService; + + @Test + public void createExchange_fails() throws IOException { + + /* mock */ + doThrow(IOException.class) + .when(channel) + .exchangeDeclare(DATABASE_1_EXCHANGE, BuiltinExchangeType.DIRECT, true); + + /* test */ + assertThrows(AmqpException.class, () -> { + messageQueueService.createExchange(DATABASE_1, USER_1_PRINCIPAL); + }); + } + + @Test + public void deleteExchange_fails() throws IOException { + + /* mock */ + doThrow(IOException.class) + .when(channel) + .exchangeDelete(DATABASE_1_EXCHANGE); + + /* test */ + assertThrows(AmqpException.class, () -> { + messageQueueService.deleteExchange(DATABASE_1); + }); + } + +} 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 new file mode 100644 index 0000000000..47b5ac1742 --- /dev/null +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/QueryStoreServiceIntegrationTest.java @@ -0,0 +1,111 @@ +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.entities.user.User; +import at.tuwien.exception.*; +import at.tuwien.mapper.DatabaseMapper; +import at.tuwien.repository.jpa.*; +import at.tuwien.service.impl.HibernateConnector; +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.AfterAll; +import org.junit.jupiter.api.BeforeAll; +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 java.sql.Connection; +import java.sql.SQLException; + +@Log4j2 +@SpringBootTest +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@ExtendWith(SpringExtension.class) +public class QueryStoreServiceIntegrationTest extends BaseUnitTest { + + @MockBean + private ReadyConfig readyConfig; + + @MockBean + private IndexConfig indexConfig; + + @MockBean + private Channel channel; + + @Autowired + private RealmRepository realmRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private ContainerRepository containerRepository; + + @Autowired + private ImageRepository imageRepository; + + @Autowired + private DatabaseRepository databaseRepository; + + @Autowired + private QueryStoreServiceImpl queryStoreService; + + @Autowired + private DatabaseMapper databaseMapper; + + @BeforeAll + public static void beforeAll() throws InterruptedException { + /* create network */ + DockerConfig.createAllNetworks(); + /* create container */ + DockerConfig.createContainer(null, CONTAINER_1, CONTAINER_1_ENV); + DockerConfig.startContainer(CONTAINER_1); + } + + @BeforeEach + public void beforeEach() { + realmRepository.save(REALM_DBREPO); + userRepository.save(USER_1); + imageRepository.save(IMAGE_1); + containerRepository.save(CONTAINER_1_SIMPLE); + databaseRepository.save(DATABASE_1_SIMPLE); + } + + @AfterAll + public static void afterAll() { + DockerConfig.removeAllContainers(); + DockerConfig.removeAllNetworks(); + } + + @Test + public void create_succeeds() throws UserNotFoundException, QueryStoreException, DatabaseConnectionException, + DatabaseNotFoundException, DatabaseMalformedException { + + /* test */ + queryStoreService.create(CONTAINER_1_ID, DATABASE_1_ID, USER_1_PRINCIPAL); + } + + @Test + public void executeQuery_succeeds() throws SQLException { + final User root = databaseMapper.containerToPrivilegedUser(CONTAINER_1); + final ComboPooledDataSource dataSource = HibernateConnector.getDataSource(CONTAINER_1_IMAGE, CONTAINER_1, DATABASE_1, root); + + /* test */ + try { + final Connection connection = dataSource.getConnection(); + queryStoreService.executeQuery(connection, "SELECT 1"); + } finally { + dataSource.close(); + } + } +} diff --git a/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java new file mode 100644 index 0000000000..6c4c0d0b74 --- /dev/null +++ b/dbrepo-database-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java @@ -0,0 +1,92 @@ +package at.tuwien.service; + +import at.tuwien.BaseUnitTest; +import at.tuwien.config.IndexConfig; +import at.tuwien.config.ReadyConfig; +import at.tuwien.entities.database.License; +import at.tuwien.entities.user.User; +import at.tuwien.exception.LicenseNotFoundException; +import at.tuwien.exception.UserNotFoundException; +import at.tuwien.repository.jpa.LicenseRepository; +import at.tuwien.repository.jpa.RealmRepository; +import at.tuwien.repository.jpa.UserRepository; +import com.rabbitmq.client.Channel; +import lombok.extern.log4j.Log4j2; +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.context.junit.jupiter.SpringExtension; + +import java.util.List; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@Log4j2 +@SpringBootTest +@ExtendWith(SpringExtension.class) +public class UserServiceIntegrationTest extends BaseUnitTest { + + @MockBean + private ReadyConfig readyConfig; + + @MockBean + private IndexConfig indexConfig; + + @MockBean + private Channel channel; + + @Autowired + private RealmRepository realmRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private UserService userService; + + @BeforeEach + public void beforeEach() { + realmRepository.save(REALM_DBREPO); + userRepository.save(USER_1); + } + + @Test + public void findByUsername_succeeds() throws UserNotFoundException { + + /* test */ + final User response = userService.findByUsername(USER_1_USERNAME); + assertEquals(USER_1_ID, response.getId()); + } + + @Test + public void findByUsername_fails() { + + /* test */ + assertThrows(UserNotFoundException.class, () -> { + userService.findByUsername("notexisting"); + }); + } + + @Test + public void find_succeeds() throws UserNotFoundException { + + /* test */ + final User response = userService.find(USER_1_ID); + assertEquals(USER_1_ID, response.getId()); + } + + @Test + public void find_fails() { + + /* test */ + assertThrows(UserNotFoundException.class, () -> { + userService.find(UUID.fromString("deadbeef-20bc-4191-acb2-77a3afcae32f")); + }); + } + +} 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 6b5efff253..e10324b97a 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 @@ -5,10 +5,12 @@ import at.tuwien.api.database.DatabaseModifyVisibilityDto; import at.tuwien.api.database.DatabaseTransferDto; import at.tuwien.entities.database.Database; import at.tuwien.exception.*; +import org.springframework.stereotype.Service; import java.security.Principal; import java.util.List; +@Service public interface DatabaseService { /** 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 a60abddb2b..2059be0057 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 @@ -9,7 +9,12 @@ import java.util.List; @Service public interface IdentifierService { - List<Identifier> findAll(Long databaseId); - Identifier find(Long databaseId, IdentifierType type) throws IdentifierNotFoundException; + /** + * Finds all identifiers in the metadata database for a database with given id. + * + * @param databaseId The database id. + * @return The list of identifiers. + */ + List<Identifier> findAll(Long databaseId); } 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 4762de2c24..308ebfed90 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 @@ -6,5 +6,17 @@ import java.security.Principal; public interface QueryStoreService { + /** + * Creates the query store in the database with given container id. + * + * @param containerId The container id. + * @param databaseId The database id. + * @param principal The principal of the user. + * @throws DatabaseNotFoundException + * @throws DatabaseConnectionException + * @throws DatabaseMalformedException + * @throws UserNotFoundException + * @throws QueryStoreException + */ void create(Long containerId, Long databaseId, Principal principal) throws DatabaseNotFoundException, DatabaseConnectionException, DatabaseMalformedException, UserNotFoundException, QueryStoreException; } 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 39532d8463..b5629aa17a 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 @@ -12,11 +12,11 @@ import org.springframework.stereotype.Service; @Service public abstract class HibernateConnector { - protected static ComboPooledDataSource getDataSource(ContainerImage image, Container container, User user) { + public static ComboPooledDataSource getDataSource(ContainerImage image, Container container, User user) { return getDataSource(image, container, null, user); } - protected static ComboPooledDataSource getDataSource(ContainerImage image, Container container, Database database, + public static ComboPooledDataSource getDataSource(ContainerImage image, Container container, Database database, User user) { final ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setJdbcUrl(url(image, container, database)); diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java b/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java index 988e18fb8c..687a630b49 100644 --- a/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java +++ b/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java @@ -28,13 +28,4 @@ public class IdentifierServiceImpl implements IdentifierService { return identifierRepository.findByDatabaseId(databaseId); } - @Override - public Identifier find(Long databaseId, IdentifierType type) throws IdentifierNotFoundException { - final Optional<Identifier> optional = identifierRepository.findByDatabaseIdAndType(databaseId, type); - if (optional.isEmpty()) { - throw new IdentifierNotFoundException("Failed to find identifier"); - } - return optional.get(); - } - } 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 69b821408c..3723ccaae8 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 @@ -65,8 +65,8 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe database = databaseRepository.findPublicOrMine(containerId, databaseId, principal.getName()); } if (database.isEmpty()) { - log.error("Failed to find database"); - throw new DatabaseNotFoundException("Failed to find database"); + log.error("Failed to find database with id {}", databaseId); + throw new DatabaseNotFoundException("Failed to find database with id "+ databaseId); } return database.get(); } @@ -77,7 +77,7 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe final Optional<Database> database = databaseRepository.findById(databaseId); if (database.isEmpty()) { log.error("Failed to find database with id {}", databaseId); - throw new DatabaseNotFoundException("could not find database with this id"); + throw new DatabaseNotFoundException("could not find database with id " + databaseId); } return database.get(); } @@ -180,6 +180,7 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe } @Override + @Transactional public Database transfer(Long containerId, Long databaseId, DatabaseTransferDto transferDto) throws DatabaseNotFoundException, UserNotFoundException { /* check */ 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 d0d8d1e78d..9c3eac20db 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 @@ -11,6 +11,7 @@ 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.io.IOException; import java.security.Principal; @@ -32,6 +33,7 @@ public class QueryStoreServiceImpl extends HibernateConnector implements QuerySt } @Override + @Transactional(rollbackFor = DatabaseMalformedException.class) public void create(Long containerId, Long databaseId, Principal principal) throws DatabaseNotFoundException, DatabaseConnectionException, DatabaseMalformedException, UserNotFoundException, QueryStoreException { final Database database = databaseService.findById(containerId, databaseId); @@ -56,19 +58,10 @@ public class QueryStoreServiceImpl extends HibernateConnector implements QuerySt log.trace("created query store in database {}", database); } - private void executeQuery(Connection connection, String statement, String... data) throws SQLException { + public void executeQuery(Connection connection, String statement) throws SQLException { log.debug("execute query, statement={}", statement); final PreparedStatement pstmt = connection.prepareStatement(statement); - if (data.length > 0) { - for (int i = 0; i < data.length; i++) { - pstmt.setString(i, data[i]); - } - } pstmt.executeUpdate(); } - private void executeQuery(Connection connection, String statement) throws SQLException { - executeQuery(connection, statement, new String[]{}); - } - } diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/container/Container.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/container/Container.java index 9fb7d40bbf..c2e510881d 100644 --- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/container/Container.java +++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/container/Container.java @@ -38,7 +38,7 @@ public class Container { @Type(type = "uuid-char") private UUID createdBy; - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) @JoinColumns({ @JoinColumn(name = "createdBy", referencedColumnName = "ID", insertable = false, updatable = false) }) @@ -49,7 +49,7 @@ public class Container { @Type(type = "uuid-char") private UUID ownedBy; - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) @JoinColumns({ @JoinColumn(name = "ownedBy", referencedColumnName = "ID", insertable = false, updatable = false) }) @@ -72,7 +72,7 @@ public class Container { @ToString.Exclude @org.springframework.data.annotation.Transient - @OneToOne(fetch = FetchType.LAZY) + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumns({ @JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false) }) diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/Database.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/Database.java index c02cf1a3ca..01c7386123 100644 --- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/Database.java +++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/Database.java @@ -41,7 +41,7 @@ public class Database implements Serializable { private UUID createdBy; @Type(type = "uuid-char") - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) @JoinColumns({ @JoinColumn(name = "created_by", referencedColumnName = "ID", insertable = false, updatable = false) }) @@ -52,7 +52,7 @@ public class Database implements Serializable { @Type(type = "uuid-char") private UUID ownedBy; - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) @JoinColumns({ @JoinColumn(name = "owned_by", referencedColumnName = "ID", insertable = false, updatable = false) }) @@ -60,7 +60,7 @@ public class Database implements Serializable { @ToString.Exclude @org.springframework.data.annotation.Transient - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) @JoinColumns({ @JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false) }) @@ -84,13 +84,13 @@ public class Database implements Serializable { private UUID contactPerson; @Type(type = "uuid-char") - @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) + @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST) @JoinColumns({ @JoinColumn(name = "contact_person", referencedColumnName = "ID", updatable = false, insertable = false) }) private User contact; - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) @JoinColumnsOrFormulas({ @JoinColumnOrFormula(formula = @JoinFormula(value = "'DATABASE'", referencedColumnName = "identifier_type")), @JoinColumnOrFormula(column = @JoinColumn(name = "id", referencedColumnName = "dbid", insertable = false, updatable = false)), @@ -99,7 +99,7 @@ public class Database implements Serializable { @ToString.Exclude @org.springframework.data.annotation.Transient - @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE) + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumns({ @JoinColumn(name = "tdbid", referencedColumnName = "id", insertable = false, updatable = false) }) @@ -107,7 +107,7 @@ public class Database implements Serializable { @ToString.Exclude @org.springframework.data.annotation.Transient - @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE) + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumns({ @JoinColumn(name = "vdbid", referencedColumnName = "id", insertable = false, updatable = false) }) diff --git a/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java index a3284343c9..1442173ab7 100644 --- a/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java +++ b/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java @@ -4204,7 +4204,7 @@ public abstract class BaseTest { public final static String IDENTIFIER_1_NORMALIZED = QUERY_1_STATEMENT; public final static Long IDENTIFIER_1_RESULT_NUMBER = QUERY_1_RESULT_NUMBER; public final static String IDENTIFIER_1_PUBLISHER = "Austrian Government"; - public final static IdentifierType IDENTIFIER_1_TYPE = IdentifierType.SUBSET; + public final static IdentifierType IDENTIFIER_1_TYPE = IdentifierType.DATABASE; public final static IdentifierTypeDto IDENTIFIER_1_TYPE_DTO = IdentifierTypeDto.DATABASE; public final static UUID IDENTIFIER_1_CREATED_BY = USER_1_ID; public final static User IDENTIFIER_1_CREATOR = USER_1; -- GitLab