diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/TenantManagementService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/TenantManagementService.java index ee0fce7bd..f3a1a2633 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/TenantManagementService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/TenantManagementService.java @@ -87,7 +87,6 @@ public class TenantManagementService { private final KeyCloakRoleManagerService keyCloakRoleManagerService; private final KeyCloakAdminClientService keycloak; - public TenantManagementService(EncryptionDecryptionService encryptionService, @Qualifier("tenantLiquibaseProperties") LiquibaseProperties liquibaseProperties, ResourceLoader resourceLoader, diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/db.changelog-master.yaml b/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/db.changelog-master.yaml index 8a632ee7b..d1fa43356 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/db.changelog-master.yaml @@ -5,3 +5,5 @@ databaseChangeLog: file: db/changelog/master/2-quartz.changelog.yaml - include: file: db/changelog/master/3-detailed-db-connection.changelog.yaml + - include: + file: db/changelog/master/4-add-unique-constraint-for-tenants-table.yaml diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/master/4-add-unique-constraint-for-tenants-table.yaml b/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/master/4-add-unique-constraint-for-tenants-table.yaml new file mode 100644 index 000000000..27baab89c --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/master/4-add-unique-constraint-for-tenants-table.yaml @@ -0,0 +1,17 @@ +databaseChangeLog: + - changeSet: + id: add-unique-constraint-for-tenants-table + author: corinaolariu + changes: + - addUniqueConstraint: + columnNames: db_host, db_schema + constraintName: unique_constraint_tenant_host_shema + tableName: tenant + - addUniqueConstraint: + columnNames: storage_s3_endpoint, storage_s3_region, storage_s3_bucket_name + constraintName: unique_constraint_tenant_s3_storage + tableName: tenant + - addUniqueConstraint: + columnNames: storage_azure_connection_string, storage_azure_container_name + constraintName: unique_constraint_tenant_azure_storage + tableName: tenant diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/TenantsTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/TenantsTest.java new file mode 100644 index 000000000..229f1bba1 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/TenantsTest.java @@ -0,0 +1,207 @@ +package com.iqser.red.service.peristence.v1.server.integration.tests; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.iqser.red.keycloak.commons.roles.ApplicationRoles; +import com.iqser.red.service.peristence.v1.server.integration.client.TenantsClient; +import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest; +import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.AzureStorageConnection; +import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.DatabaseConnection; +import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.RedUser; +import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.S3StorageConnection; +import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.SearchConnection; +import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantRequest; +import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantResponse; + +import feign.FeignException; + +public class TenantsTest extends AbstractPersistenceServerServiceTest { + + @Autowired + private TenantsClient tenantsClient; + + @Test + public void testCreateTenantWithSameHostAndSchema() { + + TenantResponse firstTenant = tenantsClient.getTenants().get(0); + + var tenantRequest = TenantRequest.builder() + .tenantId("redaction2") + .displayName("Redaction default2") + .guid(UUID.randomUUID().toString()) + .databaseConnection(DatabaseConnection.builder() + .driver("postgresql") + .host("localhost") + .port(firstTenant.getDatabaseConnection().getPort()) + .database("redaction") + .schema("myschema") + .username("redaction") + .password("redaction") + .build()) + .searchConnection(SearchConnection.builder() + .hosts(Set.of("elasticsearchHost2")) + .port(9200) + .scheme("https2") + .username("elastic") + .numberOfShards("1") + .numberOfReplicas("5") + .build()) + .s3StorageConnection(S3StorageConnection.builder() + .key("key") + .secret("secret") + .signerType("signerType") + .bucketName("bucketName2") + .region("eu") + .endpoint("endpoint2") + .build()) + .redUsers(List.of(RedUser.builder().username("user").password("password").redRoles(ApplicationRoles.ROLE_DATA.keySet()).build(), + RedUser.builder().username("manageradmin1@test.com").password("secret").redRoles(ApplicationRoles.ROLE_DATA.keySet()).build(), + RedUser.builder().username("manageradmin2@test.com").password("secret").redRoles(ApplicationRoles.ROLE_DATA.keySet()).build())) + .build(); + + Exception exception = Assertions.assertThrows(FeignException.Conflict.class, () -> { + tenantsClient.createTenant(tenantRequest); + }); + + String expectedMessage = "An object of type tenant already exists"; + String actualMessage = exception.getMessage(); + + assertThat(actualMessage).contains(expectedMessage); + + } + + @Test + public void testCreateTenantWithDuplicateStorageS3() { + + TenantResponse firstTenant = tenantsClient.getTenants().get(0); + + var tenantRequest = TenantRequest.builder() + .tenantId("redaction2") + .displayName("Redaction default2") + .guid(UUID.randomUUID().toString()) + .databaseConnection(DatabaseConnection.builder() + .driver("postgresql") + .host("localhost") + .port(firstTenant.getDatabaseConnection().getPort()) + .database("redaction") + .schema("myschema2") + .username("redaction") + .password("redaction") + .build()) + .searchConnection(SearchConnection.builder() + .hosts(Set.of("elasticsearchHost2")) + .port(9200) + .scheme("https2") + .username("elastic") + .numberOfShards("1") + .numberOfReplicas("5") + .build()) + .s3StorageConnection(S3StorageConnection.builder() + .key("key") + .secret("secret") + .signerType("signerType") + .bucketName("bucketName") + .region("eu") + .endpoint("endpoint") + .build()) + .redUsers(List.of(RedUser.builder().username("user").password("password").redRoles(ApplicationRoles.ROLE_DATA.keySet()).build(), + RedUser.builder().username("manageradmin1@test.com").password("secret").redRoles(ApplicationRoles.ROLE_DATA.keySet()).build(), + RedUser.builder().username("manageradmin2@test.com").password("secret").redRoles(ApplicationRoles.ROLE_DATA.keySet()).build())) + .build(); + + Exception exception = Assertions.assertThrows(FeignException.Conflict.class, () -> { + tenantsClient.createTenant(tenantRequest); + }); + + String expectedMessage = "An object of type tenant already exists"; + String actualMessage = exception.getMessage(); + + assertThat(actualMessage).contains(expectedMessage); + } + + @Test + public void testCreateTenantWithDuplicateAzure() { + + TenantResponse firstTenant = tenantsClient.getTenants().get(0); + + var tenantRequest = TenantRequest.builder() + .tenantId("redaction2") + .displayName("Redaction default2") + .guid(UUID.randomUUID().toString()) + .databaseConnection(DatabaseConnection.builder() + .driver("postgresql") + .host("localhost") + .port(firstTenant.getDatabaseConnection().getPort()) + .database("redaction") + .schema("myschema2") + .username("redaction") + .password("redaction") + .build()) + .searchConnection(SearchConnection.builder() + .hosts(Set.of("elasticsearchHost2")) + .port(9200) + .scheme("https2") + .username("elastic") + .numberOfShards("1") + .numberOfReplicas("5") + .build()) + .azureStorageConnection(AzureStorageConnection.builder() + .connectionString("connection") + .containerName("container") + .build()) + .redUsers(List.of(RedUser.builder().username("user").password("password").redRoles(ApplicationRoles.ROLE_DATA.keySet()).build(), + RedUser.builder().username("manageradmin1@test.com").password("secret").redRoles(ApplicationRoles.ROLE_DATA.keySet()).build(), + RedUser.builder().username("manageradmin2@test.com").password("secret").redRoles(ApplicationRoles.ROLE_DATA.keySet()).build())) + .build(); + + tenantsClient.createTenant(tenantRequest); + assertThat(tenantsClient.getTenants().size()).isEqualTo(2); + + var tenantRequest2 = TenantRequest.builder() + .tenantId("redaction2") + .displayName("Redaction default2") + .guid(UUID.randomUUID().toString()) + .databaseConnection(DatabaseConnection.builder() + .driver("postgresql") + .host("localhost") + .port(firstTenant.getDatabaseConnection().getPort()) + .database("redaction") + .schema("myschema3") + .username("redaction") + .password("redaction") + .build()) + .searchConnection(SearchConnection.builder() + .hosts(Set.of("elasticsearchHost2")) + .port(9200) + .scheme("https2") + .username("elastic") + .numberOfShards("1") + .numberOfReplicas("5") + .build()) + .azureStorageConnection(AzureStorageConnection.builder() + .connectionString("connection") + .containerName("container") + .build()) + .redUsers(List.of(RedUser.builder().username("user").password("password").redRoles(ApplicationRoles.ROLE_DATA.keySet()).build(), + RedUser.builder().username("manageradmin1@test.com").password("secret").redRoles(ApplicationRoles.ROLE_DATA.keySet()).build(), + RedUser.builder().username("manageradmin2@test.com").password("secret").redRoles(ApplicationRoles.ROLE_DATA.keySet()).build())) + .build(); + + Exception exception = Assertions.assertThrows(FeignException.Conflict.class, () -> { + tenantsClient.createTenant(tenantRequest); + }); + + String expectedMessage = "An object of type tenant already exists"; + String actualMessage = exception.getMessage(); + + assertThat(actualMessage).contains(expectedMessage); + } +}