FINERACT-2343: Fix update currency api validation

This commit is contained in:
Oleksii Novikov
2025-08-14 15:35:26 +02:00
committed by Adam Saghy
parent 8e5113ddcd
commit 56f0b83d40
2 changed files with 19 additions and 5 deletions
@@ -25,22 +25,28 @@ import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
import java.util.List; import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse; import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
import org.apache.fineract.infrastructure.core.data.ApiParameterError; import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.exception.ErrorHandler; import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Slf4j @Slf4j
@Provider @Provider
@Component @Component
@RequiredArgsConstructor
public class JakartaValidationExceptionMapper implements FineractExceptionMapper, ExceptionMapper<ConstraintViolationException> { public class JakartaValidationExceptionMapper implements FineractExceptionMapper, ExceptionMapper<ConstraintViolationException> {
private final MessageSource messageSource;
@Override @Override
public Response toResponse(final ConstraintViolationException exception) { public Response toResponse(final ConstraintViolationException exception) {
log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception)); log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
final ApiGlobalErrorResponse dataValidationErrorResponse = ApiGlobalErrorResponse.badClientRequest(exception.getMessage(), final ApiGlobalErrorResponse dataValidationErrorResponse = ApiGlobalErrorResponse
exception.getLocalizedMessage(), getApiParameterErrors(exception)); .badClientRequest("validation.msg.validation.errors.exist", "Validation errors exist.", getApiParameterErrors(exception));
return Response.status(Status.BAD_REQUEST).entity(dataValidationErrorResponse).type(MediaType.APPLICATION_JSON).build(); return Response.status(Status.BAD_REQUEST).entity(dataValidationErrorResponse).type(MediaType.APPLICATION_JSON).build();
} }
@@ -51,7 +57,14 @@ public class JakartaValidationExceptionMapper implements FineractExceptionMapper
} }
private List<ApiParameterError> getApiParameterErrors(final ConstraintViolationException exception) { private List<ApiParameterError> getApiParameterErrors(final ConstraintViolationException exception) {
return exception.getConstraintViolations().stream().map(violation -> ApiParameterError return exception.getConstraintViolations().stream().map(violation -> {
.parameterError(violation.getMessageTemplate(), violation.getMessage(), violation.getPropertyPath().toString())).toList(); final String messageTemplate = violation.getMessageTemplate();
final String messageKey = messageTemplate.replace("{", "").replace("}", "");
final String interpolatedMessage = messageSource.getMessage(messageKey, null, LocaleContextHolder.getLocale());
return ApiParameterError.parameterError(messageKey, interpolatedMessage, violation.getPropertyPath().toString());
}).toList();
} }
} }
@@ -20,6 +20,7 @@ package org.apache.fineract.organisation.monetary.api;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.ws.rs.Consumes; import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
import jakarta.ws.rs.PUT; import jakarta.ws.rs.PUT;
@@ -66,7 +67,7 @@ public class CurrenciesApiResource {
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Update Currency Configuration", description = "Updates the list of currencies permitted for use.") @Operation(summary = "Update Currency Configuration", description = "Updates the list of currencies permitted for use.")
public CurrencyUpdateResponse updateCurrencies(CurrencyUpdateRequest request) { public CurrencyUpdateResponse updateCurrencies(@Valid CurrencyUpdateRequest request) {
final var command = new CurrencyUpdateCommand(); final var command = new CurrencyUpdateCommand();
command.setId(UUID.randomUUID()); command.setId(UUID.randomUUID());