Red-6593 Add connectivity test when creating/updating a tenant for azure/s3

This commit is contained in:
Andrei Isvoran 2023-07-13 18:40:06 +02:00 committed by Timo Bejan
parent 5f3418ad3b
commit 2b250e336d
9 changed files with 147 additions and 20 deletions

View File

@ -77,6 +77,7 @@ dependencies {
implementation("org.apache.commons:commons-lang3:3.12.0")
implementation("commons-validator:commons-validator:1.7")
implementation("org.springframework.boot:spring-boot-configuration-processor")
implementation("com.iqser.red.commons:storage-commons:2.3.0")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.cloud:spring-cloud-starter-openfeign")
testImplementation("org.projectlombok:lombok")
@ -88,6 +89,8 @@ dependencies {
testImplementation("org.springframework.amqp:spring-rabbit-test")
testImplementation("org.testcontainers:postgresql:1.18.3")
testImplementation("com.github.dasniko:testcontainers-keycloak:2.5.0")
testImplementation("org.testcontainers:testcontainers:1.18.3")
testImplementation("org.testcontainers:junit-jupiter:1.18.3")
testAnnotationProcessor("org.projectlombok:lombok")
}

View File

@ -0,0 +1,32 @@
package com.knecon.fforesight.tenantusermanagement.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import com.iqser.red.storage.commons.service.azure.AzureBlobStorageService;
import com.iqser.red.storage.commons.service.s3.S3StorageService;
import lombok.Getter;
@Configuration
@Getter
@ComponentScan("com.iqser.red.storage.commons")
public class StorageConfiguration {
S3StorageService s3StorageService;
AzureBlobStorageService azureBlobStorageService;
@Autowired
public void setS3StorageService(@Lazy S3StorageService s3StorageService) {
this.s3StorageService = s3StorageService;
}
@Autowired
public void setAzureBlobStorageService(@Lazy AzureBlobStorageService azureBlobStorageService) {
this.azureBlobStorageService = azureBlobStorageService;
}
}

View File

@ -40,6 +40,7 @@ import com.knecon.fforesight.tenantcommons.model.DatabaseConnection;
import com.knecon.fforesight.tenantcommons.model.S3StorageConnection;
import com.knecon.fforesight.tenantcommons.model.SearchConnection;
import com.knecon.fforesight.tenantcommons.model.TenantResponse;
import com.knecon.fforesight.tenantusermanagement.config.StorageConfiguration;
import com.knecon.fforesight.tenantusermanagement.entity.AzureStorageConnectionEntity;
import com.knecon.fforesight.tenantusermanagement.entity.DatabaseConnectionEntity;
import com.knecon.fforesight.tenantusermanagement.entity.S3StorageConnectionEntity;
@ -62,7 +63,7 @@ import lombok.extern.slf4j.Slf4j;
public class TenantManagementService implements TenantProvider {
private static final Long MAX_WAIT_TIME = 60_000L; // 60 seconds
private static final String FRONTEND_URL_PROPERY = "frontendUrl";
private static final String FRONTEND_URL_PROPERTY = "frontendUrl";
private static final Set<String> SUPPORTED_DATABASES = Set.of("postgresql");
private final EncryptionDecryptionService encryptionService;
@ -74,6 +75,7 @@ public class TenantManagementService implements TenantProvider {
private final TenantUserManagementProperties tenantUserManagementProperties;
private final RealmService realmService;
private final RabbitTemplate rabbitTemplate;
private final StorageConfiguration storageConfiguration;
@Value("${fforesight.tenant-exchange.name}")
private String tenantExchangeName;
@ -120,6 +122,8 @@ public class TenantManagementService implements TenantProvider {
.build();
if (tenantRequest.getAzureStorageConnection() != null) {
testAzureConnection(tenantRequest.getAzureStorageConnection().getConnectionString());
tenantEntity.setAzureStorageConnection(AzureStorageConnectionEntity.builder()
.connectionString(encryptionService.encrypt(tenantRequest.getAzureStorageConnection().getConnectionString()))
.containerName(tenantRequest.getAzureStorageConnection().getContainerName())
@ -127,6 +131,8 @@ public class TenantManagementService implements TenantProvider {
}
if (tenantRequest.getS3StorageConnection() != null) {
testS3Connection(tenantRequest.getS3StorageConnection());
tenantEntity.setS3StorageConnection(S3StorageConnectionEntity.builder()
.key(tenantRequest.getS3StorageConnection().getKey())
.secret(encryptionService.encrypt(tenantRequest.getS3StorageConnection().getSecret()))
@ -241,7 +247,7 @@ public class TenantManagementService implements TenantProvider {
if (!ObjectUtils.isEmpty(tenantUserManagementProperties.getPublicServerUrl())) {
Map<String, String> attributes = new HashMap<>();
attributes.put(FRONTEND_URL_PROPERY, tenantUserManagementProperties.getPublicServerUrl());
attributes.put(FRONTEND_URL_PROPERTY, tenantUserManagementProperties.getPublicServerUrl());
realm.setAttributes(attributes);
}
@ -389,6 +395,7 @@ public class TenantManagementService implements TenantProvider {
var azureStorageConnection = tenantRequest.getAzureStorageConnection();
if (azureStorageConnection != null) {
testAzureConnection(tenantRequest.getAzureStorageConnection().getConnectionString());
tenantEntity
.setAzureStorageConnection(AzureStorageConnectionEntity.builder()
.connectionString(encryptionService.encrypt(azureStorageConnection.getConnectionString()))
@ -398,6 +405,7 @@ public class TenantManagementService implements TenantProvider {
var s3StorageConnection = tenantRequest.getS3StorageConnection();
if (s3StorageConnection != null) {
testS3Connection(s3StorageConnection);
tenantEntity
.setS3StorageConnection(S3StorageConnectionEntity.builder()
.key(s3StorageConnection.getKey())
@ -477,4 +485,29 @@ public class TenantManagementService implements TenantProvider {
return tenantResponse;
}
private void testAzureConnection(String connectionString) {
var connection = storageConfiguration.getAzureBlobStorageService().testConnection(connectionString);
if (!connection) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Could not connect to Azure storage");
}
}
private void testS3Connection(S3StorageConnection s3StorageConnection) {
var connection = storageConfiguration.getS3StorageService().testConnection(
s3StorageConnection.getKey(),
s3StorageConnection.getSecret(),
s3StorageConnection.getSignerType(),
s3StorageConnection.getBucketName(),
s3StorageConnection.getRegion(),
s3StorageConnection.getEndpoint()
);
if (!connection) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Could not connect to S3 storage");
}
}
}

View File

@ -30,5 +30,7 @@ fforesight:
springdoc:
auth-server-url: http://localhost:8080
storage:
backend: both
cors.enabled: true

View File

@ -18,6 +18,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.testcontainers.containers.GenericContainer;
import com.knecon.fforesight.feigntestclients.external.TenantsClient;
import com.knecon.fforesight.feigntestclients.internal.InternalTenantsClient;
@ -44,9 +45,24 @@ public class AbstractTenantUserManagementIntegrationTest {
public final static String TEST_TENANT_ID = "test_tenant_fforesight";
private static GenericContainer minioServer;
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(){
testTenantService.createTestTenantIfNotExists(TEST_TENANT_ID);
testTenantService.createTestTenantIfNotExists(TEST_TENANT_ID, minioPort);
}
@Slf4j

View File

@ -2,8 +2,16 @@ package com.knecon.fforesight.tests;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Duration;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.testcontainers.Testcontainers;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy;
import org.testcontainers.containers.wait.strategy.HttpWaitStrategy;
import org.testcontainers.junit.jupiter.Container;
import com.knecon.fforesight.AbstractTenantUserManagementIntegrationTest;
import com.knecon.fforesight.feigntestclients.external.GeneralSettingsClient;

View File

@ -1,6 +1,7 @@
package com.knecon.fforesight.tests;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.Map;
import java.util.Set;
@ -19,6 +20,8 @@ import com.knecon.fforesight.tenantcommons.model.SearchConnection;
import com.knecon.fforesight.tenantusermanagement.model.TenantRequest;
import com.knecon.fforesight.utils.TestTenantService;
import feign.FeignException;
public class TenantsTest extends AbstractTenantUserManagementIntegrationTest {
@Autowired
@ -34,7 +37,7 @@ public class TenantsTest extends AbstractTenantUserManagementIntegrationTest {
@Test
public void testCreateNewTenant() {
testTenantService.createTestTenantIfNotExists("new_tenant");
testTenantService.createTestTenantIfNotExists("new_tenant", minioPort);
TenantContext.setTenantId("new_tenant");
@ -45,13 +48,14 @@ public class TenantsTest extends AbstractTenantUserManagementIntegrationTest {
assertThat(tenant.getGuid()).isNotBlank();
assertThat(tenantsClient.getTenants().stream().anyMatch(t -> t.getTenantId().equals("new_tenant"))).isTrue();
TenantContext.clear();
}
@Test
public void testUpdateTenant() {
testTenantService.createTestTenantIfNotExists("new_tenant");
testTenantService.createTestTenantIfNotExists("new_tenant", minioPort);
TenantContext.setTenantId("new_tenant");
var tenantRequest = TenantRequest.builder()
@ -76,6 +80,27 @@ public class TenantsTest extends AbstractTenantUserManagementIntegrationTest {
.password("updated_pwd")
.username("updated_username")
.build())
.build();
var tenantEntity = tenantsClient.updateTenant("new_tenant", tenantRequest);
tenantRequest.getSearchConnection().setPassword(encryptionService.encrypt("updated_pwd"));
tenantRequest.getDatabaseConnection().setPassword(encryptionService.encrypt("updated_pwd"));
assertThat(tenantEntity.getDisplayName()).isEqualTo(tenantRequest.getDisplayName());
assertThat(tenantEntity.getSearchConnection()).isEqualTo(tenantRequest.getSearchConnection());
assertThat(tenantEntity.getDatabaseConnection()).isEqualTo(tenantRequest.getDatabaseConnection());
TenantContext.clear();
}
@Test
public void testUpdateTenantWithIncorrectS3Storage() {
testTenantService.createTestTenantIfNotExists("new_tenant", minioPort);
TenantContext.setTenantId("new_tenant");
var tenantRequest = TenantRequest.builder()
.tenantId("new_tenant")
.s3StorageConnection(S3StorageConnection.builder()
.key("updated_key")
.bucketName("updated_bucket")
@ -84,24 +109,29 @@ public class TenantsTest extends AbstractTenantUserManagementIntegrationTest {
.secret("updated_secret")
.signerType("updated_signer")
.build())
.build();
var exception = assertThrows(FeignException.BadRequest.class, () -> tenantsClient.updateTenant("new_tenant", tenantRequest));
assertThat(exception.getMessage()).contains("Could not connect to S3 storage");
TenantContext.clear();
}
@Test
public void testUpdateTenantWithIncorrectAzureStorage() {
testTenantService.createTestTenantIfNotExists("new_tenant", minioPort);
TenantContext.setTenantId("new_tenant");
var tenantRequest = TenantRequest.builder()
.tenantId("new_tenant")
.azureStorageConnection(AzureStorageConnection.builder()
.connectionString("updated_connection")
.containerName("updated_container")
.build())
.build();
var tenantEntity = tenantsClient.updateTenant("new_tenant", tenantRequest);
tenantRequest.getS3StorageConnection().setSecret(encryptionService.encrypt("updated_secret"));
tenantRequest.getAzureStorageConnection().setConnectionString(encryptionService.encrypt("updated_connection"));
tenantRequest.getSearchConnection().setPassword(encryptionService.encrypt("updated_pwd"));
tenantRequest.getDatabaseConnection().setPassword(encryptionService.encrypt("updated_pwd"));
assertThat(tenantEntity.getDisplayName()).isEqualTo(tenantRequest.getDisplayName());
assertThat(tenantEntity.getS3StorageConnection()).isEqualTo(tenantRequest.getS3StorageConnection());
assertThat(tenantEntity.getAzureStorageConnection()).isEqualTo(tenantRequest.getAzureStorageConnection());
assertThat(tenantEntity.getSearchConnection()).isEqualTo(tenantRequest.getSearchConnection());
assertThat(tenantEntity.getDatabaseConnection()).isEqualTo(tenantRequest.getDatabaseConnection());
var exception = assertThrows(FeignException.BadRequest.class, () -> tenantsClient.updateTenant("new_tenant", tenantRequest));
assertThat(exception.getMessage()).contains("Could not connect to Azure storage");
TenantContext.clear();
}

View File

@ -29,13 +29,13 @@ public class TestTenantService {
private final TokenService tokenService;
public void createTestTenantIfNotExists(String testTenantId) {
public void createTestTenantIfNotExists(String testTenantId, int actualPort) {
try {
var tenantExists = internalTenantsResource.getTenant(testTenantId);
assertThat(tenantExists.getGuid()).isNotBlank();
}catch (Exception e) {
} catch (Exception e) {
// not found
var tenantRequest = TenantRequest.builder()
.tenantId(testTenantId)
@ -52,7 +52,7 @@ public class TestTenantService {
.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:9000").build())
.s3StorageConnection(S3StorageConnection.builder().key("minioadmin").secret("minioadmin").bucketName("redaction").endpoint("http://localhost:" + actualPort).build())
.build();
var response = internalTenantsResource.createTenant(tenantRequest);

View File

@ -127,6 +127,9 @@ fforesight:
application-client-id: tenant-user-management
swagger-client-secret: 'testSecret123!'
storage:
backend: both
cors.enabled: true
springdoc:
packages-to-scan: [ 'com.knecon.fforesight.tenantusermanagement.controller.external' ]