From 91efd63311768ae31822d446d1e64605c9b737d3 Mon Sep 17 00:00:00 2001 From: Timo Bejan Date: Thu, 23 Mar 2023 17:15:22 +0200 Subject: [PATCH] RED-4515 - kc createRealm --- .../service/KeyCloakRoleManagerService.java | 1 + .../service/TenantManagementService.java | 36 +++++++- .../v1/server/DevConfiguration.java | 83 +++++++++++++++++-- .../tests/DossierTemplateImportTest.java | 3 +- .../src/test/resources/application.yml | 2 +- 5 files changed, 109 insertions(+), 16 deletions(-) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/KeyCloakRoleManagerService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/KeyCloakRoleManagerService.java index 079efa20b..d0c108bcc 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/KeyCloakRoleManagerService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/KeyCloakRoleManagerService.java @@ -89,6 +89,7 @@ public class KeyCloakRoleManagerService { realm.roles().create(role); } + var applicationRoleResource = realm.roles().get(applicationRole); Set composites = realm.rolesById() .getClientRoleComposites(applicationRoleResource.toRepresentation().getId(), redactionClient.toRepresentation().getId()); 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 a03c4f3ed..6e9b7d8ec 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 @@ -32,6 +32,7 @@ import org.springframework.stereotype.Service; import com.iqser.red.keycloak.commons.KeyCloakAdminClientService; import com.iqser.red.keycloak.commons.KeyCloakSettings; import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException; +import com.iqser.red.service.persistence.management.v1.processor.exception.InternalServerErrorException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.migration.AsyncMigrationStarterService; import com.iqser.red.service.persistence.management.v1.processor.multitenancy.entity.AzureStorageConnectionEntity; @@ -58,6 +59,8 @@ import lombok.extern.slf4j.Slf4j; @EnableConfigurationProperties(LiquibaseProperties.class) public class TenantManagementService { + private static final Long MAX_WAIT_TIME = 60_000L; // 60 seconds + private static final Set SUPPORTED_DATABASES = Set.of("postgresql"); private static final Set SQL_CONNECTION_ERROR_CODES = Set.of( // connection_exception @@ -88,7 +91,8 @@ public class TenantManagementService { AsyncMigrationStarterService asyncMigrationStarterService, GeneralConfigurationService generalConfigurationService, KeyCloakRoleManagerService keyCloakRoleManagerService, - KeyCloakAdminClientService keycloak, KeyCloakSettings keyCloakSettings) { + KeyCloakAdminClientService keycloak, + KeyCloakSettings keyCloakSettings) { this.encryptionService = encryptionService; this.liquibaseProperties = liquibaseProperties; @@ -165,7 +169,23 @@ public class TenantManagementService { tenantRepository.save(tenantEntity); createRealm(tenantRequest.getTenantId()); - Thread.sleep(30_000); + + var waitTime = 0; + boolean realmReady; + do { + realmReady = tryToAccessRealm(tenantRequest.getTenantId()); + if (realmReady) { + break; + } else { + Thread.sleep(1_000L); + waitTime += 1_000L; + } + + } while (waitTime < MAX_WAIT_TIME); + + if (!realmReady) { + throw new InternalServerErrorException("Failed to create KC realm"); + } generalConfigurationService.initGeneralConfiguration(tenantRequest.getTenantId()); keyCloakRoleManagerService.updateRoles(tenantRequest.getTenantId()); @@ -177,6 +197,16 @@ public class TenantManagementService { } + private boolean tryToAccessRealm(String tenantId) { + + try { + return keycloak.getAdminClient().realms().findAll().stream().anyMatch(r -> r.getRealm().equals(tenantId)); + } catch (Exception e) { + return false; + } + } + + private void createRealm(String tenantId) { var redaction = new RealmRepresentation(); @@ -192,7 +222,6 @@ public class TenantManagementService { redactionClient.setImplicitFlowEnabled(true); redactionClient.setDirectAccessGrantsEnabled(true); - var swaggerClient = new ClientRepresentation(); swaggerClient.setEnabled(true); swaggerClient.setName("swagger-ui-client"); @@ -204,7 +233,6 @@ public class TenantManagementService { swaggerClient.setAuthorizationServicesEnabled(true); swaggerClient.setSecret("OsloImWinter!23"); - var redactionSystemClient = new ClientRepresentation(); redactionSystemClient.setEnabled(true); redactionSystemClient.setName(keyCloakSettings.getClientId()); diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/DevConfiguration.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/DevConfiguration.java index 1ca279079..13fee5f79 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/DevConfiguration.java +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/DevConfiguration.java @@ -1,13 +1,23 @@ package com.iqser.red.service.peristence.v1.server; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.sql.Connection; import java.sql.DriverManager; import java.util.Set; import java.util.UUID; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; import javax.annotation.PostConstruct; import javax.sql.DataSource; +import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; @@ -17,7 +27,11 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.StatementCallback; import org.springframework.jdbc.datasource.SingleConnectionDataSource; +import com.iqser.red.service.persistence.management.v1.processor.service.DossierTemplateImportService; import com.iqser.red.service.persistence.management.v1.processor.service.TenantManagementService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository; +import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.importexport.ImportDossierTemplateRequest; 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.S3StorageConnection; import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.SearchConnection; @@ -70,30 +84,81 @@ public class DevConfiguration { .password("redaction") .build()) .searchConnection(SearchConnection.builder() - .hosts(Set.of("elasticsearchHost")) + .hosts(Set.of("localhost")) .port(9200) - .scheme("https") + .scheme("http") .username("elastic") - .password("changeMe") .numberOfShards("1") .numberOfReplicas("5") .build()) .s3StorageConnection(S3StorageConnection.builder() - .key("key") - .secret("secret") - .signerType("signerType") - .bucketName("bucketName") - .region("eu") - .endpoint("endpoint") + .key("minioadmin") + .secret("minioadmin") + .bucketName("redaction") + .endpoint("http://localhost:9000") .build()) .build(); tenantManagementService.createTenant(tenantRequest); } + + TenantContext.setTenantId("redaction"); + if(dossierTemplateRepository.count() == 0) { + testDossierTemplateImport(); + } } + @Autowired + private DossierTemplateImportService dossierTemplateImportService; + + @Autowired + private DossierTemplateRepository dossierTemplateRepository; + + public byte[] pack(String sourceDirPath) throws IOException { + + var bos = new ByteArrayOutputStream(); + var p = Paths.get(sourceDirPath); + try (ZipOutputStream zs = new ZipOutputStream(bos)) { + Stream paths = Files.walk(p); + { + paths.filter(path -> !Files.isDirectory(path)).forEach(path -> { + ZipEntry zipEntry = new ZipEntry(p.relativize(path).toString()); + try { + zs.putNextEntry(zipEntry); + Files.copy(path, zs); + zs.closeEntry(); + } catch (IOException e) { + System.err.println(e); + } + }); + } + } + + return bos.toByteArray(); + + } + + @SneakyThrows + public void testDossierTemplateImport() { + + var importDir = new File("/Users/timobejan/work/dossier-templates-v2/dev"); + + TenantContext.setTenantId("redaction"); + for (var file : importDir.listFiles()) { + if(file.isDirectory()){ + var archive = pack(file.getAbsolutePath()); + log.info("Importing file: " + file.getName() + " " + " with size: " + archive.length); + var request = new ImportDossierTemplateRequest(); + request.setArchive(archive); + request.setUpdateExistingDossierTemplate(false); + request.setUserId("system"); + dossierTemplateImportService.importDossierTemplate(request); + } + } + } + @SneakyThrows public void createSchema(String jdbcUrl, String username, String password) { diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierTemplateImportTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierTemplateImportTest.java index bcbf49ff6..80532da41 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierTemplateImportTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierTemplateImportTest.java @@ -32,10 +32,9 @@ public class DossierTemplateImportTest extends AbstractPersistenceServerServiceT @SneakyThrows @Test - @Disabled public void testDossierTemplateImport() { - var importDir = new File("/path/to/git/repo/dossier-templates-v2/dev"); + var importDir = new File("/Users/timobejan/work/dossier-templates-v2/dev"); TenantContext.setTenantId("redaction"); for (var file : importDir.listFiles()) { diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml index fb6bb961a..37310a6aa 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml +++ b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml @@ -125,7 +125,7 @@ keycloak: commons: keycloak: - application-client-id: redaction-system + application-client-id: redaction realm: master client-id: redaction-system client-secret: redaction-system