Merge branch 'imdg_hist' into dev

This commit is contained in:
etreschenkov 2023-10-18 13:39:41 +03:00
commit 02c768d273
81 changed files with 2598 additions and 23 deletions

View file

@ -21,6 +21,16 @@ public class BackEndApiImdgConfig {
return createThreadPoolTaskExecutor(1, false);
}
@Bean(name = "taskExecutorHazelcastClientInitializerHist")
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializerHist() {
return createThreadPoolTaskExecutor(1, true);
}
@Bean(name = "taskExecutorIdGeneratorAwaiterHist")
public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiterHist() {
return createThreadPoolTaskExecutor(1, false);
}
@Autowired
@Bean
public ImdgProvider imdgProvider(
@ -35,6 +45,20 @@ public class BackEndApiImdgConfig {
return imdg;
}
@Autowired
@Bean
public ImdgProvider imdgProviderHist(
@Qualifier("taskExecutorHazelcastClientInitializerHist") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
@Qualifier("taskExecutorIdGeneratorAwaiterHist") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
BackendApiSettings clientSetting
) {
ImdgProvider imdg = new HazelcastService(taskExecutorHazelcastClientInitializer,
taskExecutorIdGeneratorAwaiter,
clientSetting.getHazelcastSearch());
// todo корректное ожидание готовности imdg.waitAvailable();
return imdg;
}
private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();

View file

@ -0,0 +1,76 @@
package ru.spcex.clearing.backendapi.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.HistorySubscription;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.specific.ClearingDateFromCondition;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.specific.ClearingDateToCondition;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.specific.CreatedFromCondition;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.specific.CreatedToCondition;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import java.util.LinkedList;
import java.util.List;
@Configuration
public class HistoryConfig {
private final ImdgPredicateBuilder pb;
@Autowired
public HistoryConfig(ImdgProvider imdgProvider) {
this.pb = imdgProvider.getImdg(
IMDGDistributedNames.Map_SearchMoneyBalanceRegister,
SpcexObjectBase.class
).predicateBuilder();
}
@Bean
public List<HistorySubscription> histSubscriptions() {
List<HistorySubscription> hst = new LinkedList<>();
hst.add(moneyBalanceRegister());
hst.add(admittedLiabilitiesRegister());
hst.add(moneyPaymentInstructionRegister());
return hst;
}
private HistorySubscription moneyBalanceRegister() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("money-balance-registers");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchMoneyBalanceRegister);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_MoneyBalanceRegister);
sbscr.setConditions(List.of(
new CreatedFromCondition(pb),
new CreatedToCondition(pb)
));
return sbscr;
}
private HistorySubscription admittedLiabilitiesRegister() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("admitted-liabilities-registers");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchAdmittedLiabilitiesRegister);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_AdmittedLiabilitiesRegister);
sbscr.setConditions(List.of(
new ClearingDateFromCondition(pb),
new ClearingDateToCondition(pb)
));
return sbscr;
}
private HistorySubscription moneyPaymentInstructionRegister() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("money-payment-instruction-registers");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchMoneyPaymentInstructionRegister);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_MoneyPaymentInstructionRegister);
sbscr.setConditions(List.of(
new ClearingDateFromCondition(pb),
new ClearingDateToCondition(pb)
));
return sbscr;
}
}

View file

@ -13,6 +13,7 @@ import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
@ConfigurationProperties("backend-api")
public class BackendApiSettings {
private HazelcastClientParams hazelcast;
private HazelcastClientParams hazelcastSearch;
private KafkaProducerSettings kafkaProducer;
private KafkaConsumerSettings kafkaConsumer;
private SecuritySettings security;
@ -57,4 +58,12 @@ public class BackendApiSettings {
public void setSecurity(SecuritySettings security) {
this.security = security;
}
public HazelcastClientParams getHazelcastSearch() {
return hazelcastSearch;
}
public void setHazelcastSearch(HazelcastClientParams hazelcastSearch) {
this.hazelcastSearch = hazelcastSearch;
}
}

View file

@ -0,0 +1,95 @@
package ru.spcex.clearing.backendapi.controller.queue.history;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.ConditionProvider;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.HistorySubscription;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.backendapi.errors.BackEndError;
import ru.spcex.clearing.backendapi.meta.GetResponseFactory;
import ru.spcex.clearing.backendapi.service.IStateLoader;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
@Controller
@RequestMapping("/history")
public class HistController {
private final GetResponseFactory responseFactory;
private final IStateLoader stateLoader;
private final ConditionProvider conditionProvider;
@Autowired
public HistController(GetResponseFactory responseFactory,
IStateLoader stateLoader,
ConditionProvider conditionProvider) {
this.responseFactory = responseFactory;
this.stateLoader = stateLoader;
this.conditionProvider = conditionProvider;
}
@ApiOperation(value = "Get history")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(path = "/all", method = RequestMethod.POST)
@ResponseBody
public CommonGetAllResponse getHistory(
@ApiParam(value = "destination сущности по которой запрашивается история", example = "money-balance-registers", required = true)
@RequestParam("destination")
String destination,
@ApiParam(value = "Начальная точка поиска по дате", example = "2023-01-15")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
@RequestParam(name = "from", required = false)
LocalDate from,
@ApiParam(value = "Конечная точка поиска по дате", example = "2023-01-15")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
@RequestParam(name = "to", required = false)
LocalDate to
) {
if (to == null && from == null) {
throw new ActionValidationException(new EnumMessage(BackEndError.ValidationError, "from/to url params both empty"));
}
Optional<Class<? extends SpcexObjectBase>> entityClass = responseFactory.classByDestination(destination);
//class may be added to HistorySubscription if needed
if (entityClass.isEmpty()) {
throw new ActionValidationException(new EnumMessage(BackEndError.ValidationError,
"destination " + "'" + destination + "' not supported (meta class not found)"));
}
HistoryRequest req = new HistoryRequest();
req.setTable(destination);
req.setFrom(from);
req.setTo(to);
HistorySubscription[] subscr = new HistorySubscription[1];
ImdgPredicate[] prdct = new ImdgPredicate[1];
conditionProvider.conditionForRequest(req).map(s -> subscr[0] = s, p -> prdct[0] = p);
Collection<Map<String, Object>> searchRes = stateLoader.getAllMetaTransform(
subscr[0].getSearchProxyMapName(),
subscr[0].getFullHistoryMapName(),
entityClass.get(),
prdct[0]
);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(searchRes);
return response;
}
}

View file

@ -0,0 +1,72 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.backendapi.errors.BackEndError;
import ru.spcex.clearing.backendapi.meta.GetResponseFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.collection.Pair;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Component
public class ConditionProvider {
private final Logger log = LoggerFactory.getLogger(getClass());
private final GetResponseFactory responseFactory;
private final ImdgPredicateBuilder pb;
private final Map<String, HistorySubscription> subscriptions;
@Autowired
public ConditionProvider(GetResponseFactory responseFactory, ImdgProvider imdgProvider,
List<HistorySubscription> subscriptions) {
this.responseFactory = responseFactory;
this.subscriptions = new HashMap<>();
Imdg<SpcexObjectBase> imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SearchMoneyBalanceRegister, SpcexObjectBase.class);
this.pb = imdg.predicateBuilder();
subscriptions.forEach(s -> this.subscriptions.put(s.getDestination(), s));
}
public Pair<HistorySubscription, ImdgPredicate> conditionForRequest(HistoryRequest req) {
String destination = req.getTable();
HistorySubscription subscription = subscriptions.get(destination);
if (subscription == null) {
throw new ActionValidationException(new EnumMessage(BackEndError.ValidationError,
"destination " + "'" + destination + "' not supported (subscription info not found)"));
}
List<ImdgPredicate> predicates = subscription
.getConditions()
.stream()
.map(c -> c.condition(req))
.filter(Optional::isPresent)
.map(Optional::get)
.toList();
ImdgPredicate result;
if (predicates.size() == 0) {
//add boundary conditions?
log.warn("destination '{}' zero predicates found", destination);
result = pb.alwaysTrue();
} else if (predicates.size() == 1) {
result = predicates.iterator().next();
} else {
result = pb.and(predicates.toArray(new ImdgPredicate[0]));
}
return new Pair<>(subscription, result);
}
}

View file

@ -0,0 +1,46 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition;
import java.util.Collections;
import java.util.List;
public class HistorySubscription {
private String destination;
private List<IHistoryCondition> conditions;
private String searchProxyMapName;
private String fullHistoryMapName;
//class
public List<IHistoryCondition> getConditions() {
return conditions != null ? conditions : Collections.emptyList();
}
public void setConditions(List<IHistoryCondition> conditions) {
this.conditions = conditions;
}
public String getSearchProxyMapName() {
return searchProxyMapName;
}
public void setSearchProxyMapName(String searchProxyMapName) {
this.searchProxyMapName = searchProxyMapName;
}
public String getFullHistoryMapName() {
return fullHistoryMapName;
}
public void setFullHistoryMapName(String fullHistoryMapName) {
this.fullHistoryMapName = fullHistoryMapName;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
}

View file

@ -0,0 +1,15 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import java.util.Optional;
public interface IHistoryCondition {
Optional<ImdgPredicate> condition(HistoryRequest req);
default Optional<ImdgPredicate> of(ImdgPredicate predicate) {
return Optional.of(predicate);
}
}

View file

@ -0,0 +1,25 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition.specific;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.IHistoryCondition;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import java.util.Optional;
public class ClearingDateFromCondition implements IHistoryCondition {
private final ImdgPredicateBuilder pb;
public ClearingDateFromCondition(ImdgPredicateBuilder pb) {
this.pb = pb;
}
@Override
public Optional<ImdgPredicate> condition(HistoryRequest req) {
if (req.getFrom() != null) {
return Optional.ofNullable(pb.greatEqual("clearingDate", req.getFrom()));
}
return Optional.empty();
}
}

View file

@ -0,0 +1,25 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition.specific;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.IHistoryCondition;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import java.util.Optional;
public class ClearingDateToCondition implements IHistoryCondition {
private final ImdgPredicateBuilder pb;
public ClearingDateToCondition(ImdgPredicateBuilder pb) {
this.pb = pb;
}
@Override
public Optional<ImdgPredicate> condition(HistoryRequest req) {
if (req.getTo() != null) {
return Optional.ofNullable(pb.lessEqual("clearingDate", req.getTo()));
}
return Optional.empty();
}
}

View file

@ -0,0 +1,26 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition.specific;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.IHistoryCondition;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.time.TimeUtil;
import java.util.Optional;
public class CreatedFromCondition implements IHistoryCondition {
private final ImdgPredicateBuilder pb;
public CreatedFromCondition(ImdgPredicateBuilder pb) {
this.pb = pb;
}
@Override
public Optional<ImdgPredicate> condition(HistoryRequest req) {
if (req.getFrom() != null) {
return Optional.of(pb.greatEqual("created", TimeUtil.localDateToInstant(req.getFrom())));
}
return Optional.empty();
}
}

View file

@ -0,0 +1,26 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition.specific;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.IHistoryCondition;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.time.TimeUtil;
import java.util.Optional;
public class CreatedToCondition implements IHistoryCondition {
private final ImdgPredicateBuilder pb;
public CreatedToCondition(ImdgPredicateBuilder pb) {
this.pb = pb;
}
@Override
public Optional<ImdgPredicate> condition(HistoryRequest req) {
if (req.getTo() != null) {
return Optional.of(pb.lessEqual("created", TimeUtil.localDateToInstant(req.getTo())));
}
return Optional.empty();
}
}

View file

@ -0,0 +1,51 @@
package ru.spcex.clearing.backendapi.controller.request.cud.history;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.annotations.ApiModelProperty;
import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer;
import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer;
import java.time.LocalDate;
public class HistoryRequest {
@ApiModelProperty(value = "Таблица для поиска", example = "1200")
@JsonProperty
private String table;
@ApiModelProperty(value = "Начальный точка поиска по дате", example = "2022-12-25")
@JsonProperty
@JsonSerialize(using = LocalDateSerializer.class)
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate from;
@ApiModelProperty(value = "Конечная точка поиска по дате ", example = "2022-12-25")
@JsonProperty
@JsonSerialize(using = LocalDateSerializer.class)
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate to;
public String getTable() {
return table;
}
public void setTable(String table) {
this.table = table;
}
public LocalDate getFrom() {
return from;
}
public void setFrom(LocalDate from) {
this.from = from;
}
public LocalDate getTo() {
return to;
}
public void setTo(LocalDate to) {
this.to = to;
}
}

View file

@ -5,6 +5,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.utils.time.TimeUtil;
import java.text.SimpleDateFormat;
@ -130,6 +131,19 @@ public class GetResponseFactory {
response.put(name, data);
}
public Optional<Class<? extends SpcexObjectBase>> classByDestination(String destination) {
Map<String, ObjectExtracted> extracted = meta.getObjectsExtractedByDestination();
ObjectExtracted objectExtracted = extracted.get(destination);
if (objectExtracted == null) return Optional.empty();
try {
Class<? extends SpcexObjectBase> clazz = (Class<? extends SpcexObjectBase>) objectExtracted.getClazz();
return Optional.ofNullable(clazz);
} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
return Optional.empty();
}
}
private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss+03:00")
.withLocale(Locale.US)

View file

@ -3,6 +3,7 @@ package ru.spcex.clearing.backendapi.meta;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.spcex.platform.utils.log.ExceptionUtils;
import ru.spcex.platform.utils.text.TextUtil;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
@ -67,6 +68,8 @@ public class MetaServer extends MetaBase {
objectsExtractedByClazz.put(String.valueOf(classNameMock++), oe);
if (objectElement.getSubscription() != null && objectElement.getSubscription().destination != null) {
objectsExtractedByDestination.put(objectElement.getSubscription().destination, oe);
} else if (!TextUtil.isEmpty(objectElement.getDestination())) {
objectsExtractedByDestination.put(objectElement.getDestination(), oe);
}
for (ActionElement actionElement : objectElement.getActions()) {
if (actionElement.getClazz() == null) {

View file

@ -18,6 +18,10 @@ public class ObjectElement {
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String table = null;
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String destination = null;
@JsonProperty(value = "fields", required = true)
private List<ActionField> fields = new LinkedList<>();
@ -76,4 +80,12 @@ public class ObjectElement {
public Subscription getSubscriptionHistory() {
return subscriptionHistory;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
}

View file

@ -17,4 +17,9 @@ public interface IStateLoader {
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransformSpecificClass(String mapName, Class<T> clazz);
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(String mapName, Class<T> clazz, Map<String, ? extends Comparable<?>> conditions);
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(String mapName, Class<T> clazz, ImdgPredicate conditions);
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(
String searchMapName,
String mapName,
Class<T> clazz,
ImdgPredicate conditions);
}

View file

@ -1,6 +1,7 @@
package ru.spcex.clearing.backendapi.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.spcex.clearing.backendapi.meta.GetResponseFactory;
import ru.spcex.clearing.backendapi.service.IStateLoader;
@ -9,21 +10,24 @@ import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class StateLoaderImpl implements IStateLoader {
private final Map<String, Imdg<?>> allImdgMaps;
private final Map<String, Imdg<?>> allHistMaps;
private final ImdgProvider imdgProvider;
private final ImdgProvider imdgHistProvider;
private final GetResponseFactory responseFactory;
@Autowired
public StateLoaderImpl(ImdgProvider imdgProvider, GetResponseFactory responseFactory) {
public StateLoaderImpl(@Qualifier("imdgProvider") ImdgProvider imdgProvider,
@Qualifier("imdgProviderHist") ImdgProvider imdgHistProvider, GetResponseFactory responseFactory) {
this.imdgHistProvider = imdgHistProvider;
this.responseFactory = responseFactory;
this.allImdgMaps = new ConcurrentHashMap<>();
this.allHistMaps = new HashMap<>();
this.imdgProvider = imdgProvider;
}
@ -73,4 +77,25 @@ public class StateLoaderImpl implements IStateLoader {
private <T extends SpcexObjectBase> Imdg<T> getImdg(String mapName, Class<T> clazz) {
return (Imdg<T>) allImdgMaps.computeIfAbsent(mapName, (mapName1) -> imdgProvider.getImdg(mapName, clazz));
}
@SuppressWarnings("unchecked")
private <T extends SpcexObjectBase> Imdg<T> getHistImdg(String mapName, Class<T> clazz) {
return (Imdg<T>) allHistMaps.computeIfAbsent(mapName, (mapName1) -> imdgHistProvider.getImdg(mapName, clazz));
}
@Override
public <T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(
String searchMapName,
String mapName,
Class<T> clazz,
ImdgPredicate conditions) {
Imdg<SpcexObjectBase> imdgSearch = getHistImdg(searchMapName, SpcexObjectBase.class);
Imdg<T> imdgHistory = getHistImdg(mapName, clazz);
Collection<Long> ids = imdgSearch.getCollectionIdsByPredicate(conditions);
return ids.stream()
.map(imdgHistory::getSingleObjectByID)
.filter(Objects::nonNull)
.map(o -> responseFactory.responseFromObject(o, clazz))
.toList();
}
}

View file

@ -9,6 +9,9 @@ backend-api.example-setting=test
backend-api.hazelcast.cluster-members=127.0.0.1:5701
backend-api.hazelcast.login=dev
backend-api.hazelcast.password=dev-pass
backend-api.hazelcast-search.cluster-members=127.0.0.1:5702
backend-api.hazelcast-search.login=dev-hist
backend-api.hazelcast-search.password=dev-pass-hist
backend-api.kafka-producer.bootstrap-servers=localhost:9092
backend-api.kafka-producer.acks=all
backend-api.kafka-producer.retries=0

View file

@ -27,6 +27,6 @@ public class StateLoaderImplTestConfig {
@Bean(name = "stateLoaderImplTest")
public StateLoaderImpl createStateLoaderImpl(@Qualifier("responseFactoryTest") GetResponseFactory responseFactory) {
return new StateLoaderImpl(hazelcastServiceTest, responseFactory);
return new StateLoaderImpl(hazelcastServiceTest, null, responseFactory);
}
}

View file

@ -0,0 +1,174 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>imdg-hist</artifactId>
<packaging>jar</packaging>
<version>SPCEX-1.0.0.0</version>
<parent>
<artifactId>clearing-parent</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-1.0.0.0</version>
</parent>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>imdg</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>
<version>SPCEX-1.0.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>dictionary</artifactId>
<version>SPCEX-1.0.0.0</version>
<scope>compile</scope>
</dependency>
<!-- JDBC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
</dependency>
<!-- IMDG для MapStore -->
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-all</artifactId>
<version>${external_libraries.hazelcast.version}</version>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-imdg-api</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-imdg-api-hazelcast-impl</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-enum</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>cleaning-builders</artifactId>
<version>SPCEX-1.0.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>clearing-validation</artifactId>
</dependency>
<!-- TEST -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>application.properties</exclude>
</excludes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>ru.spcex.clearing.historyimdg.IMDGHistApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<addResources>true</addResources>
<classifier>exec</classifier>
<finalName>${project.artifactId}</finalName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.2.0-M1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0-M1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,12 @@
package ru.spcex.clearing.historyimdg;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
@SpringBootApplication
public class IMDGHistApplication {
public static void main(String[] args) {
SpringApplicationBuilder builder = new SpringApplicationBuilder(IMDGHistApplication.class);
builder.run(args);
}
}

View file

@ -0,0 +1,71 @@
package ru.spcex.clearing.historyimdg.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import ru.spcex.clearing.historyimdg.config.element.DatabaseSettings;
import ru.spcex.clearing.historyimdg.config.element.ImdgSettings;
import ru.spcex.clearing.imdg.error.ModuleInitializeException;
import javax.sql.DataSource;
import java.sql.Connection;
@SuppressWarnings("UnnecessaryLocalVariable")
@Configuration
public class HistoryDbConnectionConfig {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private final DatabaseSettings settings;
public HistoryDbConnectionConfig(ImdgSettings settings) {
this.settings = settings.getDatabase();
}
@Bean(destroyMethod = "close")
public ComboPooledDataSource dataSource() {
String login = settings.getLogin();
String password = settings.getPassword();
String logTimeoutPart = "";
String dbPath = settings.getUrl();
int timeoutSec = 30;
ComboPooledDataSource cpds = new ComboPooledDataSource();
try {
cpds.setDriverClass("org.postgresql.Driver");
} catch (Exception ue) {
throw new RuntimeException(ue);
}
cpds.setJdbcUrl(dbPath);
cpds.setUser(login);
cpds.setPassword(password);
cpds.setInitialPoolSize(10);
cpds.setMinPoolSize(10);
cpds.setMaxPoolSize(30);
int numHelperThreads = Runtime.getRuntime().availableProcessors() * 2;
cpds.setNumHelperThreads(numHelperThreads);
cpds.setCheckoutTimeout(timeoutSec * 1000);
logTimeoutPart = String.format(" (timeout=%ds)", timeoutSec);
String OPERATION_DATABASE_CONNECTION_CHECK = String.format("Database [%s] connection check", dbPath);
try {
Connection conn = cpds.getConnection();
conn.close();
log.info("{}: success", OPERATION_DATABASE_CONNECTION_CHECK);
return cpds;
} catch (Throwable e) {
String msg = String.format("%s%s: failed: %s -> %s",
OPERATION_DATABASE_CONNECTION_CHECK, logTimeoutPart, e.getClass().getSimpleName(), e.getMessage());
log.error(msg);
throw new ModuleInitializeException(msg, e);
}
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate;
}
}

View file

@ -0,0 +1,62 @@
package ru.spcex.clearing.historyimdg.config;
import com.hazelcast.config.*;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.historyimdg.config.element.HazelcastServerSettings;
import ru.spcex.clearing.historyimdg.config.element.ImdgSettings;
import java.util.List;
@Configuration
public class HistoryHazelcastConfiguration {
private final HistoryPoolMapConfigs poolMapConfigs;
private final HazelcastServerSettings hzSettings;
@Autowired
public HistoryHazelcastConfiguration(HistoryPoolMapConfigs poolMapConfigs,
ImdgSettings imdgSettings) {
this.poolMapConfigs = poolMapConfigs;
this.hzSettings = imdgSettings.getHazelcast();
}
@Bean("hazelcastInstanceImdg")
public HazelcastInstance hazelcastServerInstance(Config config) {
return Hazelcast.newHazelcastInstance(config);
}
@Bean
public Config hazelCastConfig() {
Config config = new Config();
config.setInstanceName("instance");
config.setGroupConfig(new GroupConfig()
.setName(hzSettings.getLogin())
.setPassword(hzSettings.getPassword())
);
config.setProperty("hazelcast.shutdownhook.enabled", "true");
config.setProperty("hazelcast.logging.type", "slf4j");
config.setProperty("hazelcast.operation.call.timeout.millis", "600000");
config.setNetworkConfig(new NetworkConfig()
.setPort(hzSettings.getListenPort())
.setJoin(new JoinConfig()
.setMulticastConfig(new MulticastConfig()
.setEnabled(false))
.setTcpIpConfig(new TcpIpConfig()
.setEnabled(true).setMembers(hzSettings.getClusterMembers())
)
)
);
List<MapConfig> autoMapCfg = poolMapConfigs.configureEachMapStore();
for (MapConfig cfg : autoMapCfg) {
config.addMapConfig(cfg);
}
return config;
}
}

View file

@ -0,0 +1,101 @@
package ru.spcex.clearing.historyimdg.config;
import com.hazelcast.config.*;
import com.hazelcast.core.MapLoader;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.imdg.base.AutoconfiguredMap;
import ru.spcex.clearing.imdg.base.DictionaryTMapStore;
import java.util.*;
@Configuration
public class HistoryPoolMapConfigs {
private final Logger log = LoggerFactory.getLogger(getClass());
private final List<AutoconfiguredMap<?>> autoconfiguredMaps;
@Autowired
public HistoryPoolMapConfigs(List<AutoconfiguredMap<?>> autoconfiguredMaps) {
this.autoconfiguredMaps = autoconfiguredMaps;
}
private MapStoreConfig makeDefaultMapStoreConfig(MapLoader<Long, ?> mapBean) {
return new MapStoreConfig()
.setImplementation(mapBean);
}
public MapConfig makeDefaultMapConfig(String mapName, MapLoader<Long, ?> mapBean) {
return new MapConfig()
.setName(mapName)
.setInMemoryFormat(InMemoryFormat.OBJECT)
.setMapStoreConfig(makeDefaultMapStoreConfig(mapBean));
}
private NearCacheConfig makeDefaultNearCacheConfig() {
return new NearCacheConfig()
.setMaxIdleSeconds(3600)
.setInMemoryFormat(InMemoryFormat.OBJECT)
.setSerializeKeys(true);
}
private MapIndexConfig makeMapIndexConfig(String attributeName, boolean ordered) {
return new MapIndexConfig()
.setAttribute(attributeName)
.setOrdered(ordered);
}
private MapIndexConfig makeMapIndexConfig(String attributeName) {
return makeMapIndexConfig(attributeName, false);
}
public List<MapConfig> configureEachMapStore() {
List<MapConfig> out = new ArrayList<>();
HashSet<String> existMapStores = new HashSet<>();
for (AutoconfiguredMap<?> mapStore : autoconfiguredMaps) {
try {
log.debug("Link mapstore {} to map {}", mapStore.toString(), mapStore.getMapName());
if (StringUtils.isEmpty(mapStore.getMapName())) {
throw new IllegalArgumentException("MapStore " + mapStore + " has empty mapName");
}
if (existMapStores.contains(mapStore.getMapName())) {
throw new IllegalArgumentException("MapStore " + mapStore + " has wrong mapName=\"" + mapStore.getMapName() + "\" is duplicated");
}
existMapStores.add(mapStore.getMapName()); // IMDGDistributedNames
MapConfig mapCfg = makeDefaultMapConfig(mapStore.getMapName(), mapStore);
if (mapStore.getIndexingField() != null && mapStore.getIndexingField().length > 0) {
if (log.isTraceEnabled()) {
log.trace("Create indexing filed on {}: {}", mapStore.getMapName(), Arrays.toString(mapStore.getIndexingField()));
}
for (String indexName : mapStore.getIndexingField()) {
mapCfg.addMapIndexConfig(makeMapIndexConfig(indexName));
}
}
if (mapStore instanceof DictionaryTMapStore) {
log.trace("Use near cache for {}", mapStore.getMapName());
mapCfg.setNearCacheConfig(makeDefaultNearCacheConfig());
}
out.add(mapCfg);
} catch (RuntimeException e) {
throw new RuntimeException("Can not configure MapStore " + mapStore.getMapName() + "(" + mapStore + "): " + e, e);
}
}
log.debug("Configured {} mapStore's", out.size());
return out;
}
//fixme remove
@Bean("historyMapNames")
public Set<String> historyMaps() {
Set<String> historyMaps = new HashSet<>();
// historyMaps.add(IMDGDistributedNames.Map_MoneyBalanceRegister);
return historyMaps;
}
}

View file

@ -0,0 +1,25 @@
package ru.spcex.clearing.historyimdg.config.element;
/**
* Debug config
*/
public class ControllerSettings {
private String port;
private String contextPath;
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getContextPath() {
return contextPath;
}
public void setContextPath(String contextPath) {
this.contextPath = contextPath;
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.historyimdg.config.element;
public class DatabaseSettings {
private String login;
private String password;
private String url;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}

View file

@ -0,0 +1,43 @@
package ru.spcex.clearing.historyimdg.config.element;
import java.util.List;
public class HazelcastServerSettings {
private int listenPort = 5701;
private String login;
private String password;
private List<String> clusterMembers;
public int getListenPort() {
return listenPort;
}
public void setListenPort(int listenPort) {
this.listenPort = listenPort;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<String> getClusterMembers() {
return clusterMembers;
}
public void setClusterMembers(List<String> clusterMembers) {
this.clusterMembers = clusterMembers;
}
}

View file

@ -0,0 +1,38 @@
package ru.spcex.clearing.historyimdg.config.element;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource("file:${spring.config.location}/application.properties")
@ConfigurationProperties("imdg.hist")
public class ImdgSettings {
private HazelcastServerSettings hazelcast;
private DatabaseSettings database;
private ControllerSettings debugServer;
public HazelcastServerSettings getHazelcast() {
return hazelcast;
}
public void setHazelcast(HazelcastServerSettings hazelcast) {
this.hazelcast = hazelcast;
}
public DatabaseSettings getDatabase() {
return database;
}
public void setDatabase(DatabaseSettings database) {
this.database = database;
}
public ControllerSettings getDebugServer() {
return debugServer;
}
public void setDebugServer(ControllerSettings debugServer) {
this.debugServer = debugServer;
}
}

View file

@ -0,0 +1,29 @@
package ru.spcex.clearing.historyimdg.index;
import ru.spcex.clearing.historyimdg.index.field.SearchWithId;
import ru.spcex.clearing.historyimdg.index.field.SearchWithTradingDate;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import java.time.LocalDate;
public class SearchProxy extends SpcexObjectBase implements SearchWithTradingDate, SearchWithId {
private LocalDate tradingDate;
@Override
public LocalDate getTradingDate() {
return tradingDate;
}
@Override
public void setTradingDate(LocalDate tradingDate) {
this.tradingDate = tradingDate;
}
@Override
public String toString() {
return "SearchProxy{" +
", id=" + id +
'}';
}
}

View file

@ -0,0 +1,19 @@
package ru.spcex.clearing.historyimdg.index;
import ru.spcex.clearing.historyimdg.index.field.SearchWithClearingDate;
import java.time.LocalDate;
public class SearchProxyAdmittedLiabilitiesRegister extends SearchProxy implements SearchWithClearingDate {
private LocalDate clearingDate;
@Override
public LocalDate getClearingDate() {
return clearingDate;
}
@Override
public void setClearingDate(LocalDate clearingDate) {
this.clearingDate = clearingDate;
}
}

View file

@ -0,0 +1,19 @@
package ru.spcex.clearing.historyimdg.index;
import ru.spcex.clearing.historyimdg.index.field.SearchWithClearingDate;
import java.time.LocalDate;
public class SearchProxyCoveredLiabilitiesRegister extends SearchProxy implements SearchWithClearingDate {
private LocalDate clearingDate;
@Override
public LocalDate getClearingDate() {
return clearingDate;
}
@Override
public void setClearingDate(LocalDate clearingDate) {
this.clearingDate = clearingDate;
}
}

View file

@ -0,0 +1,19 @@
package ru.spcex.clearing.historyimdg.index;
import ru.spcex.clearing.historyimdg.index.field.SearchWithCreated;
import java.time.Instant;
public class SearchProxyDepoPaymentInstructionRegister extends SearchProxy implements SearchWithCreated {
private Instant created;
@Override
public Instant getCreated() {
return created;
}
@Override
public void setCreated(Instant created) {
this.created = created;
}
}

View file

@ -0,0 +1,19 @@
package ru.spcex.clearing.historyimdg.index;
import ru.spcex.clearing.historyimdg.index.field.SearchWithCreated;
import java.time.Instant;
public class SearchProxyExcludeLiabilitiesRegister extends SearchProxy implements SearchWithCreated {
private Instant created;
@Override
public Instant getCreated() {
return created;
}
@Override
public void setCreated(Instant created) {
this.created = created;
}
}

View file

@ -0,0 +1,19 @@
package ru.spcex.clearing.historyimdg.index;
import ru.spcex.clearing.historyimdg.index.field.SearchWithTradingDate;
import java.time.LocalDate;
public class SearchProxyExecutionDeposit extends SearchProxy implements SearchWithTradingDate {
private LocalDate tradingDate;
@Override
public LocalDate getTradingDate() {
return tradingDate;
}
@Override
public void setTradingDate(LocalDate tradingDate) {
this.tradingDate = tradingDate;
}
}

View file

@ -0,0 +1,19 @@
package ru.spcex.clearing.historyimdg.index;
import ru.spcex.clearing.historyimdg.index.field.SearchWithTradingDate;
import java.time.LocalDate;
public class SearchProxyExecutionFond extends SearchProxy implements SearchWithTradingDate {
private LocalDate tradingDate;
@Override
public LocalDate getTradingDate() {
return tradingDate;
}
@Override
public void setTradingDate(LocalDate tradingDate) {
this.tradingDate = tradingDate;
}
}

View file

@ -0,0 +1,19 @@
package ru.spcex.clearing.historyimdg.index;
import ru.spcex.clearing.historyimdg.index.field.SearchWithTradingDate;
import java.time.LocalDate;
public class SearchProxyExecutionRegister extends SearchProxy implements SearchWithTradingDate {
private LocalDate tradingDate;
@Override
public LocalDate getTradingDate() {
return tradingDate;
}
@Override
public void setTradingDate(LocalDate tradingDate) {
this.tradingDate = tradingDate;
}
}

View file

@ -0,0 +1,19 @@
package ru.spcex.clearing.historyimdg.index;
import ru.spcex.clearing.historyimdg.index.field.SearchWithCreated;
import java.time.Instant;
public class SearchProxyLiabilitiesRegister extends SearchProxy implements SearchWithCreated {
private Instant created;
@Override
public Instant getCreated() {
return created;
}
@Override
public void setCreated(Instant created) {
this.created = created;
}
}

View file

@ -0,0 +1,19 @@
package ru.spcex.clearing.historyimdg.index;
import ru.spcex.clearing.historyimdg.index.field.SearchWithCreated;
import java.time.Instant;
public class SearchProxyMoneyBalanceRegister extends SearchProxy implements SearchWithCreated {
private Instant created;
@Override
public Instant getCreated() {
return created;
}
@Override
public void setCreated(Instant created) {
this.created = created;
}
}

View file

@ -0,0 +1,19 @@
package ru.spcex.clearing.historyimdg.index;
import ru.spcex.clearing.historyimdg.index.field.SearchWithClearingDate;
import java.time.LocalDate;
public class SearchProxyMoneyPaymentInstructionRegister extends SearchProxy implements SearchWithClearingDate {
private LocalDate clearingDate;
@Override
public LocalDate getClearingDate() {
return clearingDate;
}
@Override
public void setClearingDate(LocalDate clearingDate) {
this.clearingDate = clearingDate;
}
}

View file

@ -0,0 +1,7 @@
package ru.spcex.clearing.historyimdg.index.field;
public interface SearchCompanyId {
Long getCompanyId();
void setCompanyId(Long id);
}

View file

@ -0,0 +1,9 @@
package ru.spcex.clearing.historyimdg.index.field;
import java.time.LocalDate;
public interface SearchWithClearingDate {
LocalDate getClearingDate();
void setClearingDate(LocalDate value);
}

View file

@ -0,0 +1,9 @@
package ru.spcex.clearing.historyimdg.index.field;
import java.time.Instant;
public interface SearchWithCreated {
public Instant getCreated();
public void setCreated(Instant created);
}

View file

@ -0,0 +1,7 @@
package ru.spcex.clearing.historyimdg.index.field;
public interface SearchWithId {
Long getId();
void setId(Long id);
}

View file

@ -0,0 +1,9 @@
package ru.spcex.clearing.historyimdg.index.field;
import java.time.LocalDate;
public interface SearchWithTradingDate {
LocalDate getTradingDate();
void setTradingDate(LocalDate tradingDate);
}

View file

@ -0,0 +1,106 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import ru.spcex.clearing.imdg.base.AutoconfiguredMap;
import ru.spcex.platform.classes.base.interfaces.WithId;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import static ru.spcex.clearing.imdg.base.ObjectBaseMapStore.MAX_IN_CLAUSE_SIZE;
public abstract class AbstractSliceMapLoader<T extends WithId> implements AutoconfiguredMap<T> {
protected final Logger log = LoggerFactory.getLogger(getClass());
protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;
protected JdbcTemplate jdbcTemplate;
protected final DateTimeFormatter FIREBIRD_INSTANT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.systemDefault());
public AbstractSliceMapLoader(JdbcTemplate jdbcTemplate) {
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
this.jdbcTemplate = jdbcTemplate;
}
protected abstract String getTableName();
@Override
public T load(Long id) {
Collection<T> rows;
List<Long> list = Collections.singletonList(id);
try {
rows = load(list);
} catch (Throwable e) { // one retry
rows = load(list);
}
return DataAccessUtils.singleResult(rows);
}
@SuppressWarnings("Duplicates")
@Override
public Map<Long, T> loadAll(Collection<Long> keys) {
log.debug("loadAll from " + getTableName() + " " + keys.size() + " keys");
Map<Long, T> result = new HashMap<>();
long start = System.currentTimeMillis();
// загрузить данные по ключам частями, чтобы не выйти за ограничения базы по кол-ву элементов в in clause
List<Long> keysSubList = new ArrayList<>(MAX_IN_CLAUSE_SIZE);
for (Iterator<Long> iterator = keys.iterator(); iterator.hasNext(); ) {
Long key = iterator.next();
keysSubList.add(key);
if (keysSubList.size() == MAX_IN_CLAUSE_SIZE || !iterator.hasNext()) {
Collection<T> rows = load(keysSubList);
for (T row : rows) {
result.put(row.getId(), row);
}
keysSubList.clear();
}
}
log.debug("loadAll from " + getTableName() + " " + keys.size() + " keys done in " + (System.currentTimeMillis() - start) + "ms");
return result;
}
@Override
public Iterable<Long> loadAllKeys() {
log.debug("loading all keys from {}...", getTableName());
LocalDate yesterdayInstant = LocalDate.now().minus(0, ChronoUnit.DAYS);
// Instant yesterdayInstant = Instant.now().minus(0, ChronoUnit.DAYS);
LocalDate fewDaysAgo = yesterdayInstant.minus(2, ChronoUnit.DAYS);
String fieldOfDay = fieldOfDay();
List<Long> ids = jdbcTemplate.query("select id from " + getTableName() + " where " + fieldOfDay + " <= ? " +
"and " + fieldOfDay + " >= ? ",
(resultSet, i) -> resultSet.getLong("id"),
yesterdayInstant, fewDaysAgo);
log.debug("loading all keys from {} done; size={}", getTableName(), ids.size());
return ids;
}
protected abstract String fieldOfDay();
protected LocalDate getLocalDateFromSqlDate(ResultSet rs, String column) throws SQLException {
Date date = rs.getDate(column);
return date != null ? date.toLocalDate() : null;
}
protected Instant getInstantFromTimestamp(ResultSet rs, String column) throws SQLException {
Timestamp date = rs.getTimestamp(column);
return date != null ? date.toInstant() : null;
}
protected abstract Collection<T> load(Collection<Long> keys);
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister;
import ru.spcex.clearing.imdg.businessobject.AdmittedLiabilitiesRegisterMapStore;
import java.util.ArrayList;
@Component
public class AdmittedLiabilitiesRegisterHistoryMapStore extends AdmittedLiabilitiesRegisterMapStore {
public AdmittedLiabilitiesRegisterHistoryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected boolean isLoadable(Long id) {
return true;
}
@Override
protected boolean isLoadable(AdmittedLiabilitiesRegister obj) {
return true;
}
@Override
public Iterable<Long> loadAllKeys() {
log.debug("AdmittedLiabilitiesRegister loadAllKeys is called");
return new ArrayList<>();
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister;
import ru.spcex.clearing.imdg.businessobject.CoveredLiabilitiesRegisterMapStore;
import java.util.ArrayList;
@Component
public class CoveredLiabilitiesRegisterHistoryMapStore extends CoveredLiabilitiesRegisterMapStore {
public CoveredLiabilitiesRegisterHistoryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected boolean isLoadable(Long id) {
return true;
}
@Override
protected boolean isLoadable(CoveredLiabilitiesRegister obj) {
return true;
}
@Override
public Iterable<Long> loadAllKeys() {
log.debug("CoveredLiabilitiesRegister loadAllKeys is called");
return new ArrayList<>();
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.register.DepoBalanceRegister;
import ru.spcex.clearing.imdg.businessobject.DepoBalanceRegisterMapStore;
import java.util.ArrayList;
@Component
public class DepoBalanceRegisterHistoryMapStore extends DepoBalanceRegisterMapStore {
public DepoBalanceRegisterHistoryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected boolean isLoadable(Long id) {
return true;
}
@Override
protected boolean isLoadable(DepoBalanceRegister obj) {
return true;
}
@Override
public Iterable<Long> loadAllKeys() {
log.debug("DepoBalanceRegister loadAllKeys is called");
return new ArrayList<>();
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister;
import ru.spcex.clearing.imdg.businessobject.DepoPaymentInstructionRegisterMapStore;
import java.util.ArrayList;
@Component
public class DepoPaymentInstructionRegisterHistoryMapStore extends DepoPaymentInstructionRegisterMapStore {
public DepoPaymentInstructionRegisterHistoryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected boolean isLoadable(Long id) {
return true;
}
@Override
protected boolean isLoadable(DepoPaymentInstructionRegister obj) {
return true;
}
@Override
public Iterable<Long> loadAllKeys() {
log.debug("DepoPaymentInstructionRegister loadAllKeys is called");
return new ArrayList<>();
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister;
import ru.spcex.clearing.imdg.businessobject.ExcludeLiabilitiesRegisterMapStore;
import java.util.ArrayList;
@Component
public class ExcludeLiabilitiesRegisterHistoryMapStore extends ExcludeLiabilitiesRegisterMapStore {
public ExcludeLiabilitiesRegisterHistoryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected boolean isLoadable(Long id) {
return true;
}
@Override
protected boolean isLoadable(ExcludeLiabilitiesRegister obj) {
return true;
}
@Override
public Iterable<Long> loadAllKeys() {
log.debug("ExcludeLiabilitiesRegister loadAllKeys is called");
return new ArrayList<>();
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
import ru.spcex.clearing.imdg.businessobject.ExecutionDepositMapStore;
import java.util.ArrayList;
@Component
public class ExecutionDepositHistoryMapStore extends ExecutionDepositMapStore {
public ExecutionDepositHistoryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected boolean isLoadable(Long id) {
return true;
}
@Override
protected boolean isLoadable(ExecutionDeposit obj) {
return true;
}
@Override
public Iterable<Long> loadAllKeys() {
log.debug("ExecutionDeposit loadAllKeys is called");
return new ArrayList<>();
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.execution.ExecutionFond;
import ru.spcex.clearing.imdg.businessobject.ExecutionFondMapStore;
import java.util.ArrayList;
@Component
public class ExecutionFondHistoryMapStore extends ExecutionFondMapStore {
public ExecutionFondHistoryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected boolean isLoadable(Long id) {
return true;
}
@Override
protected boolean isLoadable(ExecutionFond obj) {
return true;
}
@Override
public Iterable<Long> loadAllKeys() {
log.debug("ExecutionFond loadAllKeys is called");
return new ArrayList<>();
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.register.ExecutionRegister;
import ru.spcex.clearing.imdg.businessobject.ExecutionRegisterMapStore;
import java.util.ArrayList;
@Component
public class ExecutionRegisterHistoryMapStore extends ExecutionRegisterMapStore {
public ExecutionRegisterHistoryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected boolean isLoadable(Long id) {
return true;
}
@Override
protected boolean isLoadable(ExecutionRegister obj) {
return true;
}
@Override
public Iterable<Long> loadAllKeys() {
log.debug("ExecutionRegister loadAllKeys is called");
return new ArrayList<>();
}
}

View file

@ -0,0 +1,4 @@
package ru.spcex.clearing.historyimdg.mapstores;
public interface HistMapStore {
}

View file

@ -0,0 +1,63 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
@Configuration
public class HistoryMapConfig {
private final JdbcTemplate jdbcTemplate;
@Autowired
public HistoryMapConfig(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// @Bean
// public AutoconfiguredMap<?> registryHistMapStore() {
// return new RegistryMapStore(jdbcTemplate) {
// @Override
// protected boolean isLoadable(Long id) {
// return true;
// }
//
// @Override
// protected boolean isLoadable(Registry obj) {
// return true;
// }
//
// @Override
// public Iterable<Long> loadAllKeys() {
// log.debug("RegistryHistoryMapStore loadAllKeys is called");
// return new ArrayList<>();
// }
// };
// }
//
// @Bean
// public AutoconfiguredMap<?> registrySomeMapStore(Class<? extends AutoconfiguredMap<?>> cl) {
// try {
// AutoconfiguredMap<?> map = cl.getDeclaredConstructor().newInstance(jdbcTemplate);
// } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
// throw new RuntimeException(e);
// }
// return new RegistryMapStore(jdbcTemplate) {
// @Override
// protected boolean isLoadable(Long id) {
// return true;
// }
//
// @Override
// protected boolean isLoadable(Registry obj) {
// return true;
// }
//
// @Override
// public Iterable<Long> loadAllKeys() {
// log.debug("RegistryHistoryMapStore loadAllKeys is called");
// return new ArrayList<>();
// }
// };
// }
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.register.LiabilitiesRegister;
import ru.spcex.clearing.imdg.businessobject.LiabilitiesRegisterMapStore;
import java.util.ArrayList;
@Component
public class LiabilitiesRegisterHistoryMapStore extends LiabilitiesRegisterMapStore {
public LiabilitiesRegisterHistoryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected boolean isLoadable(Long id) {
return true;
}
@Override
protected boolean isLoadable(LiabilitiesRegister obj) {
return true;
}
@Override
public Iterable<Long> loadAllKeys() {
log.debug("LiabilitiesRegister loadAllKeys is called");
return new ArrayList<>();
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.register.MoneyBalanceRegister;
import ru.spcex.clearing.imdg.businessobject.MoneyBalanceRegisterMapStore;
import java.util.ArrayList;
@Component
public class MoneyBalanceRegisterHistoryMapStore extends MoneyBalanceRegisterMapStore {
public MoneyBalanceRegisterHistoryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected boolean isLoadable(Long id) {
return true;
}
@Override
protected boolean isLoadable(MoneyBalanceRegister obj) {
return true;
}
@Override
public Iterable<Long> loadAllKeys() {
log.debug("MoneyBalanceRegisterHistoryMapStore loadAllKeys is called");
return new ArrayList<>();
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister;
import ru.spcex.clearing.imdg.businessobject.MoneyPaymentInstructionRegisterMapStore;
import java.util.ArrayList;
@Component
public class MoneyPaymentInstructionRegisterHistoryMapStore extends MoneyPaymentInstructionRegisterMapStore {
public MoneyPaymentInstructionRegisterHistoryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected boolean isLoadable(Long id) {
return true;
}
@Override
protected boolean isLoadable(MoneyPaymentInstructionRegister obj) {
return true;
}
@Override
public Iterable<Long> loadAllKeys() {
log.debug("MoneyPaymentInstructionRegisterHistoryMapStore loadAllKeys is called");
return new ArrayList<>();
}
}

View file

@ -0,0 +1,50 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.historyimdg.index.SearchProxyAdmittedLiabilitiesRegister;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@Component
public class SearchAdmittedLiabilitiesRegisterMapStore extends AbstractSliceMapLoader<SearchProxyAdmittedLiabilitiesRegister> {
public SearchAdmittedLiabilitiesRegisterMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "admitted_liabilities_register";
}
@Override
protected String fieldOfDay() {
return "clearing_date";
}
@Override
public Collection<SearchProxyAdmittedLiabilitiesRegister> load(Collection<Long> keys) {
Map<String, Collection<Long>> paramMap = Collections.singletonMap("ids", keys);
return namedParameterJdbcTemplate.query("select * from " + getTableName() + " where id in (:ids)", paramMap,
(rs, rowNum) -> {
SearchProxyAdmittedLiabilitiesRegister proxyRegister = new SearchProxyAdmittedLiabilitiesRegister();
proxyRegister.setId(rs.getObject("id", Long.class));
proxyRegister.setClearingDate(getLocalDateFromSqlDate(rs, "clearing_date"));
return proxyRegister;
});
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_SearchAdmittedLiabilitiesRegister;
}
@Override
public String[] getIndexingField() {
return new String[]{"clearingDate"};
}
}

View file

@ -0,0 +1,49 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.historyimdg.index.SearchProxyCoveredLiabilitiesRegister;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@Component
public class SearchCoveredLiabilitiesRegisterMapStore extends AbstractSliceMapLoader<SearchProxyCoveredLiabilitiesRegister> {
public SearchCoveredLiabilitiesRegisterMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "covered_liabilities_register";
}
@Override
protected String fieldOfDay() {
return "clearing_date";
}
@Override
public Collection<SearchProxyCoveredLiabilitiesRegister> load(Collection<Long> keys) {
Map<String, Collection<Long>> paramMap = Collections.singletonMap("ids", keys);
return namedParameterJdbcTemplate.query("select * from " + getTableName() + " where id in (:ids)", paramMap,
(rs, rowNum) -> {
SearchProxyCoveredLiabilitiesRegister proxyRegister = new SearchProxyCoveredLiabilitiesRegister();
proxyRegister.setId(rs.getObject("id", Long.class));
proxyRegister.setClearingDate(getLocalDateFromSqlDate(rs, "clearing_date"));
return proxyRegister;
});
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_SearchCoveredLiabilitiesRegister;
}
@Override
public String[] getIndexingField() {
return new String[]{"clearingDate"};
}
}

View file

@ -0,0 +1,48 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.historyimdg.index.SearchProxyDepoPaymentInstructionRegister;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@Component
public class SearchDepoPaymentInstructionRegisterMapStore extends AbstractSliceMapLoader<SearchProxyDepoPaymentInstructionRegister> {
public SearchDepoPaymentInstructionRegisterMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "depo_payment_instruction_register";
}
@Override
protected String fieldOfDay() {
return "CREATED_AT";
}
@Override
public Collection<SearchProxyDepoPaymentInstructionRegister> load(Collection<Long> keys) {
Map<String, Collection<Long>> paramMap = Collections.singletonMap("ids", keys);
return namedParameterJdbcTemplate.query("select * from " + getTableName() + " where id in (:ids)", paramMap,
(rs, rowNum) -> {
SearchProxyDepoPaymentInstructionRegister proxyRegistry = new SearchProxyDepoPaymentInstructionRegister();
proxyRegistry.setId(rs.getObject("id", Long.class));
proxyRegistry.setCreated(getInstantFromTimestamp(rs, "CREATED_AT"));
return proxyRegistry;
});
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_SearchDepoPaymentInstructionRegister;
}
@Override
public String[] getIndexingField() {
return new String[]{};
}
}

View file

@ -0,0 +1,48 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.historyimdg.index.SearchProxyExcludeLiabilitiesRegister;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@Component
public class SearchExcludeLiabilitiesRegisterMapStore extends AbstractSliceMapLoader<SearchProxyExcludeLiabilitiesRegister> {
public SearchExcludeLiabilitiesRegisterMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "exclude_liabilities_register";
}
@Override
protected String fieldOfDay() {
return "CREATED_AT";
}
@Override
public Collection<SearchProxyExcludeLiabilitiesRegister> load(Collection<Long> keys) {
Map<String, Collection<Long>> paramMap = Collections.singletonMap("ids", keys);
return namedParameterJdbcTemplate.query("select * from " + getTableName() + " where id in (:ids)", paramMap,
(rs, rowNum) -> {
SearchProxyExcludeLiabilitiesRegister proxyRegistry = new SearchProxyExcludeLiabilitiesRegister();
proxyRegistry.setId(rs.getObject("id", Long.class));
proxyRegistry.setCreated(getInstantFromTimestamp(rs, "CREATED_AT"));
return proxyRegistry;
});
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_SearchExcludeLiabilitiesRegister;
}
@Override
public String[] getIndexingField() {
return new String[]{};
}
}

View file

@ -0,0 +1,49 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.historyimdg.index.SearchProxyExecutionDeposit;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@Component
public class SearchExecutionDepositMapStore extends AbstractSliceMapLoader<SearchProxyExecutionDeposit> {
public SearchExecutionDepositMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "execution_deposit";
}
@Override
protected String fieldOfDay() {
return "trading_date";
}
@Override
public Collection<SearchProxyExecutionDeposit> load(Collection<Long> keys) {
Map<String, Collection<Long>> paramMap = Collections.singletonMap("ids", keys);
return namedParameterJdbcTemplate.query("select * from " + getTableName() + " where id in (:ids)", paramMap,
(rs, rowNum) -> {
SearchProxyExecutionDeposit proxyRegistry = new SearchProxyExecutionDeposit();
proxyRegistry.setId(rs.getObject("id", Long.class));
proxyRegistry.setTradingDate(getLocalDateFromSqlDate(rs,"trading_date"));
return proxyRegistry;
});
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_SearchExecutionDeposit;
}
@Override
public String[] getIndexingField() {
return new String[]{"tradingDate"};
}
}

View file

@ -0,0 +1,49 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.historyimdg.index.SearchProxyExecutionFond;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@Component
public class SearchExecutionFondMapStore extends AbstractSliceMapLoader<SearchProxyExecutionFond> {
public SearchExecutionFondMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "execution_fond";
}
@Override
protected String fieldOfDay() {
return "trading_date";
}
@Override
public Collection<SearchProxyExecutionFond> load(Collection<Long> keys) {
Map<String, Collection<Long>> paramMap = Collections.singletonMap("ids", keys);
return namedParameterJdbcTemplate.query("select * from " + getTableName() + " where id in (:ids)", paramMap,
(rs, rowNum) -> {
SearchProxyExecutionFond proxyFond = new SearchProxyExecutionFond();
proxyFond.setId(rs.getObject("id", Long.class));
proxyFond.setTradingDate(getLocalDateFromSqlDate(rs,"trading_date"));
return proxyFond;
});
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_SearchExecutionFond;
}
@Override
public String[] getIndexingField() {
return new String[]{"tradingDate"};
}
}

View file

@ -0,0 +1,49 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.historyimdg.index.SearchProxyExecutionRegister;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@Component
public class SearchExecutionRegisterMapStore extends AbstractSliceMapLoader<SearchProxyExecutionRegister> {
public SearchExecutionRegisterMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "execution_fond";
}
@Override
protected String fieldOfDay() {
return "trading_date";
}
@Override
public Collection<SearchProxyExecutionRegister> load(Collection<Long> keys) {
Map<String, Collection<Long>> paramMap = Collections.singletonMap("ids", keys);
return namedParameterJdbcTemplate.query("select * from " + getTableName() + " where id in (:ids)", paramMap,
(rs, rowNum) -> {
SearchProxyExecutionRegister proxyRegister = new SearchProxyExecutionRegister();
proxyRegister.setId(rs.getObject("id", Long.class));
proxyRegister.setTradingDate(getLocalDateFromSqlDate(rs,"trading_date"));
return proxyRegister;
});
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_SearchExecutionRegister;
}
@Override
public String[] getIndexingField() {
return new String[]{};
}
}

View file

@ -0,0 +1,49 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.historyimdg.index.SearchProxyLiabilitiesRegister;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@Component
public class SearchLiabilitiesRegisterMapStore extends AbstractSliceMapLoader<SearchProxyLiabilitiesRegister> {
public SearchLiabilitiesRegisterMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "liabilities_register";
}
@Override
protected String fieldOfDay() {
return "CREATED_AT";
}
@Override
public Collection<SearchProxyLiabilitiesRegister> load(Collection<Long> keys) {
Map<String, Collection<Long>> paramMap = Collections.singletonMap("ids", keys);
return namedParameterJdbcTemplate.query("select * from " + getTableName() + " where id in (:ids)", paramMap,
(rs, rowNum) -> {
SearchProxyLiabilitiesRegister proxyRegistry = new SearchProxyLiabilitiesRegister();
proxyRegistry.setId(rs.getObject("id", Long.class));
proxyRegistry.setCreated(getInstantFromTimestamp(rs, "CREATED_AT"));
return proxyRegistry;
});
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_SearchLiabilitiesRegister;
}
@Override
public String[] getIndexingField() {
return new String[]{};
}
}

View file

@ -0,0 +1,49 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.historyimdg.index.SearchProxyMoneyBalanceRegister;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@Component
public class SearchMoneyBalanceRegisterMapStore extends AbstractSliceMapLoader<SearchProxyMoneyBalanceRegister> {
public SearchMoneyBalanceRegisterMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "money_balance_register";
}
@Override
protected String fieldOfDay() {
return "CREATED_AT";
}
@Override
public Collection<SearchProxyMoneyBalanceRegister> load(Collection<Long> keys) {
Map<String, Collection<Long>> paramMap = Collections.singletonMap("ids", keys);
return namedParameterJdbcTemplate.query("select * from " + getTableName() + " where id in (:ids)", paramMap,
(rs, rowNum) -> {
SearchProxyMoneyBalanceRegister proxyRegistry = new SearchProxyMoneyBalanceRegister();
proxyRegistry.setId(rs.getObject("id", Long.class));
proxyRegistry.setCreated(getInstantFromTimestamp(rs, "CREATED_AT"));
return proxyRegistry;
});
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_SearchMoneyBalanceRegister;
}
@Override
public String[] getIndexingField() {
return new String[]{"created"};
}
}

View file

@ -0,0 +1,49 @@
package ru.spcex.clearing.historyimdg.mapstores;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.historyimdg.index.SearchProxyMoneyPaymentInstructionRegister;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@Component
public class SearchMoneyPaymentInstructionRegisterMapStore extends AbstractSliceMapLoader<SearchProxyMoneyPaymentInstructionRegister> {
public SearchMoneyPaymentInstructionRegisterMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "money_payment_instruction_register";
}
@Override
protected String fieldOfDay() {
return "clearing_date";
}
@Override
public Collection<SearchProxyMoneyPaymentInstructionRegister> load(Collection<Long> keys) {
Map<String, Collection<Long>> paramMap = Collections.singletonMap("ids", keys);
return namedParameterJdbcTemplate.query("select * from " + getTableName() + " where id in (:ids)", paramMap,
(rs, rowNum) -> {
SearchProxyMoneyPaymentInstructionRegister proxyRegistry = new SearchProxyMoneyPaymentInstructionRegister();
proxyRegistry.setId(rs.getObject("id", Long.class));
proxyRegistry.setClearingDate(getLocalDateFromSqlDate(rs, "clearing_date"));
return proxyRegistry;
});
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_SearchMoneyPaymentInstructionRegister;
}
@Override
public String[] getIndexingField() {
return new String[]{"clearingDate"};
}
}

View file

@ -0,0 +1,111 @@
package ru.spcex.clearing.historyimdg.services;
import com.hazelcast.core.HazelcastInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper;
import java.util.Collection;
@Service
public class HazelcastLifecycleSupport implements InitializingBean, DisposableBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final HazelcastInstance hazelcastServerInstance;
private final Collection<String> historyMapNames;
@Autowired
public HazelcastLifecycleSupport(@Qualifier("hazelcastInstanceImdg") HazelcastInstance hazelcastServerInstance, Collection<String> historyMapNames) {
this.hazelcastServerInstance = hazelcastServerInstance;
this.historyMapNames = historyMapNames;
}
@Override
public void afterPropertiesSet() throws Exception {
long loadTime = System.currentTimeMillis();
log.debug("init maps started");
for (String mapName : hazelcastServerInstance.getConfig().getMapConfigs().keySet()) {
//зачем historyMapNames - изначально чтобы соотв. MapStore не делал loadAllKeys
//по факту в Histry мапсторах метод loadAllKeys должен быть всегда переопределен в emptyList()
//можно потом убрать
if (historyMapNames.contains(mapName)) {
continue;
}
log.debug("configured '{}' map for hazelcast search server. size: {}", mapName, hazelcastServerInstance.getMap(mapName).size());
}
loadTime = System.currentTimeMillis() - loadTime;
log.info("All map load time {} ms", loadTime);
HazelcastHelper.imdgSystem_setStorageState(true, hazelcastServerInstance);
}
@Override
public void destroy() throws Exception {
}
//package com.moex.corp.search.service;
//
//import com.hazelcast.core.HazelcastInstance;
//import com.moex.platform.errors.TextErrorService;
//import com.moex.platform.hazelcast.HazelcastCommon;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.DisposableBean;
//import org.springframework.beans.factory.InitializingBean;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.stereotype.Service;
//
//import java.util.Collection;
//
//@SuppressWarnings("Duplicates")
//@Service
//public class HazelcastLifecycleSupport implements InitializingBean, DisposableBean {
// /**
// * Рабочая версия БД. Требуется вручную сверять с DDL.sql и накручивать эту переменную.
// */
// public static final String CHECK_DB_VERSION = "2.39";
//
// private final Logger log = LoggerFactory.getLogger(this.getClass());
//
// private final HazelcastInstance hazelcastServerInstance;
// private final Collection<String> historyMapNames;
//
// @Autowired
// public HazelcastLifecycleSupport(HazelcastInstance hazelcastServerInstance,
// @Qualifier("historyMapNames") Collection<String> historyMapNames) {
// this.hazelcastServerInstance = hazelcastServerInstance;
// this.historyMapNames = historyMapNames;
// }
//
// @Override
// public void afterPropertiesSet() {
// long loadTime = System.currentTimeMillis();
// log.debug("init maps started");
// for (String mapName : hazelcastServerInstance.getConfig().getMapConfigs().keySet()) {
// if (historyMapNames.contains(mapName)) {
// continue;
// }
// log.debug("configured '{}' map for hazelcast search server. size: {}", mapName, hazelcastServerInstance.getMap(mapName).size());
// }
// loadTime = System.currentTimeMillis() - loadTime;
// log.info("All map load time {} ms", loadTime);
// HazelcastCommon.otcSystem_setStorageState(true, hazelcastServerInstance);
//
// TextErrorService.setHazelcast(hazelcastServerInstance);
//
// }
//
// @Override
// public void destroy() {
// hazelcastServerInstance.shutdown();
// }
//
// public HazelcastInstance getHazelcastServerInstance() {
// return hazelcastServerInstance;
// }
//}
}

View file

@ -0,0 +1,12 @@
imdg.hist.hazelcast.listenPort=5702
imdg.hist.hazelcast.login=dev-hist
imdg.hist.hazelcast.password=dev-pass-hist
imdg.hist.hazelcast.cluster-members[0]=127.0.0.1
imdg.hist.database.login=cls_dev
imdg.hist.database.password=Aa111111
imdg.hist.database.url=jdbc:postgresql://10.200.200.133:5432/clearing?currentSchema=clearing_dev
#imdg.database.url=jdbc:postgresql://10.200.200.133:5432/postgres?currentSchema=clearing_tester
#debug tester mode:
#imdg.debug-server.port=8701
#imdg.debug-server.context-path=/imdg/reload

View file

@ -0,0 +1,5 @@
hazelcast:
network:
join:
multicast:
enabled: true

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- |%X{ru.nbch.scoring.web.logging.mdc_key}-->
<Pattern>%date{HH:mm:ss.SSS} [%thread] %-5level %class{0}:%line - %message%n</Pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/imdg.log</file>
<encoder>
<!-- |%X{ru.nbch.scoring.web.logging.mdc_key}-->
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %class{0}:%msg%n</Pattern>
<charset>utf8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>
./logs/imdg.%i.log
</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>10</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>500MB</maxFileSize>
</triggeringPolicy>
</appender>
<root level="warn">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
<logger name="ru.spcex" level="debug" additivity="false">
<appender-ref ref="FILE"/>
<appender-ref ref="CONSOLE"/>
</logger>
</configuration>

View file

@ -143,6 +143,7 @@
</executions>
<configuration>
<addResources>true</addResources>
<classifier>exec</classifier>
<finalName>${project.artifactId}</finalName>
</configuration>
</plugin>

View file

@ -1,17 +1,17 @@
package ru.spcex.clearing.imdg.base;
import com.hazelcast.core.MapLoader;
public interface AutoconfiguredMap<T> extends MapLoader<Long, T> {
/**
*
* @return IMDGDistributedNames.*
*/
String getMapName();
/**
* Список индексируемых полей, для быстрого поиска
* @return
*/
String[] getIndexingField();
}
package ru.spcex.clearing.imdg.base;
import com.hazelcast.core.MapLoader;
public interface AutoconfiguredMap<T> extends MapLoader<Long, T> {
/**
*
* @return IMDGDistributedNames.*
*/
String getMapName();
/**
* Список индексируемых полей, для быстрого поиска
* @return
*/
String[] getIndexingField();
}

View file

@ -42,6 +42,7 @@
<module>swt-exporter</module>
<module>swt-importer</module>
<module>gateway-api</module>
<module>imdg-hist</module>
</modules>
<properties>

View file

@ -232,6 +232,12 @@ public class ImdgHazelcast<T extends SpcexObjectBase> implements Imdg<T> {
return result;
}
@Override
public Collection<Long> getCollectionIdsByPredicate(ImdgPredicate prdct) {
Predicate hazelcastPredicate = ((ImdgPredicateHazelcast) prdct).getRawPredicate();
return new ArrayList<>(map.keySet(hazelcastPredicate));
}
@Override
public Long nextIDSequenceFor() {
return idGenerator.newId();

View file

@ -194,6 +194,17 @@ public final class IMDGDistributedNames {
public static final String Map_ExecutionFondHistory = "Map_ExecutionFondHistory";
public static final String Map_PriorityDictionary = "Map_PriorityDictionary";
//-------------------history and search tables
public static final String Map_SearchExecutionDeposit = "Map_SearchDeposit";
public static final String Map_SearchExecutionFond = "Map_SearchExecutionFond";
public static final String Map_SearchMoneyBalanceRegister = "Map_SearchMoneyBalanceRegister";
public static final String Map_SearchAdmittedLiabilitiesRegister = "Map_SearchAdmittedLiabilitiesRegister";
public static final String Map_SearchCoveredLiabilitiesRegister = "Map_SearchCoveredLiabilitiesRegister";
public static final String Map_SearchMoneyPaymentInstructionRegister = "Map_SearchMoneyPaymentInstructionRegister";
public static final String Map_SearchDepoPaymentInstructionRegister = "Map_SearchDepoPaymentInstructionRegister";
public static final String Map_SearchExcludeLiabilitiesRegister = "Map_SearchExcludeLiabilitiesRegister";
public static final String Map_SearchLiabilitiesRegister = "Map_SearchLiabilitiesRegister";
public static final String Map_SearchExecutionRegister = "Map_SearchExecutionRegister";
public static final String MAP_SEQUENCE_NAME = "MAP_SEQUENCE_NAME";
private IMDGDistributedNames() {

View file

@ -64,6 +64,10 @@ public interface Imdg<T extends SpcexObjectBase> {
throw new UnsupportedOperationException("not implemented getCollectionIdsBySQL");
}
default Collection<Long> getCollectionIdsByPredicate(ImdgPredicate prdct) {
throw new UnsupportedOperationException("not implemented getCollectionIdsByPredicate");
}
default Collection<T> getAllValues() {
throw new UnsupportedOperationException("not implemented getAllValues");
}

View file

@ -31,4 +31,13 @@ public class Pair<T1, T2> {
consumer.accept(p.getFirst());
consumer.accept(p.getSecond());
}
public void map(Consumer<T1> firstConsumer, Consumer<T2> secondConsumer) {
if (first != null) {
firstConsumer.accept(first);
}
if (second != null) {
secondConsumer.accept(second);
}
}
}

View file

@ -84,6 +84,11 @@
<artifactId>imdg</artifactId>
<version>${global.project.version}</version>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>imdg-hist</artifactId>
<version>${global.project.version}</version>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>

View file

@ -147,7 +147,7 @@
<configuration>
<fileSets>
<fileSet>
<sourceFile>${folder_root_clearing_imdg}/target/imdg.jar</sourceFile>
<sourceFile>${folder_root_clearing_imdg}/target/imdg-exec.jar</sourceFile>
<destinationFile>${folder.clearing.distr.bin}/imdg.jar</destinationFile>
</fileSet>
<fileSet>