diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/ControllerAdvice.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/ControllerAdvice.java index 92ad6a8..d0ca088 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/ControllerAdvice.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/controller/ControllerAdvice.java @@ -26,7 +26,7 @@ public class ControllerAdvice { @ExceptionHandler(ResponseStatusException.class) public ResponseEntity handleResponseStatusException(ResponseStatusException e) { - return new ResponseEntity<>(new ErrorMessage(e.getMessage()), e.getStatusCode()); + return new ResponseEntity<>(new ErrorMessage(e.getReason()), e.getStatusCode()); } } diff --git a/src/main/java/com/knecon/fforesight/tenantusermanagement/service/TenantManagementService.java b/src/main/java/com/knecon/fforesight/tenantusermanagement/service/TenantManagementService.java index 8d6256c..ed5e562 100644 --- a/src/main/java/com/knecon/fforesight/tenantusermanagement/service/TenantManagementService.java +++ b/src/main/java/com/knecon/fforesight/tenantusermanagement/service/TenantManagementService.java @@ -366,6 +366,10 @@ public class TenantManagementService implements TenantProvider { public TenantResponse updateTenant(String tenantId, TenantRequest tenantRequest) { + if (tenantRequest.getS3StorageConnection() != null && tenantRequest.getAzureStorageConnection() != null) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Not possible to set both azure and s3 connection, please only specify one"); + } + var tenant = tenantRepository.findById(tenantId); if (tenant.isPresent()) { var tenantEntity = tenant.get(); @@ -401,15 +405,23 @@ public class TenantManagementService implements TenantProvider { var azureStorageConnection = tenantRequest.getAzureStorageConnection(); if (azureStorageConnection != null) { + if (tenantEntity.getS3StorageConnection() != null) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Not possible to set both azure and s3 connection, please only specify one"); + } testAzureConnection(azureStorageConnection.getConnectionString(), azureStorageConnection.getContainerName()); tenantEntity.setAzureStorageConnection(AzureStorageConnectionEntity.builder() .connectionString(encryptionService.encrypt(azureStorageConnection.getConnectionString())) .containerName(azureStorageConnection.getContainerName()) .build()); + } else { + tenantEntity.setAzureStorageConnection(null); } var s3StorageConnection = tenantRequest.getS3StorageConnection(); if (s3StorageConnection != null) { + if (tenantEntity.getAzureStorageConnection() != null) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Not possible to set both azure and s3 connection, please only specify one"); + } testS3Connection(s3StorageConnection); tenantEntity.setS3StorageConnection(S3StorageConnectionEntity.builder() .key(s3StorageConnection.getKey()) @@ -419,6 +431,8 @@ public class TenantManagementService implements TenantProvider { .region(s3StorageConnection.getRegion()) .endpoint(s3StorageConnection.getEndpoint()) .build()); + } else { + tenantEntity.setS3StorageConnection(null); } return convert(tenantRepository.save(tenantEntity)); @@ -454,7 +468,6 @@ public class TenantManagementService implements TenantProvider { .database(entity.getDatabaseConnection().getDatabase()) .schema(entity.getDatabaseConnection().getSchema()) .username(entity.getDatabaseConnection().getUsername()) - .password(entity.getDatabaseConnection().getPassword()) .params(entity.getDatabaseConnection().getParams()) .build()) .searchConnection(SearchConnection.builder() @@ -462,7 +475,6 @@ public class TenantManagementService implements TenantProvider { .port(entity.getSearchConnection().getPort()) .scheme(entity.getSearchConnection().getScheme()) .username(entity.getSearchConnection().getUsername()) - .password(entity.getSearchConnection().getPassword()) .numberOfShards(entity.getSearchConnection().getNumberOfShards()) .numberOfReplicas(entity.getSearchConnection().getNumberOfReplicas()) .build()) diff --git a/src/test/java/com/knecon/fforesight/AbstractTenantUserManagementIntegrationTest.java b/src/test/java/com/knecon/fforesight/AbstractTenantUserManagementIntegrationTest.java index 8034a39..3991da8 100644 --- a/src/test/java/com/knecon/fforesight/AbstractTenantUserManagementIntegrationTest.java +++ b/src/test/java/com/knecon/fforesight/AbstractTenantUserManagementIntegrationTest.java @@ -1,5 +1,7 @@ package com.knecon.fforesight; +import java.io.IOException; + import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; @@ -24,10 +26,12 @@ import com.knecon.fforesight.feigntestclients.external.TenantsClient; import com.knecon.fforesight.feigntestclients.internal.InternalTenantsClient; import com.knecon.fforesight.tenantusermanagement.TenantUserManagementServiceApplication; import com.knecon.fforesight.testcontainers.KeyCloakTestContainer; +import com.knecon.fforesight.testcontainers.MinioTestContainer; import com.knecon.fforesight.testcontainers.RedisTestContainer; import com.knecon.fforesight.testcontainers.SpringPostgreSQLTestContainer; import com.knecon.fforesight.utils.TestTenantService; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @ExtendWith(SpringExtension.class) @@ -49,16 +53,6 @@ public class AbstractTenantUserManagementIntegrationTest { public static int minioPort; - @BeforeAll - static void setupMinioContainer() { - minioServer = new GenericContainer("minio/minio") - .withEnv("MINIO_ACCESS_KEY", "minioadmin") - .withEnv("MINIO_SECRET_KEY", "minioadmin") - .withCommand("server /entity") - .withExposedPorts(9000); - minioServer.start(); - minioPort = minioServer.getFirstMappedPort(); - } @BeforeEach public void createTestTenant(){ @@ -68,6 +62,7 @@ public class AbstractTenantUserManagementIntegrationTest { @Slf4j static class Initializer implements ApplicationContextInitializer { + @SneakyThrows public void initialize(ConfigurableApplicationContext configurableApplicationContext) { var postgreSQLContainerMaster = SpringPostgreSQLTestContainer.getInstance().withDatabaseName("integration-tests-db-master").withUsername("sa").withPassword("sa"); @@ -90,6 +85,11 @@ public class AbstractTenantUserManagementIntegrationTest { "fforesight.jobs.enabled=false", "fforesight.keycloak.enabled=true").applyTo(configurableApplicationContext.getEnvironment()); + var minioInstance = MinioTestContainer.getInstance(); + minioInstance.start(); + minioInstance.execInContainer("mc mb --with-locks redaction2"); + minioPort = minioInstance.getFirstMappedPort(); + } } diff --git a/src/test/java/com/knecon/fforesight/testcontainers/MinioTestContainer.java b/src/test/java/com/knecon/fforesight/testcontainers/MinioTestContainer.java new file mode 100644 index 0000000..fc9e082 --- /dev/null +++ b/src/test/java/com/knecon/fforesight/testcontainers/MinioTestContainer.java @@ -0,0 +1,27 @@ +package com.knecon.fforesight.testcontainers; + +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; + +public final class MinioTestContainer extends GenericContainer { + + private static final String IMAGE_VERSION = "minio/minio"; + private static MinioTestContainer container; + + private MinioTestContainer() { + + super(DockerImageName.parse(IMAGE_VERSION)); + } + + + public static MinioTestContainer getInstance() { + + if (container == null) { + container = new MinioTestContainer().withEnv("MINIO_ACCESS_KEY", "minioadmin") + .withEnv("MINIO_SECRET_KEY", "minioadmin") + .withCommand("server /entity") + .withExposedPorts(9000); + } + return container; + } +} diff --git a/src/test/java/com/knecon/fforesight/tests/TenantsTest.java b/src/test/java/com/knecon/fforesight/tests/TenantsTest.java index e2579ce..91079b5 100644 --- a/src/test/java/com/knecon/fforesight/tests/TenantsTest.java +++ b/src/test/java/com/knecon/fforesight/tests/TenantsTest.java @@ -80,16 +80,35 @@ public class TenantsTest extends AbstractTenantUserManagementIntegrationTest { .password("updated_pwd") .username("updated_username") .build()) + .s3StorageConnection(S3StorageConnection.builder() + .key("minioadmin") + .secret("minioadmin") + .bucketName("redaction2") + .endpoint("http://localhost:" + minioPort).build()) .build(); - var tenantEntity = tenantsClient.updateTenant("new_tenant", tenantRequest); + var updatedTenant = tenantsClient.updateTenant("new_tenant", tenantRequest); - tenantRequest.getSearchConnection().setPassword(encryptionService.encrypt("updated_pwd")); - tenantRequest.getDatabaseConnection().setPassword(encryptionService.encrypt("updated_pwd")); + tenantRequest.getSearchConnection().setPassword(null); + tenantRequest.getDatabaseConnection().setPassword(null); + + assertThat(updatedTenant.getDisplayName()).isEqualTo(tenantRequest.getDisplayName()); + assertThat(updatedTenant.getSearchConnection()).isEqualTo(tenantRequest.getSearchConnection()); + assertThat(updatedTenant.getDatabaseConnection()).isEqualTo(tenantRequest.getDatabaseConnection()); + assertThat(updatedTenant.getS3StorageConnection().getBucketName()).isEqualTo("redaction2"); + + var tenantEntity = tenantsClient.getTenant("new_tenant"); assertThat(tenantEntity.getDisplayName()).isEqualTo(tenantRequest.getDisplayName()); assertThat(tenantEntity.getSearchConnection()).isEqualTo(tenantRequest.getSearchConnection()); assertThat(tenantEntity.getDatabaseConnection()).isEqualTo(tenantRequest.getDatabaseConnection()); + assertThat(tenantEntity.getS3StorageConnection().getBucketName()).isEqualTo("redaction2"); + + tenantRequest.setS3StorageConnection(null); + + updatedTenant = tenantsClient.updateTenant("new_tenant", tenantRequest); + + assertThat(updatedTenant.getS3StorageConnection()).isNull(); TenantContext.clear(); } @@ -119,6 +138,25 @@ public class TenantsTest extends AbstractTenantUserManagementIntegrationTest { @Test public void testUpdateTenantWithIncorrectAzureStorage() { + testTenantService.createTestTenantWithoutStorageIfNotExist("new_tenant_without_storage"); + TenantContext.setTenantId("new_tenant_without_storage"); + + var tenantRequest = TenantRequest.builder() + .tenantId("new_tenant_without_storage") + .azureStorageConnection(AzureStorageConnection.builder() + .connectionString("updated_connection") + .containerName("updated_container") + .build()) + .build(); + + var exception = assertThrows(FeignException.BadRequest.class, () -> tenantsClient.updateTenant("new_tenant_without_storage", tenantRequest)); + assertThat(exception.getMessage()).contains("Could not connect to Azure storage"); + + TenantContext.clear(); + } + + @Test + public void testUpdateTenantWithBothAzureAndS3Storage() { testTenantService.createTestTenantIfNotExists("new_tenant", minioPort); TenantContext.setTenantId("new_tenant"); @@ -131,7 +169,7 @@ public class TenantsTest extends AbstractTenantUserManagementIntegrationTest { .build(); var exception = assertThrows(FeignException.BadRequest.class, () -> tenantsClient.updateTenant("new_tenant", tenantRequest)); - assertThat(exception.getMessage()).contains("Could not connect to Azure storage"); + assertThat(exception.getMessage()).contains("Not possible to set both azure and s3 connection, please only specify one"); TenantContext.clear(); } diff --git a/src/test/java/com/knecon/fforesight/utils/TestTenantService.java b/src/test/java/com/knecon/fforesight/utils/TestTenantService.java index 3ddf923..3f0e171 100644 --- a/src/test/java/com/knecon/fforesight/utils/TestTenantService.java +++ b/src/test/java/com/knecon/fforesight/utils/TestTenantService.java @@ -37,35 +37,57 @@ public class TestTenantService { } catch (Exception e) { // not found - var tenantRequest = TenantRequest.builder() - .tenantId(testTenantId) - .displayName(testTenantId) - .guid(UUID.randomUUID().toString()) - .defaultUsers(List.of(TenantUser.builder().roles(Set.of("SUPER_USER")).username("test@fforesight.com").password("secret").email("test@fforesight.com").build())) - .databaseConnection(DatabaseConnection.builder() - .driver("postgresql") - .host(SpringPostgreSQLTestContainer.getInstance().getHost()) - .port(String.valueOf(SpringPostgreSQLTestContainer.getInstance().getFirstMappedPort())) - .database(SpringPostgreSQLTestContainer.getInstance().getDatabaseName()) - .schema(testTenantId) - .username(SpringPostgreSQLTestContainer.getInstance().getUsername()) - .password(SpringPostgreSQLTestContainer.getInstance().getPassword()) - .build()) - .searchConnection(SearchConnection.builder().hosts(Set.of("localhost")).port(9200).scheme("http").numberOfShards("1").numberOfReplicas("5").build()) - .s3StorageConnection(S3StorageConnection.builder().key("minioadmin").secret("minioadmin").bucketName("redaction").endpoint("http://localhost:" + actualPort).build()) - .build(); - - var response = internalTenantsResource.createTenant(tenantRequest); - - assertThat(response.getGuid()).isNotBlank(); - - TenantContext.setTenantId(testTenantId); - tokenService.setUser("test@fforesight.com", "secret"); - - var tenant = tenantsClient.getTenant(testTenantId); - assertThat(tenant.getGuid()).isNotBlank(); + createUser(testTenantId, actualPort, true); } } + public void createTestTenantWithoutStorageIfNotExist(String testTenantId) { + try { + var tenantExists = internalTenantsResource.getTenant(testTenantId); + assertThat(tenantExists.getGuid()).isNotBlank(); + + } catch (Exception e) { + // not found + createUser(testTenantId, 0, false); + } + } + + private void createUser(String testTenantId, int actualPort, boolean withStorage) { + // not found + TenantRequest tenantRequest; + var tenantRequestBuilder = TenantRequest.builder() + .tenantId(testTenantId) + .displayName(testTenantId) + .guid(UUID.randomUUID().toString()) + .defaultUsers(List.of(TenantUser.builder().roles(Set.of("SUPER_USER")).username("test@fforesight.com").password("secret").email("test@fforesight.com").build())) + .databaseConnection(DatabaseConnection.builder() + .driver("postgresql") + .host(SpringPostgreSQLTestContainer.getInstance().getHost()) + .port(String.valueOf(SpringPostgreSQLTestContainer.getInstance().getFirstMappedPort())) + .database(SpringPostgreSQLTestContainer.getInstance().getDatabaseName()) + .schema(testTenantId) + .username(SpringPostgreSQLTestContainer.getInstance().getUsername()) + .password(SpringPostgreSQLTestContainer.getInstance().getPassword()) + .build()) + .searchConnection(SearchConnection.builder().hosts(Set.of("localhost")).port(9200).scheme("http").numberOfShards("1").numberOfReplicas("5").build()); + + if (withStorage) { + tenantRequest = tenantRequestBuilder + .s3StorageConnection(S3StorageConnection.builder().key("minioadmin").secret("minioadmin").bucketName("redaction").endpoint("http://localhost:" + actualPort).build()) + .build(); + } else { + tenantRequest = tenantRequestBuilder.build(); + } + var response = internalTenantsResource.createTenant(tenantRequest); + + assertThat(response.getGuid()).isNotBlank(); + + TenantContext.setTenantId(testTenantId); + tokenService.setUser("test@fforesight.com", "secret"); + + var tenant = tenantsClient.getTenant(testTenantId); + assertThat(tenant.getGuid()).isNotBlank(); + } + }