RED-6888: Add delete tenant endpoint
removed extra topic exchange removed not needed event fixed code errors tested on stack
This commit is contained in:
parent
64cecc4a7d
commit
819730d970
@ -40,7 +40,7 @@ public interface TenantsResource {
|
||||
@Operation(summary = "Deletes given tenant", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "405", description = "Operation is not allowed."), @ApiResponse(responseCode = "409", description = "Conflict while deleting user.")})
|
||||
@DeleteMapping(value = "/tenants/{tenantId}")
|
||||
void deleteTenant(@PathVariable("tenantId") String tenantId, @RequestBody TenantRequest tenant);
|
||||
void deleteTenant(@PathVariable("tenantId") String tenantId);
|
||||
|
||||
|
||||
@GetMapping(value = "/tenants", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
|
||||
@ -49,11 +49,10 @@ public class TenantsController implements TenantsResource, PublicResource {
|
||||
}
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('"+ DELETE_TENANT+ "')")
|
||||
public void deleteTenant(String tenantId, TenantRequest tenantRequest) {
|
||||
public void deleteTenant(String tenantId) {
|
||||
|
||||
try {
|
||||
tenantManagementService.deleteTenant(tenantId, tenantRequest);
|
||||
tenantManagementService.deleteTenant(tenantId);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage(), e);
|
||||
}
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
package com.knecon.fforesight.tenantusermanagement.events;
|
||||
|
||||
import com.knecon.fforesight.tenantcommons.model.SearchConnection;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class TenantDeletedEvent {
|
||||
private String tenantId;
|
||||
|
||||
private SearchConnection searchConnection;
|
||||
|
||||
}
|
||||
@ -20,13 +20,6 @@ public class MessagingConfiguration {
|
||||
return new TopicExchange(tenantExchangeName);
|
||||
}
|
||||
|
||||
@Bean
|
||||
TopicExchange deleteTenantExchange(@Value("${fforesight.tenant-exchange.name}") String tenantExchangeName) {
|
||||
|
||||
return new TopicExchange(tenantExchangeName);
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
TopicExchange userExchange(@Value("${fforesight.user-exchange.name}") String userExchangeName) {
|
||||
|
||||
|
||||
@ -14,7 +14,6 @@ import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import javax.ws.rs.BadRequestException;
|
||||
import javax.ws.rs.NotFoundException;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -34,7 +33,11 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import com.azure.storage.blob.BlobClient;
|
||||
import com.azure.storage.blob.BlobContainerClient;
|
||||
import com.azure.storage.blob.BlobServiceClient;
|
||||
import com.azure.storage.blob.BlobServiceClientBuilder;
|
||||
import com.azure.storage.blob.models.BlobItem;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService;
|
||||
import com.knecon.fforesight.tenantcommons.TenantContext;
|
||||
@ -51,7 +54,6 @@ import com.knecon.fforesight.tenantusermanagement.entity.S3StorageConnectionEnti
|
||||
import com.knecon.fforesight.tenantusermanagement.entity.SearchConnectionEntity;
|
||||
import com.knecon.fforesight.tenantusermanagement.entity.TenantEntity;
|
||||
import com.knecon.fforesight.tenantusermanagement.events.TenantCreatedEvent;
|
||||
import com.knecon.fforesight.tenantusermanagement.events.TenantDeletedEvent;
|
||||
import com.knecon.fforesight.tenantusermanagement.events.TenantSyncEvent;
|
||||
import com.knecon.fforesight.tenantusermanagement.model.TenantRequest;
|
||||
import com.knecon.fforesight.tenantusermanagement.model.TenantUser;
|
||||
@ -62,7 +64,12 @@ import com.knecon.fforesight.tenantusermanagement.utils.JDBCUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import software.amazon.awssdk.services.s3.S3Client;
|
||||
import software.amazon.awssdk.services.s3.model.DeleteBucketRequest;
|
||||
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
|
||||
import software.amazon.awssdk.services.s3.model.ListObjectsRequest;
|
||||
import software.amazon.awssdk.services.s3.model.ListObjectsResponse;
|
||||
import software.amazon.awssdk.services.s3.model.S3Object;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@ -89,10 +96,6 @@ public class TenantManagementService implements TenantProvider {
|
||||
@Value("${fforesight.tenant-exchange.name}")
|
||||
private String tenantExchangeName;
|
||||
|
||||
@Value("${fforesight.tenant-delete.name}")
|
||||
private String tenantDeleteName;
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public TenantResponse createTenant(TenantRequest tenantRequest) {
|
||||
|
||||
@ -190,61 +193,63 @@ public class TenantManagementService implements TenantProvider {
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void deleteTenant(String tenantId, TenantRequest tenantRequest) {
|
||||
public void deleteTenant(String tenantId) {
|
||||
|
||||
log.info("Requested to delete tenant for: {}", tenantRequest.getTenantId());
|
||||
TenantResponse tenant = this.getTenant(tenantId);
|
||||
log.info("Requested to delete tenant for: {}", tenant.getTenantId());
|
||||
|
||||
if (tenantRequest.getS3StorageConnection() != null && tenantRequest.getAzureStorageConnection() != null) {
|
||||
if (tenant.getS3StorageConnection() != null && tenant.getAzureStorageConnection() != null) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Not possible to set both azure and s3 connection, please only specify one");
|
||||
}
|
||||
|
||||
var tenant = tenantRepository.findByTenantId(tenantId);
|
||||
log.info("Deleting tenant: {}", tenant.getTenantId());
|
||||
log.info("Deleting search index for tenant: {}", tenant.getTenantId());
|
||||
TenantContext.setTenantId(tenant.getTenantId());
|
||||
rabbitTemplate.convertAndSend(tenantExchangeName, "tenant.deleted", tenant);
|
||||
TenantContext.clear();
|
||||
|
||||
log.info("Dispatched delete index message for tenant: {}", tenant.getTenantId());
|
||||
deleteSchema(tenant);
|
||||
if(tenant.getAzureStorageConnection() != null ) {
|
||||
log.info("Deleting azure blob for tenant: {}",tenantId);
|
||||
String connectionString = tenant.getAzureStorageConnection().getConnectionString();
|
||||
String containerName = tenant.getAzureStorageConnection().getContainerName();
|
||||
|
||||
if (tenant.isPresent()) {
|
||||
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().connectionString(connectionString).buildClient();
|
||||
BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(containerName);
|
||||
|
||||
log.info("Deleting tenant: {}", tenantRequest.getTenantId());
|
||||
var tenantEntity = tenant.get();
|
||||
|
||||
log.info("Deleting search index for tenant: {}", tenantRequest.getTenantId());
|
||||
TenantContext.setTenantId(tenantEntity.getTenantId());
|
||||
rabbitTemplate.convertAndSend(tenantDeleteName, "tenant.deleted", new TenantDeletedEvent(tenantEntity.getTenantId(),SearchConnection.builder()
|
||||
.hosts(tenantEntity.getSearchConnection().getHosts())
|
||||
.port(tenantEntity.getSearchConnection().getPort())
|
||||
.scheme(tenantEntity.getSearchConnection().getScheme())
|
||||
.username(tenantEntity.getSearchConnection().getUsername())
|
||||
.numberOfShards(tenantEntity.getSearchConnection().getNumberOfShards())
|
||||
.numberOfReplicas(tenantEntity.getSearchConnection().getNumberOfReplicas())
|
||||
.password(tenantEntity.getSearchConnection().getPassword())
|
||||
.indexPrefix(tenantEntity.getSearchConnection().getIndexPrefix())
|
||||
.build()));
|
||||
TenantContext.clear();
|
||||
|
||||
log.info("Dispatched delete index message for tenant: {}", tenantRequest.getTenantId());
|
||||
//todo: delete cache
|
||||
deleteSchema(tenantRequest);
|
||||
com.iqser.red.storage.commons.model.AzureStorageConnection azureStorageConnection = new com.iqser.red.storage.commons.model.AzureStorageConnection(tenantRequest.getAzureStorageConnection().getConnectionString(), tenantRequest.getAzureStorageConnection().getContainerName());
|
||||
if (azureStorageConnection != null) {
|
||||
log.info("Deleting azure blob for tenant: {}",tenantId);
|
||||
BlobServiceClient blobServiceClient = storageConfiguration.getAzureBlobStorageService().initBlobServiceClient(azureStorageConnection);
|
||||
blobServiceClient.deleteBlobContainer(tenantRequest.getAzureStorageConnection().getContainerName());
|
||||
// Delete all blobs within the container
|
||||
for (BlobItem blobItem : containerClient.listBlobs()) {
|
||||
BlobClient blobClient = containerClient.getBlobClient(blobItem.getName());
|
||||
blobClient.delete();
|
||||
}
|
||||
var s3StorageConnectionTemplate = tenantRequest.getS3StorageConnection();
|
||||
com.iqser.red.storage.commons.model.S3StorageConnection s3StorageConnection = new com.iqser.red.storage.commons.model.S3StorageConnection(s3StorageConnectionTemplate.getKey(), s3StorageConnectionTemplate.getSecret(), s3StorageConnectionTemplate.getSignerType(), s3StorageConnectionTemplate.getBucketName(), s3StorageConnectionTemplate.getRegion(),s3StorageConnectionTemplate.getEndpoint());
|
||||
if (s3StorageConnection != null) {
|
||||
log.info("Deleting s3 bucket for tenant: {}",tenantId);
|
||||
DeleteBucketRequest deleteBucketRequest = DeleteBucketRequest.builder()
|
||||
.bucket(s3StorageConnection.getBucketName())
|
||||
.expectedBucketOwner(tenantId)
|
||||
.build();
|
||||
storageConfiguration.getS3StorageService().initAmazonS3(s3StorageConnection).deleteBucket(deleteBucketRequest);
|
||||
}
|
||||
deleteRealm(tenantId);
|
||||
tenantRepository.delete(tenantEntity);
|
||||
|
||||
} else {
|
||||
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Tenant does not exist");
|
||||
containerClient.delete();
|
||||
}
|
||||
|
||||
if(tenant.getS3StorageConnection() != null) {
|
||||
var s3StorageConnectionTemplate = tenant.getS3StorageConnection();
|
||||
com.iqser.red.storage.commons.model.S3StorageConnection s3StorageConnection = new com.iqser.red.storage.commons.model.S3StorageConnection(s3StorageConnectionTemplate.getKey(), encryptionService.decrypt(s3StorageConnectionTemplate.getSecret()), s3StorageConnectionTemplate.getSignerType(), s3StorageConnectionTemplate.getBucketName(), s3StorageConnectionTemplate.getRegion(),s3StorageConnectionTemplate.getEndpoint());
|
||||
log.info("Deleting s3 bucket for tenant: {}",tenantId);
|
||||
S3Client client = storageConfiguration.getS3StorageService().initAmazonS3(s3StorageConnection);
|
||||
String bucketName = s3StorageConnection.getBucketName();
|
||||
ListObjectsRequest listObjects = ListObjectsRequest
|
||||
.builder()
|
||||
.bucket(bucketName)
|
||||
.build();
|
||||
ListObjectsResponse objectList = client.listObjects(listObjects);
|
||||
for (S3Object object : objectList.contents()) {
|
||||
// Delete each object
|
||||
client.deleteObject(DeleteObjectRequest.builder().bucket(bucketName).key(object.key()).build());
|
||||
}
|
||||
DeleteBucketRequest deleteBucketRequest = DeleteBucketRequest.builder()
|
||||
.bucket(bucketName)
|
||||
.expectedBucketOwner(tenantId)
|
||||
.build();
|
||||
client.deleteBucket(deleteBucketRequest);
|
||||
}
|
||||
deleteRealm(tenantId);
|
||||
tenantRepository.deleteById(tenant.getTenantId());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -321,16 +326,18 @@ public class TenantManagementService implements TenantProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteSchema(TenantRequest tenantRequest) {
|
||||
log.info("Deleting schema for tenant: {}", tenantRequest.getTenantId());
|
||||
var jdbcUrl = JDBCUtils.buildJdbcUrl(tenantRequest.getDatabaseConnection());
|
||||
|
||||
private void deleteSchema(TenantResponse tenant) {
|
||||
log.info("Deleting schema for tenant: {}", tenant.getTenantId());
|
||||
var jdbcUrl = JDBCUtils.buildJdbcUrl(tenant.getDatabaseConnection());
|
||||
try (Connection connection = DriverManager.getConnection(jdbcUrl,
|
||||
tenantRequest.getDatabaseConnection().getUsername(),
|
||||
tenantRequest.getDatabaseConnection().getPassword())) {
|
||||
tenant.getDatabaseConnection().getUsername(),
|
||||
this.encryptionService.decrypt(tenant.getDatabaseConnection().getPassword())))
|
||||
{
|
||||
DataSource tenantDataSource = new SingleConnectionDataSource(connection, false);
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(tenantDataSource);
|
||||
String deleteStatement = "DELETE SCHEMA IF EXISTS \"" + tenantRequest.getDatabaseConnection().getSchema() + "\"";
|
||||
jdbcTemplate.execute(deleteStatement);
|
||||
String deleteStatement = "DROP SCHEMA IF EXISTS \"" + tenant.getDatabaseConnection().getSchema() + "\" CASCADE;";
|
||||
jdbcTemplate.execute(deleteStatement);
|
||||
} catch (Exception e) {
|
||||
log.warn("Could not delete schema:", e);
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Tenant deletion failed: " + e.getMessage(), e);
|
||||
|
||||
@ -110,8 +110,6 @@ fforesight:
|
||||
app-prefix: 'fforesight'
|
||||
tenant-exchange:
|
||||
name: 'tenants-exchange'
|
||||
tenant-delete:
|
||||
name: 'tenant-delete-queue'
|
||||
user-exchange:
|
||||
name: 'users-exchange'
|
||||
springdoc:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user