diff --git a/clearing-parent/classes/src/main/java/ru/clearing/classes/StaticData/Misc/KeyRate.java b/clearing-parent/classes/src/main/java/ru/clearing/classes/StaticData/Misc/KeyRate.java
index fa0891ef5..61cf1fd3a 100644
--- a/clearing-parent/classes/src/main/java/ru/clearing/classes/StaticData/Misc/KeyRate.java
+++ b/clearing-parent/classes/src/main/java/ru/clearing/classes/StaticData/Misc/KeyRate.java
@@ -1,59 +1,59 @@
-package ru.clearing.classes.StaticData.Misc;
-
-import ru.spcex.platform.classes.base.SpcexObjectBase;
-
-import java.math.BigDecimal;
-import java.time.Instant;
-
-/**
- * Ключевая ставка ЦБ
- *
- * DB table: KEY_RATE
- **/
-public class KeyRate extends SpcexObjectBase {
- private BigDecimal rate;
- private Instant startDate;
- private Instant endDate;
- private String document;
- private String workflowStatus;
-
- public BigDecimal getRate() {
- return rate;
- }
-
- public void setRate(BigDecimal rate) {
- this.rate = rate;
- }
-
- public Instant getStartDate() {
- return startDate;
- }
-
- public void setStartDate(Instant startDate) {
- this.startDate = startDate;
- }
-
- public Instant getEndDate() {
- return endDate;
- }
-
- public void setEndDate(Instant endDate) {
- this.endDate = endDate;
- }
-
- public String getDocument() {
- return document;
- }
-
- public void setDocument(String document) {
- this.document = document;
- }
-
- public String getWorkflowStatus() {
- return workflowStatus;
- }
-
- public void setWorkflowStatus(String workflowStatus) {
- this.workflowStatus = workflowStatus;
- }
-}
+package ru.clearing.classes.StaticData.Misc;
+
+import ru.spcex.platform.classes.base.SpcexObjectBase;
+
+import java.math.BigDecimal;
+import java.time.Instant;
+
+/**
+ * Ключевая ставка ЦБ
+ *
+ * DB table: KEY_RATE
+ **/
+public class KeyRate extends SpcexObjectBase {
+ private Double rate;
+ private Instant startDate;
+ private Instant endDate;
+ private String document;
+ private String workflowStatus;
+
+ public Double getRate() {
+ return rate;
+ }
+
+ public void setRate(Double rate) {
+ this.rate = rate;
+ }
+
+ public Instant getStartDate() {
+ return startDate;
+ }
+
+ public void setStartDate(Instant startDate) {
+ this.startDate = startDate;
+ }
+
+ public Instant getEndDate() {
+ return endDate;
+ }
+
+ public void setEndDate(Instant endDate) {
+ this.endDate = endDate;
+ }
+
+ public String getDocument() {
+ return document;
+ }
+
+ public void setDocument(String document) {
+ this.document = document;
+ }
+
+ public String getWorkflowStatus() {
+ return workflowStatus;
+ }
+
+ public void setWorkflowStatus(String workflowStatus) {
+ this.workflowStatus = workflowStatus;
+ }
+}
diff --git a/clearing-parent/classes/src/main/java/ru/clearing/classes/StaticData/Misc/MoneyMarketSecurity.java b/clearing-parent/classes/src/main/java/ru/clearing/classes/StaticData/Misc/MoneyMarketSecurity.java
index 40f57035e..de1669439 100644
--- a/clearing-parent/classes/src/main/java/ru/clearing/classes/StaticData/Misc/MoneyMarketSecurity.java
+++ b/clearing-parent/classes/src/main/java/ru/clearing/classes/StaticData/Misc/MoneyMarketSecurity.java
@@ -1,95 +1,95 @@
-package ru.clearing.classes.StaticData.Misc;
-
-import ru.spcex.platform.classes.base.SpcexObjectBase;
-
-import java.math.BigDecimal;
-import java.time.Instant;
-
-/**
- * Инструменты Денежного рынка
- *
- * DB table: MONEY_MARKET_SECURITY
- **/
-public class MoneyMarketSecurity extends SpcexObjectBase {
- private Long securityId;// (linked to security)
- private String description;
- private Instant startDate;
- private Instant endDate;
- private BigDecimal nominalValue;
- private Long nominalCurrency; // (linked to currencyCode)
- private String instrumentType; // (linked to instrumentType)
- private String fullName;
- private String securitySymbol;
-
- public Long getSecurityId() {
- return securityId;
- }
-
- public void setSecurityId(Long securityId) {
- this.securityId = securityId;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public Instant getStartDate() {
- return startDate;
- }
-
- public void setStartDate(Instant startDate) {
- this.startDate = startDate;
- }
-
- public Instant getEndDate() {
- return endDate;
- }
-
- public void setEndDate(Instant endDate) {
- this.endDate = endDate;
- }
-
- public BigDecimal getNominalValue() {
- return nominalValue;
- }
-
- public void setNominalValue(BigDecimal nominalValue) {
- this.nominalValue = nominalValue;
- }
-
- public Long getNominalCurrency() {
- return nominalCurrency;
- }
-
- public void setNominalCurrency(Long nominalCurrency) {
- this.nominalCurrency = nominalCurrency;
- }
-
- public String getInstrumentType() {
- return instrumentType;
- }
-
- public void setInstrumentType(String instrumentType) {
- this.instrumentType = instrumentType;
- }
-
- public String getFullName() {
- return fullName;
- }
-
- public void setFullName(String fullName) {
- this.fullName = fullName;
- }
-
- public String getSecuritySymbol() {
- return securitySymbol;
- }
-
- public void setSecuritySymbol(String securitySymbol) {
- this.securitySymbol = securitySymbol;
- }
-}
+package ru.clearing.classes.StaticData.Misc;
+
+import ru.spcex.platform.classes.base.SpcexObjectBase;
+
+import java.math.BigDecimal;
+import java.time.Instant;
+
+/**
+ * Инструменты Денежного рынка
+ *
+ * DB table: MONEY_MARKET_SECURITY
+ **/
+public class MoneyMarketSecurity extends SpcexObjectBase {
+ private Long securityId;// (linked to security)
+ private String description;
+ private Instant startDate;
+ private Instant endDate;
+ private BigDecimal nominalValue;
+ private Long nominalCurrency; // (linked to currencyCode)
+ private String instrumentType; // (linked to instrumentType)
+ private String fullName;
+ private String securitySymbol;
+
+ public Long getSecurityId() {
+ return securityId;
+ }
+
+ public void setSecurityId(Long securityId) {
+ this.securityId = securityId;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Instant getStartDate() {
+ return startDate;
+ }
+
+ public void setStartDate(Instant startDate) {
+ this.startDate = startDate;
+ }
+
+ public Instant getEndDate() {
+ return endDate;
+ }
+
+ public void setEndDate(Instant endDate) {
+ this.endDate = endDate;
+ }
+
+ public BigDecimal getNominalValue() {
+ return nominalValue;
+ }
+
+ public void setNominalValue(BigDecimal nominalValue) {
+ this.nominalValue = nominalValue;
+ }
+
+ public Long getNominalCurrency() {
+ return nominalCurrency;
+ }
+
+ public void setNominalCurrency(Long nominalCurrency) {
+ this.nominalCurrency = nominalCurrency;
+ }
+
+ public String getInstrumentType() {
+ return instrumentType;
+ }
+
+ public void setInstrumentType(String instrumentType) {
+ this.instrumentType = instrumentType;
+ }
+
+ public String getFullName() {
+ return fullName;
+ }
+
+ public void setFullName(String fullName) {
+ this.fullName = fullName;
+ }
+
+ public String getSecuritySymbol() {
+ return securitySymbol;
+ }
+
+ public void setSecuritySymbol(String securitySymbol) {
+ this.securitySymbol = securitySymbol;
+ }
+}
diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/object/KeyRateMapStore.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/object/KeyRateMapStore.java
index 9cfe9c445..6280d351c 100644
--- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/object/KeyRateMapStore.java
+++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/object/KeyRateMapStore.java
@@ -42,7 +42,7 @@ public class KeyRateMapStore extends TemplateMapStore {
protected KeyRate objectReader(ResultSet resultSet) throws SQLException {
KeyRate keyRate = new KeyRate();
keyRate.setId(resultSet.getObject("ID", Long.class));
- keyRate.setRate(resultSet.getObject("RATE", BigDecimal.class));
+ keyRate.setRate(resultSet.getObject("RATE", Double.class));
keyRate.setStartDate(getInstantFromTimestamp(resultSet,"START_DATE"));
keyRate.setEndDate(getInstantFromTimestamp(resultSet, "END_DATE"));
keyRate.setDocument(resultSet.getObject("DOCUMENT", String.class));
diff --git a/clearing-parent/pom.xml b/clearing-parent/pom.xml
index 3c0360f3e..b0cdf7411 100644
--- a/clearing-parent/pom.xml
+++ b/clearing-parent/pom.xml
@@ -24,6 +24,7 @@
dbf-importer
dbf-exporter
securities-service
+ utility-service
diff --git a/clearing-parent/utility-service/pom.xml b/clearing-parent/utility-service/pom.xml
new file mode 100644
index 000000000..2aed17aef
--- /dev/null
+++ b/clearing-parent/utility-service/pom.xml
@@ -0,0 +1,70 @@
+
+
+
+ clearing-parent
+ ru.spcex.clearing
+ SPCEX-1.0.0.0
+
+ 4.0.0
+
+ utility-service
+
+
+ 17
+ 17
+
+
+
+ ru.spcex.platform
+ platform-messaging
+
+
+ ru.spcex.platform
+ platform-imdg-api-hazelcast-impl
+
+
+ ru.spcex.clearing
+ classes
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
+
+
+
+ src/main/resources
+
+ application.properties
+
+ false
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+ ${project.artifactId}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/UtilityServiceApplication.java b/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/UtilityServiceApplication.java
new file mode 100644
index 000000000..e4775c6e5
--- /dev/null
+++ b/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/UtilityServiceApplication.java
@@ -0,0 +1,12 @@
+package ru.spcex.clearing.utility;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class UtilityServiceApplication {
+ public static void main(String[] args) {
+ SpringApplication springApplication = new SpringApplication(UtilityServiceApplication.class);
+ springApplication.run(args);
+ }
+}
diff --git a/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/config/KafkaConfig.java b/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/config/KafkaConfig.java
new file mode 100644
index 000000000..e9284ce25
--- /dev/null
+++ b/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/config/KafkaConfig.java
@@ -0,0 +1,17 @@
+package ru.spcex.clearing.utility.config;
+
+import org.apache.kafka.clients.consumer.Consumer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import ru.spcex.clearing.platform.messaging.config.KafkaConsumerFactory;
+import ru.spcex.clearing.utility.config.settings.UtilityServiceSettings;
+
+@Configuration
+public class KafkaConfig {
+ @Autowired
+ @Bean
+ public Consumer createProducer(UtilityServiceSettings settings) {
+ return KafkaConsumerFactory.consumer(settings.getKafka());
+ }
+}
diff --git a/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/config/UtilityServiceImdgConfig.java b/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/config/UtilityServiceImdgConfig.java
new file mode 100644
index 000000000..2330cb2f6
--- /dev/null
+++ b/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/config/UtilityServiceImdgConfig.java
@@ -0,0 +1,49 @@
+package ru.spcex.clearing.utility.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import ru.spcex.clearing.utility.config.settings.UtilityServiceSettings;
+import ru.spcex.platform.imdg.api.ImdgProvider;
+import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
+
+@Configuration
+public class UtilityServiceImdgConfig {
+ @Bean(name = "taskExecutorHazelcastClientInitializer")
+ public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() {
+ return createThreadPoolTaskExecutor(1, true);
+ }
+
+ @Bean(name = "taskExecutorIdGeneratorAwaiter")
+ public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() {
+ return createThreadPoolTaskExecutor(1, false);
+ }
+
+ @Autowired
+ @Bean
+ public ImdgProvider imdgProvider(
+ @Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
+ @Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
+ UtilityServiceSettings settings
+ ) {
+ return new HazelcastService(taskExecutorHazelcastClientInitializer,
+ taskExecutorIdGeneratorAwaiter,
+ settings.getHazelcast());
+ }
+
+
+ private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
+ ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
+ if (maxPoolSz > 2) {
+ pool.setKeepAliveSeconds(60);
+ pool.setAllowCoreThreadTimeOut(true);
+ }
+ pool.setCorePoolSize(maxPoolSz);
+ pool.setWaitForTasksToCompleteOnShutdown(waitForCompletion);
+ return pool;
+ }
+
+}
diff --git a/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/config/settings/UtilityServiceSettings.java b/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/config/settings/UtilityServiceSettings.java
new file mode 100644
index 000000000..54f22e60c
--- /dev/null
+++ b/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/config/settings/UtilityServiceSettings.java
@@ -0,0 +1,31 @@
+package ru.spcex.clearing.utility.config.settings;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.stereotype.Component;
+import ru.spcex.clearing.platform.messaging.config.element.KafkaConsumerSettings;
+import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
+
+@Component
+@PropertySource("file:${spring.config.location}/application.properties")
+@ConfigurationProperties("utility-service")
+public class UtilityServiceSettings {
+ private HazelcastClientParams hazelcast;
+ private KafkaConsumerSettings kafka;
+
+ public HazelcastClientParams getHazelcast() {
+ return hazelcast;
+ }
+
+ public void setHazelcast(HazelcastClientParams hazelcast) {
+ this.hazelcast = hazelcast;
+ }
+
+ public KafkaConsumerSettings getKafka() {
+ return kafka;
+ }
+
+ public void setKafka(KafkaConsumerSettings kafka) {
+ this.kafka = kafka;
+ }
+}
diff --git a/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/service/KeyRateService.java b/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/service/KeyRateService.java
new file mode 100644
index 000000000..f77e2eb5d
--- /dev/null
+++ b/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/service/KeyRateService.java
@@ -0,0 +1,75 @@
+package ru.spcex.clearing.utility.service;
+
+import org.apache.kafka.clients.consumer.Consumer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import ru.clearing.classes.StaticData.Misc.KeyRate;
+import ru.spcex.clearing.imdg.IMDGDistributedNames;
+import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
+import ru.spcex.clearing.platform.messaging.domain.Consts;
+import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
+import ru.spcex.clearing.platform.messaging.domain.cud.utilities.KeyRateNewRequest;
+import ru.spcex.clearing.platform.messaging.domain.cud.utilities.KeyRateUpdateRequest;
+import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
+import ru.spcex.platform.imdg.api.Imdg;
+import ru.spcex.platform.imdg.api.ImdgProvider;
+
+@Service
+public class KeyRateService extends QueueConsumer implements InitializingBean {
+ private final Logger log = LoggerFactory.getLogger(getClass());
+ private final Imdg keyRateMap;
+
+ @Autowired
+ public KeyRateService(Consumer kafkaQueue, ImdgProvider imdgProvider) {
+ super(kafkaQueue);
+ this.keyRateMap = imdgProvider.getImdg(IMDGDistributedNames.Map_KeyRate, KeyRate.class);
+ }
+
+ @Override
+ public void afterPropertiesSet() {
+ callback(KeyRateNewRequest.class)
+ .setConsumer(this::newKeyRate)
+ .forDestination(Consts.DESTINATION_KEY_RATE_NEW, callbacks::put);
+ callback(KeyRateUpdateRequest.class)
+ .setConsumer(this::updateKeyRate)
+ .forDestination(Consts.DESTINATION_KEY_RATE_UPDATE, callbacks::put);
+ callback(CommonDeleteRequest.class)
+ .setConsumer(this::deleteKeyRate)
+ .forDestination(Consts.DESTINATION_KEY_RATE_DELETE, callbacks::put);
+ init();
+ }
+
+ private void newKeyRate(BaseRequest userRequest) {
+ KeyRateNewRequest req = userRequest.getRequestPayload();
+ log.debug("MoneyMarketSecurityNewRequest received");
+ KeyRate keyRate = new KeyRate();
+ keyRate.setEndDate(req.getEndDate());
+ keyRate.setDocument(req.getDocument());
+ keyRate.setRate(req.getKeyRate());
+ keyRate.setStartDate(req.getStartDate());
+ keyRateMap.insert(keyRate);
+ log.debug("successfully processed, new id {}", keyRate.getId());
+ }
+
+ private void updateKeyRate(BaseRequest userRequest) {
+ KeyRateUpdateRequest req = userRequest.getRequestPayload();
+ log.debug("MoneyMarketSecurityUpdateRequest received id = {}", req.getId());
+ KeyRate keyRate = keyRateMap.getSingleObjectByID(req.getId());
+ keyRate.setEndDate(req.getEndDate());
+ keyRate.setDocument(req.getDocument());
+ keyRate.setRate(req.getKeyRate());
+ keyRate.setStartDate(req.getStartDate());
+ keyRateMap.update(keyRate);
+ }
+
+ private void deleteKeyRate(BaseRequest userRequest) {
+ CommonDeleteRequest req = userRequest.getRequestPayload();
+ log.debug("CommonDeleteRequest received id = {}", req.getId());
+ KeyRate keyRate = keyRateMap.getSingleObjectByID(req.getId());
+ keyRateMap.delete(keyRate);
+ }
+
+}
diff --git a/clearing-parent/utility-service/src/main/resources/application.properties b/clearing-parent/utility-service/src/main/resources/application.properties
new file mode 100644
index 000000000..f3f6bd027
--- /dev/null
+++ b/clearing-parent/utility-service/src/main/resources/application.properties
@@ -0,0 +1,13 @@
+spring.main.web-application-type=none
+
+utility-service.hazelcast.cluster-members=127.0.0.1
+utility-service.hazelcast.login=dev
+utility-service.hazelcast.password=dev-pass
+
+utility-service.kafka.bootstrap-servers=localhost:9092
+utility-service.kafka.group-id=dev-group
+utility-service.kafka.enable-auto-commit=false
+utility-service.kafka.session-timeout-ms=30000
+utility-service.kafka.auto-offset-reset=latest
+utility-service.kafka.linger-ms=1
+utility-service.kafka.buffer-memory=33554432
\ No newline at end of file
diff --git a/clearing-parent/utility-service/src/main/resources/logback.xml b/clearing-parent/utility-service/src/main/resources/logback.xml
new file mode 100644
index 000000000..f23c2dc81
--- /dev/null
+++ b/clearing-parent/utility-service/src/main/resources/logback.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+ %date{HH:mm:ss.SSS} [%thread] %-5level %class{0}:%line - %message%n
+ utf-8
+
+
+
+ ./logs/securities-service.log
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %class{0}:%msg%n
+ utf8
+
+
+
+ ./logs/securities-service.%i.log
+
+ 1
+ 10
+
+
+ 500MB
+
+
+
+
+
+
+
+
+
+
+
+
+