Ivan Nikolaev-Axenov 2024-09-10 16:55:50 +03:00
parent 30d1d660f1
commit f95541fa79
47 changed files with 2502 additions and 317 deletions

View file

@ -2,11 +2,11 @@ package ru.spcex.clearing.xml.importer.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import ru.spcex.clearing.xml.importer.config.settings.ImportXMLServiceSettings;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@Configuration
@ -33,14 +33,28 @@ public class ImporterImdgConfig {
}
@Autowired
@Bean
public HazelcastService imdgProvider(
@Bean(name = "sdfImdgProvider")
@ConditionalOnProperty(value = "import-xml-service.process-sdf-files", havingValue = "true")
public HazelcastService sdfImdgProvider(
@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
@Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
ImportXMLServiceSettings settings
) {
return new HazelcastService(taskExecutorHazelcastClientInitializer,
taskExecutorIdGeneratorAwaiter,
settings.getHazelcast());
settings.getSdfHazelcastAndKafka().getHazelcast());
}
@Autowired
@Bean(name = "lksImdgProvider")
@ConditionalOnProperty(value = "import-xml-service.process-lks-files", havingValue = "true")
public HazelcastService lksImdgProvider(
@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
@Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
ImportXMLServiceSettings settings
) {
return new HazelcastService(taskExecutorHazelcastClientInitializer,
taskExecutorIdGeneratorAwaiter,
settings.getLksHazelcastAndKafka().getHazelcast());
}
}

View file

@ -3,7 +3,9 @@ package ru.spcex.clearing.xml.importer.config;
import java.util.function.Supplier;
import org.apache.kafka.clients.consumer.Consumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@ -22,21 +24,54 @@ import ru.spcex.platform.imdg.api.ImdgProvider;
@Configuration
public class KafkaConfig {
@Bean
public ProducerFactory<String, Object> pf(ImportXMLServiceSettings settings) {
KafkaProducerSettings kafkaSettings = settings.getKafkaProducer();
@Bean(name = "pfSdf")
@ConditionalOnProperty(value = "import-xml-service.process-sdf-files", havingValue = "true")
public ProducerFactory<String, Object> pfSdf(ImportXMLServiceSettings settings) {
KafkaProducerSettings kafkaSettings = settings.getSdfHazelcastAndKafka().getKafkaProducer();
return KafkaProducerFactory.producerFactory(kafkaSettings);
}
@Bean("kafkaTemplate")
public KafkaTemplate<String, Object> kafkaTemplate(ProducerFactory<String, Object> pf) {
@Bean(name = "pfLks")
@ConditionalOnProperty(value = "import-xml-service.process-lks-files", havingValue = "true")
public ProducerFactory<String, Object> pfLks(ImportXMLServiceSettings settings) {
KafkaProducerSettings kafkaSettings = settings.getLksHazelcastAndKafka().getKafkaProducer();
return KafkaProducerFactory.producerFactory(kafkaSettings);
}
@Bean("kafkaTemplateSdf")
@ConditionalOnProperty(value = "import-xml-service.process-sdf-files", havingValue = "true")
public KafkaTemplate<String, Object> kafkaTemplateSdf(@Qualifier("pfSdf") ProducerFactory<String, Object> pf) {
return new KafkaTemplate<>(pf);
}
@Bean("kafkaTemplateLks")
@ConditionalOnProperty(value = "import-xml-service.process-lks-files", havingValue = "true")
public KafkaTemplate<String, Object> kafkaTemplateLks(@Qualifier("pfLks") ProducerFactory<String, Object> pf) {
return new KafkaTemplate<>(pf);
}
@Autowired
@Bean
public Supplier<KafkaSender> kafkaSender(KafkaTemplate<String, Object> kafkaTemplate,
ImdgProvider imdgProvider) {
@Bean("kafkaSenderSdf")
@ConditionalOnProperty(value = "import-xml-service.process-sdf-files", havingValue = "true")
public Supplier<KafkaSender> kafkaSenderSdf(@Qualifier("kafkaTemplateSdf") KafkaTemplate<String, Object> kafkaTemplate,
@Qualifier("sdfImdgProvider") ImdgProvider imdgProvider) {
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
return () -> KafkaSender
.setup()
.setKafkaTemplate(kafkaTemplate)
.idGenerator(imdgIdGenerator::nextId)
.imdgProvider(s -> {
Imdg<RequestInfo> imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class);
return imdg::insert;
})
.build();
}
@Autowired
@Bean("kafkaSenderLks")
@ConditionalOnProperty(value = "import-xml-service.process-lks-files", havingValue = "true")
public Supplier<KafkaSender> kafkaSenderLks(@Qualifier("kafkaTemplateLks") KafkaTemplate<String, Object> kafkaTemplate,
@Qualifier("lksImdgProvider") ImdgProvider imdgProvider) {
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
return () -> KafkaSender
.setup()
@ -51,8 +86,17 @@ public class KafkaConfig {
@Autowired
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean
public Consumer<String, Object> createConsumer(ImportXMLServiceSettings settings) {
return KafkaConsumerFactory.consumer(settings.getKafkaConsumer());
@Bean("createConsumerSdf")
@ConditionalOnProperty(value = "import-xml-service.process-sdf-files", havingValue = "true")
public Consumer<String, Object> createConsumerSdf(ImportXMLServiceSettings settings) {
return KafkaConsumerFactory.consumer(settings.getSdfHazelcastAndKafka().getKafkaConsumer());
}
@Autowired
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean("createConsumerLks")
@ConditionalOnProperty(value = "import-xml-service.process-lks-files", havingValue = "true")
public Consumer<String, Object> createConsumerLks(ImportXMLServiceSettings settings) {
return KafkaConsumerFactory.consumer(settings.getLksHazelcastAndKafka().getKafkaConsumer());
}
}

View file

@ -7,6 +7,8 @@ import java.io.File;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@ -28,40 +30,90 @@ import ru.spcex.clearing.xml.importer.config.settings.ImportXMLServiceSettings;
public class SFTPConfig {
private final Logger log = LoggerFactory.getLogger(getClass());
@Bean
public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory(ImportXMLServiceSettings settings) {
@Bean("sftpSessionFactorySdf")
@ConditionalOnProperty(value = "import-xml-service.process-sdf-files", havingValue = "true")
public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactorySdf(ImportXMLServiceSettings settings) {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost(settings.getStore().getSftpIn().getServerIp());
factory.setPort(settings.getStore().getSftpIn().getServerPort());
factory.setUser(settings.getStore().getSftpIn().getUser());
factory.setPassword(settings.getStore().getSftpIn().getPassword());
factory.setHost(settings.getStoreSdf().getSftpIn().getServerIp());
factory.setPort(settings.getStoreSdf().getSftpIn().getServerPort());
factory.setUser(settings.getStoreSdf().getSftpIn().getUser());
factory.setPassword(settings.getStoreSdf().getSftpIn().getPassword());
factory.setAllowUnknownKeys(true);
return new CachingSessionFactory<>(factory);
}
@Bean("sftpSessionFactoryLks")
@ConditionalOnProperty(value = "import-xml-service.process-lks-files", havingValue = "true")
public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactoryLks(ImportXMLServiceSettings settings) {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost(settings.getStoreLks().getSftpIn().getServerIp());
factory.setPort(settings.getStoreLks().getSftpIn().getServerPort());
factory.setUser(settings.getStoreLks().getSftpIn().getUser());
factory.setPassword(settings.getStoreLks().getSftpIn().getPassword());
factory.setAllowUnknownKeys(true);
return new CachingSessionFactory<>(factory);
}
// https://stackoverflow.com/questions/53655208/profile-doesnt-work-with-messaging-gateway
@Bean("xmlGateway")
public AnnotationGatewayProxyFactoryBean xmlGateway() {
return new AnnotationGatewayProxyFactoryBean(XmlGateway.class);
}
public interface XmlGateway {
@Gateway(requestChannel = "listSftpChannel")
public interface XmlGatewaySdf {
@Gateway(requestChannel = "listSftpChannelSdf")
List<File> listFiles(String dir);
}
@Bean
public MessageChannel listSftpChannel(SessionFactory<ChannelSftp.LsEntry> sessionFactory, ImportXMLServiceSettings settings) {
public interface XmlGatewayLks {
@Gateway(requestChannel = "listSftpChannelLks")
List<File> listFiles(String dir);
}
@Bean("xmlGatewaySdf")
@ConditionalOnProperty(value = "import-xml-service.process-sdf-files", havingValue = "true")
public AnnotationGatewayProxyFactoryBean xmlGatewaySdf() {
return new AnnotationGatewayProxyFactoryBean(XmlGatewaySdf.class);
}
@Bean("xmlGatewayLks")
@ConditionalOnProperty(value = "import-xml-service.process-lks-files", havingValue = "true")
public AnnotationGatewayProxyFactoryBean xmlGatewayLks() {
return new AnnotationGatewayProxyFactoryBean(XmlGatewayLks.class);
}
@Bean("listSftpChannelSdf")
@ConditionalOnProperty(value = "import-xml-service.process-sdf-files", havingValue = "true")
public MessageChannel listSftpChannelSdf(@Qualifier("sftpSessionFactorySdf") SessionFactory<ChannelSftp.LsEntry> sessionFactory,
ImportXMLServiceSettings settings) {
DirectChannel dc = new DirectChannel();
dc.subscribe(handlerList(sessionFactory, settings));
dc.subscribe(handlerListSdf(sessionFactory, settings));
return dc;
}
@Bean("listSftpChannelLks")
@ConditionalOnProperty(value = "import-xml-service.process-lks-files", havingValue = "true")
public MessageChannel listSftpChannelLks(@Qualifier("sftpSessionFactoryLks") SessionFactory<ChannelSftp.LsEntry> sessionFactory,
ImportXMLServiceSettings settings) {
DirectChannel dc = new DirectChannel();
dc.subscribe(handlerListLks(sessionFactory, settings));
return dc;
}
@Bean
@ServiceActivator(inputChannel = "listSftpChannel")
public MessageHandler handlerList(SessionFactory<ChannelSftp.LsEntry> sessionFactory, ImportXMLServiceSettings settings) {
@ConditionalOnProperty(value = "import-xml-service.process-sdf-files", havingValue = "true")
@ServiceActivator(inputChannel = "listSftpChannelSdf")
public MessageHandler handlerListSdf(@Qualifier("sftpSessionFactorySdf") SessionFactory<ChannelSftp.LsEntry> sessionFactory,
ImportXMLServiceSettings settings) {
SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sessionFactory, MGET.getCommand(), null);
sftpOutboundGateway.setLocalDirectory(new File(settings.getStore().getSrcDir()));
sftpOutboundGateway.setLocalDirectory(new File(settings.getStoreSdf().getSrcDir()));
sftpOutboundGateway.setAutoCreateLocalDirectory(true);
sftpOutboundGateway.setOption(AbstractRemoteFileOutboundGateway.Option.DELETE);
return sftpOutboundGateway;
}
@Bean
@ConditionalOnProperty(value = "import-xml-service.process-lks-files", havingValue = "true")
@ServiceActivator(inputChannel = "listSftpChannelLks")
public MessageHandler handlerListLks(@Qualifier("sftpSessionFactoryLks") SessionFactory<ChannelSftp.LsEntry> sessionFactory,
ImportXMLServiceSettings settings) {
SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sessionFactory, MGET.getCommand(), null);
sftpOutboundGateway.setLocalDirectory(new File(settings.getStoreLks().getSrcDir()));
sftpOutboundGateway.setAutoCreateLocalDirectory(true);
sftpOutboundGateway.setOption(AbstractRemoteFileOutboundGateway.Option.DELETE);
return sftpOutboundGateway;

View file

@ -3,6 +3,7 @@ package ru.spcex.clearing.xml.importer.config;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@ -10,13 +11,26 @@ import org.springframework.context.annotation.Profile;
@Profile("test")
@Configuration
public class SFTPMockConfig {
@Bean("xmlGateway")
public SFTPConfig.XmlGateway xmlGateway(){
return new XGateway();
@Bean("xmlGatewaySdf")
@ConditionalOnProperty(value = "import-xml-service.process-sdf-files", havingValue = "true")
public SFTPConfig.XmlGatewaySdf xmlGatewaySdf(){
return new XGatewaySdf();
}
public static class XGateway implements SFTPConfig.XmlGateway{
public static class XGatewaySdf implements SFTPConfig.XmlGatewaySdf{
@Override
public List<File> listFiles(String dir) {
return new ArrayList<>();
}
}
@Bean("xmlGatewayLks")
@ConditionalOnProperty(value = "import-xml-service.process-lks-files", havingValue = "true")
public SFTPConfig.XmlGatewayLks xmlGatewayLks(){
return new XGatewayLks();
}
public static class XGatewayLks implements SFTPConfig.XmlGatewayLks{
@Override
public List<File> listFiles(String dir) {
return new ArrayList<>();

View file

@ -13,6 +13,8 @@ import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
@ -41,7 +43,7 @@ public class XMLImporterConfig {
public XMLImporterConfig(ImportXMLServiceSettings settings,
ApplicationContext context,
ImdgProvider hazelcastService) {
@Qualifier("sdfImdgProvider") ImdgProvider hazelcastService) {
this.settings = settings;
this.context = context;
this.hazelcastService = hazelcastService;
@ -62,6 +64,7 @@ public class XMLImporterConfig {
}
@Bean("mapOfTable")
@ConditionalOnProperty(value = "import-xml-service.process-sdf-files", havingValue = "true")
public Map<ETable, ImdgHazelcast<? extends SpcexObjectBase>> getMapOfTables() {
Map<ETable, ImdgHazelcast<? extends SpcexObjectBase>> map = new HashMap<>();
map.put(ETable.DF_01, (ImdgHazelcast<? extends SpcexObjectBase>) hazelcastService.getImdg(IMDGDistributedNames.Map_SDf01, SDf01.class));

View file

@ -1,45 +1,62 @@
package ru.spcex.clearing.xml.importer.config.settings;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
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("import-xml-service")
public class ImportXMLServiceSettings {
private HazelcastClientParams hazelcast;
private KafkaProducerSettings kafkaProducer;
private KafkaConsumerSettings kafkaConsumer;
@NestedConfigurationProperty
private KafkaHazelcastSettings sdfHazelcastAndKafka;
@NestedConfigurationProperty
private KafkaHazelcastSettings lksHazelcastAndKafka;
@NestedConfigurationProperty
private StoreSettings storeSdf;
@NestedConfigurationProperty
private StoreSettings storeLks;
@NestedConfigurationProperty
private Common common;
private Store store;
@NestedConfigurationProperty
private Cron cron;
public HazelcastClientParams getHazelcast() {
return hazelcast;
private boolean processSdfFiles;
private boolean processLksFiles;
public KafkaHazelcastSettings getSdfHazelcastAndKafka() {
return sdfHazelcastAndKafka;
}
public void setHazelcast(HazelcastClientParams hazelcast) {
this.hazelcast = hazelcast;
public void setSdfHazelcastAndKafka(KafkaHazelcastSettings sdfHazelcastAndKafka) {
this.sdfHazelcastAndKafka = sdfHazelcastAndKafka;
}
public KafkaProducerSettings getKafkaProducer() {
return kafkaProducer;
public KafkaHazelcastSettings getLksHazelcastAndKafka() {
return lksHazelcastAndKafka;
}
public void setKafkaProducer(KafkaProducerSettings kafkaProducer) {
this.kafkaProducer = kafkaProducer;
public void setLksHazelcastAndKafka(KafkaHazelcastSettings lksHazelcastAndKafka) {
this.lksHazelcastAndKafka = lksHazelcastAndKafka;
}
public KafkaConsumerSettings getKafkaConsumer() {
return kafkaConsumer;
public StoreSettings getStoreSdf() {
return storeSdf;
}
public void setKafkaConsumer(KafkaConsumerSettings kafkaConsumer) {
this.kafkaConsumer = kafkaConsumer;
public void setStoreSdf(StoreSettings storeSdf) {
this.storeSdf = storeSdf;
}
public StoreSettings getStoreLks() {
return storeLks;
}
public void setStoreLks(StoreSettings storeLks) {
this.storeLks = storeLks;
}
public Common getCommon() {
@ -50,14 +67,6 @@ public class ImportXMLServiceSettings {
this.common = common;
}
public Store getStore() {
return store;
}
public void setStore(Store store) {
this.store = store;
}
public Cron getCron() {
return cron;
}
@ -65,4 +74,20 @@ public class ImportXMLServiceSettings {
public void setCron(Cron cron) {
this.cron = cron;
}
public boolean isProcessSdfFiles() {
return processSdfFiles;
}
public void setProcessSdfFiles(boolean processSdfFiles) {
this.processSdfFiles = processSdfFiles;
}
public boolean isProcessLksFiles() {
return processLksFiles;
}
public void setProcessLksFiles(boolean processLksFiles) {
this.processLksFiles = processLksFiles;
}
}

View file

@ -0,0 +1,41 @@
package ru.spcex.clearing.xml.importer.config.settings;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
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;
public class KafkaHazelcastSettings {
@NestedConfigurationProperty
private HazelcastClientParams hazelcast;
@NestedConfigurationProperty
private KafkaProducerSettings kafkaProducer;
@NestedConfigurationProperty
private KafkaConsumerSettings kafkaConsumer;
public HazelcastClientParams getHazelcast() {
return hazelcast;
}
public void setHazelcast(HazelcastClientParams hazelcast) {
this.hazelcast = hazelcast;
}
public KafkaProducerSettings getKafkaProducer() {
return kafkaProducer;
}
public void setKafkaProducer(KafkaProducerSettings kafkaProducer) {
this.kafkaProducer = kafkaProducer;
}
public KafkaConsumerSettings getKafkaConsumer() {
return kafkaConsumer;
}
public void setKafkaConsumer(KafkaConsumerSettings kafkaConsumer) {
this.kafkaConsumer = kafkaConsumer;
}
}

View file

@ -1,14 +1,18 @@
package ru.spcex.clearing.xml.importer.config.settings;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import ru.spcex.platform.utils.config.SftpInboundFolderSetting;
public class Store {
public class StoreSettings {
private String srcDir;
private String outDir;
private String outDirError;
private boolean deleteSrcFiles = true;
//sftp settings
@NestedConfigurationProperty
private SftpInboundFolderSetting sftpIn;
public String getSrcDir() {
return srcDir;
}

View file

@ -4,18 +4,18 @@ import java.io.File;
import java.util.UUID;
import ru.spcex.clearing.xml.importer.logic.data.enums.ETable;
import ru.spcex.clearing.xml.importer.logic.data.enums.StageResult;
import ru.spcex.clearing.xml.importer.logic.data.tags.DocumentTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.XmlFile;
public class ResultContainer {
private UUID uuid;
private ETable xmlTable;
private File xmlFile;
private File xmlFilePath;
private StageResult lastStageStatus;
private DocumentTag documentTag;
private XmlFile xmlFile;
public ResultContainer(ETable xmlTable, File xmlFile) {
public ResultContainer(ETable xmlTable, File xmlFilePath) {
this.xmlTable = xmlTable;
this.xmlFile = xmlFile;
this.xmlFilePath = xmlFilePath;
this.uuid = UUID.randomUUID();
}
@ -27,12 +27,12 @@ public class ResultContainer {
this.xmlTable = xmlTable;
}
public File getXmlFile() {
return xmlFile;
public File getXmlFilePath() {
return xmlFilePath;
}
public void setXmlFile(File xmlFile) {
this.xmlFile = xmlFile;
public void setXmlFilePath(File xmlFilePath) {
this.xmlFilePath = xmlFilePath;
}
public UUID getUuid() {
@ -51,11 +51,11 @@ public class ResultContainer {
this.lastStageStatus = lastStageRes;
}
public DocumentTag getDocumentTag() {
return documentTag;
public XmlFile getXmlFile() {
return xmlFile;
}
public void setDocumentTag(DocumentTag documentTag) {
this.documentTag = documentTag;
public void setXmlFile(XmlFile xmlFile) {
this.xmlFile = xmlFile;
}
}

View file

@ -1,39 +1,39 @@
package ru.spcex.clearing.xml.importer.logic.data.enums;
public enum ETable {
DF_01("DF-01"),
DF_04("DF-04"),
DF_06("DF-06"),
DF_52("DF-52"),
DF_55("DF-55"),
DF_57("DF-57");
import java.util.regex.Pattern;
public String getPrefix() {
return prefix;
public enum ETable {
DF_01(Pattern.compile("DF-01_\\w_.*_.*.XML"), FileType.SDF),
DF_04(Pattern.compile("DF-04_\\w_.*_.*.XML"), FileType.SDF),
DF_06(Pattern.compile("DF-06_\\w_.*_.*.XML"), FileType.SDF),
DF_52(Pattern.compile("DF-52_\\w_.*_.*.XML"), FileType.SDF),
DF_55(Pattern.compile("DF-55_\\w_.*_.*.XML"), FileType.SDF),
DF_57(Pattern.compile("DF-57_\\w_.*_.*.XML"), FileType.SDF),
ACCOUNT_LIST_RUB(Pattern.compile(".*_ACCOUNT_LIST_\\d{8}_RUB_\\d{5}.XML"), FileType.LKS),
ACCOUNT_LIST_CUR(Pattern.compile(".*_ACCOUNT_LIST_\\d{8}_\\w{3}_\\d{5}.XML"), FileType.LKS);
private final Pattern pattern;
private final FileType fileType;
ETable(Pattern pattern, FileType fileType) {
this.pattern = pattern;
this.fileType = fileType;
}
private final String prefix;
public Pattern getPattern() {
return pattern;
}
ETable(String prefix) {
this.prefix = prefix;
public FileType getFileType() {
return fileType;
}
public static ETable getTableForFilename(String filename) {
for (ETable table : ETable.values()) {
if (table.fileForThisTable(filename)) return table;
}
return null;
}
public static ETable tableForName(String name) {
for (ETable table : values()) {
if (name.equalsIgnoreCase(table.name()))
if (table.getPattern().matcher(filename.toUpperCase()).matches()) {
return table;
}
}
return null;
}
public boolean fileForThisTable(String filename) {
return filename != null && filename.startsWith(prefix);
}
}

View file

@ -0,0 +1,6 @@
package ru.spcex.clearing.xml.importer.logic.data.enums;
public enum FileType {
SDF,
LKS
}

View file

@ -0,0 +1,4 @@
package ru.spcex.clearing.xml.importer.logic.data.tags;
public interface XmlFile {
}

View file

@ -0,0 +1,66 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.lks;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.Objects;
import ru.spcex.clearing.xml.importer.logic.data.tags.XmlFile;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.document.DocumentTagCur;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.RegistratorTagCur;
@JacksonXmlRootElement(localName = "FIRM_DOC")
public class AccountListCur implements XmlFile {
@JacksonXmlProperty(localName = "DOCUMENT")
@JsonProperty(required = true)
private DocumentTagCur document;
@JacksonXmlProperty(localName = "REGISTRATOR")
@JsonProperty(required = true)
private RegistratorTagCur registrator;
public AccountListCur() {
}
public AccountListCur(DocumentTagCur document,
RegistratorTagCur registrator) {
this.document = document;
this.registrator = registrator;
}
public DocumentTagCur getDocument() {
return document;
}
public void setDocument(DocumentTagCur document) {
this.document = document;
}
public RegistratorTagCur getRegistrator() {
return registrator;
}
public void setRegistrator(RegistratorTagCur registrator) {
this.registrator = registrator;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AccountListCur that = (AccountListCur) o;
return Objects.equals(document, that.document) && Objects.equals(registrator, that.registrator);
}
@Override
public int hashCode() {
return Objects.hash(document, registrator);
}
@Override
public String toString() {
return "AccountListCur{" +
"document=" + document +
", registrator=" + registrator +
'}';
}
}

View file

@ -0,0 +1,65 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.lks;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.Objects;
import ru.spcex.clearing.xml.importer.logic.data.tags.XmlFile;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.document.DocumentTagRub;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.RegistratorTagRub;
@JacksonXmlRootElement(localName = "FIRM_DOC")
public class AccountListRub implements XmlFile {
@JacksonXmlProperty(localName = "DOCUMENT")
@JsonProperty(required = true)
private DocumentTagRub document;
@JacksonXmlProperty(localName = "REGISTRATOR")
@JsonProperty(required = true)
private RegistratorTagRub registrator;
public AccountListRub() {
}
public AccountListRub(DocumentTagRub document, RegistratorTagRub registrator) {
this.document = document;
this.registrator = registrator;
}
public DocumentTagRub getDocument() {
return document;
}
public void setDocument(DocumentTagRub document) {
this.document = document;
}
public RegistratorTagRub getRegistrator() {
return registrator;
}
public void setRegistrator(RegistratorTagRub registrator) {
this.registrator = registrator;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AccountListRub that = (AccountListRub) o;
return Objects.equals(document, that.document) && Objects.equals(registrator, that.registrator);
}
@Override
public int hashCode() {
return Objects.hash(document, registrator);
}
@Override
public String toString() {
return "AccountListRub{" +
"document=" + document +
", registrator=" + registrator +
'}';
}
}

View file

@ -0,0 +1,111 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.lks.document;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Objects;
public class DocumentTagCur {
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "AUTHOR")
private String author;
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "TIME")
@JsonFormat(pattern = "HH:mm:ss")
private LocalTime time;
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "DATE")
@JsonFormat(pattern = "dd.MM.yyyy")
private LocalDate date;
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "NAME")
private String name;
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "DOC_NUM")
private String docNum;
public DocumentTagCur() {
}
public DocumentTagCur(String author,
LocalTime time,
LocalDate date,
String name,
String docNum) {
this.author = author;
this.time = time;
this.date = date;
this.name = name;
this.docNum = docNum;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public LocalTime getTime() {
return time;
}
public void setTime(LocalTime time) {
this.time = time;
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDocNum() {
return docNum;
}
public void setDocNum(String docNum) {
this.docNum = docNum;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DocumentTagCur that = (DocumentTagCur) o;
return Objects.equals(author, that.author) && Objects.equals(time, that.time) && Objects.equals(date, that.date) && Objects.equals(name, that.name) && Objects.equals(docNum, that.docNum);
}
@Override
public int hashCode() {
return Objects.hash(author, time, date, name, docNum);
}
@Override
public String toString() {
return "DocumentTagCur{" +
"author='" + author + '\'' +
", time=" + time +
", date=" + date +
", name='" + name + '\'' +
", docNum='" + docNum + '\'' +
'}';
}
}

View file

@ -0,0 +1,111 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.lks.document;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Objects;
public class DocumentTagRub {
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "AUTHOR")
private String author;
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "TIME")
@JsonFormat(pattern = "HH:mm:ss")
private LocalTime time;
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "DATE")
@JsonFormat(pattern = "dd.MM.yyyy")
private LocalDate date;
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "NAME")
private String name;
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "DOC_NUM")
private String docNum;
public DocumentTagRub() {
}
public DocumentTagRub(String author,
LocalTime time,
LocalDate date,
String name,
String docNum) {
this.author = author;
this.time = time;
this.date = date;
this.name = name;
this.docNum = docNum;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public LocalTime getTime() {
return time;
}
public void setTime(LocalTime time) {
this.time = time;
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDocNum() {
return docNum;
}
public void setDocNum(String docNum) {
this.docNum = docNum;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DocumentTagRub that = (DocumentTagRub) o;
return Objects.equals(author, that.author) && Objects.equals(time, that.time) && Objects.equals(date, that.date) && Objects.equals(name, that.name) && Objects.equals(docNum, that.docNum);
}
@Override
public int hashCode() {
return Objects.hash(author, time, date, name, docNum);
}
@Override
public String toString() {
return "DocumentTagRub{" +
"author='" + author + '\'' +
", time=" + time +
", date=" + date +
", name='" + name + '\'' +
", docNum='" + docNum + '\'' +
'}';
}
}

View file

@ -0,0 +1,77 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.util.Objects;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.ClientTagCur;
public class RegistratorTagCur {
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "FIRMID")
private String firmId;
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "NAME")
private String name;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "CLIENT")
private ClientTagCur client;
public RegistratorTagCur() {
}
public RegistratorTagCur(String firmId,
String name,
ClientTagCur client) {
this.firmId = firmId;
this.name = name;
this.client = client;
}
public String getFirmId() {
return firmId;
}
public void setFirmId(String firmId) {
this.firmId = firmId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ClientTagCur getClient() {
return client;
}
public void setClient(ClientTagCur client) {
this.client = client;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RegistratorTagCur that = (RegistratorTagCur) o;
return Objects.equals(firmId, that.firmId) && Objects.equals(name, that.name) && Objects.equals(client, that.client);
}
@Override
public int hashCode() {
return Objects.hash(firmId, name, client);
}
@Override
public String toString() {
return "RegistratorTagCur{" +
"firmId='" + firmId + '\'' +
", name='" + name + '\'' +
", client=" + client +
'}';
}
}

View file

@ -0,0 +1,77 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.util.Objects;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.ClientTagRub;
public class RegistratorTagRub {
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "FIRMID")
private String firmId;
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "NAME")
private String name;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "CLIENT")
private ClientTagRub client;
public RegistratorTagRub() {
}
public RegistratorTagRub(String firmId,
String name,
ClientTagRub client) {
this.firmId = firmId;
this.name = name;
this.client = client;
}
public String getFirmId() {
return firmId;
}
public void setFirmId(String firmId) {
this.firmId = firmId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ClientTagRub getClient() {
return client;
}
public void setClient(ClientTagRub client) {
this.client = client;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RegistratorTagRub that = (RegistratorTagRub) o;
return Objects.equals(firmId, that.firmId) && Objects.equals(name, that.name) && Objects.equals(client, that.client);
}
@Override
public int hashCode() {
return Objects.hash(firmId, name, client);
}
@Override
public String toString() {
return "RegistratorTagRub{" +
"firmId='" + firmId + '\'' +
", name='" + name + '\'' +
", client=" + client +
'}';
}
}

View file

@ -0,0 +1,61 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.util.Objects;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account.AccountTagCur;
public class ClientTagCur {
@JsonProperty
@JacksonXmlProperty(isAttribute = true, localName = "CLIENT_NAME")
private String clientName;
@JsonProperty
@JacksonXmlProperty(localName = "ACCOUNT")
private AccountTagCur account;
public ClientTagCur() {
}
public ClientTagCur(String clientName, AccountTagCur account) {
this.clientName = clientName;
this.account = account;
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public AccountTagCur getAccount() {
return account;
}
public void setAccount(AccountTagCur account) {
this.account = account;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ClientTagCur that = (ClientTagCur) o;
return Objects.equals(clientName, that.clientName) && Objects.equals(account, that.account);
}
@Override
public int hashCode() {
return Objects.hash(clientName, account);
}
@Override
public String toString() {
return "ClientTagCur{" +
"clientName='" + clientName + '\'' +
", account=" + account +
'}';
}
}

View file

@ -0,0 +1,62 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.util.Objects;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account.AccountTagRub;
public class ClientTagRub {
@JsonProperty
@JacksonXmlProperty(isAttribute = true, localName = "CLIENT_NAME")
private String clientName;
@JsonProperty
@JacksonXmlProperty(localName = "ACCOUNT")
private AccountTagRub account;
public ClientTagRub() {
}
public ClientTagRub(String clientName,
AccountTagRub account) {
this.clientName = clientName;
this.account = account;
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public AccountTagRub getAccount() {
return account;
}
public void setAccount(AccountTagRub account) {
this.account = account;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ClientTagRub that = (ClientTagRub) o;
return Objects.equals(clientName, that.clientName) && Objects.equals(account, that.account);
}
@Override
public int hashCode() {
return Objects.hash(clientName, account);
}
@Override
public String toString() {
return "ClientTagRub{" +
"clientName='" + clientName + '\'' +
", account=" + account +
'}';
}
}

View file

@ -0,0 +1,317 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.util.Objects;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account.respond.RespondTagCur;
public class AccountTagCur {
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "CURRENCY")
private String currency;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "NAME")
private String name;
@JsonProperty
@JacksonXmlProperty(localName = "SWIFT_CODE")
private String swiftCode;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "ADDRESS")
private String address;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "ACCOUNT")
private String account;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "BANK_NAME")
private String bankName;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "BANK_ADDRESS")
private String bankAddress;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "BANK_SWIFT_CODE")
private String bankSwiftCode;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "BANK_ACCOUNT")
private String bankAccount;
@JsonProperty
@JacksonXmlProperty(localName = "BANK_NAME_1")
private String bankName1;
@JsonProperty
@JacksonXmlProperty(localName = "BANK_ADDRESS_1")
private String bankAddress1;
@JsonProperty
@JacksonXmlProperty(localName = "BANK_ACCOUNT_1")
private String bankAccount1;
@JsonProperty
@JacksonXmlProperty(localName = "INTERMEDIARY_SWIFT_CODE")
private String intermediarySwiftCode1;
@JsonProperty
@JacksonXmlProperty(localName = "BANK_NAME_2")
private String bankName2;
@JsonProperty
@JacksonXmlProperty(localName = "BANK_ADDRESS_2")
private String bankAddress2;
@JsonProperty
@JacksonXmlProperty(localName = "BANK_ACCOUNT_2")
private String bankAccount2;
@JsonProperty
@JacksonXmlProperty(localName = "INTERMEDIARY_SWIFT_CODE_2")
private String intermediarySwiftCode2;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "DESTINATION")
private String destination;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "RESPOND")
private RespondTagCur respondTag;
public AccountTagCur() {
}
public AccountTagCur(String currency,
String name,
String swiftCode,
String address,
String account,
String bankName,
String bankAddress,
String bankSwiftCode,
String bankAccount,
String bankName1,
String bankAddress1,
String bankAccount1,
String intermediarySwiftCode1,
String bankName2,
String bankAddress2,
String bankAccount2,
String intermediarySwiftCode2,
String destination,
RespondTagCur respondTag) {
this.currency = currency;
this.name = name;
this.swiftCode = swiftCode;
this.address = address;
this.account = account;
this.bankName = bankName;
this.bankAddress = bankAddress;
this.bankSwiftCode = bankSwiftCode;
this.bankAccount = bankAccount;
this.bankName1 = bankName1;
this.bankAddress1 = bankAddress1;
this.bankAccount1 = bankAccount1;
this.intermediarySwiftCode1 = intermediarySwiftCode1;
this.bankName2 = bankName2;
this.bankAddress2 = bankAddress2;
this.bankAccount2 = bankAccount2;
this.intermediarySwiftCode2 = intermediarySwiftCode2;
this.destination = destination;
this.respondTag = respondTag;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSwiftCode() {
return swiftCode;
}
public void setSwiftCode(String swiftCode) {
this.swiftCode = swiftCode;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getBankName() {
return bankName;
}
public void setBankName(String bankName) {
this.bankName = bankName;
}
public String getBankAddress() {
return bankAddress;
}
public void setBankAddress(String bankAddress) {
this.bankAddress = bankAddress;
}
public String getBankSwiftCode() {
return bankSwiftCode;
}
public void setBankSwiftCode(String bankSwiftCode) {
this.bankSwiftCode = bankSwiftCode;
}
public String getBankAccount() {
return bankAccount;
}
public void setBankAccount(String bankAccount) {
this.bankAccount = bankAccount;
}
public String getBankName1() {
return bankName1;
}
public void setBankName1(String bankName1) {
this.bankName1 = bankName1;
}
public String getBankAddress1() {
return bankAddress1;
}
public void setBankAddress1(String bankAddress1) {
this.bankAddress1 = bankAddress1;
}
public String getBankAccount1() {
return bankAccount1;
}
public void setBankAccount1(String bankAccount1) {
this.bankAccount1 = bankAccount1;
}
public String getIntermediarySwiftCode1() {
return intermediarySwiftCode1;
}
public void setIntermediarySwiftCode1(String intermediarySwiftCode1) {
this.intermediarySwiftCode1 = intermediarySwiftCode1;
}
public String getBankName2() {
return bankName2;
}
public void setBankName2(String bankName2) {
this.bankName2 = bankName2;
}
public String getBankAddress2() {
return bankAddress2;
}
public void setBankAddress2(String bankAddress2) {
this.bankAddress2 = bankAddress2;
}
public String getBankAccount2() {
return bankAccount2;
}
public void setBankAccount2(String bankAccount2) {
this.bankAccount2 = bankAccount2;
}
public String getIntermediarySwiftCode2() {
return intermediarySwiftCode2;
}
public void setIntermediarySwiftCode2(String intermediarySwiftCode2) {
this.intermediarySwiftCode2 = intermediarySwiftCode2;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public RespondTagCur getRespondTag() {
return respondTag;
}
public void setRespondTag(RespondTagCur respondTag) {
this.respondTag = respondTag;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AccountTagCur that = (AccountTagCur) o;
return Objects.equals(currency, that.currency) && Objects.equals(name, that.name) && Objects.equals(swiftCode, that.swiftCode) && Objects.equals(address, that.address) && Objects.equals(account, that.account) && Objects.equals(bankName, that.bankName) && Objects.equals(bankAddress, that.bankAddress) && Objects.equals(bankSwiftCode, that.bankSwiftCode) && Objects.equals(bankAccount, that.bankAccount) && Objects.equals(bankName1, that.bankName1) && Objects.equals(bankAddress1, that.bankAddress1) && Objects.equals(bankAccount1, that.bankAccount1) && Objects.equals(intermediarySwiftCode1, that.intermediarySwiftCode1) && Objects.equals(bankName2, that.bankName2) && Objects.equals(bankAddress2, that.bankAddress2) && Objects.equals(bankAccount2, that.bankAccount2) && Objects.equals(intermediarySwiftCode2, that.intermediarySwiftCode2) && Objects.equals(destination, that.destination) && Objects.equals(respondTag, that.respondTag);
}
@Override
public int hashCode() {
return Objects.hash(currency, name, swiftCode, address, account, bankName, bankAddress, bankSwiftCode, bankAccount, bankName1, bankAddress1, bankAccount1, intermediarySwiftCode1, bankName2, bankAddress2, bankAccount2, intermediarySwiftCode2, destination, respondTag);
}
@Override
public String toString() {
return "AccountTagCur{" +
"currency='" + currency + '\'' +
", name='" + name + '\'' +
", swiftCode='" + swiftCode + '\'' +
", address='" + address + '\'' +
", account='" + account + '\'' +
", bankName='" + bankName + '\'' +
", bankAddress='" + bankAddress + '\'' +
", bankSwiftCode='" + bankSwiftCode + '\'' +
", bankAccount='" + bankAccount + '\'' +
", bankName1='" + bankName1 + '\'' +
", bankAddress1='" + bankAddress1 + '\'' +
", bankAccount1='" + bankAccount1 + '\'' +
", intermediarySwiftCode1='" + intermediarySwiftCode1 + '\'' +
", bankName2='" + bankName2 + '\'' +
", bankAddress2='" + bankAddress2 + '\'' +
", bankAccount2='" + bankAccount2 + '\'' +
", intermediarySwiftCode2='" + intermediarySwiftCode2 + '\'' +
", destination='" + destination + '\'' +
", respondTag=" + respondTag +
'}';
}
}

View file

@ -0,0 +1,257 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.util.Objects;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account.respond.RespondTagRub;
public class AccountTagRub {
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "CURRENCY")
private String currency;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "NAME")
private String name;
@JsonProperty
@JacksonXmlProperty(localName = "PERSONAL_ACCOUNT")
private String personalAccount;
@JsonProperty
@JacksonXmlProperty(localName = "BUDGET_CLASSIFICATION_CODE")
private String budgetClassificationCode;
@JsonProperty
@JacksonXmlProperty(localName = "OKTMO")
private String oktmo;
@JsonProperty
@JacksonXmlProperty(localName = "TIN")
private String tin;
@JsonProperty
@JacksonXmlProperty(localName = "TRRC")
private String trrc;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "ACCOUNT")
private String account;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "BANK_NAME")
private String bankName;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "BANK_ADDRESS")
private String bankAddress;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "BIC")
private String bic;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "CORRESPONDENT_ACCOUNT")
private String correspondentAccount;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "DESTINATION")
private String destination;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "DISCONTINUATION_DATE")
private String discontinuationDate;
@JsonProperty(required = true)
@JacksonXmlProperty(localName = "RESPOND")
private RespondTagRub respondTag;
public AccountTagRub() {
}
public AccountTagRub(String currency,
String name,
String personalAccount,
String budgetClassificationCode,
String oktmo,
String tin,
String trrc,
String account,
String bankName,
String bankAddress,
String bic,
String correspondentAccount,
String destination,
String discontinuationDate,
RespondTagRub respondTag) {
this.currency = currency;
this.name = name;
this.personalAccount = personalAccount;
this.budgetClassificationCode = budgetClassificationCode;
this.oktmo = oktmo;
this.tin = tin;
this.trrc = trrc;
this.account = account;
this.bankName = bankName;
this.bankAddress = bankAddress;
this.bic = bic;
this.correspondentAccount = correspondentAccount;
this.destination = destination;
this.discontinuationDate = discontinuationDate;
this.respondTag = respondTag;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPersonalAccount() {
return personalAccount;
}
public void setPersonalAccount(String personalAccount) {
this.personalAccount = personalAccount;
}
public String getBudgetClassificationCode() {
return budgetClassificationCode;
}
public void setBudgetClassificationCode(String budgetClassificationCode) {
this.budgetClassificationCode = budgetClassificationCode;
}
public String getOktmo() {
return oktmo;
}
public void setOktmo(String oktmo) {
this.oktmo = oktmo;
}
public String getTin() {
return tin;
}
public void setTin(String tin) {
this.tin = tin;
}
public String getTrrc() {
return trrc;
}
public void setTrrc(String trrc) {
this.trrc = trrc;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getBankName() {
return bankName;
}
public void setBankName(String bankName) {
this.bankName = bankName;
}
public String getBankAddress() {
return bankAddress;
}
public void setBankAddress(String bankAddress) {
this.bankAddress = bankAddress;
}
public String getBic() {
return bic;
}
public void setBic(String bic) {
this.bic = bic;
}
public String getCorrespondentAccount() {
return correspondentAccount;
}
public void setCorrespondentAccount(String correspondentAccount) {
this.correspondentAccount = correspondentAccount;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getDiscontinuationDate() {
return discontinuationDate;
}
public void setDiscontinuationDate(String discontinuationDate) {
this.discontinuationDate = discontinuationDate;
}
public void setRespondTag(RespondTagRub respondTag) {
this.respondTag = respondTag;
}
public RespondTagRub getRespondTag() {
return respondTag;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AccountTagRub that = (AccountTagRub) o;
return Objects.equals(currency, that.currency) && Objects.equals(name, that.name) && Objects.equals(personalAccount, that.personalAccount) && Objects.equals(budgetClassificationCode, that.budgetClassificationCode) && Objects.equals(oktmo, that.oktmo) && Objects.equals(tin, that.tin) && Objects.equals(trrc, that.trrc) && Objects.equals(account, that.account) && Objects.equals(bankName, that.bankName) && Objects.equals(bankAddress, that.bankAddress) && Objects.equals(bic, that.bic) && Objects.equals(correspondentAccount, that.correspondentAccount) && Objects.equals(destination, that.destination) && Objects.equals(discontinuationDate, that.discontinuationDate) && Objects.equals(respondTag, that.respondTag);
}
@Override
public int hashCode() {
return Objects.hash(currency, name, personalAccount, budgetClassificationCode, oktmo, tin, trrc, account, bankName, bankAddress, bic, correspondentAccount, destination, discontinuationDate, respondTag);
}
@Override
public String toString() {
return "AccountTagRub{" +
"currency='" + currency + '\'' +
", name='" + name + '\'' +
", personalAccount='" + personalAccount + '\'' +
", budgetClassificationCode='" + budgetClassificationCode + '\'' +
", oktmo='" + oktmo + '\'' +
", tin='" + tin + '\'' +
", trrc='" + trrc + '\'' +
", account='" + account + '\'' +
", bankName='" + bankName + '\'' +
", bankAddress='" + bankAddress + '\'' +
", bic='" + bic + '\'' +
", correspondentAccount='" + correspondentAccount + '\'' +
", destination='" + destination + '\'' +
", discontinuationDate='" + discontinuationDate + '\'' +
", respondTag=" + respondTag +
'}';
}
}

View file

@ -0,0 +1,46 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account.respond;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.util.Objects;
public class RespondTagCur {
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "STATUS")
private String status;
public RespondTagCur() {
}
public RespondTagCur(String status) {
this.status = status;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RespondTagCur that = (RespondTagCur) o;
return Objects.equals(status, that.status);
}
@Override
public int hashCode() {
return Objects.hashCode(status);
}
@Override
public String toString() {
return "RespondTagCur{" +
"status='" + status + '\'' +
'}';
}
}

View file

@ -0,0 +1,46 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account.respond;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.util.Objects;
public class RespondTagRub {
@JsonProperty(required = true)
@JacksonXmlProperty(isAttribute = true, localName = "STATUS")
private String status;
public RespondTagRub() {
}
public RespondTagRub(String status) {
this.status = status;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RespondTagRub that = (RespondTagRub) o;
return Objects.equals(status, that.status);
}
@Override
public int hashCode() {
return Objects.hashCode(status);
}
@Override
public String toString() {
return "RespondTagRub{" +
"status='" + status + '\'' +
'}';
}
}

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.xml.importer.logic.data.tags;
package ru.spcex.clearing.xml.importer.logic.data.tags.sdf;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
@ -8,11 +8,11 @@ import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.Objects;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.ObjectTag;
import ru.spcex.platform.classes.base.SpcexObjectBase;
@JacksonXmlRootElement(localName = "DOCUMENT")
public class DocumentTag {
public class DocumentTag implements ru.spcex.clearing.xml.importer.logic.data.tags.XmlFile {
@JacksonXmlProperty(isAttribute = true, localName = "MESSAGEID")
private String messageId;

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.xml.importer.logic.data.tags;
package ru.spcex.clearing.xml.importer.logic.data.tags.sdf;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.util.Objects;

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.objects;
package ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.objects;
package ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.objects;
package ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.objects;
package ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.objects;
package ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.objects;
package ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.xml.importer.logic.data.tags.objects;
package ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonSubTypes;

View file

@ -12,6 +12,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.xml.importer.config.settings.ImportXMLServiceSettings;
import ru.spcex.clearing.xml.importer.logic.data.ResultContainer;
import ru.spcex.clearing.xml.importer.logic.data.enums.FileType;
import ru.spcex.clearing.xml.importer.logic.data.enums.StageResult;
import ru.spcex.platform.utils.time.TimeUtil;
@ -27,27 +28,33 @@ public class ChangeDirOfFileStage {
public StageResult process(ResultContainer resultContainer) {
log.info("uuid {}. Stage: Change directory of file", resultContainer.getUuid());
File srcDir = new File(settings.getStore().getSrcDir());
File srcDir = new File(resultContainer.getXmlTable().getFileType().equals(FileType.SDF) ?
settings.getStoreSdf().getSrcDir() :
settings.getStoreLks().getSrcDir());
File outDir;
if (resultContainer.getLastStageStatus().equals(StageResult.ERROR)) {
outDir = new File(settings.getStore().getOutDirError());
outDir = new File(resultContainer.getXmlTable().getFileType().equals(FileType.SDF) ?
settings.getStoreSdf().getOutDirError() :
settings.getStoreLks().getOutDirError());
} else {
outDir = new File(settings.getStore().getOutDir());
outDir = new File(resultContainer.getXmlTable().getFileType().equals(FileType.SDF) ?
settings.getStoreSdf().getOutDir() :
settings.getStoreLks().getOutDir());
}
File xmlFile = resultContainer.getXmlFile();
File xmlFile = resultContainer.getXmlFilePath();
if (!srcDir.exists()) {
log.error("SettlementHouse_DocIn does not exists!");
log.error("Input directory does not exists!");
notifyWithCode(resultContainer, StageResult.ERROR);
return StageResult.ERROR;
}
if (!outDir.exists()) {
log.warn("ouput directory {} does not exists! Trying to made new!", outDir.getAbsolutePath());
log.warn("Output directory {} does not exists! Trying to made new!", outDir.getAbsolutePath());
if (outDir.mkdir()) {
log.error("Made dir {} successfully!", outDir.getName());
log.error("Made directory {} successfully!", outDir.getName());
} else {
log.error("SettlementHouse_DocIn does not exists!");
log.error("Can't create output directory {}!", outDir.getName());
notifyWithCode(resultContainer, StageResult.ERROR);
return StageResult.ERROR;
}

View file

@ -2,13 +2,17 @@ package ru.spcex.clearing.xml.importer.logic.steps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.sdf.SDf57;
import ru.spcex.clearing.xml.importer.logic.data.ResultContainer;
import ru.spcex.clearing.xml.importer.logic.data.enums.ETable;
import ru.spcex.clearing.xml.importer.logic.data.enums.FileType;
import ru.spcex.clearing.xml.importer.logic.data.enums.StageResult;
import ru.spcex.clearing.xml.importer.logic.data.tags.DocumentTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.AccountListCur;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.AccountListRub;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.DocumentTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.ObjectTag;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.ObjectType;
import ru.spcex.platform.enumeration.Priority;
@ -17,24 +21,35 @@ import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@Component
public class ImportToDB {
private final Logger log = LoggerFactory.getLogger(getClass());
private final HazelcastService hazelcastService;
private final HazelcastService hazelcastServiceSdf;
private final HazelcastService hazelcastServiceLks;
private final XmlImportKafkaMessenger kafkaMessenger;
public ImportToDB(HazelcastService hazelcastService,
public ImportToDB(@Qualifier("sdfImdgProvider") HazelcastService hazelcastServiceSdf,
@Qualifier("lksImdgProvider") HazelcastService hazelcastServiceLks,
XmlImportKafkaMessenger kafkaMessenger) {
this.hazelcastService = hazelcastService;
this.hazelcastServiceSdf = hazelcastServiceSdf;
this.hazelcastServiceLks = hazelcastServiceLks;
this.kafkaMessenger = kafkaMessenger;
}
public StageResult process(ResultContainer resultContainer) {
log.info("uuid {}. Stage: Import to DB", resultContainer.getUuid());
ETable currTable = resultContainer.getXmlTable();
DocumentTag documentTag = resultContainer.getDocumentTag();
String fileName = resultContainer.getXmlFile().getName();
Long fileId = hazelcastService.getImdgIdGenerator().nextId();
return switch (resultContainer.getXmlTable().getFileType()) {
case SDF -> processSdfFile(resultContainer);
case LKS -> processLksFile(resultContainer);
};
}
private StageResult processSdfFile(ResultContainer resultContainer) {
ETable currTable = resultContainer.getXmlTable();
DocumentTag documentTag = (DocumentTag) resultContainer.getXmlFile();
String fileName = resultContainer.getXmlFilePath().getName();
Long fileId = hazelcastServiceSdf.getImdgIdGenerator().nextId();
for (ObjectTag o : documentTag.getObjects()) {
o.setHazelcastService(hazelcastService);
o.setHazelcastService(hazelcastServiceSdf);
o.setFileName(fileName);
o.setGenerationId(fileId);
@ -42,14 +57,14 @@ public class ImportToDB {
if (!o.checkOnExisting(entityTable) && entityTable instanceof SDf57) {
kafkaMessenger.sendUserNotification(ObjectType.rgst,
"Номер транзакции " + ((SDf57) entityTable).getDbfId() + " в полученном df57 уже был обработан ранее",
Priority.HIGH);
Priority.HIGH, FileType.SDF);
} else {
o.injectEntity(entityTable);
}
}
if (ETable.DF_01.equals(currTable)) {
kafkaMessenger.sendPairSdfRequest(fileName, fileId, currTable.getPrefix());
kafkaMessenger.sendPairSdfRequest(fileName, fileId, currTable.name());
}
kafkaMessenger.notifySystemIfNeeded(currTable, fileId);
kafkaMessenger.notifyUserAboutSuccessLoad(resultContainer);
@ -57,4 +72,21 @@ public class ImportToDB {
log.info("uuid {}. Stage import to DB finished with status {}", resultContainer.getUuid(), StageResult.OK);
return StageResult.OK;
}
private StageResult processLksFile(ResultContainer resultContainer) {
if (resultContainer.getXmlTable().equals(ETable.ACCOUNT_LIST_RUB)) {
AccountListRub accountListRub = (AccountListRub) resultContainer.getXmlFile();
log.info(accountListRub.toString());
return StageResult.OK;
} else if (resultContainer.getXmlTable().equals(ETable.ACCOUNT_LIST_CUR)) {
AccountListCur accountListCur = (AccountListCur) resultContainer.getXmlFile();
log.info(accountListCur.toString());
return StageResult.OK;
}
log.error("Table type {} is not supported", resultContainer.getXmlTable());
return StageResult.ERROR;
}
}

View file

@ -7,8 +7,12 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.xml.importer.logic.data.ResultContainer;
import ru.spcex.clearing.xml.importer.logic.data.enums.ETable;
import ru.spcex.clearing.xml.importer.logic.data.enums.FileType;
import ru.spcex.clearing.xml.importer.logic.data.enums.StageResult;
import ru.spcex.clearing.xml.importer.logic.data.tags.DocumentTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.AccountListCur;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.AccountListRub;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.DocumentTag;
import ru.spcex.platform.utils.log.ExceptionUtils;
@Component
@ -26,7 +30,16 @@ public class ReadXMLFile {
public StageResult process(ResultContainer resultContainer) {
log.info("uuid {}. Stage: Reading XML file", resultContainer.getUuid());
try {
resultContainer.setDocumentTag(xmlMapper.readValue(resultContainer.getXmlFile(), DocumentTag.class));
if (resultContainer.getXmlTable().getFileType().equals(FileType.SDF)) {
resultContainer.setXmlFile(xmlMapper.readValue(resultContainer.getXmlFilePath(), DocumentTag.class));
} else if (resultContainer.getXmlTable().getFileType().equals(FileType.LKS)) {
if (resultContainer.getXmlTable().equals(ETable.ACCOUNT_LIST_RUB)) {
resultContainer.setXmlFile(xmlMapper.readValue(resultContainer.getXmlFilePath(), AccountListRub.class));
} else if (resultContainer.getXmlTable().equals(ETable.ACCOUNT_LIST_CUR)) {
resultContainer.setXmlFile(xmlMapper.readValue(resultContainer.getXmlFilePath(), AccountListCur.class));
}
}
return StageResult.OK;
} catch (IOException e) {
log.error(ExceptionUtils.getStackTrace(e));

View file

@ -9,6 +9,7 @@ import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
@ -17,8 +18,10 @@ import ru.spcex.clearing.platform.messaging.domain.cud.utilities.NotificationNew
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.PairSdfRequest;
import ru.spcex.clearing.platform.messaging.serialization.LogFormatter;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.xml.importer.config.settings.ImportXMLServiceSettings;
import ru.spcex.clearing.xml.importer.logic.data.ResultContainer;
import ru.spcex.clearing.xml.importer.logic.data.enums.ETable;
import ru.spcex.clearing.xml.importer.logic.data.enums.FileType;
import ru.spcex.clearing.xml.importer.logic.data.enums.StageResult;
import ru.spcex.platform.enumeration.ObjectType;
import ru.spcex.platform.enumeration.Priority;
@ -27,22 +30,29 @@ import ru.spcex.platform.enumeration.SdfTable;
@Component
public class XmlImportKafkaMessenger implements InitializingBean {
final Logger log = LoggerFactory.getLogger(getClass());
private final Supplier<KafkaSender> kafka;
private final Supplier<KafkaSender> kafkaSdf;
private final Supplier<KafkaSender> kafkaLks;
private final Map<ETable, Consumer<Long>> messengers;
public XmlImportKafkaMessenger(Supplier<KafkaSender> kafka) {
this.kafka = kafka;
private final ImportXMLServiceSettings settings;
public XmlImportKafkaMessenger(@Qualifier("kafkaSenderSdf") Supplier<KafkaSender> kafkaSdf,
@Qualifier("kafkaSenderLks") Supplier<KafkaSender> kafkaLks,
ImportXMLServiceSettings settings) {
this.kafkaSdf = kafkaSdf;
this.kafkaLks = kafkaLks;
this.settings = settings;
this.messengers = new HashMap<>();
}
@Override
public void afterPropertiesSet() {
messengers.put(ETable.DF_01, groupId -> messageStatement(groupId, SdfTable.SDF_01));
messengers.put(ETable.DF_04, groupId -> messageStatement(groupId, SdfTable.SDF_04));
messengers.put(ETable.DF_06, groupId -> messageStatement(groupId, SdfTable.SDF_06, Consts.STATEMENT_PROCESS_SDF06));
messengers.put(ETable.DF_52, groupId -> messageStatement(groupId, SdfTable.SDF_52, Consts.ACCOUNT_PROCESS_SDF52));
messengers.put(ETable.DF_55, groupId -> messageStatement(groupId, SdfTable.SDF_55));
messengers.put(ETable.DF_57, groupId -> messageStatement(groupId, SdfTable.SDF_57));
messengers.put(ETable.DF_01, groupId -> messageStatement(groupId, SdfTable.SDF_01, FileType.SDF));
messengers.put(ETable.DF_04, groupId -> messageStatement(groupId, SdfTable.SDF_04, FileType.SDF));
messengers.put(ETable.DF_06, groupId -> messageStatement(groupId, SdfTable.SDF_06, Consts.STATEMENT_PROCESS_SDF06, FileType.SDF));
messengers.put(ETable.DF_52, groupId -> messageStatement(groupId, SdfTable.SDF_52, Consts.ACCOUNT_PROCESS_SDF52, FileType.SDF));
messengers.put(ETable.DF_55, groupId -> messageStatement(groupId, SdfTable.SDF_55, FileType.SDF));
messengers.put(ETable.DF_57, groupId -> messageStatement(groupId, SdfTable.SDF_57, FileType.SDF));
}
/**
@ -57,12 +67,12 @@ public class XmlImportKafkaMessenger implements InitializingBean {
}
public void notifyUserAboutErrorParsing(Throwable error, ResultContainer resultContainer) {
if (resultContainer == null || resultContainer.getXmlFile() == null)
if (resultContainer == null || resultContainer.getXmlFilePath() == null)
return;
String fileName = resultContainer.getXmlFile().getName();
String fileName = resultContainer.getXmlFilePath().getName();
log.debug("Notify user about error {} \"{}\"",
resultContainer.getXmlTable(), fileName);
sendUserNotification(ObjectType.rgst, String.format("Файл \"%s\" не сохранен", fileName), Priority.HIGH);
sendUserNotification(ObjectType.rgst, String.format("Файл \"%s\" не сохранен", fileName), Priority.HIGH, resultContainer.getXmlTable().getFileType());
}
public void notifyUserAboutSuccessLoad(ResultContainer resultContainer) {
@ -70,35 +80,54 @@ public class XmlImportKafkaMessenger implements InitializingBean {
if (!(StageResult.OK == resultContainer.getLastStageStatus() || StageResult.COMPLETE == resultContainer.getLastStageStatus())) {
return;
}
String fileName = resultContainer.getXmlFile().getName();
String fileName = resultContainer.getXmlFilePath().getName();
log.debug("Notify user about success {} \"{}\"",
resultContainer.getXmlTable(), fileName);
sendUserNotification(ObjectType.rgst, String.format("Загружен \"%s\" - успешно", fileName), Priority.LOW);
sendUserNotification(ObjectType.rgst, String.format("Загружен \"%s\" - успешно", fileName), Priority.LOW, resultContainer.getXmlTable().getFileType());
}
}
public void sendUserNotification(ObjectType objectType, String comment, Priority priority) {
public void sendUserNotification(ObjectType objectType, String comment, Priority priority, FileType fileType) {
final String destination = Consts.NOTIFICATION_NEW;
NotificationNewRequest request = new NotificationNewRequest();
request.setObjectType(objectType.getKey());
request.setPriority(priority.getKey());
request.setComment(comment);
log.debug("Send message to kafka \"{}\": {}", destination, LogFormatter.toStringWrapper(request));
Long rKey = kafka.get().sendRequestToQueue(destination, request);
log.trace("For user send message, request id={}", rKey);
switch (fileType) {
case SDF -> {
Long rKey = kafkaSdf.get().sendRequestToQueue(destination, request);
log.trace("For user send message to SDF kafka, request id={}", rKey);
}
case LKS -> {
Long rKey = kafkaLks.get().sendRequestToQueue(destination, request);
log.trace("For user send message to LKS kafka, request id={}", rKey);
}
}
}
private void messageStatement(Long groupId, SdfTable table) {
messageStatement(groupId, table, Consts.STATEMENT_PROCESS);
private void messageStatement(Long groupId, SdfTable table, FileType fileType) {
messageStatement(groupId, table, Consts.STATEMENT_PROCESS, fileType);
}
private void messageStatement(Long groupId, SdfTable table, String destination) {
private void messageStatement(Long groupId, SdfTable table, String destination, FileType fileType) {
StatementRequest statementRequest = new StatementRequest();
statementRequest.setGroupId(groupId);
statementRequest.setTable(table);
Long msgId = kafka.get().sendRequestToQueue(destination, statementRequest);
log.debug("Send StatementRequest({}, {}) message id={} to kafka \"{}\"",
groupId, table, msgId, destination);
switch (fileType) {
case SDF -> {
Long msgId = kafkaSdf.get().sendRequestToQueue(destination, statementRequest);
log.debug("Send StatementRequest({}, {}) message id={} to SDF kafka \"{}\"",
groupId, table, msgId, destination);
}
case LKS -> {
Long msgId = kafkaLks.get().sendRequestToQueue(destination, statementRequest);
log.debug("Send StatementRequest({}, {}) message id={} to LKS kafka \"{}\"",
groupId, table, msgId, destination);
}
}
}
public void sendPairSdfRequest(String fileName, Long fileId, String tableSdf) {
@ -106,13 +135,15 @@ public class XmlImportKafkaMessenger implements InitializingBean {
request.setFileNameSDf(fileName);
request.setGenerationId(fileId);
request.setTableSDf(tableSdf);
Long msgId = kafka.get().sendRequestToQueue(PAIR_SDF, request);
log.info("Send PairSdfRequest={} message id={} to kafka \"{}\"", LogFormatter.toString(request), msgId, PAIR_SDF);
Long msgId = kafkaSdf.get().sendRequestToQueue(PAIR_SDF, request);
log.info("Send PairSdfRequest={} message id={} to SDF kafka \"{}\"", LogFormatter.toString(request), msgId, PAIR_SDF);
}
private void messageDf04(Long groupId) {
Sdf04Request sdf04ImportNotification = new Sdf04Request();
sdf04ImportNotification.setGroupId(groupId);
kafka.get().sendRequestToQueue(Consts.SDF04_PROCESS, sdf04ImportNotification);
kafkaSdf.get().sendRequestToQueue(Consts.SDF04_PROCESS, sdf04ImportNotification);
}
}

View file

@ -20,24 +20,45 @@ import org.springframework.stereotype.Service;
import ru.spcex.clearing.xml.importer.config.SFTPConfig;
import ru.spcex.clearing.xml.importer.config.settings.ImportXMLServiceSettings;
import ru.spcex.clearing.xml.importer.logic.data.enums.ETable;
import ru.spcex.clearing.xml.importer.logic.data.enums.FileType;
import ru.spcex.platform.utils.log.ExceptionUtils;
@Service("fileChecker")
public class FileChecker {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private final ImportXMLServiceSettings settings;
private final SFTPConfig.XmlGateway gateway;
private final SFTPConfig.XmlGatewaySdf gatewaySdf;
private final SFTPConfig.XmlGatewayLks gatewayLks;
public FileChecker(ImportXMLServiceSettings settings, SFTPConfig.XmlGateway gateway) {
public FileChecker(ImportXMLServiceSettings settings,
SFTPConfig.XmlGatewaySdf gatewaySdf,
SFTPConfig.XmlGatewayLks gatewayLks) {
this.settings = settings;
this.gateway = gateway;
this.gatewaySdf = gatewaySdf;
this.gatewayLks = gatewayLks;
}
public Map<ETable, List<File>> checkNewFiles(ETable specificTable) {
Map<ETable, List<File>> newFiles = new EnumMap<>(ETable.class);
String srcDir = settings.getStore().getSrcDir();
List<File> xmlFiles = lsXML(srcDir);
List<String> srcDir = new ArrayList<>();
if (specificTable == null) {
if (settings.isProcessSdfFiles()) {
srcDir.add(settings.getStoreSdf().getSrcDir());
}
if (settings.isProcessLksFiles()) {
srcDir.add(settings.getStoreLks().getSrcDir());
}
} else {
srcDir.add(specificTable.getFileType().equals(FileType.SDF) ?
settings.getStoreSdf().getSrcDir() :
settings.getStoreLks().getSrcDir());
}
List<File> xmlFiles = srcDir.stream()
.map(this::lsXML)
.flatMap(List::stream)
.toList();
if (xmlFiles.isEmpty()) return newFiles;
for (File xmlFile : xmlFiles) {
@ -60,7 +81,7 @@ public class FileChecker {
.map(Path::toFile)
.filter(file -> file.getName().toLowerCase(Locale.ROOT).endsWith(".xml"))
.sorted(Comparator.comparingLong(File::lastModified))
.collect(Collectors.toList());
.toList();
} catch (IOException e) {
log.error("Error reading 'service.store.src-dir' : {}", ExceptionUtils.getStackTrace(e));
}
@ -69,15 +90,31 @@ public class FileChecker {
}
public void checkAndLoadSFTP() {
if (settings.getStore().getSftpIn().getSftpSrcPayValDir() == null || settings.getStore().getSftpIn().getSftpSrcPayValDir().isEmpty()) {
log.error("No SFTP scanning directories, need will be adding setting like 'import-xml-service.store.sftp-in.sftp-src-pay-val-dir.VAL=/VAL' and restart app");
if (settings.isProcessSdfFiles() && (settings.getStoreSdf().getSftpIn().getSftpSrcPayValDir() == null || settings.getStoreSdf().getSftpIn().getSftpSrcPayValDir().isEmpty())) {
log.error("No SFTP scanning directories, need will be adding setting like 'import-xml-service.store-sdf.sftp-in.sftp-src-pay-val-dir.VAL=/VAL' and restart app");
return;
}
List<File> files = new ArrayList<>();
log.trace("Load from SFTP paths: {}", settings.getStore().getSftpIn().getSftpSrcPayValDir().values());
for (String path : settings.getStore().getSftpIn().getSftpSrcPayValDir().values()) {
files.addAll(gateway.listFiles(path));
if (settings.isProcessLksFiles() && (settings.getStoreLks().getSftpIn().getSftpSrcPayValDir() == null || settings.getStoreLks().getSftpIn().getSftpSrcPayValDir().isEmpty())) {
log.error("No SFTP scanning directories, need will be adding setting like 'import-xml-service.store-lks.sftp-in.sftp-src-pay-val-dir.VAL=/VAL' and restart app");
return;
}
List<File> files = new ArrayList<>();
if (settings.isProcessSdfFiles()) {
log.trace("Load from SFTP paths: {}", settings.getStoreSdf().getSftpIn().getSftpSrcPayValDir().values());
for (String path : settings.getStoreSdf().getSftpIn().getSftpSrcPayValDir().values()) {
files.addAll(gatewaySdf.listFiles(path));
}
if (!files.isEmpty())
log.info("Loaded from SFTP SDF files count={}", files.size());
}
if (settings.isProcessLksFiles()) {
log.trace("Load from SFTP paths: {}", settings.getStoreLks().getSftpIn().getSftpSrcPayValDir().values());
for (String path : settings.getStoreLks().getSftpIn().getSftpSrcPayValDir().values()) {
files.addAll(gatewayLks.listFiles(path));
}
if (!files.isEmpty())
log.info("Loaded from SFTP LKS files count={}", files.size());
}
if (!files.isEmpty()) log.info("Loaded from SFTP files count={}", files.size());
}
}

View file

@ -21,6 +21,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;
import ru.spcex.clearing.xml.importer.config.settings.ImportXMLServiceSettings;
import ru.spcex.clearing.xml.importer.logic.data.ResultContainer;
import ru.spcex.clearing.xml.importer.logic.data.enums.ETable;
import ru.spcex.clearing.xml.importer.logic.data.enums.StageResult;
@ -41,22 +42,30 @@ public class XMLImporterService {
private final ImportToDB importToDB;
private final ChangeDirOfFileStage changeDirOfFileStage;
private final ImportXMLServiceSettings settings;
public XMLImporterService(@Qualifier("fileChecker") FileChecker fileChecker,
@Qualifier("executor") ThreadPoolTaskExecutor executorService,
ReadXMLFile readXMLFile,
ImportToDB importToDB,
ChangeDirOfFileStage changeDirOfFileStage) {
ChangeDirOfFileStage changeDirOfFileStage,
ImportXMLServiceSettings settings) {
this.fileChecker = fileChecker;
this.executorService = executorService;
this.readXMLFile = readXMLFile;
this.importToDB = importToDB;
this.changeDirOfFileStage = changeDirOfFileStage;
this.settings = settings;
this.filesCurrentlyInProcess = new HashSet<>();
}
@Scheduled(cron = "${import-xml-service.scheduler.check-src-dir-cron}")
@Scheduled(cron = "${import-xml-service.cron.check-src-dir-cron}")
public void run() {
processTable(null);
if (settings.isProcessSdfFiles() || settings.isProcessLksFiles()) {
processTable(null);
} else {
log.warn("Turn on SDF or LKS file processing in application.properties!");
}
}
public void processTable(ETable specificTable) {

View file

@ -2,42 +2,85 @@ server.port=8081
server.servlet.context-path=/xml-importer
spring.main.web-application-type=servlet
import-xml-service.scheduler.check-src-dir-cron=* * * * 1 ?
import-xml-service.process-sdf-files=true
import-xml-service.process-lks-files=true
import-xml-service.store.delete-src-files=false
import-xml-service.store.src-dir=/opt/clearing/file/xml-importer/
import-xml-service.store.out-dir=/opt/clearing/file/xml-importer/loaded/
import-xml-service.store.out-dir-error=/opt/clearing/file/xml-importer/error/
import-xml-service.cron.check-src-dir-cron=* * * * 1 ?
import-xml-service.common.encoding-source=cp866
import-xml-service.common.insert-batch-size=100
import-xml-service.common.threads-count=10
#sftpSrcDir
import-xml-service.store.sftp-in.sftp-src-pay-val-dir.rub=clearing_xml-importer_sftp/rub/
import-xml-service.store.sftp-in.sftp-src-pay-val-dir.eur=clearing_xml-importer_sftp/eur/
import-xml-service.store.sftp-in.sftp-src-dir=clearing_xml-importer_sftp
import-xml-service.store.sftp-in.user=user
import-xml-service.store.sftp-in.password=*********
import-xml-service.store.sftp-in.server-ip=127.0.0.1
import-xml-service.store.sftp-in.server-port=22
# SDF settings
# Hazelcast cluster
import-xml-service.sdf-hazelcast-and-kafka.hazelcast.cluster-members=10.200.200.181:5701
import-xml-service.sdf-hazelcast-and-kafka.hazelcast.login=dev
import-xml-service.sdf-hazelcast-and-kafka.hazelcast.password=dev-pass
import-xml-service.hazelcast.cluster-members=10.200.200.181:5701
import-xml-service.hazelcast.login=dev
import-xml-service.hazelcast.password=dev-pass
# Store directories
import-xml-service.store-sdf.delete-src-files=false
import-xml-service.store-sdf.src-dir=/opt/clearing/file/xml-importer/
import-xml-service.store-sdf.out-dir=/opt/clearing/file/xml-importer/loaded/
import-xml-service.store-sdf.out-dir-error=/opt/clearing/file/xml-importer/error/=
# Sftp directories and credentials
import-xml-service.store-sdf.sftp-in.sftp-src-pay-val-dir.rub=clearing_xml-importer_sftp/rub/
import-xml-service.store-sdf.sftp-in.sftp-src-pay-val-dir.eur=clearing_xml-importer_sftp/eur/
import-xml-service.store-sdf.sftp-in.sftp-src-dir=clearing_xml-importer_sftp
import-xml-service.store-sdf.sftp-in.user=user
import-xml-service.store-sdf.sftp-in.password=*********
import-xml-service.store-sdf.sftp-in.server-ip=127.0.0.1
import-xml-service.store-sdf.sftp-in.server-port=22
import-xml-service.kafka-producer.bootstrap-servers=localhost:9092
import-xml-service.kafka-producer.acks=all
import-xml-service.kafka-producer.retries=0
import-xml-service.kafka-producer.batch-size=16384
import-xml-service.kafka-producer.linger-ms=1
import-xml-service.kafka-producer.buffer-memory=33554432
# Kafka settings
# Kafka producer
import-xml-service.sdf-hazelcast-and-kafka.kafka-producer.bootstrap-servers=localhost:9092
import-xml-service.sdf-hazelcast-and-kafka.kafka-producer.acks=all
import-xml-service.sdf-hazelcast-and-kafka.kafka-producer.retries=0
import-xml-service.sdf-hazelcast-and-kafka.kafka-producer.batch-size=16384
import-xml-service.sdf-hazelcast-and-kafka.kafka-producer.linger-ms=1
import-xml-service.sdf-hazelcast-and-kafka.kafka-producer.buffer-memory=33554432
import-xml-service.kafka-consumer.bootstrap-servers=localhost:9092
import-xml-service.kafka-consumer.group-id=dev-group-clearing-service
import-xml-service.kafka-consumer.enable-auto-commit=false
import-xml-service.kafka-consumer.session-timeout-ms=30000
import-xml-service.kafka-consumer.auto-offset-reset=latest
import-xml-service.kafka-consumer.linger-ms=1
import-xml-service.kafka-consumer.buffer-memory=33554432
# Kafka consumer
import-xml-service.sdf-hazelcast-and-kafka.kafka-consumer.bootstrap-servers=localhost:9092
import-xml-service.sdf-hazelcast-and-kafka.kafka-consumer.group-id=dev-group-clearing-service
import-xml-service.sdf-hazelcast-and-kafka.kafka-consumer.enable-auto-commit=false
import-xml-service.sdf-hazelcast-and-kafka.kafka-consumer.session-timeout-ms=30000
import-xml-service.sdf-hazelcast-and-kafka.kafka-consumer.auto-offset-reset=latest
# LKS settings
# Hazelcast cluster
import-xml-service.lks-hazelcast-and-kafka.hazelcast.cluster-members=10.200.200.181:5701
import-xml-service.lks-hazelcast-and-kafka.hazelcast.login=dev
import-xml-service.lks-hazelcast-and-kafka.hazelcast.password=dev-pass
# Store directories
import-xml-service.store-lks.delete-src-files=false
import-xml-service.store-lks.src-dir=/opt/clearing/file/xml-importer/
import-xml-service.store-lks.out-dir=/opt/clearing/file/xml-importer/loaded/
import-xml-service.store-lks.out-dir-error=/opt/clearing/file/xml-importer/error/=
# Sftp directories and credentials
import-xml-service.store-lks.sftp-in.sftp-src-pay-val-dir.rub=clearing_xml-importer_sftp/rub/
import-xml-service.store-lks.sftp-in.sftp-src-pay-val-dir.eur=clearing_xml-importer_sftp/eur/
import-xml-service.store-lks.sftp-in.sftp-src-dir=clearing_xml-importer_sftp
import-xml-service.store-lks.sftp-in.user=user
import-xml-service.store-lks.sftp-in.password=*********
import-xml-service.store-lks.sftp-in.server-ip=127.0.0.1
import-xml-service.store-lks.sftp-in.server-port=22
# Kafka settings
# Kafka producer
import-xml-service.lks-hazelcast-and-kafka.kafka-producer.bootstrap-servers=localhost:9092
import-xml-service.lks-hazelcast-and-kafka.kafka-producer.acks=all
import-xml-service.lks-hazelcast-and-kafka.kafka-producer.retries=0
import-xml-service.lks-hazelcast-and-kafka.kafka-producer.batch-size=16384
import-xml-service.lks-hazelcast-and-kafka.kafka-producer.linger-ms=1
import-xml-service.lks-hazelcast-and-kafka.kafka-producer.buffer-memory=33554432
# Kafka consumer
import-xml-service.lks-hazelcast-and-kafka.kafka-consumer.bootstrap-servers=localhost:9092
import-xml-service.lks-hazelcast-and-kafka.kafka-consumer.group-id=dev-group-clearing-service
import-xml-service.lks-hazelcast-and-kafka.kafka-consumer.enable-auto-commit=false
import-xml-service.lks-hazelcast-and-kafka.kafka-consumer.session-timeout-ms=30000
import-xml-service.lks-hazelcast-and-kafka.kafka-consumer.auto-offset-reset=latest

View file

@ -0,0 +1,117 @@
package ru.spcex.clearing.xml.importer.config;
import com.hazelcast.config.Config;
import com.hazelcast.config.JoinConfig;
import com.hazelcast.config.MulticastConfig;
import com.hazelcast.config.NetworkConfig;
import com.hazelcast.config.TcpIpConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
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.clearing.classes.statics.data.user.UserRoleSession;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.enumeration.UserRole;
import ru.spcex.platform.imdg.api.Imdg;
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;
import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper;
@Configuration
public class ImporterImdgTestConfig {
public static final AtomicLong currentID = new AtomicLong(0L);
public static final Long defaultAdminId = 1000L;
private HazelcastInstance hazelcastInstance;
private static ImdgProvider imdgProvider;
public static void waitAvailableImdgProviderAndAddAdminWithDefaultId(){
imdgProvider.waitAvailable();
Imdg<UserRoleSession> userRoleSessions = imdgProvider.getImdg(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class);
UserRoleSession userRoleSession = new UserRoleSession();
userRoleSession.setUserId(defaultAdminId);
userRoleSession.setUserRole(UserRole.Admin.getKey());
userRoleSession.setStatus(Status.Active.getKey());
userRoleSessions.insert(userRoleSession);
}
private static ThreadPoolTaskExecutor createThreadPoolTestTaskExecutor(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 = "taskExecutorHazelcastTestClientInitializerXmlImporter")
public ThreadPoolTaskExecutor taskExecutorHazelcastTestClientInitializer() {
return createThreadPoolTestTaskExecutor(1, true);
}
@Bean(name = "taskExecutorTestIdGeneratorAwaiterXmlImporter")
public ThreadPoolTaskExecutor taskExecutorTestIdGeneratorAwaiter() {
return createThreadPoolTestTaskExecutor(1, false);
}
@Autowired
@Bean(name = "sdfImdgProvider")
public HazelcastService imdgTestProviderSdf(
@Qualifier("taskExecutorHazelcastTestClientInitializerXmlImporter") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
@Qualifier("taskExecutorTestIdGeneratorAwaiterXmlImporter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
@Qualifier("hazelcastClientParamsXmlImporter") HazelcastClientParams params) {
Config cfg = new Config();
cfg.setInstanceName("localhost");
NetworkConfig networkConfig = new NetworkConfig();
JoinConfig joinConfig = new JoinConfig();
joinConfig.setMulticastConfig(new MulticastConfig().setEnabled(false));
joinConfig.setTcpIpConfig(new TcpIpConfig().setEnabled(true).setMembers(List.of("127.0.0.1")));
networkConfig.setJoin(joinConfig);
cfg.setNetworkConfig(networkConfig);
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg);
HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance);
return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params);
}
@Autowired
@Bean(name = "lksImdgProvider")
public HazelcastService imdgTestProviderLks(
@Qualifier("taskExecutorHazelcastTestClientInitializerXmlImporter") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
@Qualifier("taskExecutorTestIdGeneratorAwaiterXmlImporter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
@Qualifier("hazelcastClientParamsXmlImporter") HazelcastClientParams params) {
Config cfg = new Config();
cfg.setInstanceName("localhost");
NetworkConfig networkConfig = new NetworkConfig();
JoinConfig joinConfig = new JoinConfig();
joinConfig.setMulticastConfig(new MulticastConfig().setEnabled(false));
joinConfig.setTcpIpConfig(new TcpIpConfig().setEnabled(true).setMembers(List.of("127.0.0.1")));
networkConfig.setJoin(joinConfig);
cfg.setNetworkConfig(networkConfig);
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg);
HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance);
return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params);
}
@Bean(name = "hazelcastClientParamsXmlImporter")
public HazelcastClientParams getHazelcastClientParams() {
HazelcastClientParams params = new HazelcastClientParams();
params.setLogin("dev");
params.setPassword("dev-pass");
params.setClusterMembers("127.0.0.1");
params.setInstanceName("hzTestClient" + new Random().nextInt());
// params.setNearCacheConfig(new NearCacheConfig()); Если добавить будет с опазданием(8-12с) обновлятся данные для метода Imdg.getSingleObjectByID
// (getSingleObjectByFieldValues, getAllValues, getSingleObjectBySQL работают корректно) при ТРАНЗАКЦИЯХ. Используется в проде(по факту нет) если в конфиг добавить эту настройку..
return params;
}
}

View file

@ -0,0 +1,172 @@
package ru.spcex.clearing.xml.importer.config;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.test.mock.mockito.MockReset;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Scope;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.requestreply.ReplyingKafkaTemplate;
import org.springframework.kafka.requestreply.RequestReplyFuture;
import org.springframework.kafka.support.SendResult;
import org.springframework.util.concurrent.ListenableFuture;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.test.TestUtils;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
@Configuration
@Import(ImporterImdgTestConfig.class)
public class KafkaTestConfig {
public static final Map<Producer<String, Object>, ArgumentCaptor<ProducerRecord>> producerCaptors = new HashMap<>();
public static final Map<KafkaTemplate<String, Object>, ArgumentCaptor<ProducerRecord>> templateCaptors = new HashMap<>();
//из-за очисткой перед каждым тестом(MockReset.withSettings(MockReset.AFTER) необходимо каждый раз обновлять doReturn
public static ArgumentCaptor<ProducerRecord> getCaptor(Producer<String, Object> mockProducer) {
ArgumentCaptor<ProducerRecord> captor = producerCaptors.get(mockProducer);
setFuture(captor, mockProducer);
return captor;
}
public static ArgumentCaptor<ProducerRecord> getCaptor(KafkaTemplate<String, Object> kafkaTemplate) {
ArgumentCaptor<ProducerRecord> captor = templateCaptors.get(kafkaTemplate);
setFuture(captor, (ReplyingKafkaTemplate<String, Object, Object>) kafkaTemplate);
return captor;
}
public static void setFuture(ArgumentCaptor<ProducerRecord> captor, Producer<String, Object> mockProducer) {
TestUtils.FutureRecordMetadata future = spy(new TestUtils.FutureRecordMetadata());
doReturn(future).when(mockProducer).send(captor.capture());
}
/**
* Позволяет избежать NPE при вызове Future.get(), из-за очисткой перед каждым тестом(MockReset.withSettings(MockReset.AFTER) необходимо обновлять перед вызовом
*
* @param mockProducer
*/
public static void setMockFuture(Producer<String, Object> mockProducer) {
ArgumentCaptor<ProducerRecord> captor = producerCaptors.get(mockProducer);
setFuture(captor, mockProducer);
}
public static void setFuture(ArgumentCaptor<ProducerRecord> recordArgumentCaptor, ReplyingKafkaTemplate<String, Object, Object> kafkaTemplate) {
//sendToQueueWaitForAnswer
RequestReplyFuture<String, Object, Object> replyFuture = spy(RequestReplyFuture.class);
doReturn(replyFuture).when(kafkaTemplate).sendAndReceive(recordArgumentCaptor.capture());
ConsumerRecord<String, Object> consumerRecord = mock(ConsumerRecord.class);
try {
doReturn(consumerRecord).when(replyFuture).get(10, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException | ClassCastException e) {
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
}
doReturn(null).when(consumerRecord).value();
//sendRequestToQueue
ListenableFuture<SendResult<String, Object>> send = mock(ListenableFuture.class);
doReturn(send).when(kafkaTemplate).send(recordArgumentCaptor.capture());
try {
doReturn(null).when(send).get();
} catch (InterruptedException | ExecutionException e) {
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
}
}
/**
* Позволяет избежать NPE при вызове Future.get(), из-за очисткой перед каждым тестом(MockReset.withSettings(MockReset.AFTER) необходимо обновлять перед вызовом
*
* @param kafkaTemplate
*/
public static void setMockFuture(KafkaTemplate<String, Object> kafkaTemplate) {
ArgumentCaptor<ProducerRecord> captor = templateCaptors.get(kafkaTemplate);
setFuture(captor, (ReplyingKafkaTemplate<String, Object, Object>) kafkaTemplate);
}
// @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean("mockProducer")
public Producer<String, Object> kafkaProducer() {
Producer<String, Object> mockProducer = mock(MockProducer.class, MockReset.withSettings(MockReset.AFTER));
ArgumentCaptor<ProducerRecord> recordArgumentCaptor = ArgumentCaptor.forClass(ProducerRecord.class);
setFuture(recordArgumentCaptor, mockProducer);
producerCaptors.put(mockProducer, recordArgumentCaptor);
return mockProducer;
}
@Bean("kafkaTestTemplate")
public KafkaTemplate<String, Object> kafkaTemplate() {
ReplyingKafkaTemplate<String, Object, Object> kafkaTemplate = mock(ReplyingKafkaTemplate.class, MockReset.withSettings(MockReset.AFTER));
ArgumentCaptor<ProducerRecord> recordArgumentCaptor = ArgumentCaptor.forClass(ProducerRecord.class);
setFuture(recordArgumentCaptor, kafkaTemplate);
templateCaptors.put(kafkaTemplate, recordArgumentCaptor);
return kafkaTemplate;
}
@Bean("kafkaSenderSdf")
public Supplier<KafkaSender> kafkaSenderSdf(@Qualifier("kafkaTestTemplate") KafkaTemplate<String, Object> kafkaTemplate,
@Qualifier("sdfImdgProvider") ImdgProvider imdgProvider,
Producer<String, Object> mockProducer) {
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
return () -> KafkaSender
.setup()
.setKafkaTemplate(kafkaTemplate)
.producer(mockProducer)
.idGenerator(imdgIdGenerator::nextId)
.imdgProvider(s -> {
Imdg<RequestInfo> imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class);
return imdg::insert;
})
.build();
}
@Bean("kafkaSenderLks")
public Supplier<KafkaSender> kafkaSenderLks(@Qualifier("kafkaTestTemplate") KafkaTemplate<String, Object> kafkaTemplate,
@Qualifier("lksImdgProvider") ImdgProvider imdgProvider,
Producer<String, Object> mockProducer) {
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
return () -> KafkaSender
.setup()
.setKafkaTemplate(kafkaTemplate)
.producer(mockProducer)
.idGenerator(imdgIdGenerator::nextId)
.imdgProvider(s -> {
Imdg<RequestInfo> imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class);
return imdg::insert;
})
.build();
}
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean
public MockConsumer<String, Object> createTestConsumer() {
return new MockConsumer<>(OffsetResetStrategy.EARLIEST);
}
}

View file

@ -9,19 +9,13 @@ import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import javax.annotation.PostConstruct;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.TestPropertySource;
import ru.clearing.classes.statics.data.sdf.SDf01;
@ -32,31 +26,31 @@ import ru.clearing.classes.statics.data.sdf.SDf55;
import ru.clearing.classes.statics.data.sdf.SDf57;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.test.TestObjectCreator;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.clearing.xml.importer.config.ImporterImdgTestConfig;
import ru.spcex.clearing.xml.importer.config.KafkaTestConfig;
import ru.spcex.clearing.xml.importer.config.XMLImporterConfig;
import ru.spcex.clearing.xml.importer.config.settings.ImportXMLServiceSettings;
import ru.spcex.clearing.xml.importer.logic.data.ResultContainer;
import ru.spcex.clearing.xml.importer.logic.data.enums.ETable;
import ru.spcex.clearing.xml.importer.logic.data.enums.StageResult;
import ru.spcex.clearing.xml.importer.logic.data.tags.DocumentTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.ParentDocTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.DF01ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.DF04ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.DF06ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.DF52ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.DF55ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.DF57ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.DocumentTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.ParentDocTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF01ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF04ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF06ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF52ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF55ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF57ObjectTag;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@SpringBootTest(classes = {
ImporterImdgTestConfig.class,
KafkaTestConfig.class,
ImportToDB.class,
ImportXMLServiceSettings.class,
XmlImportKafkaMessenger.class,
XMLImporterConfig.class,
ImdgTestConfig.class,
KafkaTestConfig.class,
})
@TestPropertySource(properties = {"spring.config.location=./src/test/resources/"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@ -65,17 +59,9 @@ class ImportToDBTest {
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yy");
@Autowired
@Qualifier("hazelcastServiceTest")
@Qualifier("sdfImdgProvider")
private HazelcastService hazelcastService;
@Captor
private ArgumentCaptor<ProducerRecord> producerRecord;
@SpyBean
private MockProducer<String, Object> producer;
@Autowired
@Qualifier("mockProducer")
protected Producer<String, Object> mockProducer;
@Autowired
private ImportToDB importToDB;
@ -120,7 +106,7 @@ class ImportToDBTest {
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-01_S_PRC1604240915_1.xml")).getFile()));
actualResultContainer.setDocumentTag(expectedDocumentTag);
actualResultContainer.setXmlFile(expectedDocumentTag);
StageResult stageResult = importToDB.process(actualResultContainer);
@ -179,7 +165,7 @@ class ImportToDBTest {
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-04_S_PRC1604240915_1.xml")).getFile()));
actualResultContainer.setDocumentTag(expectedDocumentTag);
actualResultContainer.setXmlFile(expectedDocumentTag);
StageResult stageResult = importToDB.process(actualResultContainer);
@ -239,7 +225,7 @@ class ImportToDBTest {
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-06_S_PRC1604240915_1.xml")).getFile()));
actualResultContainer.setDocumentTag(expectedDocumentTag);
actualResultContainer.setXmlFile(expectedDocumentTag);
StageResult stageResult = importToDB.process(actualResultContainer);
@ -292,7 +278,7 @@ class ImportToDBTest {
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-52_S_PRC1604240915_1.xml")).getFile()));
actualResultContainer.setDocumentTag(expectedDocumentTag);
actualResultContainer.setXmlFile(expectedDocumentTag);
StageResult stageResult = importToDB.process(actualResultContainer);
@ -363,7 +349,7 @@ class ImportToDBTest {
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-55_S_PRC1604240915_1.xml")).getFile()));
actualResultContainer.setDocumentTag(expectedDocumentTag);
actualResultContainer.setXmlFile(expectedDocumentTag);
StageResult stageResult = importToDB.process(actualResultContainer);
@ -457,7 +443,7 @@ class ImportToDBTest {
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-57_S_PRC1604240915_1.xml")).getFile()));
actualResultContainer.setDocumentTag(expectedDocumentTag);
actualResultContainer.setXmlFile(expectedDocumentTag);
StageResult stageResult = importToDB.process(actualResultContainer);

View file

@ -3,6 +3,7 @@ package ru.spcex.clearing.xml.importer.logic.steps;
import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URISyntaxException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Objects;
@ -14,27 +15,40 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.clearing.xml.importer.config.ImporterImdgTestConfig;
import ru.spcex.clearing.xml.importer.config.KafkaTestConfig;
import ru.spcex.clearing.xml.importer.config.XMLImporterConfig;
import ru.spcex.clearing.xml.importer.config.settings.ImportXMLServiceSettings;
import ru.spcex.clearing.xml.importer.logic.data.ResultContainer;
import ru.spcex.clearing.xml.importer.logic.data.enums.ETable;
import ru.spcex.clearing.xml.importer.logic.data.enums.StageResult;
import ru.spcex.clearing.xml.importer.logic.data.tags.DocumentTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.DF01ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.DF04ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.DF06ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.DF52ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.DF55ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.DF57ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.AccountListCur;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.AccountListRub;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.document.DocumentTagCur;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.document.DocumentTagRub;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.RegistratorTagCur;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.RegistratorTagRub;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.ClientTagCur;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.ClientTagRub;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account.AccountTagCur;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account.AccountTagRub;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account.respond.RespondTagCur;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account.respond.RespondTagRub;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.DocumentTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF01ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF04ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF06ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF52ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF55ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF57ObjectTag;
@SpringBootTest(classes = {
ImporterImdgTestConfig.class,
KafkaTestConfig.class,
ReadXMLFile.class,
ImportXMLServiceSettings.class,
XmlImportKafkaMessenger.class,
XMLImporterConfig.class,
ImdgTestConfig.class,
KafkaTestConfig.class,
})
@TestPropertySource(properties = {"spring.config.location=./src/test/resources/"})
class ReadXMLFileTest {
@ -44,11 +58,39 @@ class ReadXMLFileTest {
private ReadXMLFile readXMLFile;
@Test
void process_shouldReadSDf01XMLFile() {
void process_shouldReadSDf01XMLFileAndTestHeaders() throws URISyntaxException {
ResultContainer actualResultContainer = new ResultContainer(ETable.DF_01,
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-01_S_PRC1604240915_1.xml")).getFile()));
.getResource("xml/DF-01_S_PRC1604240915_1.xml")).toURI()));
StageResult processResult = readXMLFile.process(actualResultContainer);
DocumentTag expectedDocumentTag = new DocumentTag();
expectedDocumentTag.setMessageId("qq");
expectedDocumentTag.setMessageType("DF01");
expectedDocumentTag.setMessageName("ww");
expectedDocumentTag.setMessageDate(LocalDate.parse("2024-03-14"));
expectedDocumentTag.setMessageTime(LocalTime.parse("09:15:31"));
expectedDocumentTag.setSender("БИСКВИТ");
expectedDocumentTag.setReceiver("");
Assertions.assertThat(processResult).isEqualTo(StageResult.OK);
Assertions.assertThat(((DocumentTag) actualResultContainer.getXmlFile()).getMessageId()).isEqualTo(expectedDocumentTag.getMessageId());
Assertions.assertThat(((DocumentTag) actualResultContainer.getXmlFile()).getMessageType()).isEqualTo(expectedDocumentTag.getMessageType());
Assertions.assertThat(((DocumentTag) actualResultContainer.getXmlFile()).getMessageName()).isEqualTo(expectedDocumentTag.getMessageName());
Assertions.assertThat(((DocumentTag) actualResultContainer.getXmlFile()).getMessageDate()).isEqualTo(expectedDocumentTag.getMessageDate());
Assertions.assertThat(((DocumentTag) actualResultContainer.getXmlFile()).getMessageTime()).isEqualTo(expectedDocumentTag.getMessageTime());
Assertions.assertThat(((DocumentTag) actualResultContainer.getXmlFile()).getSender()).isEqualTo(expectedDocumentTag.getSender());
Assertions.assertThat(((DocumentTag) actualResultContainer.getXmlFile()).getReceiver()).isEqualTo(expectedDocumentTag.getReceiver());
}
@Test
void process_shouldReadSDf01XMLFile() throws URISyntaxException {
ResultContainer actualResultContainer = new ResultContainer(ETable.DF_01,
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-01_S_PRC1604240915_1.xml")).toURI()));
StageResult processResult = readXMLFile.process(actualResultContainer);
@ -66,7 +108,7 @@ class ReadXMLFileTest {
expectedObjectTag.setSumunblock("test10");
expectedObjectTag.setFileType("1");
DF01ObjectTag actualObjectTag = (DF01ObjectTag) actualResultContainer.getDocumentTag().getObjects().get(0);
DF01ObjectTag actualObjectTag = (DF01ObjectTag) ((DocumentTag) actualResultContainer.getXmlFile()).getObjects().get(0);
Assertions.assertThat(processResult).isEqualTo(StageResult.OK);
Assertions.assertThat(actualObjectTag.getCurrCode()).isEqualTo(expectedObjectTag.getCurrCode());
@ -84,11 +126,11 @@ class ReadXMLFileTest {
}
@Test
void process_shouldReadSDf04XMLFile() {
void process_shouldReadSDf04XMLFile() throws URISyntaxException {
ResultContainer actualResultContainer = new ResultContainer(ETable.DF_04,
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-04_S_PRC1604240915_1.xml")).getFile()));
.getResource("xml/DF-04_S_PRC1604240915_1.xml")).toURI()));
StageResult processResult = readXMLFile.process(actualResultContainer);
@ -107,7 +149,7 @@ class ReadXMLFileTest {
expectedObjectTag.setSpecif1("test11");
expectedObjectTag.setImpResult("t12");
DF04ObjectTag actualObjectTag = (DF04ObjectTag) actualResultContainer.getDocumentTag().getObjects().get(0);
DF04ObjectTag actualObjectTag = (DF04ObjectTag) ((DocumentTag) actualResultContainer.getXmlFile()).getObjects().get(0);
Assertions.assertThat(processResult).isEqualTo(StageResult.OK);
Assertions.assertThat(actualObjectTag.getSegType()).isEqualTo(expectedObjectTag.getSegType());
@ -126,11 +168,11 @@ class ReadXMLFileTest {
}
@Test
void process_shouldReadSDf06XMLFile() {
void process_shouldReadSDf06XMLFile() throws URISyntaxException {
ResultContainer actualResultContainer = new ResultContainer(ETable.DF_06,
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-06_S_PRC1604240915_1.xml")).getFile()));
.getResource("xml/DF-06_S_PRC1604240915_1.xml")).toURI()));
StageResult processResult = readXMLFile.process(actualResultContainer);
@ -149,7 +191,7 @@ class ReadXMLFileTest {
expectedObjectTag.setDocDate(LocalDate.parse("2024-03-14"));
expectedObjectTag.setPayVal("test12");
DF06ObjectTag actualObjectTag = (DF06ObjectTag) actualResultContainer.getDocumentTag().getObjects().get(0);
DF06ObjectTag actualObjectTag = (DF06ObjectTag) ((DocumentTag) actualResultContainer.getXmlFile()).getObjects().get(0);
Assertions.assertThat(processResult).isEqualTo(StageResult.OK);
Assertions.assertThat(actualObjectTag.getAccount()).isEqualTo(expectedObjectTag.getAccount());
@ -168,11 +210,11 @@ class ReadXMLFileTest {
}
@Test
void process_shouldReadSDf52XMLFile() {
void process_shouldReadSDf52XMLFile() throws URISyntaxException {
ResultContainer actualResultContainer = new ResultContainer(ETable.DF_52,
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-52_S_PRC1604240915_1.xml")).getFile()));
.getResource("xml/DF-52_S_PRC1604240915_1.xml")).toURI()));
StageResult processResult = readXMLFile.process(actualResultContainer);
@ -184,7 +226,7 @@ class ReadXMLFileTest {
expectedObjectTag.setAccType("t5");
expectedObjectTag.setStatus(1L);
DF52ObjectTag actualObjectTag = (DF52ObjectTag) actualResultContainer.getDocumentTag().getObjects().get(0);
DF52ObjectTag actualObjectTag = (DF52ObjectTag) ((DocumentTag) actualResultContainer.getXmlFile()).getObjects().get(0);
Assertions.assertThat(processResult).isEqualTo(StageResult.OK);
Assertions.assertThat(actualObjectTag.getAccount()).isEqualTo(expectedObjectTag.getAccount());
@ -196,11 +238,11 @@ class ReadXMLFileTest {
}
@Test
void process_shouldReadSDf55XMLFile() {
void process_shouldReadSDf55XMLFile() throws URISyntaxException {
ResultContainer actualResultContainer = new ResultContainer(ETable.DF_55,
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-55_S_PRC1604240915_1.xml")).getFile()));
.getResource("xml/DF-55_S_PRC1604240915_1.xml")).toURI()));
StageResult processResult = readXMLFile.process(actualResultContainer);
@ -237,7 +279,7 @@ class ReadXMLFileTest {
expectedObjectTag.setSwiftBen("test27");
expectedObjectTag.setSwiftInt("test28");
DF55ObjectTag actualObjectTag = (DF55ObjectTag) actualResultContainer.getDocumentTag().getObjects().get(0);
DF55ObjectTag actualObjectTag = (DF55ObjectTag) ((DocumentTag) actualResultContainer.getXmlFile()).getObjects().get(0);
Assertions.assertThat(processResult).isEqualTo(StageResult.OK);
Assertions.assertThat(actualObjectTag.getSegType()).isEqualTo(expectedObjectTag.getSegType());
@ -274,11 +316,11 @@ class ReadXMLFileTest {
}
@Test
void process_shouldReadSDf57XMLFile() {
void process_shouldReadSDf57XMLFile() throws URISyntaxException {
ResultContainer actualResultContainer = new ResultContainer(ETable.DF_57,
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-57_S_PRC1604240915_1.xml")).getFile()));
.getResource("xml/DF-57_S_PRC1604240915_1.xml")).toURI()));
StageResult processResult = readXMLFile.process(actualResultContainer);
@ -313,7 +355,7 @@ class ReadXMLFileTest {
expectedObjectTag.setDtOut("test25");
expectedObjectTag.setKtOut("test26");
DF57ObjectTag actualObjectTag = (DF57ObjectTag) actualResultContainer.getDocumentTag().getObjects().get(0);
DF57ObjectTag actualObjectTag = (DF57ObjectTag) ((DocumentTag) actualResultContainer.getXmlFile()).getObjects().get(0);
Assertions.assertThat(processResult).isEqualTo(StageResult.OK);
Assertions.assertThat(actualObjectTag.getId()).isEqualTo(expectedObjectTag.getId());
@ -348,30 +390,118 @@ class ReadXMLFileTest {
}
@Test
void process_shouldReadSDf01XMLFileAndTestHeaders() {
ResultContainer actualResultContainer = new ResultContainer(ETable.DF_01,
void process_shouldReaLKSAccountListRubXMLFile() throws URISyntaxException {
ResultContainer actualResultContainer = new ResultContainer(ETable.ACCOUNT_LIST_RUB,
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/DF-01_S_PRC1604240915_1.xml")).getFile()));
.getResource("xml/FIRMID_ACCOUNT_LIST_20240910_RUB_00001.XML")).toURI()));
StageResult processResult = readXMLFile.process(actualResultContainer);
DocumentTag expectedDocumentTag = new DocumentTag();
expectedDocumentTag.setMessageId("qq");
expectedDocumentTag.setMessageType("DF01");
expectedDocumentTag.setMessageName("ww");
expectedDocumentTag.setMessageDate(LocalDate.parse("2024-03-14"));
expectedDocumentTag.setMessageTime(LocalTime.parse("09:15:31"));
expectedDocumentTag.setSender("БИСКВИТ");
expectedDocumentTag.setReceiver("");
DocumentTagRub expectedDocumentTagRub = new DocumentTagRub();
expectedDocumentTagRub.setAuthor("Система БИС");
expectedDocumentTagRub.setTime(LocalTime.parse("14:23:01"));
expectedDocumentTagRub.setDate(LocalDate.parse("2024-08-21"));
expectedDocumentTagRub.setName("Запрос на согласование перечня счетов в рублях");
expectedDocumentTagRub.setDocNum("1");
RespondTagRub expectedRespondTagRub = new RespondTagRub("1");
AccountTagRub expectedAccountTagRub = new AccountTagRub();
expectedAccountTagRub.setCurrency("RUB");
expectedAccountTagRub.setName("Public Join Stock Company «Romashka»");
expectedAccountTagRub.setPersonalAccount("test1");
expectedAccountTagRub.setBudgetClassificationCode("test2");
expectedAccountTagRub.setOktmo("test3");
expectedAccountTagRub.setTin("test4");
expectedAccountTagRub.setTrrc("test5");
expectedAccountTagRub.setAccount("test6");
expectedAccountTagRub.setBankName("test7");
expectedAccountTagRub.setBankAddress("test8");
expectedAccountTagRub.setBic("test9");
expectedAccountTagRub.setCorrespondentAccount("test10");
expectedAccountTagRub.setDestination("test11");
expectedAccountTagRub.setDiscontinuationDate("test12");
expectedAccountTagRub.setRespondTag(expectedRespondTagRub);
ClientTagRub expectedClientTagRub = new ClientTagRub();
expectedClientTagRub.setClientName("ПАО ВТБ");
expectedClientTagRub.setAccount(expectedAccountTagRub);
RegistratorTagRub expectedRegistratorTagRub = new RegistratorTagRub();
expectedRegistratorTagRub.setFirmId("001");
expectedRegistratorTagRub.setName("ПРЦ");
expectedRegistratorTagRub.setClient(expectedClientTagRub);
AccountListRub expectedAccountListRub = new AccountListRub();
expectedAccountListRub.setDocument(expectedDocumentTagRub);
expectedAccountListRub.setRegistrator(expectedRegistratorTagRub);
AccountListRub actualAccountListRub = (AccountListRub) actualResultContainer.getXmlFile();
Assertions.assertThat(processResult).isEqualTo(StageResult.OK);
Assertions.assertThat(actualResultContainer.getDocumentTag().getMessageId()).isEqualTo(expectedDocumentTag.getMessageId());
Assertions.assertThat(actualResultContainer.getDocumentTag().getMessageType()).isEqualTo(expectedDocumentTag.getMessageType());
Assertions.assertThat(actualResultContainer.getDocumentTag().getMessageName()).isEqualTo(expectedDocumentTag.getMessageName());
Assertions.assertThat(actualResultContainer.getDocumentTag().getMessageDate()).isEqualTo(expectedDocumentTag.getMessageDate());
Assertions.assertThat(actualResultContainer.getDocumentTag().getMessageTime()).isEqualTo(expectedDocumentTag.getMessageTime());
Assertions.assertThat(actualResultContainer.getDocumentTag().getSender()).isEqualTo(expectedDocumentTag.getSender());
Assertions.assertThat(actualResultContainer.getDocumentTag().getReceiver()).isEqualTo(expectedDocumentTag.getReceiver());
Assertions.assertThat(actualAccountListRub)
.usingRecursiveComparison()
.isEqualTo(expectedAccountListRub);
}
@Test
void process_shouldReaLKSAccountListCurXMLFile() throws URISyntaxException {
ResultContainer actualResultContainer = new ResultContainer(ETable.ACCOUNT_LIST_CUR,
new File(Objects.requireNonNull(getClass()
.getClassLoader()
.getResource("xml/FIRMID_ACCOUNT_LIST_20240910_CNY_00001.XML")).toURI()));
StageResult processResult = readXMLFile.process(actualResultContainer);
DocumentTagCur expectedDocumentTagCur = new DocumentTagCur();
expectedDocumentTagCur.setAuthor("Система БИС");
expectedDocumentTagCur.setTime(LocalTime.parse("14:23:01"));
expectedDocumentTagCur.setDate(LocalDate.parse("2024-08-21"));
expectedDocumentTagCur.setName("Запрос на согласование перечня счетов в юанях");
expectedDocumentTagCur.setDocNum("1");
RespondTagCur expectedRespondTagCur = new RespondTagCur("1");
AccountTagCur expectedAccountTagCur = new AccountTagCur();
expectedAccountTagCur.setCurrency("CNY");
expectedAccountTagCur.setName("Public Join Stock Company «Romashka»");
expectedAccountTagCur.setSwiftCode("SUBRRUMM");
expectedAccountTagCur.setAddress("Moscow,Russia");
expectedAccountTagCur.setAccount("BR1500000000000010932840814P2");
expectedAccountTagCur.setBankName("Cberbank PJSC");
expectedAccountTagCur.setBankAddress("Moscow, Russia");
expectedAccountTagCur.setBankSwiftCode("SUBRRUMM");
expectedAccountTagCur.setBankAccount("30101840000000000225");
expectedAccountTagCur.setBankName1("ZiaBao");
expectedAccountTagCur.setBankAddress1("Beijing, China");
expectedAccountTagCur.setBankAccount1("8900085754");
expectedAccountTagCur.setIntermediarySwiftCode1("BKCHCNBJ");
expectedAccountTagCur.setBankName2("XuiTao Inc");
expectedAccountTagCur.setBankAddress2("Beijing, China");
expectedAccountTagCur.setBankAccount2("890008777");
expectedAccountTagCur.setIntermediarySwiftCode2("BKCHCXXX");
expectedAccountTagCur.setDestination("Clearing services agr. № 45872 from 21.05.2023");
expectedAccountTagCur.setRespondTag(expectedRespondTagCur);
ClientTagCur expectedClientTagCur = new ClientTagCur();
expectedClientTagCur.setClientName("ПАО ВТБ");
expectedClientTagCur.setAccount(expectedAccountTagCur);
RegistratorTagCur expectedRegistratorTagCur = new RegistratorTagCur();
expectedRegistratorTagCur.setFirmId("001");
expectedRegistratorTagCur.setName("ПРЦ");
expectedRegistratorTagCur.setClient(expectedClientTagCur);
AccountListCur expectedAccountListCur = new AccountListCur();
expectedAccountListCur.setDocument(expectedDocumentTagCur);
expectedAccountListCur.setRegistrator(expectedRegistratorTagCur);
AccountListCur actualAccountListCur = (AccountListCur) actualResultContainer.getXmlFile();
Assertions.assertThat(processResult).isEqualTo(StageResult.OK);
Assertions.assertThat(actualAccountListCur)
.usingRecursiveComparison()
.isEqualTo(expectedAccountListCur);
}
}

View file

@ -2,42 +2,85 @@ server.port=8081
server.servlet.context-path=/xml-importer
spring.main.web-application-type=servlet
import-xml-service.scheduler.check-src-dir-cron=* * * * 1 ?
import-xml-service.process-sdf-files=true
import-xml-service.process-lks-files=true
import-xml-service.store.delete-src-files=false
import-xml-service.store.src-dir=/opt/clearing/file/xml-importer/
import-xml-service.store.out-dir=/opt/clearing/file/xml-importer/loaded/
import-xml-service.store.out-dir-error=/opt/clearing/file/xml-importer/error/
import-xml-service.cron.check-src-dir-cron=* * * * 1 ?
import-xml-service.common.encoding-source=cp866
import-xml-service.common.insert-batch-size=100
import-xml-service.common.threads-count=10
#sftpSrcDir
import-xml-service.store.sftp-in.sftp-src-pay-val-dir.rub=clearing_xml-importer_sftp/rub/
import-xml-service.store.sftp-in.sftp-src-pay-val-dir.eur=clearing_xml-importer_sftp/eur/
import-xml-service.store.sftp-in.sftp-src-dir=clearing_xml-importer_sftp
import-xml-service.store.sftp-in.user=user
import-xml-service.store.sftp-in.password=*********
import-xml-service.store.sftp-in.server-ip=127.0.0.1
import-xml-service.store.sftp-in.server-port=22
# SDF settings
# Hazelcast cluster
import-xml-service.sdf-hazelcast-and-kafka.hazelcast.cluster-members=localhost:5701
import-xml-service.sdf-hazelcast-and-kafka.hazelcast.login=dev
import-xml-service.sdf-hazelcast-and-kafka.hazelcast.password=dev-pass
import-xml-service.hazelcast.cluster-members=127.0.0.1:5701
import-xml-service.hazelcast.login=dev
import-xml-service.hazelcast.password=dev-pass
# Store directories
import-xml-service.store-sdf.delete-src-files=false
import-xml-service.store-sdf.src-dir=/opt/clearing/file/xml-importer/
import-xml-service.store-sdf.out-dir=/opt/clearing/file/xml-importer/loaded/
import-xml-service.store-sdf.out-dir-error=/opt/clearing/file/xml-importer/error/=
# Sftp directories and credentials
import-xml-service.store-sdf.sftp-in.sftp-src-pay-val-dir.rub=clearing_xml-importer_sftp/rub/
import-xml-service.store-sdf.sftp-in.sftp-src-pay-val-dir.eur=clearing_xml-importer_sftp/eur/
import-xml-service.store-sdf.sftp-in.sftp-src-dir=clearing_xml-importer_sftp
import-xml-service.store-sdf.sftp-in.user=user
import-xml-service.store-sdf.sftp-in.password=*********
import-xml-service.store-sdf.sftp-in.server-ip=127.0.0.1
import-xml-service.store-sdf.sftp-in.server-port=22
import-xml-service.kafka-producer.bootstrap-servers=localhost:9092
import-xml-service.kafka-producer.acks=all
import-xml-service.kafka-producer.retries=0
import-xml-service.kafka-producer.batch-size=16384
import-xml-service.kafka-producer.linger-ms=1
import-xml-service.kafka-producer.buffer-memory=33554432
# Kafka settings
# Kafka producer
import-xml-service.sdf-hazelcast-and-kafka.kafka-producer.bootstrap-servers=localhost:9092
import-xml-service.sdf-hazelcast-and-kafka.kafka-producer.acks=all
import-xml-service.sdf-hazelcast-and-kafka.kafka-producer.retries=0
import-xml-service.sdf-hazelcast-and-kafka.kafka-producer.batch-size=16384
import-xml-service.sdf-hazelcast-and-kafka.kafka-producer.linger-ms=1
import-xml-service.sdf-hazelcast-and-kafka.kafka-producer.buffer-memory=33554432
import-xml-service.kafka-consumer.bootstrap-servers=localhost:9092
import-xml-service.kafka-consumer.group-id=dev-group-clearing-service
import-xml-service.kafka-consumer.enable-auto-commit=false
import-xml-service.kafka-consumer.session-timeout-ms=30000
import-xml-service.kafka-consumer.auto-offset-reset=latest
import-xml-service.kafka-consumer.linger-ms=1
import-xml-service.kafka-consumer.buffer-memory=33554432
# Kafka consumer
import-xml-service.sdf-hazelcast-and-kafka.kafka-consumer.bootstrap-servers=localhost:9092
import-xml-service.sdf-hazelcast-and-kafka.kafka-consumer.group-id=dev-group-clearing-service
import-xml-service.sdf-hazelcast-and-kafka.kafka-consumer.enable-auto-commit=false
import-xml-service.sdf-hazelcast-and-kafka.kafka-consumer.session-timeout-ms=30000
import-xml-service.sdf-hazelcast-and-kafka.kafka-consumer.auto-offset-reset=latest
# LKS settings
# Hazelcast cluster
import-xml-service.lks-hazelcast-and-kafka.hazelcast.cluster-members=localhost:5701
import-xml-service.lks-hazelcast-and-kafka.hazelcast.login=dev
import-xml-service.lks-hazelcast-and-kafka.hazelcast.password=dev-pass
# Store directories
import-xml-service.store-lks.delete-src-files=false
import-xml-service.store-lks.src-dir=/opt/clearing/file/xml-importer/
import-xml-service.store-lks.out-dir=/opt/clearing/file/xml-importer/loaded/
import-xml-service.store-lks.out-dir-error=/opt/clearing/file/xml-importer/error/=
# Sftp directories and credentials
import-xml-service.store-lks.sftp-in.sftp-src-pay-val-dir.rub=clearing_xml-importer_sftp/rub/
import-xml-service.store-lks.sftp-in.sftp-src-pay-val-dir.eur=clearing_xml-importer_sftp/eur/
import-xml-service.store-lks.sftp-in.sftp-src-dir=clearing_xml-importer_sftp
import-xml-service.store-lks.sftp-in.user=user
import-xml-service.store-lks.sftp-in.password=*********
import-xml-service.store-lks.sftp-in.server-ip=127.0.0.1
import-xml-service.store-lks.sftp-in.server-port=22
# Kafka settings
# Kafka producer
import-xml-service.lks-hazelcast-and-kafka.kafka-producer.bootstrap-servers=localhost:9092
import-xml-service.lks-hazelcast-and-kafka.kafka-producer.acks=all
import-xml-service.lks-hazelcast-and-kafka.kafka-producer.retries=0
import-xml-service.lks-hazelcast-and-kafka.kafka-producer.batch-size=16384
import-xml-service.lks-hazelcast-and-kafka.kafka-producer.linger-ms=1
import-xml-service.lks-hazelcast-and-kafka.kafka-producer.buffer-memory=33554432
# Kafka consumer
import-xml-service.lks-hazelcast-and-kafka.kafka-consumer.bootstrap-servers=localhost:9092
import-xml-service.lks-hazelcast-and-kafka.kafka-consumer.group-id=dev-group-clearing-service
import-xml-service.lks-hazelcast-and-kafka.kafka-consumer.enable-auto-commit=false
import-xml-service.lks-hazelcast-and-kafka.kafka-consumer.session-timeout-ms=30000
import-xml-service.lks-hazelcast-and-kafka.kafka-consumer.auto-offset-reset=latest

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<FIRM_DOC>
<DOCUMENT AUTHOR="Система БИС"
TIME="14:23:01"
DATE="21.08.2024"
NAME="Запрос на согласование перечня счетов в юанях"
DOC_NUM="1"/>
<REGISTRATOR FIRMID="001"
NAME="ПРЦ">
<CLIENT CLIENT_NAME="ПАО ВТБ">
<ACCOUNT CURRENCY="CNY"
NAME="Public Join Stock Company «Romashka»"
SWIFT_CODE="SUBRRUMM"
ADDRESS="Moscow,Russia"
ACCOUNT="BR1500000000000010932840814P2"
BANK_NAME="Cberbank PJSC"
BANK_ADDRESS="Moscow, Russia"
BANK_SWIFT_CODE="SUBRRUMM"
BANK_ACCOUNT="30101840000000000225"
BANK_NAME_1="ZiaBao"
BANK_ADDRESS_1="Beijing, China"
BANK_ACCOUNT_1="8900085754"
INTERMEDIARY_SWIFT_CODE="BKCHCNBJ"
BANK_NAME_2="XuiTao Inc"
BANK_ADDRESS_2="Beijing, China"
BANK_ACCOUNT_2="890008777"
INTERMEDIARY_SWIFT_CODE_2="BKCHCXXX"
DESTINATION="Clearing services agr. № 45872 from 21.05.2023">
<RESPOND STATUS="1"/>
</ACCOUNT>
</CLIENT>
</REGISTRATOR>
</FIRM_DOC>

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<FIRM_DOC>
<DOCUMENT AUTHOR="Система БИС"
TIME="14:23:01"
DATE="21.08.2024"
NAME="Запрос на согласование перечня счетов в рублях"
DOC_NUM="1"/>
<REGISTRATOR FIRMID="001"
NAME="ПРЦ">
<CLIENT CLIENT_NAME="ПАО ВТБ">
<ACCOUNT CURRENCY="RUB"
NAME="Public Join Stock Company «Romashka»"
PERSONAL_ACCOUNT="test1"
BUDGET_CLASSIFICATION_CODE="test2"
OKTMO="test3"
TIN="test4"
TRRC="test5"
ACCOUNT="test6"
BANK_NAME="test7"
BANK_ADDRESS="test8"
BIC="test9"
CORRESPONDENT_ACCOUNT="test10"
DESTINATION="test11"
DISCONTINUATION_DATE="test12">
<RESPOND STATUS="1"></RESPOND>
</ACCOUNT>
</CLIENT>
</REGISTRATOR>
</FIRM_DOC>