diff --git a/clearing-parent/backend-api/src/main/resources/meta/data.xml b/clearing-parent/backend-api/src/main/resources/meta/data.xml
index e0653a143..07c4637d0 100644
--- a/clearing-parent/backend-api/src/main/resources/meta/data.xml
+++ b/clearing-parent/backend-api/src/main/resources/meta/data.xml
@@ -103,6 +103,7 @@
+
diff --git a/clearing-parent/db-scripts/src/main/resources/db/DATA.sql b/clearing-parent/db-scripts/src/main/resources/db/DATA.sql
index a6b4710f4..d9c6571a6 100644
--- a/clearing-parent/db-scripts/src/main/resources/db/DATA.sql
+++ b/clearing-parent/db-scripts/src/main/resources/db/DATA.sql
@@ -208,6 +208,8 @@ INSERT INTO INSTRUMENT_TYPE_DICTIONARY(ID, CODE, NAME) values (4, 'BOND', 'Об
INSERT INTO INSTRUMENT_TYPE_DICTIONARY(ID, CODE, NAME) values (5, 'MFND', 'ПАИ') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
+INSERT INTO INSTRUMENT_TYPE_DICTIONARY(ID, CODE, NAME) values (6, 'CURR', 'Валютная пара') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
+
INSERT INTO TERM_TYPE_DICTIONARY(ID, CODE, NAME) values (1, 'S', 'Срочный') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO TERM_TYPE_DICTIONARY(ID, CODE, NAME) values (2, 'K', 'Комбинированный') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
diff --git a/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/config/SFTPConfig.java b/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/config/SFTPConfig.java
index 8c02f7fe9..2402aa45c 100644
--- a/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/config/SFTPConfig.java
+++ b/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/config/SFTPConfig.java
@@ -5,13 +5,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.expression.common.LiteralExpression;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
-import org.springframework.integration.dsl.IntegrationFlow;
-import org.springframework.integration.dsl.IntegrationFlows;
+import org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway;
import org.springframework.integration.file.remote.session.CachingSessionFactory;
import org.springframework.integration.file.remote.session.SessionFactory;
import org.springframework.integration.sftp.gateway.SftpOutboundGateway;
@@ -20,6 +20,8 @@ import org.springframework.integration.sftp.session.DefaultSftpSessionFactory;
import org.springframework.integration.sftp.session.SftpFileInfo;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.messaging.handler.annotation.Payload;
import ru.spcex.clearing.dbf.exporter.config.settings.ExportDBFServiceSettings;
import java.io.File;
@@ -30,7 +32,7 @@ import static org.springframework.integration.file.remote.gateway.AbstractRemote
@Configuration
public class SFTPConfig {
protected Logger log = LoggerFactory.getLogger(getClass());
-
+ protected static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
@Bean
public SessionFactory sftpSessionFactory(ExportDBFServiceSettings settings) {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
@@ -44,10 +46,9 @@ public class SFTPConfig {
@Bean
@ServiceActivator(inputChannel = "toSftpChannel")
- public MessageHandler handler(SessionFactory sessionFactory, ExportDBFServiceSettings settings) {
+ public MessageHandler handler(SessionFactory sessionFactory) {
SftpMessageHandler handler = new SftpMessageHandler(sessionFactory);
- handler.setRemoteDirectoryExpression(new LiteralExpression(settings.getStore().getOutDir()));
- log.info("Configure sftp output directory \"{}\"", settings.getStore().getOutDir());
+ handler.setRemoteDirectoryExpression(EXPRESSION_PARSER.parseExpression("headers['path']"));
handler.setAutoCreateDirectory(true);
handler.setFileNameGenerator(message -> {
if (message.getPayload() instanceof File) {
@@ -62,38 +63,31 @@ public class SFTPConfig {
@MessagingGateway
public interface DbfGateway {
@Gateway(requestChannel = "toSftpChannel")
- void sendToSftp(File file);
+ void sendToSftp(@Payload File file, @Header("path") String path);
@Gateway(requestChannel = "listSftpChannel")
- List listFiles(String dir);
+ List listFiles(@Payload String dir);
}
@Bean
- public MessageChannel listSftpChannel(SessionFactory sessionFactory, ExportDBFServiceSettings settings) {
+ public MessageChannel listSftpChannel(SessionFactory sessionFactory) {
DirectChannel dc = new DirectChannel();
- dc.subscribe(handlerList(sessionFactory, settings));
+ dc.subscribe(handlerList(sessionFactory));
return dc;
}
@Bean
- public MessageChannel toSftpChannel(SessionFactory sessionFactory, ExportDBFServiceSettings settings) {
+ public MessageChannel toSftpChannel(SessionFactory sessionFactory) {
DirectChannel dc = new DirectChannel();
- dc.subscribe(handler(sessionFactory, settings));
+ dc.subscribe(handler(sessionFactory));
return dc;
}
@Bean
@ServiceActivator(inputChannel = "listSftpChannel")
- public MessageHandler handlerList(SessionFactory sessionFactory, ExportDBFServiceSettings settings) {
- String expression = "'/%s'".formatted(settings.getStore().getOutDir());
- SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sessionFactory, LS.getCommand(), expression);
+ public MessageHandler handlerList(SessionFactory sessionFactory) {
+ SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sessionFactory, LS.getCommand(), "payload");
+ sftpOutboundGateway.setOption(AbstractRemoteFileOutboundGateway.Option.RECURSIVE);
return sftpOutboundGateway;
}
-
- @Bean
- public IntegrationFlow sftpOutboundListFlow(SessionFactory sessionFactory, ExportDBFServiceSettings settings) {
- return IntegrationFlows.from("listSftpChannel")
- .handle(new SftpOutboundGateway(sessionFactory, "ls", "payload")
- ).get();
- }
}
diff --git a/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/config/settings/Store.java b/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/config/settings/Store.java
index 74b55277c..022ba28ff 100644
--- a/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/config/settings/Store.java
+++ b/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/config/settings/Store.java
@@ -1,5 +1,7 @@
package ru.spcex.clearing.dbf.exporter.config.settings;
+import java.util.Map;
+
public class Store {
private String outDir;
@@ -8,6 +10,7 @@ public class Store {
private String password;
private String serverIp;
private int serverPort;
+ private Map outPayValDir;
public String getUser() {
return user;
@@ -56,4 +59,12 @@ public class Store {
public void setLocalTempDir(String localTempDir) {
this.localTempDir = localTempDir;
}
+
+ public Map getOutPayValDir() {
+ return outPayValDir;
+ }
+
+ public void setOutPayValDir(Map outPayValDir) {
+ this.outPayValDir = outPayValDir;
+ }
}
diff --git a/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/logic/stages/ExportFromHazelcast.java b/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/logic/stages/ExportFromHazelcast.java
index 0cebae430..671dc60c4 100644
--- a/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/logic/stages/ExportFromHazelcast.java
+++ b/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/logic/stages/ExportFromHazelcast.java
@@ -4,15 +4,15 @@ import com.linuxense.javadbf.DBFField;
import com.linuxense.javadbf.DBFWriter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
-import ru.clearing.classes.statics.data.sdf.*;
import ru.spcex.clearing.dbf.exporter.config.SFTPConfig;
import ru.spcex.clearing.dbf.exporter.config.settings.ExportDBFServiceSettings;
import ru.spcex.clearing.dbf.exporter.exceptions.ConfigException;
import ru.spcex.clearing.dbf.exporter.logic.data.ResultContainer;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.StageResult;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
-import ru.spcex.clearing.dbf.exporter.services.converters.*;
+import ru.spcex.clearing.dbf.exporter.services.converters.DFConverter;
import ru.spcex.platform.classes.base.SpcexObjectBase;
+import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
@@ -20,6 +20,8 @@ import java.io.File;
import java.nio.charset.Charset;
import java.util.*;
+import static ru.spcex.clearing.dbf.exporter.services.converters.DFConverter.ruCurrency;
+
/**
* Выгрузка данных из мапы hazelcast и их запись в файлы
*/
@@ -28,15 +30,8 @@ public class ExportFromHazelcast extends Stage implements InitializingBean {
private final ExportDBFServiceSettings settings;
private final ImdgProvider imdgProvider;
private final SFTPConfig.DbfGateway gateway;
+ private final List converters;
- private final S_DF02_Converter s_df02_converter;
- private final S_DF03_Converter s_df03_converter;
- private final S_DF05_Converter s_df05_converter;
- private final S_DF07_Converter s_df07_converter;
- private final S_DF51_Converter s_df51_converter;
- private final S_DF53_Converter s_df53_converter;
- private final S_DF54_Converter s_df54_converter;
- private final S_DF56_Converter s_df56_converter;
private final Map dbfFieldsForTable = new HashMap<>();
private Charset dbfCharset;
@@ -44,25 +39,11 @@ public class ExportFromHazelcast extends Stage implements InitializingBean {
public ExportFromHazelcast(ExportDBFServiceSettings settings,
ImdgProvider imdgProvider,
SFTPConfig.DbfGateway gateway,
- S_DF02_Converter s_df02_converter,
- S_DF03_Converter s_df03_converter,
- S_DF07_Converter s_df07_converter,
- S_DF05_Converter s_df05_converter,
- S_DF51_Converter s_df51_converter,
- S_DF54_Converter s_df54_converter,
- S_DF53_Converter s_df53_converter,
- S_DF56_Converter s_df56_converter) {
+ List converters) {
this.settings = settings;
this.imdgProvider = imdgProvider;
this.gateway = gateway;
- this.s_df02_converter = s_df02_converter;
- this.s_df03_converter = s_df03_converter;
- this.s_df07_converter = s_df07_converter;
- this.s_df05_converter = s_df05_converter;
- this.s_df51_converter = s_df51_converter;
- this.s_df54_converter = s_df54_converter;
- this.s_df53_converter = s_df53_converter;
- this.s_df56_converter = s_df56_converter;
+ this.converters = converters;
}
@Override
@@ -75,8 +56,9 @@ public class ExportFromHazelcast extends Stage implements InitializingBean {
File dbfFile = resultContainer.getFileForExport();
boolean writeOk = false;
boolean emptyMap = true;
+ String currency = null;
+ String path = null;
try (DBFWriter dbfWriter = new DBFWriter(dbfFile, dbfCharset)) {
- dbfWriter.setFields(dbfFieldsForTable.get(table));
Collection extends SpcexObjectBase> tableRows;
if (resultContainer.getGroupId() != null) {
Map queryParams = Map.of("generationId", resultContainer.getGroupId());
@@ -97,18 +79,20 @@ public class ExportFromHazelcast extends Stage implements InitializingBean {
((ArrayList) tableRows).sort(Comparator.comparing(SpcexObjectBase::getId));
}
for (SpcexObjectBase value : tableRows) {
- Object[] values;
- if (value instanceof SDf02 sDf02Value) values = s_df02_converter.toObjectArray(sDf02Value);
- else if (value instanceof SDf03 sDf03Value) values = s_df03_converter.toObjectArray(sDf03Value);
- else if (value instanceof SDf05 sDf05Value) values = s_df05_converter.toObjectArray(sDf05Value);
- else if (value instanceof SDf07 sDf07Value) values = s_df07_converter.toObjectArray(sDf07Value);
- else if (value instanceof SDf51 sDf51Value) values = s_df51_converter.toObjectArray(sDf51Value);
- else if (value instanceof SDf53 sDf53Value) values = s_df53_converter.toObjectArray(sDf53Value);
- else if (value instanceof SDf54 sDf54Value) values = s_df54_converter.toObjectArray(sDf54Value);
- else if (value instanceof SDf56 sDf56Value) values = s_df56_converter.toObjectArray(sDf56Value);
- else throw new Exception("Get unknown object from imdg. Class: " + value.getClass().getSimpleName());
- dbfWriter.addRecord(values);
+ DFConverter currentConverter = converters.stream().filter(c -> c.canProcessing(value)).findFirst()
+ .orElseThrow(() -> new Exception("Get unknown object from imdg. Class: " + value.getClass().getSimpleName()));
+ if (currency == null) {
+ currency = currentConverter.getCurrency(value);
+ dbfWriter.setFields(currentConverter.getDBFHeaders());
+ }
+ dbfWriter.addRecord(currentConverter.toObjectArray(value));
}
+ if (CurrencyCode.isRub(currency))
+ path = settings.getStore().getOutPayValDir().get(ruCurrency);
+ else path = settings.getStore().getOutPayValDir().get(currency);
+
+ if (path == null)
+ throw new Exception("Get unknown currency=" + currency + ", need will be adding settings like 'export-dbf-service.store.out-pay-val-dir.RUB=/RUB' and restart app");
writeOk = true;
emptyMap = tableRows.isEmpty();
} catch (Exception e) {
@@ -124,7 +108,7 @@ public class ExportFromHazelcast extends Stage implements InitializingBean {
}
} else {
log.debug("uuid {}, send to SFTP", resultContainer.getUuid());
- gateway.sendToSftp(dbfFile);
+ gateway.sendToSftp(dbfFile, path);
}
}
@@ -137,24 +121,9 @@ public class ExportFromHazelcast extends Stage implements InitializingBean {
*/
@Override
public void afterPropertiesSet() {
- initExportFileStructure();
initDBFCharset();
}
- /**
- * Инициализация структуры выходных файлов (заголовки столбцов)
- */
- private void initExportFileStructure() {
- dbfFieldsForTable.put(Table.S_DF02, s_df02_converter.getDBFHeaders());
- dbfFieldsForTable.put(Table.S_DF03, s_df03_converter.getDBFHeaders());
- dbfFieldsForTable.put(Table.S_DF05, s_df05_converter.getDBFHeaders());
- dbfFieldsForTable.put(Table.S_DF07, s_df07_converter.getDBFHeaders());
- dbfFieldsForTable.put(Table.S_DF51, s_df51_converter.getDBFHeaders());
- dbfFieldsForTable.put(Table.S_DF53, s_df53_converter.getDBFHeaders());
- dbfFieldsForTable.put(Table.S_DF54, s_df54_converter.getDBFHeaders());
- dbfFieldsForTable.put(Table.S_DF56, s_df56_converter.getDBFHeaders());
- }
-
private void initDBFCharset() {
try {
dbfCharset = Charset.forName(settings.getCommon().getEncoding());
diff --git a/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/logic/stages/PrepareDBFFile.java b/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/logic/stages/PrepareDBFFile.java
index 74775fae4..f7cb84f1a 100644
--- a/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/logic/stages/PrepareDBFFile.java
+++ b/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/logic/stages/PrepareDBFFile.java
@@ -15,10 +15,7 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
-import java.util.EnumMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
/**
* Создание DBF файла
@@ -38,8 +35,15 @@ public class PrepareDBFFile extends Stage implements InitializingBean {
@Override
public StageResult process(ResultContainer resultContainer) {
Objects.requireNonNull(resultContainer.getTableForExport());
- List files = gateway.listFiles(settings.getStore().getOutDir());
- log.debug("From sFTP dir \"{}\" list {} file names.", settings.getStore().getOutDir(), files.size());
+ if (settings.getStore().getOutPayValDir() == null || settings.getStore().getOutPayValDir().size() == 0) {
+ log.error("No SFTP scanning directories, need will be adding settings like 'export-dbf-service.store.out-pay-val-dir.RUB=/RUB' and restart app");
+ return StageResult.ERROR;
+ }
+ List files = new ArrayList<>();
+ for (String path : settings.getStore().getOutPayValDir().values()) {
+ files.addAll(gateway.listFiles(path));
+ }
+ log.info("There are {} files on the sFTP server in the search directories.", files.size());
Table table = resultContainer.getTableForExport();
LocalDateTime currentDateTime = LocalDateTime.now();
resultContainer.setRegistrationDateTime(currentDateTime);
@@ -53,8 +57,8 @@ public class PrepareDBFFile extends Stage implements InitializingBean {
return StageResult.ERROR;
}
resultContainer.setFileForExport(dbfFile);
- log.debug("uuid {}. GenerationId {} will be export to temp file \"{}\"", resultContainer.getUuid(),
- resultContainer.getGroupId(), dbfFile);
+ log.info("uuid {}. Rows from {} with generationId {} will be export to temp file \"{}\"", resultContainer.getUuid(),
+ resultContainer.getTableForExport().getFilePrefix(), resultContainer.getGroupId(), dbfFile);
return StageResult.OK;
}
diff --git a/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/services/converters/DFConverter.java b/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/services/converters/DFConverter.java
index c8c15f2ad..dbba5bb77 100644
--- a/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/services/converters/DFConverter.java
+++ b/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/services/converters/DFConverter.java
@@ -2,6 +2,7 @@ package ru.spcex.clearing.dbf.exporter.services.converters;
import com.linuxense.javadbf.DBFField;
import ru.spcex.platform.classes.base.SpcexObjectBase;
+import ru.spcex.platform.enumeration.CurrencyCode;
import java.math.BigDecimal;
import java.sql.Date;
@@ -12,9 +13,15 @@ import java.time.LocalDate;
import java.time.LocalTime;
public abstract class DFConverter {
+ public final static String ruCurrency = CurrencyCode.RUB.getKey();
+ public Class clazz;
+ public DFConverter (Class clazz) {
+ this.clazz = clazz;
+ }
public abstract Object[] toObjectArray(T entity);
public abstract DBFField[] getDBFHeaders();
+ public abstract String getCurrency(T entity);
/**
* Приведение типов в соответствие (для записи)
* @param src исходный объект
@@ -36,4 +43,8 @@ public abstract class DFConverter {
if (s == null) return null;
return new BigDecimal(s).setScale(0);
}
+
+ public boolean canProcessing(SpcexObjectBase entity) {
+ return entity.getClass().equals(clazz);
+ }
}
diff --git a/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/services/converters/S_DF02_Converter.java b/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/services/converters/S_DF02_Converter.java
index df3089be9..148aae24c 100644
--- a/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/services/converters/S_DF02_Converter.java
+++ b/clearing-parent/dbf-exporter/src/main/java/ru/spcex/clearing/dbf/exporter/services/converters/S_DF02_Converter.java
@@ -10,6 +10,10 @@ import java.util.List;
@Service
public class S_DF02_Converter extends DFConverter {
+ public S_DF02_Converter() {
+ super(SDf02.class);
+ }
+
@Override
public Object[] toObjectArray(SDf02 entity) {
List