http://jira.mfd.msk:8088/browse/CLS-11 добавил возможность валидации для экшенов

This commit is contained in:
ialbert 2022-10-28 09:10:49 +03:00
parent 8cdd8ce17b
commit dd958a36eb
6 changed files with 120 additions and 10 deletions

View file

@ -5,13 +5,14 @@ import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.backendapi.errors.BackEndError;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.platform.classes.base.interfaces.WithId;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class CommonDeleteAction implements IAction<CommonDeleteRequest> {
public class CommonDeleteAction implements IAction<CommonDeleteRequest>, WithId {
@JsonProperty
public Long id;

View file

@ -8,10 +8,11 @@ import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer;
import ru.spcex.platform.classes.base.interfaces.WithId;
import java.time.LocalDate;
public class MoneyMarketSecurityUpdateAction implements IAction<MoneyMarketSecurityUpdateRequest> {
public class MoneyMarketSecurityUpdateAction implements IAction<MoneyMarketSecurityUpdateRequest>, WithId {
@ApiModelProperty(hidden = true)
@JsonProperty
public Long id;

View file

@ -8,6 +8,7 @@ import ru.spcex.clearing.backendapi.controller.response.cud.QueueSuccessResponse
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.backendapi.service.IOperator;
import ru.spcex.clearing.backendapi.service.validation.ActionValidationProvider;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
@ -15,6 +16,7 @@ import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator;
import java.util.Collection;
import java.util.concurrent.ExecutionException;
@ -25,16 +27,18 @@ public class OperatorImpl implements IOperator {
private final Producer<String, Object> kafka;
private final ImdgId idGenerator;
private final ImdgProvider imdgProvider;
private final ActionValidationProvider validation;
public OperatorImpl(Producer<String, Object> kafka, ImdgProvider imdgProvider) {
public OperatorImpl(Producer<String, Object> kafka, ImdgProvider imdgProvider, ActionValidationProvider validation) {
this.kafka = kafka;
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.imdgProvider = imdgProvider;
this.validation = validation;
}
@Override
public QueueSuccessResponse sendRequestToQueue(String destination, IAction<?> iAction) throws ExecutionException, InterruptedException {
throwValidate(iAction);
throwValidate(destination, iAction);
BaseRequest<Object> request = new BaseRequest<>();
request.setId(idGenerator.nextId());
request.setActionType(iAction.getActionType());
@ -52,10 +56,16 @@ public class OperatorImpl implements IOperator {
requestStorage.insert(requestInfo);
}
private void throwValidate(IAction<?> iAction) {
private void throwValidate(String destination, IAction<?> iAction) {
Collection<EnumMessage> validationErrors = iAction.validate();
if (validationErrors.size() > 0) {
throw new ActionValidationException(validationErrors);
}
IValidator validator = validation.getValidator(destination, iAction);
if (validator != null) {
validator.tillFirstError().ifPresent(enumMessage -> {
throw new ActionValidationException(enumMessage);
});
}
}
}

View file

@ -0,0 +1,75 @@
package ru.spcex.clearing.backendapi.service.validation;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.backendapi.controller.request.cud.securities.MoneyMarketSecurityUpdateAction;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.backendapi.service.validation.rules.PresentById;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.classes.base.interfaces.WithId;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@Component
public class ActionValidationProvider implements InitializingBean {
private final Map<String, Imdg<?>> allImdgMaps;
private final ImdgProvider imdgProvider;
private final Map<String, Function<?, IValidator>> validators;
public ActionValidationProvider(ImdgProvider imdgProvider) {
this.validators = new HashMap<>();
this.allImdgMaps = new HashMap<>();
this.imdgProvider = imdgProvider;
}
@Override
public void afterPropertiesSet() throws Exception {
validators.put(Consts.DESTINATION_MONEY_MARKET_SECURITY_UPDATE, idPresent(IMDGDistributedNames.Map_MoneyMarketSecurity));
validators.put(Consts.DESTINATION_MONEY_MARKET_SECURITY_DELETE, idPresent(IMDGDistributedNames.Map_MoneyMarketSecurity));
}
@SuppressWarnings("unchecked")
public IValidator getValidator(String destination, Object action) {
Function<Object, IValidator> constructor = (Function<Object, IValidator>) validators.get(destination);
if (constructor != null)
return constructor.apply(action);
return null;
}
private Function<MoneyMarketSecurityUpdateAction, IValidator> mmsValidator() {
return mmsObj -> {
ImdgValidationContext<MoneyMarketSecurityUpdateAction> ctx = new ImdgValidationContext<>();
ctx.setValidatedObject(mmsObj);
ValidatorImpl<ImdgValidationContext<MoneyMarketSecurityUpdateAction>> iValidtor = new ValidatorImpl<>(ctx);
iValidtor.addRule(new PresentById(getImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, SpcexObjectBase.class)));
return iValidtor;
};
}
private <T extends IAction<?> & WithId> Function<T, IValidator> idPresent(String mapName) {
return iAction -> {
ImdgValidationContext<T> ctx = new ImdgValidationContext<>();
ctx.setValidatedObject(iAction);
ValidatorImpl<ImdgValidationContext<T>> iValidator = new ValidatorImpl<>(ctx);
iValidator.addRule(new PresentById(getImdg(mapName, SpcexObjectBase.class)));
return iValidator;
};
}
@SuppressWarnings("unchecked")
private <T extends SpcexObjectBase> Imdg<T> getImdg(String mapName, Class<T> clazz) {
return (Imdg<T>) allImdgMaps.computeIfAbsent(mapName, (mapName1) -> imdgProvider.getImdg(mapName, clazz));
}
}

View file

@ -0,0 +1,28 @@
package ru.spcex.clearing.backendapi.service.validation.rules;
import ru.spcex.clearing.backendapi.errors.BackEndError;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.classes.base.interfaces.WithId;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.util.Optional;
public class PresentById implements IValidationRule<ImdgValidationContext<WithId>> {
private final Imdg<SpcexObjectBase> map;
public PresentById(Imdg<SpcexObjectBase> map) {
this.map = map;
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<WithId> context) {
WithId actionById = context.getValidatedObject();
if (map.getSingleObjectByID(actionById.getId()) == null) {
return of(BackEndError.ResourceNotFound, actionById.getId());
} else {
return empty();
}
}
}

View file

@ -1,5 +0,0 @@
package ru.clearing.common.interfaces;
public interface WithId {
Long getId();
}