Merge remote-tracking branch 'origin/CLS-262' into dev
This commit is contained in:
commit
39167a2e8e
17 changed files with 812 additions and 1 deletions
112
clearing-parent/lim-exporter/pom.xml
Normal file
112
clearing-parent/lim-exporter/pom.xml
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
<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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>lim-exporter</artifactId>
|
||||
<name>Lim exporter</name>
|
||||
<version>SPCEX-1.0.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>ru.spcex.clearing</groupId>
|
||||
<artifactId>clearing-parent</artifactId>
|
||||
<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>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-sftp</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.platform</groupId>
|
||||
<artifactId>platform-messaging</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>
|
||||
|
||||
<!-- TEST -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.spcex.clearing</groupId>
|
||||
<artifactId>test-clearing</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.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<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>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package ru.spcex.clearing.lim.exporter;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
|
||||
@SpringBootApplication
|
||||
public class LimExportApplication {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
SpringApplicationBuilder builder = new SpringApplicationBuilder(LimExportApplication.class);
|
||||
builder.run(args);
|
||||
} catch (Throwable e) {
|
||||
LoggerFactory.getLogger(LimExportApplication.class).error("DBF-Loader start failed: {} -> {}", e.getClass().getSimpleName(), e.getMessage());
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package ru.spcex.clearing.lim.exporter.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.lim.exporter.config.settings.ExportLimServiceSettings;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||
|
||||
@Configuration
|
||||
public class ImdgConfig {
|
||||
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;
|
||||
}
|
||||
|
||||
@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,
|
||||
ExportLimServiceSettings settings) {
|
||||
return new HazelcastService(taskExecutorHazelcastClientInitializer,
|
||||
taskExecutorIdGeneratorAwaiter,
|
||||
settings.getHazelcast());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package ru.spcex.clearing.lim.exporter.config;
|
||||
|
||||
import org.apache.kafka.clients.consumer.Consumer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import ru.spcex.clearing.lim.exporter.config.settings.ExportLimServiceSettings;
|
||||
import ru.spcex.clearing.platform.messaging.config.KafkaConsumerFactory;
|
||||
import ru.spcex.clearing.platform.messaging.config.KafkaProducerFactory;
|
||||
|
||||
@Configuration
|
||||
public class KafkaConfig {
|
||||
@Autowired
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
@Bean
|
||||
public Consumer<String, Object> createConsumer(ExportLimServiceSettings settings) {
|
||||
return KafkaConsumerFactory.consumer(settings.getKafkaConsumer());
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Bean
|
||||
public Producer<String, Object> createProducer(ExportLimServiceSettings settings) {
|
||||
return KafkaProducerFactory.producer(settings.getKafkaProducer());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package ru.spcex.clearing.lim.exporter.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import ru.spcex.clearing.lim.exporter.config.settings.ExportLimServiceSettings;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@ComponentScan(basePackages = {"ru.spcex.clearing.lim.exporter"})
|
||||
public class LimExporterConfig {
|
||||
|
||||
@Bean("taskExecutorHazelcastClientInitializer")
|
||||
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() {
|
||||
return createThreadPoolTaskExecutor(1, true);
|
||||
}
|
||||
|
||||
@Bean("taskExecutorIdGeneratorAwaiter")
|
||||
public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() {
|
||||
return createThreadPoolTaskExecutor(1, false);
|
||||
}
|
||||
|
||||
@Bean("imdgProvider")
|
||||
public ImdgProvider imdgProvider(@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
|
||||
@Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
|
||||
ExportLimServiceSettings settings) {
|
||||
HazelcastClientParams params = new HazelcastClientParams();
|
||||
params.setClusterMembers(settings.getHazelcast().getClusterMembers());
|
||||
params.setLogin(settings.getHazelcast().getLogin());
|
||||
params.setPassword(settings.getHazelcast().getPassword());
|
||||
return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params);
|
||||
}
|
||||
|
||||
@Bean("executor")
|
||||
public ThreadPoolTaskExecutor executor(ExportLimServiceSettings settings) {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setMaxPoolSize(settings.getCommon().getThreadsCount());
|
||||
executor.setCorePoolSize(settings.getCommon().getThreadsCount());
|
||||
executor.setThreadNamePrefix("dbf-exporter");
|
||||
executor.setWaitForTasksToCompleteOnShutdown(true);
|
||||
executor.setAwaitTerminationSeconds(300);
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package ru.spcex.clearing.lim.exporter.config;
|
||||
|
||||
import com.jcraft.jsch.ChannelSftp;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.MessagingGateway;
|
||||
import org.springframework.integration.annotation.ServiceActivator;
|
||||
import org.springframework.integration.file.remote.session.CachingSessionFactory;
|
||||
import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
import org.springframework.integration.sftp.outbound.SftpMessageHandler;
|
||||
import org.springframework.integration.sftp.session.DefaultSftpSessionFactory;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import ru.spcex.clearing.lim.exporter.config.settings.ExportLimServiceSettings;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@Configuration
|
||||
public class SFTPConfig {
|
||||
|
||||
@Bean
|
||||
public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory(ExportLimServiceSettings settings) {
|
||||
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
|
||||
factory.setHost(settings.getStore().getServerIp());
|
||||
factory.setPort(settings.getStore().getServerPort());
|
||||
factory.setUser(settings.getStore().getUser());
|
||||
factory.setPassword(settings.getStore().getPassword());
|
||||
factory.setAllowUnknownKeys(true);
|
||||
return new CachingSessionFactory<>(factory);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ServiceActivator(inputChannel = "toSftpChannel")
|
||||
public MessageHandler handler(SessionFactory<ChannelSftp.LsEntry> sessionFactory, ExportLimServiceSettings settings) {
|
||||
SftpMessageHandler handler = new SftpMessageHandler(sessionFactory);
|
||||
handler.setRemoteDirectoryExpression(new LiteralExpression(settings.getStore().getOutDir()));
|
||||
handler.setAutoCreateDirectory(true);
|
||||
handler.setFileNameGenerator(message -> {
|
||||
if (message.getPayload() instanceof File) {
|
||||
return ((File) message.getPayload()).getName();
|
||||
}else {
|
||||
throw new IllegalArgumentException("File expected as payload.");
|
||||
}
|
||||
});
|
||||
return handler;
|
||||
}
|
||||
|
||||
@MessagingGateway
|
||||
public interface LimGateway {
|
||||
@Gateway(requestChannel = "toSftpChannel")
|
||||
void sendToSftp(File file);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package ru.spcex.clearing.lim.exporter.config.settings;
|
||||
|
||||
public class Common {
|
||||
|
||||
private String encoding;
|
||||
private int insertBatchSize;
|
||||
private int threadsCount;
|
||||
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
public void setEncoding(String encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
public int getInsertBatchSize() {
|
||||
return insertBatchSize;
|
||||
}
|
||||
|
||||
public void setInsertBatchSize(int insertBatchSize) {
|
||||
this.insertBatchSize = insertBatchSize;
|
||||
}
|
||||
|
||||
public int getThreadsCount() {
|
||||
return threadsCount;
|
||||
}
|
||||
|
||||
public void setThreadsCount(int threadsCount) {
|
||||
this.threadsCount = threadsCount;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package ru.spcex.clearing.lim.exporter.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.clearing.platform.messaging.config.element.KafkaProducerSettings;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
|
||||
|
||||
@Component
|
||||
@PropertySource("file:${spring.config.location}/application.properties")
|
||||
@ConfigurationProperties("export-lim-service")
|
||||
public class ExportLimServiceSettings {
|
||||
private HazelcastClientParams hazelcast;
|
||||
private KafkaConsumerSettings kafkaConsumer;
|
||||
private KafkaProducerSettings kafkaProducer;
|
||||
private Store sFTPStore;
|
||||
private Common common;
|
||||
|
||||
public HazelcastClientParams getHazelcast() {
|
||||
return hazelcast;
|
||||
}
|
||||
|
||||
public void setHazelcast(HazelcastClientParams hazelcast) {
|
||||
this.hazelcast = hazelcast;
|
||||
}
|
||||
|
||||
public KafkaConsumerSettings getKafkaConsumer() {
|
||||
return kafkaConsumer;
|
||||
}
|
||||
|
||||
public void setKafkaConsumer(KafkaConsumerSettings kafkaConsumer) {
|
||||
this.kafkaConsumer = kafkaConsumer;
|
||||
}
|
||||
|
||||
public Store getStore() {
|
||||
return sFTPStore;
|
||||
}
|
||||
|
||||
public void setStore(Store Store) {
|
||||
this.sFTPStore = Store;
|
||||
}
|
||||
|
||||
public KafkaProducerSettings getKafkaProducer() {
|
||||
return kafkaProducer;
|
||||
}
|
||||
|
||||
public void setKafkaProducer(KafkaProducerSettings kafkaProducer) {
|
||||
this.kafkaProducer = kafkaProducer;
|
||||
}
|
||||
|
||||
public Common getCommon() {
|
||||
return common;
|
||||
}
|
||||
|
||||
public void setCommon(Common common) {
|
||||
this.common = common;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package ru.spcex.clearing.lim.exporter.config.settings;
|
||||
|
||||
public class Store {
|
||||
|
||||
private String outDir;
|
||||
private String user;
|
||||
private String password;
|
||||
private String serverIp;
|
||||
private int serverPort;
|
||||
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(String user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getServerIp() {
|
||||
return serverIp;
|
||||
}
|
||||
|
||||
public void setServerIp(String serverIp) {
|
||||
this.serverIp = serverIp;
|
||||
}
|
||||
|
||||
public int getServerPort() {
|
||||
return serverPort;
|
||||
}
|
||||
|
||||
public void setServerPort(int serverPort) {
|
||||
this.serverPort = serverPort;
|
||||
}
|
||||
|
||||
public String getOutDir() {
|
||||
return outDir;
|
||||
}
|
||||
|
||||
public void setOutDir(String outDir) {
|
||||
this.outDir = outDir;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package ru.spcex.clearing.lim.exporter.services;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import ru.spcex.clearing.lim.exporter.config.SFTPConfig;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Collection;
|
||||
|
||||
public abstract class AbstractExporterService {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private static final DateTimeFormatter dtFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
||||
private final SFTPConfig.LimGateway gateway;
|
||||
|
||||
protected AbstractExporterService(SFTPConfig.LimGateway gateway) {
|
||||
this.gateway = gateway;
|
||||
}
|
||||
|
||||
public abstract Collection<String> getLimFileRows();
|
||||
public abstract String getTargetFileName();
|
||||
|
||||
public void process() {
|
||||
log.debug("Start export {} Lim file", getTargetFileName());
|
||||
String fileName = getTargetFileName();
|
||||
File limFile = new File(fileName);
|
||||
|
||||
Path limFilePath = limFile.toPath();
|
||||
try {
|
||||
Files.write(limFilePath, getLimFileRows());
|
||||
gateway.sendToSftp(limFile);
|
||||
|
||||
log.debug("Successfully exported {} file", fileName);
|
||||
Files.deleteIfExists(limFilePath);
|
||||
} catch (IOException e) {
|
||||
log.error("Failed export {} file", fileName);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected String prepareFileName(String target){
|
||||
StringBuilder result = new StringBuilder();
|
||||
String dt = dtFormatter.format(LocalDateTime.now());
|
||||
|
||||
result.append("limits_");
|
||||
result.append(target);
|
||||
result.append('_');
|
||||
result.append(dt);
|
||||
result.append(".lim");
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package ru.spcex.clearing.lim.exporter.services;
|
||||
|
||||
import org.apache.kafka.clients.consumer.Consumer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||
import ru.spcex.platform.enumeration.Task;
|
||||
|
||||
@Service
|
||||
public class LauncherCommandReceiver extends QueueConsumer implements InitializingBean {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final MoneyExporterService moneyExporterService;
|
||||
private final SecurityExporterService securityExporterService;
|
||||
|
||||
public LauncherCommandReceiver(Consumer<String, Object> kafkaQueue,
|
||||
MoneyExporterService moneyExporterService,
|
||||
SecurityExporterService securityExporterService) {
|
||||
super(kafkaQueue);
|
||||
this.moneyExporterService = moneyExporterService;
|
||||
this.securityExporterService = securityExporterService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
callback(LauncherCommandRequest.class)
|
||||
.setConsumer(action -> moneyExporterService.process())
|
||||
.forDestination(Task.unloadingSession_LIMM.topic(), callbacks::put); // LIMM
|
||||
callback(LauncherCommandRequest.class)
|
||||
.setConsumer(action -> securityExporterService.process())
|
||||
.forDestination(Task.unloadingSession_LIMS.topic(), callbacks::put); // LIMS
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
package ru.spcex.clearing.lim.exporter.services;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.lim.exporter.config.SFTPConfig;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class MoneyExporterService extends AbstractExporterService {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Imdg<Registry> registryImdg;
|
||||
private final List<String> validStatus = List.of("ACTV", "ROPN");
|
||||
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
|
||||
|
||||
public MoneyExporterService(SFTPConfig.LimGateway gateway, ImdgProvider imdgProvider) {
|
||||
super(gateway);
|
||||
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTargetFileName() {
|
||||
return prepareFileName("money");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getLimFileRows() {
|
||||
log.debug("Started loading and formation of money file lines");
|
||||
LocalDate currentDate = LocalDate.now();
|
||||
List<String> limFileRows = new ArrayList<>();
|
||||
Collection<Registry> registriesA = registryImdg.getCollectionObjectsByFieldValues(
|
||||
Map.of("registryDesignation", "A",
|
||||
"registryInstrumentType", "M",
|
||||
"registryCode", "F",
|
||||
"clearingDate", currentDate));
|
||||
Collection<Registry> registriesD = registryImdg.getCollectionObjectsByFieldValues(
|
||||
Map.of("registryDesignation", "D",
|
||||
"registryInstrumentType", "M",
|
||||
"registryCode", "T",
|
||||
"clearingDate", currentDate));
|
||||
Map<String, List<Registry>> byTcrA = registriesA.stream()
|
||||
.collect(Collectors.groupingBy(Registry::getTradingClearingRegistry));
|
||||
Map<String, List<Registry>> byTcrD = registriesD.stream()
|
||||
.collect(Collectors.groupingBy(Registry::getTradingClearingRegistry));
|
||||
|
||||
for(Map.Entry<String, List<Registry>> entryA : byTcrA.entrySet()){
|
||||
List<Registry> registriesListA = entryA.getValue();
|
||||
List<Registry> registriesListB = byTcrD.get(entryA.getKey());
|
||||
for (Registry registry : registriesListA){
|
||||
if(checkNotBloked(registry)){
|
||||
//из ТЗ пока не понятно как соотнести Registry из registriesListA и registriesListB по валюте(RUB, USD) и вычислить остаток на денежном счете
|
||||
// limFileRows.add(getRow(...));
|
||||
}
|
||||
}
|
||||
}
|
||||
log.debug("Successfully completed the formation of rows: {} for export money", limFileRows.size());
|
||||
return limFileRows;
|
||||
}
|
||||
|
||||
private boolean checkNotBloked(Registry registry){
|
||||
TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getSingleObjectByID(registry.getTradingClearingRegistryId());
|
||||
return validStatus.contains(tradingClearingRegistry.getStatus());
|
||||
}
|
||||
|
||||
//поменяется при обновлении ТЗ
|
||||
private String getRow(Registry registryA, Registry registryB){
|
||||
StringBuilder row = new StringBuilder();
|
||||
|
||||
row.append("MONEY: FIRM_ID = ");
|
||||
row.append(registryA.getTradingCode());
|
||||
|
||||
row.append("; TAG = SPVB");
|
||||
|
||||
row.append("; CURR_CODE = ");
|
||||
// MoneyMarketSecurity mms = moneyMarketSecurityMap.getSingleObjectByFieldValues(Map.of("securityId", ));
|
||||
|
||||
row.append("; CLIENT_CODE = ");
|
||||
row.append(registryA.getTradingClearingRegistry());
|
||||
|
||||
row.append("; OPEN_BALANCE = ");
|
||||
BigDecimal balance = registryA.getBalance() != null ?
|
||||
registryB.getBalance() != null ? registryA.getBalance().subtract(registryB.getBalance()) : registryA.getBalance() :
|
||||
BigDecimal.ZERO;
|
||||
row.append(balance);
|
||||
|
||||
row.append("; OPEN_LIMIT = 0.00");
|
||||
|
||||
row.append("; LIMIT_KIND = 0;");
|
||||
return row.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
package ru.spcex.clearing.lim.exporter.services;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.lim.exporter.config.SFTPConfig;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class SecurityExporterService extends AbstractExporterService {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final Imdg<Registry> registryImdg;
|
||||
|
||||
public SecurityExporterService(SFTPConfig.LimGateway gateway, ImdgProvider imdgProvider) {
|
||||
super(gateway);
|
||||
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getTargetFileName() {
|
||||
return prepareFileName("security");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getLimFileRows(){
|
||||
log.debug("Started loading and formation of DEPO file lines");
|
||||
LocalDate currentDate = LocalDate.now();
|
||||
List<String> limFileRows = new ArrayList<>();
|
||||
Collection<Registry> registries = registryImdg.getCollectionObjectsByFieldValues(
|
||||
Map.of("registryDesignation", "A",
|
||||
"registryInstrumentType", "S",
|
||||
"registryCode", "T",
|
||||
"clearingDate", currentDate));
|
||||
for (Registry registry : registries){
|
||||
limFileRows.add(getRow(registry));
|
||||
}
|
||||
log.debug("Successfully completed the formation of rows: {} for export DEPO", limFileRows.size());
|
||||
return limFileRows;
|
||||
}
|
||||
|
||||
private String getRow(Registry registry){
|
||||
StringBuilder row = new StringBuilder();
|
||||
|
||||
row.append("DEPO: FIRM_ID = ");
|
||||
row.append(registry.getTradingCode());
|
||||
|
||||
row.append("; SECCODE = ");
|
||||
row.append(getSecurityShortName(registry));
|
||||
|
||||
row.append("; CLIENT_CODE = ");
|
||||
row.append(registry.getTradingClearingRegistry());
|
||||
|
||||
row.append("; OPEN_BALANCE = ");
|
||||
row.append(registry.getBalance());
|
||||
|
||||
row.append("; OPEN_LIMIT = 0");
|
||||
|
||||
row.append("; TRDACCID = ");
|
||||
row.append(registry.getTradingClearingRegistry());
|
||||
|
||||
row.append("; LIMIT_KIND = 0;");
|
||||
|
||||
return row.toString();
|
||||
}
|
||||
|
||||
//скорее всего в новой редакции ТЗ не понадобится
|
||||
private String getSecurityShortName(Registry registry){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
spring.main.web-application-type=none
|
||||
|
||||
export-lim-service.hazelcast.cluster-members=10.200.200.181:5701
|
||||
export-lim-service.hazelcast.login=dev
|
||||
export-lim-service.hazelcast.password=dev-pass
|
||||
|
||||
export-lim-service.common.encoding=cp866
|
||||
export-lim-service.common.threads-count=10
|
||||
|
||||
export-lim-service.store.out-dir=DocOut
|
||||
export-lim-service.store.user:tester
|
||||
export-lim-service.store.password=password
|
||||
export-lim-service.store.server-ip=10.230.238.53
|
||||
export-lim-service.store.server-port=2222
|
||||
|
||||
export-lim-service.hazelcast.cluster-members=127.0.0.1:5701
|
||||
export-lim-service.hazelcast.login=dev
|
||||
export-lim-service.hazelcast.password=dev-pass
|
||||
|
||||
export-lim-service.kafka-consumer.bootstrap-servers=localhost:9092
|
||||
export-lim-service.kafka-consumer.group-id=dev-group-balance-service
|
||||
export-lim-service.kafka-consumer.enable-auto-commit=false
|
||||
export-lim-service.kafka-consumer.session-timeout-ms=30000
|
||||
export-lim-service.kafka-consumer.auto-offset-reset=latest
|
||||
export-lim-service.kafka-consumer.linger-ms=1
|
||||
export-lim-service.kafka-consumer.buffer-memory=33554432
|
||||
|
||||
export-lim-service.kafka-producer.bootstrap-servers=localhost:9092
|
||||
export-lim-service.kafka-producer.acks=all
|
||||
export-lim-service.kafka-producer.retries=0
|
||||
export-lim-service.kafka-producer.batch-size=16384
|
||||
export-lim-service.kafka-producer.linger-ms=1
|
||||
export-lim-service.kafka-producer.buffer-memory=33554432
|
||||
37
clearing-parent/lim-exporter/src/main/resources/logback.xml
Normal file
37
clearing-parent/lim-exporter/src/main/resources/logback.xml
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<configuration>
|
||||
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<charset>UTF-8</charset>
|
||||
<pattern>%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>./logs/lim-exporter.log</file>
|
||||
<encoder>
|
||||
<charset>UTF-8</charset>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
|
||||
<fileNamePattern>
|
||||
../logs/lim-exporter.%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>
|
||||
|
|
@ -37,6 +37,7 @@
|
|||
<module>test-clearing</module>
|
||||
<module>cleaning-builders</module>
|
||||
<module>trade-importer</module>
|
||||
<module>lim-exporter</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ public enum Task implements IEnumKey {
|
|||
createOrderConfirm("CORC"),
|
||||
getAllBalance("GALB"),
|
||||
createReport_GREP("GREP"), // Создание отчёта (report-service) RPRT нескольких видов, этот GREP
|
||||
unloadingSession_LIMM("LIMM"),//Выгрузка в торговую систему остатков секции МКР
|
||||
unloadingSession_LIMM("LIMM"),//Выгрузка в торговую систему остатков по деньгам
|
||||
unloadingSession_LIMS("LIMS"),//Выгрузка в торговую систему остатков по бумагам
|
||||
unloadingSession_LIMF("LIMF"),//Выгрузка в торговую систему остатков Фондовой секции
|
||||
liquidationSession_LIQU("LIQU"),//Ликвидационная сессия по обязательтсвам участника
|
||||
startSession_STRM("STRM"),//Начало торговой сессии секции МКР
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue