This commit is contained in:
parent
7b0c48f785
commit
a980ff8a0c
3 changed files with 202 additions and 15 deletions
|
|
@ -49,6 +49,7 @@ import static ru.spcex.platform.imdg.api.predicate.specific.IdEqualPredicate.byI
|
||||||
import ru.spcex.platform.imdg.api.predicate.specific.SecuritySelector;
|
import ru.spcex.platform.imdg.api.predicate.specific.SecuritySelector;
|
||||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||||
import ru.spcex.platform.imdg.validation.LogPrefixId;
|
import ru.spcex.platform.imdg.validation.LogPrefixId;
|
||||||
|
import ru.spcex.platform.imdg.validation.rule.CollectionByPredicate;
|
||||||
import ru.spcex.platform.imdg.validation.rule.PresentById;
|
import ru.spcex.platform.imdg.validation.rule.PresentById;
|
||||||
import ru.spcex.platform.imdg.validation.rule.PresentByPredicate;
|
import ru.spcex.platform.imdg.validation.rule.PresentByPredicate;
|
||||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||||
|
|
@ -455,7 +456,7 @@ public class ValidationConfig {
|
||||||
.store(OrderCurrencyValidationStored.TCR)
|
.store(OrderCurrencyValidationStored.TCR)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
var counterOrderPresent = PresentByPredicate
|
var counterOrderPresentV2 = CollectionByPredicate
|
||||||
.builder(r -> {
|
.builder(r -> {
|
||||||
OrderCurrency oc = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency);
|
OrderCurrency oc = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency);
|
||||||
ImdgPredicateBuilder pb = orderCurrencyImdg.predicateBuilder();
|
ImdgPredicateBuilder pb = orderCurrencyImdg.predicateBuilder();
|
||||||
|
|
@ -470,6 +471,7 @@ public class ValidationConfig {
|
||||||
.mapName(IMDGDistributedNames.Map_OrderCurrency)
|
.mapName(IMDGDistributedNames.Map_OrderCurrency)
|
||||||
.errorProvider(r -> recordNotFound("counter OrderCurrency"))
|
.errorProvider(r -> recordNotFound("counter OrderCurrency"))
|
||||||
.store(OrderCurrencyValidationStored.CounterOrderCurrency)
|
.store(OrderCurrencyValidationStored.CounterOrderCurrency)
|
||||||
|
.greaterOrEquals(1)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
//fixme проверить что tcr.getCompanyId() = companyId из запроса?
|
//fixme проверить что tcr.getCompanyId() = companyId из запроса?
|
||||||
|
|
@ -481,7 +483,7 @@ public class ValidationConfig {
|
||||||
OrderCurrencyCompanyNotChanged.INSTANCE,
|
OrderCurrencyCompanyNotChanged.INSTANCE,
|
||||||
//OrderCurrencyByCompanyAndTcrAlreadyPresent.getInstance(OrderCompanyUpdateRequest.class),
|
//OrderCurrencyByCompanyAndTcrAlreadyPresent.getInstance(OrderCompanyUpdateRequest.class),
|
||||||
OrderCurrencyPLBLCheck.INSTANCE,
|
OrderCurrencyPLBLCheck.INSTANCE,
|
||||||
counterOrderPresent);
|
counterOrderPresentV2);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -502,7 +504,7 @@ public class ValidationConfig {
|
||||||
.store(OrderCurrencyValidationStored.OrderCurrency)
|
.store(OrderCurrencyValidationStored.OrderCurrency)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
var counterOrderPresent = PresentByPredicate
|
var counterOrderPresentV2 = CollectionByPredicate
|
||||||
.builder(r -> {
|
.builder(r -> {
|
||||||
OrderCurrency oc = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency);
|
OrderCurrency oc = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency);
|
||||||
ImdgPredicateBuilder pb = orderCurrencyImdg.predicateBuilder();
|
ImdgPredicateBuilder pb = orderCurrencyImdg.predicateBuilder();
|
||||||
|
|
@ -517,11 +519,12 @@ public class ValidationConfig {
|
||||||
.mapName(IMDGDistributedNames.Map_OrderCurrency)
|
.mapName(IMDGDistributedNames.Map_OrderCurrency)
|
||||||
.errorProvider(r -> recordNotFound("counter OrderCurrency"))
|
.errorProvider(r -> recordNotFound("counter OrderCurrency"))
|
||||||
.store(OrderCurrencyValidationStored.CounterOrderCurrency)
|
.store(OrderCurrencyValidationStored.CounterOrderCurrency)
|
||||||
|
.greaterOrEquals(1)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return new ValidatorImpl<>(ctx,
|
return new ValidatorImpl<>(ctx,
|
||||||
orderCurrencyPresent,
|
orderCurrencyPresent,
|
||||||
counterOrderPresent);
|
counterOrderPresentV2);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,10 @@ import java.math.BigDecimal;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import org.apache.kafka.clients.consumer.Consumer;
|
import org.apache.kafka.clients.consumer.Consumer;
|
||||||
import org.apache.kafka.clients.producer.Producer;
|
import org.apache.kafka.clients.producer.Producer;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
@ -362,7 +364,7 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing
|
||||||
OrderCurrency order = validator.getStored(OrderCurrencyValidationStored.OrderCurrency);
|
OrderCurrency order = validator.getStored(OrderCurrencyValidationStored.OrderCurrency);
|
||||||
Company company = validator.getStored(OrderCurrencyValidationStored.Company);
|
Company company = validator.getStored(OrderCurrencyValidationStored.Company);
|
||||||
TradingClearingRegistry tcr = validator.getStored(OrderCurrencyValidationStored.TCR);
|
TradingClearingRegistry tcr = validator.getStored(OrderCurrencyValidationStored.TCR);
|
||||||
OrderCurrency counterOrder = validator.getStored(OrderCurrencyValidationStored.CounterOrderCurrency);
|
Collection<OrderCurrency> counterOrders = validator.getStored(OrderCurrencyValidationStored.CounterOrderCurrency);
|
||||||
|
|
||||||
order.setCompanyId(payload.getCompanyId());
|
order.setCompanyId(payload.getCompanyId());
|
||||||
order.setTradingClearingRegistryId(payload.getTradingClearingRegistryId());
|
order.setTradingClearingRegistryId(payload.getTradingClearingRegistryId());
|
||||||
|
|
@ -371,14 +373,18 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing
|
||||||
order.setTradingCode(company.getTradingCode());
|
order.setTradingCode(company.getTradingCode());
|
||||||
order.setUpdated(now);
|
order.setUpdated(now);
|
||||||
|
|
||||||
counterOrder.setCounterPartyId(payload.getCompanyId());
|
log.info("updating OrderCurrency[{}, {}]", order.getId(),
|
||||||
counterOrder.setCounterTradingCode(company.getTradingCode());
|
counterOrders.stream().map(OrderCurrency::getId).map(Object::toString).collect(Collectors.joining(",")));
|
||||||
counterOrder.setQuantityLot(new BigDecimal(payload.getQuantityLot()));
|
|
||||||
counterOrder.setUpdated(now);
|
|
||||||
|
|
||||||
log.info("updating OrderCurrency[{}, {}]", order.getId(), counterOrder.getId());
|
|
||||||
orderCurrencyImdg.update(order);
|
orderCurrencyImdg.update(order);
|
||||||
orderCurrencyImdg.update(counterOrder);
|
|
||||||
|
counterOrders.forEach(counterOrder -> {
|
||||||
|
counterOrder.setCounterPartyId(payload.getCompanyId());
|
||||||
|
counterOrder.setCounterTradingCode(company.getTradingCode());
|
||||||
|
counterOrder.setQuantityLot(new BigDecimal(payload.getQuantityLot()));
|
||||||
|
counterOrder.setUpdated(now);
|
||||||
|
orderCurrencyImdg.update(counterOrder);
|
||||||
|
}
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -390,11 +396,12 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing
|
||||||
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(error.get()));
|
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(error.get()));
|
||||||
}
|
}
|
||||||
OrderCurrency order = validator.getStored(OrderCurrencyValidationStored.OrderCurrency);
|
OrderCurrency order = validator.getStored(OrderCurrencyValidationStored.OrderCurrency);
|
||||||
OrderCurrency counterOrder = validator.getStored(OrderCurrencyValidationStored.CounterOrderCurrency);
|
Collection<OrderCurrency> counterOrders = validator.getStored(OrderCurrencyValidationStored.CounterOrderCurrency);
|
||||||
|
|
||||||
log.info("deleting OrderCurrency[{}, {}]", order.getId(), counterOrder.getId());
|
log.info("deleting OrderCurrency[{}, {}]", order.getId(),
|
||||||
|
counterOrders.stream().map(OrderCurrency::getId).map(Object::toString).collect(Collectors.joining(",")));
|
||||||
reject(order);
|
reject(order);
|
||||||
reject(counterOrder);
|
counterOrders.forEach(this::reject);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
package ru.spcex.platform.imdg.validation.rule;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||||
|
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||||
|
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||||
|
import ru.spcex.platform.utils.validation.IValidationRule;
|
||||||
|
|
||||||
|
public class CollectionByPredicate<T> implements IValidationRule<ImdgValidationContext<T>> {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CollectionByPredicate.class);
|
||||||
|
|
||||||
|
private final String mapName;
|
||||||
|
private final Function<T, EnumMessage> errorProvider;
|
||||||
|
private final Function<T, ImdgPredicate> predicateProvider;
|
||||||
|
private final Enum<?> storeEnabled;
|
||||||
|
private Integer precise;
|
||||||
|
private Integer min;
|
||||||
|
private Integer max;
|
||||||
|
|
||||||
|
private CollectionByPredicate(
|
||||||
|
String mapName,
|
||||||
|
Function<T, ImdgPredicate> predicateProvider,
|
||||||
|
Function<T, EnumMessage> errorProvider,
|
||||||
|
Enum<?> storeEnabled
|
||||||
|
) {
|
||||||
|
this.mapName = mapName;
|
||||||
|
this.errorProvider = errorProvider;
|
||||||
|
this.storeEnabled = storeEnabled;
|
||||||
|
this.predicateProvider = predicateProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrecise(Integer precise) {
|
||||||
|
this.precise = precise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMin(Integer min) {
|
||||||
|
this.min = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMax(Integer max) {
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> PredicateStep<T> builder(Function<T, ImdgPredicate> predicateProvider) {
|
||||||
|
return new Builder<>(predicateProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<EnumMessage> validate(ImdgValidationContext<T> context) {
|
||||||
|
T validatedObject = context.getValidatedObject();
|
||||||
|
Imdg<SpcexObjectBase> targetMap = context.obtainMap(mapName, SpcexObjectBase.class);
|
||||||
|
|
||||||
|
ImdgPredicate predicate = predicateProvider.apply(validatedObject);
|
||||||
|
Collection<SpcexObjectBase> obj = targetMap.getCollectionObjectsByPredicate(predicate);
|
||||||
|
String specificMsg = "[too many...]";
|
||||||
|
if (obj.size() <= 20) {
|
||||||
|
specificMsg = obj
|
||||||
|
.stream()
|
||||||
|
.map(SpcexObjectBase::getId)
|
||||||
|
.map(Object::toString)
|
||||||
|
.collect(Collectors.joining(",", "[", "]"));
|
||||||
|
}
|
||||||
|
log.debug("objects found by predicate [{}]: size {}, ids {}", predicate, obj.size(), specificMsg);
|
||||||
|
|
||||||
|
if (precise != null && obj.size() != precise) {
|
||||||
|
log.debug("predicate: {}; expected size: {}, actual: {}", predicate, precise, obj.size());
|
||||||
|
return Optional.of(errorProvider.apply(validatedObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max != null && obj.size() > max) {
|
||||||
|
log.debug("predicate: {}; more objects found ({}) than expected ({})", predicate, obj.size(), max);
|
||||||
|
return Optional.of(errorProvider.apply(validatedObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min != null && obj.size() < min) {
|
||||||
|
log.debug("predicate: {}; fewer objects were found ({}) than expected ({}) ", predicate, obj.size(), min);
|
||||||
|
return Optional.of(errorProvider.apply(validatedObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (storeEnabled != null) {
|
||||||
|
context.storeObject(storeEnabled, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface PredicateStep<T> {
|
||||||
|
MapStep<T> mapName(String mapName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface MapStep<T> {
|
||||||
|
OptionsStep<T> errorProvider(Function<T, EnumMessage> errorProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OptionsStep<T> {
|
||||||
|
OptionsStep<T> store(Enum<?> storeEnabled);
|
||||||
|
OptionsStep<T> precise(int number);
|
||||||
|
OptionsStep<T> greaterOrEquals(int number);
|
||||||
|
OptionsStep<T> lessThanOrEquals(int number);
|
||||||
|
CollectionByPredicate<T> build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class Builder<T>
|
||||||
|
implements PredicateStep<T>, MapStep<T>, OptionsStep<T> {
|
||||||
|
|
||||||
|
private final Function<T, ImdgPredicate> predicateProvider;
|
||||||
|
private String mapName;
|
||||||
|
private Function<T, EnumMessage> errorProvider;
|
||||||
|
private Enum<?> storeEnabled;
|
||||||
|
private int precise;
|
||||||
|
private int min;
|
||||||
|
private int max;
|
||||||
|
|
||||||
|
|
||||||
|
private Builder(Function<T, ImdgPredicate> predicateProvider) {
|
||||||
|
this.predicateProvider = predicateProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapStep<T> mapName(String mapName) {
|
||||||
|
this.mapName = mapName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OptionsStep<T> errorProvider(Function<T, EnumMessage> errorProvider) {
|
||||||
|
this.errorProvider = errorProvider;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OptionsStep<T> store(Enum<?> storeEnabled) {
|
||||||
|
this.storeEnabled = storeEnabled;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OptionsStep<T> precise(int number) {
|
||||||
|
this.precise = number;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OptionsStep<T> greaterOrEquals(int number) {
|
||||||
|
this.min = number;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OptionsStep<T> lessThanOrEquals(int number) {
|
||||||
|
this.max = number;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionByPredicate<T> build() {
|
||||||
|
CollectionByPredicate<T> rule = new CollectionByPredicate<>(
|
||||||
|
mapName,
|
||||||
|
predicateProvider,
|
||||||
|
errorProvider,
|
||||||
|
storeEnabled
|
||||||
|
);
|
||||||
|
rule.setMax(max);
|
||||||
|
rule.setMin(min);
|
||||||
|
rule.setPrecise(precise);
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue