Pull request #560: RED-5293: 500 for invalid tenant
Merge in RED/persistence-service from RED-5293 to master * commit '9b7d1536ebb8bb2056c4e5519c0428f1f865a81e': RED-5293: Changed output to client to explain which argument is broken RED-5293: Changed output to client to explain which argument is broken RED-5293: Changed error message for empty parameters to show client which parameter is broken RED-5293: 500 for invalid tenant RED-5293: 500 for invalid tenant RED-5293: 500 for invalid tenant RED-5293: 500 for invalid tenant RED-5293: 500 for invalid tenant RED-5293: 500 for invalid tenant RED-5293: 500 for invalid tenant
This commit is contained in:
commit
6333d9e087
@ -14,11 +14,12 @@ import lombok.NoArgsConstructor;
|
||||
@NoArgsConstructor
|
||||
public class TenantRequest {
|
||||
|
||||
@NotNull
|
||||
@NotBlank
|
||||
private String tenantId;
|
||||
@NotBlank
|
||||
private String displayName;
|
||||
private String guid;
|
||||
@NotBlank
|
||||
private String jdbcUrl;
|
||||
@NotBlank
|
||||
private String user;
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
package com.iqser.red.service.peristence.v1.server.controller;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.postgresql.util.PSQLException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
@ -83,8 +85,8 @@ public class ControllerAdvice {
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ExceptionHandler(value = PSQLException.class)
|
||||
public ResponseEntity<ErrorMessage> handleSQLException(PSQLException e) {
|
||||
@ExceptionHandler(value = SQLException.class)
|
||||
public ResponseEntity<ErrorMessage> handleSQLException(SQLException e) {
|
||||
|
||||
if (e.getMessage().contains("violates unique constraint")) {
|
||||
return new ResponseEntity<>(new ErrorMessage(OffsetDateTime.now(), "Unique constraint violation"), HttpStatus.CONFLICT);
|
||||
@ -99,8 +101,9 @@ public class ControllerAdvice {
|
||||
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
|
||||
@ExceptionHandler(value = MethodArgumentNotValidException.class)
|
||||
public ErrorMessage handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
||||
|
||||
return new ErrorMessage(OffsetDateTime.now(), e.getMessage());
|
||||
var errorList = e.getFieldErrors();
|
||||
String errorListAsString = errorList.stream().map(fieldError -> fieldError.getField() + ": " + fieldError.getDefaultMessage()).collect(Collectors.joining(", "));
|
||||
return new ErrorMessage(OffsetDateTime.now(), String.format("You have empty/wrong formatted parameters: %s", errorListAsString));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
package com.iqser.red.service.peristence.v1.server.service;
|
||||
|
||||
import java.net.URI;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -16,7 +18,6 @@ import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.multitenancy.entity.TenantEntity;
|
||||
@ -28,11 +29,15 @@ import com.iqser.red.service.persistence.service.v1.api.model.multitenancy.Tenan
|
||||
import liquibase.exception.LiquibaseException;
|
||||
import liquibase.integration.spring.SpringLiquibase;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@EnableConfigurationProperties(LiquibaseProperties.class)
|
||||
public class TenantManagementService {
|
||||
|
||||
private static final Set<String> SQL_CONNECTION_ERROR_CODES = Set.of("08000", "08003", "08006");
|
||||
|
||||
private final EncryptionDecryptionService encryptionService;
|
||||
|
||||
private final LiquibaseProperties liquibaseProperties;
|
||||
@ -58,11 +63,16 @@ public class TenantManagementService {
|
||||
|
||||
if (tenantRepository.findById(tenantRequest.getTenantId()).isEmpty()) {
|
||||
|
||||
validateJdbcUrl(tenantRequest.getJdbcUrl());
|
||||
|
||||
String encryptedPassword = encryptionService.encrypt(tenantRequest.getPassword());
|
||||
|
||||
try (Connection connection = DriverManager.getConnection(tenantRequest.getJdbcUrl(), tenantRequest.getUser(), tenantRequest.getPassword())) {
|
||||
DataSource tenantDataSource = new SingleConnectionDataSource(connection, false);
|
||||
runLiquibase(tenantDataSource);
|
||||
} catch (PSQLException e) {
|
||||
handleClientException(e);
|
||||
handleInternalException(e);
|
||||
}
|
||||
|
||||
TenantEntity tenantEntity = TenantEntity.builder()
|
||||
@ -80,6 +90,25 @@ public class TenantManagementService {
|
||||
}
|
||||
|
||||
|
||||
private void handleClientException(PSQLException e) {
|
||||
|
||||
if (e.getSQLState().equals("28000") || e.getSQLState().equals("28P01")) {
|
||||
throw new IllegalArgumentException("Database credentials are not correct. Please check them.");
|
||||
}
|
||||
if (SQL_CONNECTION_ERROR_CODES.contains(e.getSQLState())) {
|
||||
throw new IllegalArgumentException("Error when connecting to tenant database. Please check the jdbcUrl parameter.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void handleInternalException(PSQLException e) {
|
||||
|
||||
log.error(String.format("Connection to tenant DB failed with SQL state %s. Please check if the tenant DB is still running. " + //
|
||||
"If yes please check the connection configuration.", e.getSQLState()), e);
|
||||
throw new RuntimeException("Could not connect to the tenant DB. This is an internal error.", e);
|
||||
}
|
||||
|
||||
|
||||
public List<TenantResponse> getTenants() {
|
||||
|
||||
return tenantRepository.findAll().stream().map(this::convert).collect(Collectors.toList());
|
||||
@ -92,6 +121,14 @@ public class TenantManagementService {
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
private void validateJdbcUrl(String jdbcUrl) {
|
||||
// just create a URI object to check if the string is a valid URI
|
||||
new URI(jdbcUrl);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private TenantResponse convert(TenantEntity entity) {
|
||||
|
||||
return TenantResponse.builder()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user