Tenant Creation exception rework
This commit is contained in:
parent
1ede240122
commit
7e28e5574e
@ -38,7 +38,7 @@ public interface InternalTenantsResource {
|
||||
@PostMapping(value = "/tenants", consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Creates a new Tenant", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
|
||||
void createTenant(@RequestBody TenantRequest tenant);
|
||||
TenantResponse createTenant(@RequestBody TenantRequest tenant);
|
||||
|
||||
|
||||
@GetMapping(value = "/tenants", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package com.knecon.fforesight.tenantusermanagement.controller;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import com.knecon.fforesight.tenantusermanagement.model.ErrorMessage;
|
||||
|
||||
@RestControllerAdvice
|
||||
public class ControllerAdvice {
|
||||
|
||||
@ExceptionHandler(ResponseStatusException.class)
|
||||
public ResponseEntity<ErrorMessage> handleResponseStatusException(ResponseStatusException e) {
|
||||
|
||||
return new ResponseEntity<>(new ErrorMessage(e.getMessage()), e.getStatusCode());
|
||||
}
|
||||
|
||||
}
|
||||
@ -35,10 +35,10 @@ public class InternalTenantsController implements InternalTenantsResource {
|
||||
}
|
||||
|
||||
|
||||
public void createTenant(@Valid @RequestBody TenantRequest tenantRequest) {
|
||||
public TenantResponse createTenant(@Valid @RequestBody TenantRequest tenantRequest) {
|
||||
|
||||
try {
|
||||
tenantManagementService.createTenant(tenantRequest);
|
||||
return tenantManagementService.createTenant(tenantRequest);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage(), e);
|
||||
}
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package com.knecon.fforesight.tenantusermanagement.model;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Data
|
||||
@RequiredArgsConstructor
|
||||
public class ErrorMessage {
|
||||
|
||||
private OffsetDateTime timestamp = OffsetDateTime.now();
|
||||
private final String message;
|
||||
|
||||
}
|
||||
@ -3,11 +3,15 @@ package com.knecon.fforesight.tenantusermanagement.model;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TenantUser {
|
||||
|
||||
private String username;
|
||||
|
||||
@ -13,6 +13,7 @@ import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import javax.ws.rs.ClientErrorException;
|
||||
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
@ -66,6 +67,7 @@ public class TenantManagementService implements TenantProvider {
|
||||
|
||||
private final EncryptionDecryptionService encryptionService;
|
||||
private final TenantRepository tenantRepository;
|
||||
private final TenantPersistenceService tenantPersistenceService;
|
||||
private final GeneralConfigurationService generalConfigurationService;
|
||||
private final KeyCloakRoleManagerService keyCloakRoleManagerService;
|
||||
private final KeyCloakAdminClientService keycloak;
|
||||
@ -78,8 +80,9 @@ public class TenantManagementService implements TenantProvider {
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void createTenant(TenantRequest tenantRequest) {
|
||||
public TenantResponse createTenant(TenantRequest tenantRequest) {
|
||||
|
||||
log.info("Tenants are: {}",tenantRepository.findAll().stream().map(t-> t.getTenantId()).collect(Collectors.toList()));
|
||||
log.info("Requested to create tenant for: {}", tenantRequest.getTenantId());
|
||||
|
||||
try {
|
||||
@ -134,32 +137,11 @@ public class TenantManagementService implements TenantProvider {
|
||||
.build());
|
||||
}
|
||||
|
||||
createRealm(tenantRequest.getTenantId(), tenantRequest.getDefaultUsers());
|
||||
log.info("Created realm for tenant: {}", tenantRequest.getTenantId());
|
||||
|
||||
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 ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Failed to create KC realm");
|
||||
}
|
||||
|
||||
generalConfigurationService.initGeneralConfiguration(tenantRequest.getTenantId());
|
||||
keyCloakRoleManagerService.updateRoles(tenantRequest.getTenantId());
|
||||
propagateTenantToKeyCloak(tenantRequest);
|
||||
|
||||
log.info("Updated roles for tenant: {}", tenantRequest.getTenantId());
|
||||
|
||||
tenantRepository.save(tenantEntity);
|
||||
var saved = tenantPersistenceService.save(tenantEntity);
|
||||
|
||||
log.info("Persisted tenant: {}", tenantRequest.getTenantId());
|
||||
|
||||
@ -169,17 +151,50 @@ public class TenantManagementService implements TenantProvider {
|
||||
|
||||
log.info("Dispatched message for tenant: {}", tenantRequest.getTenantId());
|
||||
|
||||
return convert(saved);
|
||||
} else {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, "Tenant exists");
|
||||
}
|
||||
} catch (ClientErrorException e) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Tenant creation failed: " + e.getMessage(), e);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Tenant creation failed, rolling back", e);
|
||||
tenantRepository.deleteById(tenantRequest.getTenantId());
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Tenant creation failed", e);
|
||||
if (!(e instanceof ResponseStatusException)) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Tenant creation failed: " + e.getMessage(), e);
|
||||
}else{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void propagateTenantToKeyCloak(TenantRequest tenantRequest) throws InterruptedException {
|
||||
|
||||
createRealm(tenantRequest.getTenantId(), tenantRequest.getDefaultUsers());
|
||||
log.info("Created realm for tenant: {}", tenantRequest.getTenantId());
|
||||
|
||||
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 ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Failed to create KC realm");
|
||||
}
|
||||
|
||||
generalConfigurationService.initGeneralConfiguration(tenantRequest.getTenantId());
|
||||
keyCloakRoleManagerService.updateRoles(tenantRequest.getTenantId());
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
private void validateJdbcUrl(String jdbcUrl) {
|
||||
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
package com.knecon.fforesight.tenantusermanagement.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.knecon.fforesight.tenantusermanagement.entity.TenantEntity;
|
||||
import com.knecon.fforesight.tenantusermanagement.repository.TenantRepository;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TenantPersistenceService {
|
||||
|
||||
private final TenantRepository tenantRepository;
|
||||
|
||||
|
||||
@Transactional
|
||||
public TenantEntity save(TenantEntity tenant) {
|
||||
|
||||
return tenantRepository.save(tenant);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user