Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
ialbert 2023-05-19 19:23:57 +03:00
commit 697017a8e8
52 changed files with 2025 additions and 617 deletions

View file

@ -323,6 +323,31 @@
</transformationSets>
</configuration>
</execution>
<execution>
<!-- Generate java_classes.java from META file
command: mvn xml:transform@java -->
<id>java</id>
<goals>
<goal>transform</goal>
</goals>
<configuration>
<transformationSets>
<transformationSet>
<dir>src/main/resources/meta</dir>
<includes>
<include>meta.xml</include>
</includes>
<stylesheet>src/main/resources/meta/xsl/java.xsl</stylesheet>
<fileMappers>
<fileMapper
implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
<targetExtension>java_classes.java</targetExtension>
</fileMapper>
</fileMappers>
</transformationSet>
</transformationSets>
</configuration>
</execution>
</executions>
</plugin>
<plugin>

View file

@ -0,0 +1,467 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output version="1.0" method="text" indent="no" encoding="UTF-8"/>
<xsl:variable name="lcletters">abcdefghijklmnopqrstuvwxyz</xsl:variable>
<xsl:variable name="ucletters">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
<xsl:variable name="avoidletters">_0123456789</xsl:variable>
<xsl:template match="/"><xsl:apply-templates select="*"/></xsl:template>
<xsl:template match="meta">// JAVA classes for DB version: <xsl:value-of select="@version"/><xsl:apply-templates select="*"/></xsl:template>
<xsl:template match="enums">
/* Dictionaries */
<xsl:apply-templates select="*" mode="enums"/>
</xsl:template>
<xsl:template match="objects">
/* Business objects */
<xsl:apply-templates select="*" mode="objects"/>
</xsl:template>
<xsl:template match="types">
// Data types
<xsl:apply-templates select="*" mode="types"/>
</xsl:template>
<xsl:template match="type" mode="types">
// <xsl:value-of select="@id"/>. <xsl:value-of select="name()"/> : <xsl:value-of select="@type"/> - <xsl:value-of select="@name"/>
<xsl:if test="position() != last()">,</xsl:if>
</xsl:template>
<xsl:template match="*" mode="enums">
// ----------------- <xsl:value-of select="name()"/> - <xsl:value-of select="@name"/>
<xsl:variable name="dbTableName"><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='concat(name(),"Dictionary")'/></xsl:call-template></xsl:variable>
<xsl:variable name="nameObjFmt"><xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:variable>
package ru.clearing.platform.dictionary;<!-- todo remove extract last class <xsl:value-of select="@class"/> - only package-->
<!-- import ru.clearing.dictionarys.ConstDictionarySerializable; -->
/**
* <xsl:value-of select="@name"/>
*
* Dictionary DB table: <xsl:value-of select="$dbTableName"/>
**/
public class <xsl:value-of select="$nameObjFmt"/>Dictionary extends AbstractDictionary {
private static final long serialVersionUID = ConstDictionarySerializable.serialVersionUID;
<xsl:apply-templates select="*" mode="field-enums"/> <!-- ignore default AbstractDictionary field -->
<xsl:apply-templates select="*" mode="getter-setter-enums"/>
}
// -- mapstore --
package ru.spcex.clearing.imdg.dictionary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.platform.dictionary.<xsl:value-of select="$nameObjFmt"/>Dictionary; <!-- or <xsl:value-of select="@class"/> -->
import ru.spcex.clearing.imdg.base.DictionaryTMapStore;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
@Component
public class <xsl:value-of select="$nameObjFmt"/>DictionaryMapStore extends DictionaryTMapStore&lt;<xsl:value-of select="$nameObjFmt"/>Dictionary&gt; {
public <xsl:value-of select="$nameObjFmt"/>DictionaryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_<xsl:value-of select="$nameObjFmt"/>Dictionary;
}
@Override
public String getTableName() {
return "<xsl:value-of select="$dbTableName"/>";
}
@Override
public <xsl:value-of select="$nameObjFmt"/>Dictionary getDictionaryObject() {
return new <xsl:value-of select="$nameObjFmt"/>Dictionary();
}
<xsl:apply-templates select="*" mode="mapstore-field-enums"/> <!-- защита от нестандартного Dictionary -->
}
</xsl:template>
<xsl:template match="*" mode="mapstore-field-enums" >
<xsl:choose>
<xsl:when test="name()='id'"></xsl:when>
<xsl:when test="name()='code'"></xsl:when>
<xsl:when test="name()='name'"></xsl:when>
<xsl:otherwise>
!! Нестандартное поле !! <xsl:value-of select="name()"/> // FIXME Нестандартный словарь! Требуется писать код вручную.
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="*" mode="objects">
// ------------------ <xsl:value-of select="name()"/> - <xsl:value-of select="@name"/>
<xsl:variable name="dbTableName"><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:variable>
<xsl:variable name="nameObjFmt"><xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:variable>
package <xsl:value-of select="@class"/>;<!-- todo remove extract last class - only package-->
import ru.clearing.classes.ConstSerializable;
import ru.spcex.platform.classes.base.SpcexObjectBase;
/**
* <xsl:value-of select="@name"/>
*
* DB table: <xsl:value-of select="$dbTableName"/>
**/
public class <xsl:value-of select="$nameObjFmt"/> extends SpcexObjectBase {
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
<xsl:apply-templates select="*[@name or @dbname or @type]" mode="field"/>
<xsl:apply-templates select="*[@name or @dbname or @type]" mode="getter-setter-objects"/>
}
//mapstore
// -- mapstore --
package ru.spcex.clearing.imdg.object;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import <xsl:value-of select="@class"/>; <!-- or ...<xsl:value-of select="$nameObjFmt"/> -->
import ru.spcex.clearing.imdg.base.TemplateMapStore;<!-- ObjectBaseMapStore; -->
import ru.spcex.platform.utils.time.TimeUtil;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
@Component
public class <xsl:value-of select="$nameObjFmt"/>MapStore extends TemplateMapStore&lt;<xsl:value-of select="$nameObjFmt"/>&gt; {
public <xsl:value-of select="$nameObjFmt"/>MapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_<xsl:value-of select="$nameObjFmt"/>;
}
@Override
public String getTableName() {
return "<xsl:value-of select="$dbTableName"/>";
}
@Override
public String[] getFields() {
return new String[]{
<xsl:apply-templates select="*[@name or @dbname or @type]" mode="mapstore-field-getFields"/>
};
}
@Override
public <xsl:value-of select="$nameObjFmt"/> objectReader(ResultSet resultSet) throws SQLException {
<xsl:value-of select="$nameObjFmt"/> object = new <xsl:value-of select="$nameObjFmt"/>(); <xsl:apply-templates select="*[@name or @dbname or @type]" mode="mapstore-field-setters"/>
return object;
}
@Override
public Object[] objectToField(<xsl:value-of select="$nameObjFmt"/> object) {
Object[] args = new Object[]{<xsl:apply-templates select="*[@name or @dbname or @type]" mode="mapstore-field-getters"/>
};
return args;
}
}
<xsl:if test="@logUpdates">
// todo добавить класс <xsl:value-of select="$nameObjFmt"/>History
package <xsl:value-of select="@class"/>;<!-- todo remove extract last class - only package-->
import ru.clearing.classes.ConstSerializable;
import ru.clearing.classes.objects.BusinessEvent;
import java.io.Serial;
/**
* Изменение состояния объекта <xsl:value-of select="@name"/>
*
* DB table: <xsl:value-of select="$dbTableName"/>_HISTORY
**/
public class <xsl:value-of select="$nameObjFmt"/>History extends BusinessEvent&lt;<xsl:value-of select="$nameObjFmt"/>&gt; {
@Serial
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
private <xsl:value-of select="$nameObjFmt"/> object;
@Override
public <xsl:value-of select="$nameObjFmt"/> getObject() {
return object;
}
@Override
public void setObject(<xsl:value-of select="$nameObjFmt"/> object) {
this.object = object;
}
}
// -- History mapstore для журналирования --
package ru.spcex.clearing.imdg.businessevent;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import <xsl:value-of select="@class"/>;
import <xsl:value-of select="@class"/>History; <!-- or ...<xsl:value-of select="$nameObjFmt"/> -->
import ru.spcex.clearing.imdg.base.TemplateEventMapStore;<!-- ObjectBaseMapStore; -->
import ru.spcex.platform.utils.time.TimeUtil;
@Component
public class <xsl:value-of select="$nameObjFmt"/>HistoryMapStore extends TemplateEventMapStore&lt;<xsl:value-of select="$nameObjFmt"/>History&gt; {
public <xsl:value-of select="$nameObjFmt"/>HistoryMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_<xsl:value-of select="$nameObjFmt"/>History;
}
@Override
public String getTableName() {
return "<xsl:value-of select="$dbTableName"/>_HISTORY";
}
@Override
public String[] getFields() {
return new String[]{"ID","EVENT_TIME", "EVENT_USER_ID", "EVENT_TYPE", <!-- todo покрасивее сделать ?_ID, а то код вручную приодится править -->
<xsl:value-of select="$dbTableName"/>_<xsl:apply-templates select="*[@name or @dbname or @type]" mode="mapstore-field-getFields"/>
};
}
@Override
public Object[] objectToField(<xsl:value-of select="$nameObjFmt"/>History historyLog) {
<xsl:value-of select="$nameObjFmt"/> object=historyLog.getObject();
Object[] args = new Object[]{
historyLog.getId(),
TimeUtil.toDateFromInstant(historyLog.getEventTime()),
historyLog.getUserId(),
historyLog.getEventType(),
<xsl:apply-templates select="*[@name or @dbname or @type]" mode="mapstore-field-getters"/>
};
return args;
}
}
</xsl:if>
</xsl:template>
<xsl:template match="*" mode="mapstore-field-getFields" ><xsl:if test="position() != '1'">, </xsl:if> "<xsl:choose>
<xsl:when test="@dbfield"><xsl:value-of select="@dbfield"/></xsl:when>
<xsl:otherwise><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:otherwise>
</xsl:choose>"</xsl:template>
<xsl:template match="*" mode="mapstore-field-setters" >
<xsl:variable name="tp" select="@type"/>
<xsl:variable name="javatp" select="/meta/types/*[@id=$tp]/@javatype"/> <xsl:choose>
<xsl:when test="$javatp='Instant'">
object.set<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>(getInstantFromTimestamp(resultSet, "<xsl:choose>
<xsl:when test="@dbfield"><xsl:value-of select="@dbfield"/></xsl:when>
<xsl:otherwise><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:otherwise>
</xsl:choose>"))</xsl:when>
<xsl:when test="$javatp='LocalDate'">
object.set<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>(getLocalDateFromSqlDate(resultSet, "<xsl:choose>
<xsl:when test="@dbfield"><xsl:value-of select="@dbfield"/></xsl:when>
<xsl:otherwise><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:otherwise>
</xsl:choose>"))</xsl:when>
<xsl:when test="$javatp='LocalTime'">
object.set<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>(getLocalTimeFromSqlTime(resultSet, "<xsl:choose>
<xsl:when test="@dbfield"><xsl:value-of select="@dbfield"/></xsl:when>
<xsl:otherwise><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:otherwise>
</xsl:choose>"))</xsl:when>
<xsl:otherwise>
object.set<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>(resultSet.getObject("<xsl:choose>
<xsl:when test="@dbfield"><xsl:value-of select="@dbfield"/></xsl:when>
<xsl:otherwise><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:otherwise>
</xsl:choose>", <xsl:value-of select="$javatp"/>.class))</xsl:otherwise>
</xsl:choose>;</xsl:template>
<xsl:template match="*" mode="mapstore-field-getters" ><xsl:if test="position() != '1'">, </xsl:if><!-- todo запятую в конце а не в начале, см. last()-->
<xsl:variable name="tp" select="@type"/>
<xsl:variable name="javatp" select="/meta/types/*[@id=$tp]/@javatype"/>
<xsl:choose>
<xsl:when test="$javatp='Instant'">
TimeUtil.toDateFromInstant(object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>())</xsl:when>
<xsl:when test="$javatp='LocalDate'">
TimeUtil.toDateFromLocalDate(object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>())</xsl:when>
<xsl:when test="$javatp='LocalTime'">
TimeUtil.toDateFromLocalTime(object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>())</xsl:when>
<xsl:otherwise>
object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>()</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="*" mode="field" >
<xsl:variable name="tp" select="@type"/>
<xsl:if test="name()='id'"> // (in parent) </xsl:if> private <xsl:value-of select="/meta/types/*[@id=$tp]/@javatype"/> <xsl:text> <!-- space &#160; --></xsl:text><xsl:value-of select="name()"/>;
<xsl:choose>
<xsl:when test="@dbfield"> // DB field: <xsl:value-of select="@dbfield"/></xsl:when>
<!-- new line -->
<xsl:otherwise> </xsl:otherwise></xsl:choose>
<!-- todo pretty comment: <xsl:if test="@link"> // (linked to <xsl:value-of select="@link"/>)
</xsl:if>-->
<!-- fixme т.к. тут атрибуты перебираются - не работают переносы а ещё знак пробела надо пропатчить, а то NBSP -->
</xsl:template>
<xsl:template match="*" mode="field-enums" >
<xsl:variable name="tp" select="@type"/>
<xsl:choose>
<xsl:when test="name()='id'"></xsl:when><!-- определено в родительском классе AbstractDictionary -->
<xsl:when test="name()='code'"></xsl:when><!-- определено в родительском классе AbstractDictionary -->
<xsl:when test="name()='name'"></xsl:when><!-- определено в родительском классе AbstractDictionary -->
<xsl:otherwise><!-- нестандартное поле -->
private <xsl:value-of select="/meta/types/*[@id=$tp]/@javatype"/> <xsl:text> <!-- space &#160; --> </xsl:text><xsl:value-of select="name()"/>;
<xsl:choose>
<xsl:when test="@dbfield"> // DB field: <xsl:value-of select="@dbfield"/></xsl:when>
<!-- new line -->
<xsl:otherwise> </xsl:otherwise>
</xsl:choose><xsl:if test="@link"> // (linked to <xsl:value-of select="@link"/>)
<!--new line--></xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="*" mode="getter-setter-enums">
<xsl:variable name="tp" select="@type"/>
<xsl:choose>
<xsl:when test="name()='id'"></xsl:when><!-- todo other restrictions of parent AbstractDictionary -->
<xsl:when test="name()='code'"></xsl:when><!-- todo other restrictions of parent AbstractDictionary -->
<xsl:when test="name()='name'"></xsl:when><!-- todo other restrictions of parent AbstractDictionary -->
<xsl:otherwise><!-- нестандартное поле -->
<xsl:variable name="NameFmt"><xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:variable>
public <xsl:value-of select="/meta/types/*[@id=$tp]/@javatype"/> get<xsl:value-of select="$NameFmt"/>() {
return <xsl:value-of select="name()"/>;
}
public void set<xsl:value-of select="$NameFmt"/>(<xsl:value-of select="/meta/types/*[@id=$tp]/@javatype"/> value) {
this.<xsl:value-of select="name()"/>=value;
}
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="*" mode="getter-setter-objects">
<xsl:variable name="tp" select="@type"/>
<xsl:choose>
<xsl:when test="name()='id'"></xsl:when>
<xsl:otherwise>
<xsl:variable name="NameFmt"><xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:variable>
public <xsl:value-of select="/meta/types/*[@id=$tp]/@javatype"/> get<xsl:value-of select="$NameFmt"/>() {
return <xsl:value-of select="name()"/>;
}
public void set<xsl:value-of select="$NameFmt"/>(<xsl:value-of select="/meta/types/*[@id=$tp]/@javatype"/> value) {
this.<xsl:value-of select="name()"/>=value;
}
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name='convertDbStyle'>
<xsl:param name='toconvert' />
<xsl:variable name="added_">
<xsl:call-template name='add_'>
<xsl:with-param name='toconvert' select='$toconvert' />
</xsl:call-template>
</xsl:variable>
<xsl:call-template name='convertcase'>
<xsl:with-param name='toconvert' select='$added_' />
<xsl:with-param name='conversion' select="'upper'" />
</xsl:call-template>
</xsl:template>
<xsl:template name='convertcase'>
<xsl:param name='toconvert' />
<xsl:param name='conversion' />
<xsl:choose>
<xsl:when test='$conversion="lower"'>
<xsl:value-of select="translate($toconvert,$ucletters,$lcletters)"/>
</xsl:when>
<xsl:when test='$conversion="upper"'>
<xsl:value-of select="translate($toconvert,$lcletters,$ucletters)"/>
</xsl:when>
<xsl:when test='$conversion="proper"'>
<xsl:call-template name='convertpropercase'>
<xsl:with-param name='toconvert'>
<xsl:value-of select="translate($toconvert,$ucletters,$lcletters)"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select='$toconvert' />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name='convertpropercase'>
<xsl:param name='toconvert' />
<xsl:if test="string-length($toconvert) > 0">
<xsl:variable name='f' select='substring($toconvert, 1, 1)' />
<xsl:variable name='s' select='substring($toconvert, 2)' />
<xsl:call-template name='convertcase'>
<xsl:with-param name='toconvert' select='$f' />
<xsl:with-param name='conversion'>upper</xsl:with-param>
</xsl:call-template>
<xsl:choose>
<xsl:when test="contains($s,' ')">
<xsl:value-of select='substring-before($s," ")'/>
<xsl:call-template name='convertpropercase'>
<xsl:with-param name='toconvert' select='substring-after($s," ")' />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select='$s'/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template name='add_'>
<xsl:param name='toconvert' />
<xsl:if test="string-length($toconvert) > 0">
<xsl:variable name='f' select='substring($toconvert, 1, 1)' />
<xsl:variable name='s' select='substring($toconvert, 2)' />
<xsl:choose>
<xsl:when test="$f = translate($f, $lcletters,$ucletters)"><xsl:if test="translate($f, $avoidletters,'')">_</xsl:if><xsl:value-of select='$f'/></xsl:when>
<xsl:otherwise><xsl:value-of select='$f'/></xsl:otherwise>
</xsl:choose>
<xsl:if test="string-length($toconvert) > 1">
<xsl:call-template name='add_'>
<xsl:with-param name='toconvert' select='$s'/>
</xsl:call-template>
</xsl:if>
</xsl:if>
</xsl:template>
<!-- todo должен первую букву прописной сделать -->
<xsl:template name='convertFirstUC_'>
<xsl:param name='toconvert' />
<xsl:if test="string-length($toconvert) > 0">
<xsl:variable name='f' select='translate(substring($toconvert, 1, 1),$lcletters,$ucletters)' />
<xsl:variable name='s' select='substring($toconvert, 2)' />
<xsl:value-of select='$f'/><xsl:value-of select='$s'/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

View file

@ -9,7 +9,7 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.session.stage.ISessionStage;
import ru.spcex.clearing.session.stage.StageResult;
import ru.spcex.clearing.session.stage.Task;
import ru.spcex.clearing.session.stage.task.RegistryOnObligationsAndSettlementRequirementsPayload;
import ru.spcex.clearing.session.stage.task.FormingRegistersOnOSPayload;
import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryInstrumentType;
@ -39,10 +39,10 @@ public class FormingRegistersOnOS implements ISessionStage {
@Override
public StageResult<?> submit(Task<?> task) {
RegistryOnObligationsAndSettlementRequirementsPayload payload = (RegistryOnObligationsAndSettlementRequirementsPayload) task.getData();
FormingRegistersOnOSPayload payload = (FormingRegistersOnOSPayload) task.getData();
switch (task.getTaskType()) {
case FormingRegistersOnOS -> {
return createRegistryOnObligationsAndSettlementRequirements(payload.getSessionId());
return createRegistryOnObligationsAndSettlementRequirements();
}
default -> {
throw new IllegalStateException("Unknown task type: " + task.getTaskType());
@ -53,12 +53,10 @@ public class FormingRegistersOnOS implements ISessionStage {
/**
* Select Registry by: registryCode = [O/T][S/M][*][T] & registryStatus=OK
*
* @param sessionId
* @return
*/
protected Collection<Registry> selectRegistry(Long sessionId) {
String registrySQL = "sessionId = " + sessionId;
registrySQL += " and (registryDesignation=" + RegistryDesignation.O.getKey() + " or registryDesignation=" + RegistryDesignation.T.getKey() + ")";
protected Collection<Registry> selectRegistry() {
String registrySQL = "(registryDesignation=" + RegistryDesignation.O.getKey() + " or registryDesignation=" + RegistryDesignation.T.getKey() + ")";
registrySQL += " and (registryInstrumentType=" + RegistryInstrumentType.S.getKey() + " or registryInstrumentType=" + RegistryInstrumentType.M.getKey() + ")";
registrySQL += " and (registryUnit=" + RegistryUnit.T.getKey() + ")";
registrySQL += " and registryStatus=" + RegistryStatus.OK.getKey() + ")";
@ -67,8 +65,8 @@ public class FormingRegistersOnOS implements ISessionStage {
return result;
}
protected StageResult<?> createRegistryOnObligationsAndSettlementRequirements(Long sessionId) {
Collection<Registry> forRegistries = selectRegistry(sessionId);
protected StageResult<?> createRegistryOnObligationsAndSettlementRequirements() {
Collection<Registry> forRegistries = selectRegistry();
ArrayList<Registry> newRegistries = new ArrayList<>();
//todo oreder by обрабатываться группами по полю registry.groupId

View file

@ -15,6 +15,7 @@ import ru.spcex.platform.enumeration.RegistryInstrumentType;
import ru.spcex.platform.enumeration.RegistryUnit;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.ImdgTransaction;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
@ -26,10 +27,12 @@ import java.util.Collection;
public class UnlockResources implements ISessionStage {
private final Logger log = LoggerFactory.getLogger(getClass());
protected final ImdgProvider imdgProvider;
private final Imdg<Registry> registryImdg;
@Autowired
public UnlockResources(ImdgProvider imdgProvider) {
this.imdgProvider = imdgProvider;
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
}
@ -39,7 +42,7 @@ public class UnlockResources implements ISessionStage {
switch (task.getTaskType()) {
case UnlockResources -> {
UnlockResourcesPayload payload = (UnlockResourcesPayload) task.getData();
return unlockResources(payload.getSdfMode(), payload.getSessionId(),
return unlockResources(payload.getSdfMode(),
payload.getAccount(),
payload.getSecurityId(),
payload.getFullNames(),
@ -52,26 +55,18 @@ public class UnlockResources implements ISessionStage {
}
}
/**
* Select Registry by: account; fullName* / securityId
*/
protected Collection<Registry> selectRegistry(Long sessionId, String account, Long securityId, Collection<String> fullNames) {
protected Collection<Registry> selectRegistryForSDF04(String account, Collection<String> fullNames) {
ImdgPredicateBuilder pb = registryImdg.predicateBuilder();
ImdgPredicate queryPart;
if (securityId != null) {
queryPart = pb.in("securityId", securityId);
} else if (fullNames != null && !fullNames.isEmpty()) {
queryPart = pb.in("fullName", fullNames.toArray(new String[fullNames.size()]));
} else {
throw new IllegalArgumentException("Required securityId or fullNames");
}
ImdgPredicate query = pb.and(
pb.and(
pb.equals("sessionId", sessionId),
pb.equals("registryDesignation", RegistryDesignation.A.getKey()) // не все нужны, только с этим кодом отфильтруем.
pb.equals("registryDesignation", RegistryDesignation.A.getKey()),
pb.equals("registryInstrumentType", RegistryInstrumentType.M.getKey()),
// pb.equals("registryCapacity", *),
pb.or(pb.equals("registryUnit", RegistryUnit.F.getKey()),
pb.equals("registryUnit", RegistryUnit.B.getKey()))
),
pb.equals("account", account),
queryPart
pb.in("fullName", fullNames.toArray(new String[fullNames.size()]))
);
Collection<Registry> result = registryImdg.getCollectionObjectsByPredicate(query);
@ -79,50 +74,74 @@ public class UnlockResources implements ISessionStage {
return result;
}
/**
* Select Registry by: account; fullName* / securityId
*/
protected Collection<Registry> selectRegistryForSDF12(String account, Long securityId) {
ImdgPredicateBuilder pb = registryImdg.predicateBuilder();
ImdgPredicate query = pb.and(
pb.and(
pb.equals("registryDesignation", RegistryDesignation.A.getKey()),
pb.equals("registryInstrumentType", RegistryInstrumentType.S.getKey()),
// pb.equals("registryCapacity", *),
pb.or(pb.equals("registryUnit", RegistryUnit.F.getKey()),
pb.equals("registryUnit", RegistryUnit.B.getKey()))
),
pb.equals("account", account),
pb.in("securityId", securityId)
);
Collection<Registry> result = registryImdg.getCollectionObjectsByPredicate(query);
log.trace("Selected {} registry's by sql: {}", result.size(), query);
return result;
}
/**
* @param sdfMode UnlockResourcesPayload.sdfMode
* @param sessionId
* @param account
* @param securityId
* @param fullNames
* @return
*/
protected StageResult<?> unlockResources(String sdfMode, Long sessionId, String account, Long securityId, Collection<String> fullNames, BigDecimal value) {
Collection<Registry> forRegistries = selectRegistry(sessionId, account, securityId, fullNames);
protected StageResult<?> unlockResources(String sdfMode, String account, Long securityId, Collection<String> fullNames, BigDecimal value) {
Collection<Registry> forRegistries;
//todo при перезапуске после незапланированного завершения стадии: надо ли проверять уже созданные регистры и не создавать дубликаты?
if (UnlockResourcesPayload.MODE_SDF04.equals(sdfMode)) {
forRegistries = forRegistries.stream().filter(
(Registry r) ->
RegistryDesignation.A.equalsByKey(r.getRegistryDesignation())
&&
RegistryInstrumentType.M.equalsByKey(r.getRegistryInstrumentType())
&&
(RegistryUnit.F.equalsByKey(r.getRegistryUnit()) || RegistryUnit.B.equalsByKey(r.getRegistryUnit()))
).toList();
forRegistries = selectRegistryForSDF04(account, fullNames);
} else if (UnlockResourcesPayload.MODE_SDF12.equals(sdfMode)) {
forRegistries = forRegistries.stream().filter(
(Registry r) ->
RegistryDesignation.A.equalsByKey(r.getRegistryDesignation())
&&
RegistryInstrumentType.S.equalsByKey(r.getRegistryInstrumentType())
&&
(RegistryUnit.F.equalsByKey(r.getRegistryUnit()) || RegistryUnit.B.equalsByKey(r.getRegistryUnit()))
).toList();
forRegistries = selectRegistryForSDF12(account, securityId);
} else {
throw new IllegalArgumentException("Mode not support: " + sdfMode);
}
for (Registry registry : forRegistries) {
boolean modified = unlockRegistry(registry, value);
if (modified) {
registry.setUpdated(Instant.now());
registryImdg.update(registry);
log.trace("Registry {} changed; value +- registry",
registry.getId(), registry.getRegistryCode(), value);
ImdgTransaction tx = imdgProvider.newTransaction();
boolean txOk = false;
try {
log.debug("Processing transaction {}, input {} registers.", tx, forRegistries.size());
Imdg<Registry> registryTxImdg = tx.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
int nUpdates = 0;
for (Registry registry : forRegistries) {
boolean modified = unlockRegistry(registry, value);
if (modified) {
registry.setUpdated(Instant.now());
registryTxImdg.update(registry);
nUpdates++;
log.trace("Registry {} (registryCode={}) changed; value +- {}",
registry.getId(), registry.getRegistryCode(), value);
}
}
log.info("Updated {} registry's (under transaction {}", nUpdates, tx);
txOk = true;
} finally {
if (txOk) {
log.debug("Commit transaction {}.", tx);
tx.commitTransaction();
} else {
log.info("Rollback transaction {}", tx);
tx.rollbackTransaction();
}
}
//todo рекомендуется делать транзакцией.
StageResult<Collection<Registry>> res = new StageResult<>(null, true);
res.setStageResult(forRegistries);

View file

@ -0,0 +1,5 @@
package ru.spcex.clearing.session.stage.task;
public class FormingRegistersOnOSPayload {
}

View file

@ -1,31 +0,0 @@
package ru.spcex.clearing.session.stage.task;
public class RegistryOnObligationsAndSettlementRequirementsPayload {
private Long sessionId;
// private Long companyId;
// private Long securityId;
public Long getSessionId() {
return sessionId;
}
public void setSessionId(Long sessionId) {
this.sessionId = sessionId;
}
// public Long getCompanyId() {
// return companyId;
// }
//
// public void setCompanyId(Long companyId) {
// this.companyId = companyId;
// }
//
// public Long getSecurityId() {
// return securityId;
// }
//
// public void setSecurityId(Long securityId) {
// this.securityId = securityId;
// }
}

View file

@ -12,8 +12,6 @@ public class UnlockResourcesPayload {
*/
private String sdfMode;
private Long sessionId;
/**
* sDf04.c_acc_cred
* sDf12.depoCodeSender
@ -46,13 +44,6 @@ public class UnlockResourcesPayload {
}
public Long getSessionId() {
return sessionId;
}
public void setSessionId(Long sessionId) {
this.sessionId = sessionId;
}
public String getAccount() {
return account;

View file

@ -65,6 +65,7 @@ public record FieldRequiredRule<R, V>(
}
@Override
// todo replace for error fieldName to fieldValue
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
V value = getter.apply(validatedObject);

View file

@ -23,11 +23,15 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-sftp</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- DBF files -->
@ -49,6 +53,21 @@
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>
</dependency>
<!-- TEST -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>test-clearing</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

View file

@ -1,80 +1,11 @@
package ru.spcex.clearing.dbf.exporter.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import ru.spcex.clearing.dbf.exporter.config.settings.ExportDBFServiceSettings;
import ru.spcex.clearing.dbf.exporter.logic.stages.ExportFromHazelcast;
import ru.spcex.clearing.dbf.exporter.logic.stages.PrepareDBFFile;
import ru.spcex.clearing.dbf.exporter.logic.stages.Stage;
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 java.util.LinkedList;
import java.util.List;
@Configuration
@EnableConfigurationProperties
@ComponentScan(basePackages = {"ru.spcex.clearing.dbf.exporter"})
public class DBFExporterConfig {
@Bean("taskExecutorHazelcastClientInitializer")
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() {
return createThreadPoolTaskExecutor(1, true);
}
@Bean("taskExecutorIdGeneratorAwaiter")
public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() {
return createThreadPoolTaskExecutor(1, false);
}
@Bean("imdgProvider")
public ImdgProvider imdgProvider(@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
@Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
ExportDBFServiceSettings settings) {
HazelcastClientParams params = new HazelcastClientParams();
params.setClusterMembers(settings.getHazelcast().getClusterMembers());
params.setLogin(settings.getHazelcast().getLogin());
params.setPassword(settings.getHazelcast().getPassword());
return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params);
}
@Bean("pipeline")
public List<Stage> pipeline(ApplicationContext context) {
List<Stage> pipeline = new LinkedList<>();
pipeline.add(context.getBean(PrepareDBFFile.class));
pipeline.add(context.getBean(ExportFromHazelcast.class));
return pipeline;
}
@Bean("executor")
public ThreadPoolTaskExecutor executor(ExportDBFServiceSettings settings) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(settings.getCommon().getThreadsCount());
executor.setCorePoolSize(settings.getCommon().getThreadsCount());
executor.setThreadNamePrefix("dbf-exporter");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(300);
executor.initialize();
return executor;
}
private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
if (maxPoolSz > 2) {
pool.setKeepAliveSeconds(60);
pool.setAllowCoreThreadTimeOut(true);
}
pool.setCorePoolSize(maxPoolSz);
pool.setWaitForTasksToCompleteOnShutdown(waitForCompletion);
return pool;
}
}

View file

@ -0,0 +1,63 @@
package ru.spcex.clearing.dbf.exporter.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import ru.spcex.clearing.dbf.exporter.config.settings.ExportDBFServiceSettings;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@Configuration
@EnableConfigurationProperties
@ComponentScan(basePackages = {"ru.spcex.clearing.dbf.exporter"})
public class ImdgConfig {
@Bean("taskExecutorHazelcastClientInitializer")
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() {
return createThreadPoolTaskExecutor(1, true);
}
@Bean("taskExecutorIdGeneratorAwaiter")
public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() {
return createThreadPoolTaskExecutor(1, false);
}
@Bean("imdgProvider")
public ImdgProvider imdgProvider(@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
@Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
ExportDBFServiceSettings settings) {
HazelcastClientParams params = new HazelcastClientParams();
params.setClusterMembers(settings.getHazelcast().getClusterMembers());
params.setLogin(settings.getHazelcast().getLogin());
params.setPassword(settings.getHazelcast().getPassword());
return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params);
}
@Bean("executor")
public ThreadPoolTaskExecutor executor(ExportDBFServiceSettings settings) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(settings.getCommon().getThreadsCount());
executor.setCorePoolSize(settings.getCommon().getThreadsCount());
executor.setThreadNamePrefix("dbf-exporter");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(300);
executor.initialize();
return executor;
}
private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
if (maxPoolSz > 2) {
pool.setKeepAliveSeconds(60);
pool.setAllowCoreThreadTimeOut(true);
}
pool.setCorePoolSize(maxPoolSz);
pool.setWaitForTasksToCompleteOnShutdown(waitForCompletion);
return pool;
}
}

View file

@ -17,6 +17,8 @@ import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.util.function.Supplier;
//отдельный конфиг для sender чтобы сделать required false
@Configuration
public class KafkaSenderConfig {
@ -38,7 +40,6 @@ public class KafkaSenderConfig {
return KafkaProducerFactory.producerFactory(kafkaSettings);
}
@Autowired(required = false)
@Bean("kafkaTemplate")
public KafkaTemplate<String, Object> kafkaTemplate(ProducerFactory<String, Object> pf) {
if (pf == null) {
@ -47,16 +48,11 @@ public class KafkaSenderConfig {
return new KafkaTemplate<>(pf);
}
@Autowired(required = false)
@Bean
public KafkaSender kafkaSender(KafkaTemplate<String, Object> kafkaTemplate,
ImdgProvider imdgProvider) {
if (kafkaTemplate == null) {
log.info("Can not create KafkaSender: no kafka-producer settings");
return null;
}
public Supplier<KafkaSender> kafkaSenderSupplier(KafkaTemplate<String, Object> kafkaTemplate,
ImdgProvider imdgProvider) {
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
return KafkaSender
return () -> KafkaSender
.setup()
.setKafkaTemplate(kafkaTemplate)
.idGenerator(imdgIdGenerator::nextId)

View file

@ -0,0 +1,26 @@
package ru.spcex.clearing.dbf.exporter.config;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.dbf.exporter.logic.stages.ExportFromHazelcast;
import ru.spcex.clearing.dbf.exporter.logic.stages.Journal;
import ru.spcex.clearing.dbf.exporter.logic.stages.PrepareDBFFile;
import ru.spcex.clearing.dbf.exporter.logic.stages.Stage;
import java.util.LinkedList;
import java.util.List;
@Configuration
public class PipelineConfig {
@Bean("pipeline")
public List<Stage> pipeline(ApplicationContext context) {
List<Stage> pipeline = new LinkedList<>();
pipeline.add(context.getBean(PrepareDBFFile.class));
pipeline.add(context.getBean(ExportFromHazelcast.class));
pipeline.add(context.getBean(Journal.class));
return pipeline;
}
}

View file

@ -0,0 +1,95 @@
package ru.spcex.clearing.dbf.exporter.config;
import com.jcraft.jsch.ChannelSftp;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.file.remote.session.CachingSessionFactory;
import org.springframework.integration.file.remote.session.SessionFactory;
import org.springframework.integration.sftp.gateway.SftpOutboundGateway;
import org.springframework.integration.sftp.outbound.SftpMessageHandler;
import org.springframework.integration.sftp.session.DefaultSftpSessionFactory;
import org.springframework.integration.sftp.session.SftpFileInfo;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import ru.spcex.clearing.dbf.exporter.config.settings.ExportDBFServiceSettings;
import java.io.File;
import java.util.List;
import static org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.Command.LS;
@Configuration
public class SFTPConfig {
@Bean
public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory(ExportDBFServiceSettings settings) {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost(settings.getStore().getServerIp());
factory.setPort(settings.getStore().getServerPort());
factory.setUser(settings.getStore().getUser());
factory.setPassword(settings.getStore().getPassword());
factory.setAllowUnknownKeys(true);
return new CachingSessionFactory<>(factory);
}
@Bean
@ServiceActivator(inputChannel = "toSftpChannel")
public MessageHandler handler(SessionFactory<ChannelSftp.LsEntry> sessionFactory, ExportDBFServiceSettings settings) {
SftpMessageHandler handler = new SftpMessageHandler(sessionFactory);
handler.setRemoteDirectoryExpression(new LiteralExpression(settings.getStore().getOutDir()));
handler.setAutoCreateDirectory(true);
handler.setFileNameGenerator(message -> {
if (message.getPayload() instanceof File) {
return ((File) message.getPayload()).getName();
}else {
throw new IllegalArgumentException("File must expected as payload.");
}
});
return handler;
}
@MessagingGateway
public interface DbfGateway {
@Gateway(requestChannel = "toSftpChannel")
void sendToSftp(File file);
@Gateway(requestChannel = "listSftpChannel")
List<SftpFileInfo> listFiles(String dir);
}
@Bean
public MessageChannel listSftpChannel(SessionFactory<ChannelSftp.LsEntry> sessionFactory, ExportDBFServiceSettings settings) {
DirectChannel dc = new DirectChannel();
dc.subscribe(handlerList(sessionFactory, settings));
return dc;
}
@Bean
public MessageChannel toSftpChannel(SessionFactory<ChannelSftp.LsEntry> sessionFactory, ExportDBFServiceSettings settings) {
DirectChannel dc = new DirectChannel();
dc.subscribe(handler(sessionFactory, settings));
return dc;
}
@Bean
@ServiceActivator(inputChannel = "listSftpChannel")
public MessageHandler handlerList(SessionFactory<ChannelSftp.LsEntry> sessionFactory, ExportDBFServiceSettings settings) {
String expression = "'/%s'".formatted(settings.getStore().getOutDir());
SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sessionFactory, LS.getCommand(), expression);
return sftpOutboundGateway;
}
@Bean
public IntegrationFlow sftpOutboundListFlow(SessionFactory<ChannelSftp.LsEntry> sessionFactory, ExportDBFServiceSettings settings) {
return IntegrationFlows.from("listSftpChannel")
.handle(new SftpOutboundGateway(sessionFactory, "ls", "payload")
).get();
}
}

View file

@ -3,6 +3,43 @@ package ru.spcex.clearing.dbf.exporter.config.settings;
public class Store {
private String outDir;
private String localTempDir;
private String user;
private String password;
private String serverIp;
private int serverPort;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getServerIp() {
return serverIp;
}
public void setServerIp(String serverIp) {
this.serverIp = serverIp;
}
public int getServerPort() {
return serverPort;
}
public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}
public String getOutDir() {
return outDir;
@ -11,4 +48,12 @@ public class Store {
public void setOutDir(String outDir) {
this.outDir = outDir;
}
public String getLocalTempDir() {
return localTempDir;
}
public void setLocalTempDir(String localTempDir) {
this.localTempDir = localTempDir;
}
}

View file

@ -1,37 +0,0 @@
package ru.spcex.clearing.dbf.exporter.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import ru.spcex.clearing.dbf.exporter.services.DBFExportService;
@Controller("/")
public class ExporterController implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final DBFExportService dbfExportService;
public ExporterController(@Qualifier("dbfExportService") DBFExportService dbfExportService) {
this.dbfExportService = dbfExportService;
}
@RequestMapping(method = RequestMethod.GET, path = "/export", produces = MediaType.TEXT_PLAIN_VALUE)
@ResponseBody
public String exportTables() {
log.info("Call export method for exporter controller");
dbfExportService.run();
return "export done";
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("controller started");
}
}

View file

@ -4,6 +4,7 @@ import ru.spcex.clearing.dbf.exporter.logic.data.enums.StageResult;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
import java.io.File;
import java.time.LocalDateTime;
import java.util.UUID;
/**
@ -15,6 +16,8 @@ public class ResultContainer {
private File fileForExport;
private Long groupId;
private StageResult lastStageResult;
private LocalDateTime registrationDateTime;
private String mamberCode;
protected ResultContainer() {}
@ -64,4 +67,20 @@ public class ResultContainer {
public void setLastStageResult(StageResult lastStageResult) {
this.lastStageResult = lastStageResult;
}
public LocalDateTime getRegistrationDateTime() {
return registrationDateTime;
}
public void setRegistrationDateTime(LocalDateTime registrationDateTime) {
this.registrationDateTime = registrationDateTime;
}
public String getMamberCode() {
return mamberCode;
}
public void setMamberCode(String mamberCode) {
this.mamberCode = mamberCode;
}
}

View file

@ -0,0 +1,108 @@
package ru.spcex.clearing.dbf.exporter.logic.data.enums;
import org.springframework.integration.sftp.session.SftpFileInfo;
import ru.spcex.clearing.dbf.exporter.logic.data.ResultContainer;
import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Locale;
import static ru.spcex.clearing.dbf.exporter.logic.stages.PrepareDBFFile.SECTION;
import static ru.spcex.clearing.dbf.exporter.logic.stages.PrepareDBFFile.outDir;
public enum FilenameTemplate {
df_section_dateTime {
@Override
public String getFileName(ResultContainer resultContainer, List<SftpFileInfo> files) {
return appendSection(resultContainer)
.append(dateTime(resultContainer))
.append(".DBF").toString();
}
},
df_section_dateTime_counter {
@Override
public String getFileName(ResultContainer resultContainer, List<SftpFileInfo> files) {
return appendSection(resultContainer)
.append(dateTime(resultContainer))
.append(counter(resultContainer, files))
.append(".DBF").toString();
}
},
df_section_dateTime_counter_mamberCode {
@Override
public String getFileName(ResultContainer resultContainer, List<SftpFileInfo> files) {
return appendSection(resultContainer)
.append(dateTime(resultContainer))
.append(counter(resultContainer, files))
.append(mamberCode(resultContainer))
.append(".DBF").toString();
}
};
protected StringBuilder appendSection(ResultContainer resultContainer) {
StringBuilder result = new StringBuilder();
result.append(outDir);
result.append(File.separator);
result.append(resultContainer.getTableForExport().getFilePrefix().toUpperCase(Locale.ROOT));
result.append('_');
result.append(SECTION);
return result;
}
protected StringBuilder dateTime(ResultContainer resultContainer) {
StringBuilder result = new StringBuilder();
result.append('_');
result.append("PRC");
result.append(tsFormatter.format(resultContainer.getRegistrationDateTime()));
return result;
}
protected StringBuilder counter(ResultContainer resultContainer, List<SftpFileInfo> files) {
StringBuilder result = new StringBuilder();
result.append('_');
result.append(countSameFilesInDir(resultContainer.getTableForExport().getFilePrefix(), files) + 1);
return result;
}
protected StringBuilder mamberCode(ResultContainer resultContainer) {
StringBuilder result = new StringBuilder();
result.append('_');
result.append(resultContainer.getMamberCode());
return result;
}
protected Integer countSameFilesInDir(String prefixOfTable, List<SftpFileInfo> files) {
int res = 0;
String timestampNow = utilFormatter.format(LocalDateTime.now());
for (SftpFileInfo file : files) {
if (file.isDirectory()) continue;
String name = file.getFilename();
String[] splitName = name.split("_");
if (splitName.length < 3)
throw new IllegalArgumentException("Filename did not contains 3 or 4 separator \"_\": " + name);
String prefix = splitName[0];
String timestamp = splitName[2];
if (prefix.equalsIgnoreCase(prefixOfTable) && timestamp.contains(timestampNow)) {
if (splitName.length < 4)
throw new IllegalArgumentException("Filename did not contains 4 separator \"_\": " + name);
String counter = splitName[3];
int positionOfDot = counter.indexOf('.');
if (positionOfDot != -1) {
counter = counter.substring(0, positionOfDot);
}
res = Integer.max(res, Integer.parseInt(counter));
}
}
return res;
}
private static final DateTimeFormatter tsFormatter = DateTimeFormatter.ofPattern("yyMMddHHmm");
private static final DateTimeFormatter utilFormatter = DateTimeFormatter.ofPattern("yyMMdd");
public String getFileName(ResultContainer resultContainer, List<SftpFileInfo> files) {
return null;
}
}

View file

@ -7,11 +7,13 @@ import ru.spcex.platform.classes.base.SpcexObjectBase;
public enum Table {
S_DF02("DF-02", IMDGDistributedNames.Map_SDf02, SDf02.class),
S_DF03("DF-03", IMDGDistributedNames.Map_SDf03, SDf03.class),
S_DF08("DF-08", IMDGDistributedNames.Map_SDf08, SDf08.class),
S_DF11("DF-11", IMDGDistributedNames.Map_SDf11, SDf11.class),
S_DF18("DF-18", IMDGDistributedNames.Map_SDf18, SDf18.class),
S_DF10("DF-10", IMDGDistributedNames.Map_SDf10, SDf10.class),
S_DF17("DF-17", IMDGDistributedNames.Map_SDf17, SDf17.class);
S_DF05("DF-05", IMDGDistributedNames.Map_SDf05, SDf05.class),
S_DF07("DF-07", IMDGDistributedNames.Map_SDf07, SDf07.class),
S_DF51("DF-51", IMDGDistributedNames.Map_SDf51, SDf51.class),
S_DF53("DF-53", IMDGDistributedNames.Map_SDf53, SDf53.class),
S_DF54("DF-54", IMDGDistributedNames.Map_SDf54, SDf54.class),
S_DF56("DF-56", IMDGDistributedNames.Map_SDf56, SDf56.class);
/**
* Префикс имени файла для экспорта

View file

@ -3,9 +3,9 @@ package ru.spcex.clearing.dbf.exporter.logic.stages;
import com.linuxense.javadbf.DBFField;
import com.linuxense.javadbf.DBFWriter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.sdf.*;
import ru.spcex.clearing.dbf.exporter.config.SFTPConfig;
import ru.spcex.clearing.dbf.exporter.config.settings.ExportDBFServiceSettings;
import ru.spcex.clearing.dbf.exporter.exceptions.ConfigException;
import ru.spcex.clearing.dbf.exporter.logic.data.ResultContainer;
@ -30,36 +30,42 @@ import java.util.Objects;
public class ExportFromHazelcast extends Stage implements InitializingBean {
private final ExportDBFServiceSettings settings;
private final ImdgProvider imdgProvider;
private final SFTPConfig.DbfGateway gateway;
private final S_DF02_Converter s_df02_converter;
private final S_DF03_Converter s_df03_converter;
private final S_DF08_Converter s_df08_converter;
private final S_DF11_Converter s_df11_converter;
private final S_DF18_Converter s_df18_converter;
private final S_DF10_Converter s_df10_converter;
private final S_DF17_Converter s_df17_converter;
private final S_DF05_Converter s_df05_converter;
private final S_DF07_Converter s_df07_converter;
private final S_DF51_Converter s_df51_converter;
private final S_DF53_Converter s_df53_converter;
private final S_DF54_Converter s_df54_converter;
private final S_DF56_Converter s_df56_converter;
private final Map<Table, DBFField[]> dbfFieldsForTable = new HashMap<>();
private Charset dbfCharset;
public ExportFromHazelcast(ExportDBFServiceSettings settings,
@Qualifier("imdgProvider") ImdgProvider imdgProvider,
ImdgProvider imdgProvider,
SFTPConfig.DbfGateway gateway,
S_DF02_Converter s_df02_converter,
S_DF03_Converter s_df03_converter,
S_DF08_Converter s_df08_converter,
S_DF11_Converter s_df11_converter,
S_DF18_Converter s_df18_converter,
S_DF10_Converter s_df10_converter,
S_DF17_Converter s_df17_converter) {
S_DF07_Converter s_df07_converter,
S_DF05_Converter s_df05_converter,
S_DF51_Converter s_df51_converter,
S_DF54_Converter s_df54_converter,
S_DF53_Converter s_df53_converter,
S_DF56_Converter s_df56_converter) {
this.settings = settings;
this.imdgProvider = imdgProvider;
this.gateway = gateway;
this.s_df02_converter = s_df02_converter;
this.s_df03_converter = s_df03_converter;
this.s_df08_converter = s_df08_converter;
this.s_df11_converter = s_df11_converter;
this.s_df18_converter = s_df18_converter;
this.s_df10_converter = s_df10_converter;
this.s_df17_converter = s_df17_converter;
this.s_df07_converter = s_df07_converter;
this.s_df05_converter = s_df05_converter;
this.s_df51_converter = s_df51_converter;
this.s_df54_converter = s_df54_converter;
this.s_df53_converter = s_df53_converter;
this.s_df56_converter = s_df56_converter;
}
@Override
@ -89,13 +95,15 @@ public class ExportFromHazelcast extends Stage implements InitializingBean {
Object[] values;
if (value instanceof SDf02 sDf02Value) values = s_df02_converter.toObjectArray(sDf02Value);
else if (value instanceof SDf03 sDf03Value) values = s_df03_converter.toObjectArray(sDf03Value);
else if (value instanceof SDf08 sDf08Value) values = s_df08_converter.toObjectArray(sDf08Value);
else if (value instanceof SDf11 sDf11Value) values = s_df11_converter.toObjectArray(sDf11Value);
else if (value instanceof SDf18 sDf18Value) values = s_df18_converter.toObjectArray(sDf18Value);
else if (value instanceof SDf10 sDf10Value) values = s_df10_converter.toObjectArray(sDf10Value);
else if (value instanceof SDf17 sDf17Value) values = s_df17_converter.toObjectArray(sDf17Value);
else if (value instanceof SDf05 sDf05Value) values = s_df05_converter.toObjectArray(sDf05Value);
else if (value instanceof SDf07 sDf07Value) values = s_df07_converter.toObjectArray(sDf07Value);
else if (value instanceof SDf51 sDf51Value) values = s_df51_converter.toObjectArray(sDf51Value);
else if (value instanceof SDf53 sDf53Value) values = s_df53_converter.toObjectArray(sDf53Value);
else if (value instanceof SDf54 sDf54Value) values = s_df54_converter.toObjectArray(sDf54Value);
else if (value instanceof SDf56 sDf56Value) values = s_df56_converter.toObjectArray(sDf56Value);
else throw new Exception("Get unknown object from imdg. Class: " + value.getClass().getSimpleName());
dbfWriter.addRecord(values);
gateway.sendToSftp(dbfFile);
}
writeOk = true;
emptyMap = tableRows.isEmpty();
@ -131,11 +139,12 @@ public class ExportFromHazelcast extends Stage implements InitializingBean {
private void initExportFileStructure() {
dbfFieldsForTable.put(Table.S_DF02, s_df02_converter.getDBFHeaders());
dbfFieldsForTable.put(Table.S_DF03, s_df03_converter.getDBFHeaders());
dbfFieldsForTable.put(Table.S_DF08, s_df08_converter.getDBFHeaders());
dbfFieldsForTable.put(Table.S_DF18, s_df18_converter.getDBFHeaders());
dbfFieldsForTable.put(Table.S_DF10, s_df10_converter.getDBFHeaders());
dbfFieldsForTable.put(Table.S_DF11, s_df11_converter.getDBFHeaders());
dbfFieldsForTable.put(Table.S_DF17, s_df17_converter.getDBFHeaders());
dbfFieldsForTable.put(Table.S_DF05, s_df05_converter.getDBFHeaders());
dbfFieldsForTable.put(Table.S_DF07, s_df07_converter.getDBFHeaders());
dbfFieldsForTable.put(Table.S_DF51, s_df51_converter.getDBFHeaders());
dbfFieldsForTable.put(Table.S_DF53, s_df53_converter.getDBFHeaders());
dbfFieldsForTable.put(Table.S_DF54, s_df54_converter.getDBFHeaders());
dbfFieldsForTable.put(Table.S_DF56, s_df56_converter.getDBFHeaders());
}
private void initDBFCharset() {

View file

@ -11,25 +11,25 @@ import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
import ru.spcex.clearing.platform.messaging.domain.cud.system.JournalSdf;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import java.time.LocalDate;
import java.time.LocalTime;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.EnumMap;
import java.util.Map;
import java.util.function.Supplier;
import static ru.spcex.clearing.platform.messaging.domain.Consts.EXPORT_COMPLETED;
@Component
public class Journal extends Stage implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final KafkaSender kafkaSender;
private final Supplier<KafkaSender> kafkaSender;
@Autowired(required = false)
public Journal(KafkaSender kafkaSender) {
@Autowired
public Journal(Supplier<KafkaSender> kafkaSender) {
this.kafkaSender = kafkaSender;
}
public Journal() {
this.kafkaSender = null;
}
@Override
public boolean skipCompleted() {
return false;
@ -43,13 +43,21 @@ public class Journal extends Stage implements InitializingBean {
}
JournalSdf journalSdf = new JournalSdf();
//todo read file attibutes
journalSdf.setRegistrationDate(LocalDate.now());
journalSdf.setRegistrationTime(LocalTime.now());
journalSdf.setRegistrationDate(resultContainer.getRegistrationDateTime().toLocalDate());
journalSdf.setRegistrationTime(resultContainer.getRegistrationDateTime().toLocalTime());
journalSdf.setRegistrationNumber(resultContainer.getGroupId());
journalSdf.setDocumentName(documentNames.get(resultContainer.getTableForExport()));
journalSdf.setDossierNumber(dossierNumber.get(resultContainer.getTableForExport()));
journalSdf.setResultStatus(StageResult.ERROR.equals(resultContainer.getLastStageResult()) ? "NACK" : "ACK");
// kafkaSender.sendRequestToQueue();
kafkaSender.get().sendRequestToQueue(EXPORT_COMPLETED, journalSdf);
//удалим временный файл
File dbfFile = resultContainer.getFileForExport();
try {
Files.deleteIfExists(dbfFile.toPath());
} catch (IOException e) {
throw new RuntimeException(e);
}
return StageResult.COMPLETE;
}
@ -61,23 +69,23 @@ public class Journal extends Stage implements InitializingBean {
static {
documentNames.put(Table.S_DF02, "Уведомлений об исполнении операции загрузки денежных средств или уведомление об ошибке");
documentNames.put(Table.S_DF03, "Сводное платёжное поручение по итогу проведения расчетов, направляемое в РО");
//documentNames.put(Table.S_DF05, "Уведомление о завершении расчетов в секции");
documentNames.put(Table.S_DF08, "Запрос остатков по всем счетам, направляемый в РО");
documentNames.put(Table.S_DF10, "Подтверждение о загрузке по поступлению на клиринговый счет");
documentNames.put(Table.S_DF11, "Распоряжение на списание с ТБС УК на Клиринговый счет (по итогам проведения расчетов по возврату депозита) / Распоряжение на списание с ТБС УК на Корреспонденский счет УК");
//documentNames.put(Table.S_DF13, "Распоряжение на списание денежных средств УК категории В (с клирингового счета)");
documentNames.put(Table.S_DF17, "Подтверждение о загрузке Уведомления о возврате ден.ср. по договору депозита");
documentNames.put(Table.S_DF05, "Уведомление о завершении расчетов в секции");
documentNames.put(Table.S_DF07, "Подтверждение о загрузке Уведомления о возврате ден.ср. по договору депозита");
documentNames.put(Table.S_DF51, "Запрос остатков по всем счетам, направляемый в РО");
documentNames.put(Table.S_DF53, "");
documentNames.put(Table.S_DF54, "Распоряжение на списание денежных средств УК категории В (с клирингового счета)");
documentNames.put(Table.S_DF56, "");
}
private static final Map<Table, String> dossierNumber = new EnumMap<>(Table.class);
static {
dossierNumber.put(Table.S_DF02, "07-50");
dossierNumber.put(Table.S_DF03, "07-51");
//dossierNumber.put(Table.S_DF05, "07-53");
dossierNumber.put(Table.S_DF08, "07-55");
dossierNumber.put(Table.S_DF10, "07-56");
dossierNumber.put(Table.S_DF11, "07-36");
//dossierNumber.put(Table.S_DF13, "07-48");
dossierNumber.put(Table.S_DF17, "07-58");
dossierNumber.put(Table.S_DF05, "07-53");
dossierNumber.put(Table.S_DF07, "07-58");
dossierNumber.put(Table.S_DF51, "07-55");
dossierNumber.put(Table.S_DF53, "");
dossierNumber.put(Table.S_DF54, "07-48");
dossierNumber.put(Table.S_DF56, "");
}
}

View file

@ -1,9 +1,12 @@
package ru.spcex.clearing.dbf.exporter.logic.stages;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.sftp.session.SftpFileInfo;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.dbf.exporter.config.SFTPConfig;
import ru.spcex.clearing.dbf.exporter.config.settings.ExportDBFServiceSettings;
import ru.spcex.clearing.dbf.exporter.logic.data.ResultContainer;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.FilenameTemplate;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.StageResult;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
@ -12,8 +15,9 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
@ -21,23 +25,25 @@ import java.util.Objects;
*/
@Component
public class PrepareDBFFile extends Stage implements InitializingBean {
private static final String SECTION = "U";
private static final String CODE_OF_MEMBER = null;
private static final DateTimeFormatter tsFormatter = DateTimeFormatter.ofPattern("yyMMddHHmm");
private static final DateTimeFormatter utilFormatter = DateTimeFormatter.ofPattern("yyMMdd");
public static final String SECTION = "S";
private final ExportDBFServiceSettings settings;
private String outDir;
public static String outDir;
private final SFTPConfig.DbfGateway gateway;
public PrepareDBFFile(ExportDBFServiceSettings settings) {
public PrepareDBFFile(ExportDBFServiceSettings settings, SFTPConfig.DbfGateway gateway) {
this.settings = settings;
this.gateway = gateway;
}
@Override
public StageResult process(ResultContainer resultContainer) {
Objects.requireNonNull(resultContainer.getTableForExport());
List<SftpFileInfo> files = gateway.listFiles(settings.getStore().getOutDir());
log.debug("From sFTP dir \"{}\" list {} file names.", settings.getStore().getOutDir(), files.size());
Table table = resultContainer.getTableForExport();
File dbfFile = new File(prepareFilename(table, SECTION, CODE_OF_MEMBER, outDir));
LocalDateTime currentDateTime = LocalDateTime.now();
resultContainer.setRegistrationDateTime(currentDateTime);
File dbfFile = new File(nameTemplates.get(table).getFileName(resultContainer, files));
try {
Path dbfFilePath = dbfFile.toPath();
Files.deleteIfExists(dbfFilePath);
@ -53,58 +59,25 @@ public class PrepareDBFFile extends Stage implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
String outDirPath = settings.getStore().getOutDir();
String outDirPath = settings.getStore().getLocalTempDir();
File outDirFile = new File(outDirPath);
if (outDirFile.exists() && !outDirFile.isDirectory())
throw new IOException("Output directory " + outDirPath + " is file.");
if (!outDirFile.exists()) Files.createDirectories(outDirFile.toPath());
this.outDir = outDirPath;
log.info("Output directory: {}", outDirFile.getAbsolutePath());
}
private String prepareFilename(Table table, String section, String codeOfMember, String outDir) {
StringBuilder result = new StringBuilder();
String prefixOfTable = table.getFilePrefix();
String time = "PRC" + tsFormatter.format(LocalDateTime.now());
private static final Map<Table, FilenameTemplate> nameTemplates = new EnumMap<>(Table.class);
result.append(outDir);
result.append(File.separator);
result.append(prefixOfTable.toUpperCase(Locale.ROOT));
result.append('_');
result.append(section);
result.append('_');
result.append(time);
result.append('_');
result.append(countSameFilesInDir(prefixOfTable, outDir) + 1);
if (codeOfMember != null) {
result.append('_');
result.append(codeOfMember);
}
result.append(".DBF");
return result.toString();
}
private Integer countSameFilesInDir(String prefixOfTable, String outDir) {
int res = 0;
File directory = new File(outDir);
if (directory.exists()) {
for (File file : Objects.requireNonNull(directory.listFiles())) {
String name = file.getName();
String[] splitName = name.split("_");
String prefix = splitName[0];
String timestamp = splitName[2];
String timestampNow = utilFormatter.format(LocalDateTime.now());
if (prefix.equalsIgnoreCase(prefixOfTable) && timestamp.contains(timestampNow)) {
String counter = splitName[3];
int positionOfDot = counter.indexOf('.');
if (positionOfDot != -1) {
counter = counter.substring(0, positionOfDot);
}
res = Integer.max(res, Integer.parseInt(counter));
}
}
}
return res;
static {
nameTemplates.put(Table.S_DF02, FilenameTemplate.df_section_dateTime_counter);
nameTemplates.put(Table.S_DF03, FilenameTemplate.df_section_dateTime_counter);
nameTemplates.put(Table.S_DF05, FilenameTemplate.df_section_dateTime);
nameTemplates.put(Table.S_DF07, FilenameTemplate.df_section_dateTime_counter);
nameTemplates.put(Table.S_DF51, FilenameTemplate.df_section_dateTime_counter);
nameTemplates.put(Table.S_DF53, FilenameTemplate.df_section_dateTime_counter);
nameTemplates.put(Table.S_DF54, FilenameTemplate.df_section_dateTime_counter);
nameTemplates.put(Table.S_DF56, FilenameTemplate.df_section_dateTime_counter);
}
}

View file

@ -35,12 +35,30 @@ public class CommandService extends QueueConsumer implements InitializingBean {
callback(ExportToFileRequest.class)
.setConsumer(this::process)
.forDestination(Consts.EXPORT_PROCESS, callbacks::put);
callback(SdfClearingRequest.class)
.setConsumer(r -> processSpecial(Table.S_DF02, r))
.forDestination(Consts.SDF02_PROCESS, callbacks::put);
callback(SdfClearingRequest.class)
.setConsumer(r -> processSpecial(Table.S_DF03, r)) // todo необходимо в отдельную папку: "в отдельную директорию SettlementHouse_Fail (чтобы не отдавать такие файлы в ПРЦ"
.forDestination(Consts.SDF03_PROCESS, callbacks::put);
callback(SdfClearingRequest.class)
.setConsumer(r -> processSpecial(Table.S_DF11, r))
.forDestination(Consts.SDF11_PROCESS, callbacks::put);
.setConsumer(r -> processSpecial(Table.S_DF05, r))
.forDestination(Consts.SDF05_PROCESS, callbacks::put);
callback(SdfClearingRequest.class)
.setConsumer(r -> processSpecial(Table.S_DF07, r))
.forDestination(Consts.SDF07_PROCESS, callbacks::put);
callback(SdfClearingRequest.class)
.setConsumer(r -> processSpecial(Table.S_DF51, r))
.forDestination(Consts.SDF51_PROCESS, callbacks::put);
callback(SdfClearingRequest.class)
.setConsumer(r -> processSpecial(Table.S_DF53, r))
.forDestination(Consts.SDF53_PROCESS, callbacks::put);
callback(SdfClearingRequest.class)
.setConsumer(r -> processSpecial(Table.S_DF54, r))
.forDestination(Consts.SDF54_PROCESS, callbacks::put);
callback(SdfClearingRequest.class)
.setConsumer(r -> processSpecial(Table.S_DF56, r))
.forDestination(Consts.SDF56_PROCESS, callbacks::put);
init();
}

View file

@ -1,40 +0,0 @@
package ru.spcex.clearing.dbf.exporter.services;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import ru.spcex.clearing.dbf.exporter.logic.Processor;
import ru.spcex.clearing.dbf.exporter.logic.data.ResultContainer;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.util.Arrays;
@Service("dbfExportService")
public class DBFExportService {
Logger log = LoggerFactory.getLogger(getClass());
private final ThreadPoolTaskExecutor executor;
private final Processor processor;
protected final ImdgProvider imdgProvider;
public DBFExportService(@Qualifier("executor") ThreadPoolTaskExecutor executor,
@Qualifier("processor") Processor processor,
ImdgProvider imdgProvider) {
this.executor = executor;
this.processor = processor;
this.imdgProvider = imdgProvider;
log.debug("Check IMDG...");
imdgProvider.waitAvailable();
log.debug("IMDG ready...");
}
public void run() {
log.debug("Do export for all: {}", Arrays.toString(Table.values()));
for (Table tableForExport : Table.values()) {
executor.submit(() -> processor.process(ResultContainer.createNewTask(tableForExport)));
}
}
}

View file

@ -3,6 +3,7 @@ package ru.spcex.clearing.dbf.exporter.services.converters;
import com.linuxense.javadbf.DBFField;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
@ -25,4 +26,14 @@ public abstract class DFConverter<T extends SpcexObjectBase> {
if (src instanceof LocalTime srcLocalTime) return Time.valueOf(srcLocalTime);
return src;
}
protected Long convertStrToLong(String s) {
if (s == null) return null;
return Long.valueOf(s);
}
protected BigDecimal convertStrToBigDecimal(String s) {
if (s == null) return null;
return new BigDecimal(s).setScale(0);
}
}

View file

@ -43,7 +43,7 @@ public class S_DF02_Converter extends DFConverter<SDf02> {
dbfFields.add(new DBFField("ACC_TYPE", DBFDataType.CHARACTER, 2));
dbfFields.add(new DBFField("SUMENGAGE", DBFDataType.CHARACTER, 22));
dbfFields.add(new DBFField("SUMUNBLOCK", DBFDataType.CHARACTER, 22));
dbfFields.add(new DBFField("FILE_TYPE", DBFDataType.CHARACTER, 22));
dbfFields.add(new DBFField("FILE_TYPE", DBFDataType.CHARACTER, 1));
dbfFields.add(new DBFField("RESULT", DBFDataType.CHARACTER, 3));
return dbfFields.toArray(DBFField[]::new);
}

View file

@ -17,15 +17,12 @@ public class S_DF03_Converter extends DFConverter<SDf03> {
values.add(typeMatch(entity.getDoc_type()));
values.add(typeMatch(entity.getDocnm_ref()));
values.add(typeMatch(entity.getDocnmprev()));
// values.add(typeMatch(entity.getPriority()));
// values.add(typeMatch(entity.getSbankcode()));
values.add(typeMatch(entity.getC_acc_deb()));
values.add(typeMatch(entity.getSbanknam1()));
values.add(typeMatch(entity.getSbanknam2()));
values.add(typeMatch(entity.getSbanknam3()));
values.add(typeMatch(entity.getSbanknam4()));
values.add(typeMatch(entity.getSbanknam5()));
// values.add(typeMatch(entity.getRbankcode()));
values.add(typeMatch(entity.getC_acc_cred()));
values.add(typeMatch(entity.getRbanknam1()));
values.add(typeMatch(entity.getRbanknam2()));
@ -33,31 +30,9 @@ public class S_DF03_Converter extends DFConverter<SDf03> {
values.add(typeMatch(entity.getRbanknam4()));
values.add(typeMatch(entity.getRbanknam5()));
values.add(typeMatch(entity.getPay_date()));
// values.add(typeMatch(entity.getExt_date()));
values.add(typeMatch(entity.getPay_val()));
values.add(typeMatch(entity.getSum_deb()));
// values.add(typeMatch(entity.getSclientn1()));
// values.add(typeMatch(entity.getSclientn2()));
// values.add(typeMatch(entity.getSclientn3()));
// values.add(typeMatch(entity.getSclientn4()));
// values.add(typeMatch(entity.getSc_code()));
// values.add(typeMatch(entity.getAcc_deb()));
// values.add(typeMatch(entity.getRclientn1()));
// values.add(typeMatch(entity.getRclientn2()));
// values.add(typeMatch(entity.getRclientn3()));
// values.add(typeMatch(entity.getRclientn4()));
// values.add(typeMatch(entity.getAcc_kr_1()));
// values.add(typeMatch(entity.getAcc_kr_2()));
// values.add(typeMatch(entity.getSp_code()));
values.add(typeMatch(entity.getSpecif_1()));
// values.add(typeMatch(entity.getSpecif_2()));
// values.add(typeMatch(entity.getSpecif_3()));
// values.add(typeMatch(entity.getSpecif_4()));
// values.add(typeMatch(entity.getSpecif_5()));
// values.add(typeMatch(entity.getSpecif_6()));
// values.add(typeMatch(entity.getSend_type()));
// values.add(typeMatch(entity.getServdate()));
// values.add(typeMatch(entity.getDoc_result()));
values.add(typeMatch(entity.getImp_result()));
return values.toArray(Object[]::new);
}
@ -69,15 +44,12 @@ public class S_DF03_Converter extends DFConverter<SDf03> {
dbfFields.add(new DBFField("DOC_TYPE", DBFDataType.CHARACTER, 4));
dbfFields.add(new DBFField("DOCNM_REF", DBFDataType.CHARACTER, 16));
dbfFields.add(new DBFField("DOCNMPREV", DBFDataType.CHARACTER, 16));
dbfFields.add(new DBFField("PRIORITY", DBFDataType.CHARACTER, 1));
dbfFields.add(new DBFField("SBANKCODE", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("C_ACC_DEB", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM5", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKCODE", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("C_ACC_CRED", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM2", DBFDataType.CHARACTER, 35));
@ -85,31 +57,9 @@ public class S_DF03_Converter extends DFConverter<SDf03> {
dbfFields.add(new DBFField("RBANKNAM4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM5", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("PAY_DATE", DBFDataType.CHARACTER, 8));
dbfFields.add(new DBFField("EXT_DATE", DBFDataType.CHARACTER, 8));
dbfFields.add(new DBFField("PAY_VAL", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("SUM_DEB", DBFDataType.CHARACTER, 22));
dbfFields.add(new DBFField("SCLIENTN1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SCLIENTN2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SCLIENTN3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SCLIENTN4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SC_CODE", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("ACC_DEB", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RCLIENTN1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RCLIENTN2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RCLIENTN3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RCLIENTN4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("ACC_KR_1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("ACC_KR_2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SP_CODE", DBFDataType.CHARACTER, 2));
dbfFields.add(new DBFField("SPECIF_1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SPECIF_2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SPECIF_3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SPECIF_4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SPECIF_5", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SPECIF_6", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SEND_TYPE", DBFDataType.CHARACTER, 10));
dbfFields.add(new DBFField("SERVDATE", DBFDataType.CHARACTER, 8));
dbfFields.add(new DBFField("DOC_RESULT", DBFDataType.CHARACTER, 2));
dbfFields.add(new DBFField("SPECIF_1", DBFDataType.CHARACTER, 254));
dbfFields.add(new DBFField("IMP_RESULT", DBFDataType.CHARACTER, 3));
return dbfFields.toArray(DBFField[]::new);
}

View file

@ -0,0 +1,35 @@
package ru.spcex.clearing.dbf.exporter.services.converters;
import com.linuxense.javadbf.DBFDataType;
import com.linuxense.javadbf.DBFField;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.sdf.SDf05;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
@Service
public class S_DF05_Converter extends DFConverter<SDf05> {
@Override
public Object[] toObjectArray(SDf05 entity) {
List<Object> values = new LinkedList<>();
values.add(typeMatch(entity.getTp()));
values.add(typeMatch(entity.getDt()));
values.add(typeMatch(entity.getTm()));
values.add(typeMatch(entity.getPr()));
return values.toArray(Object[]::new);
}
@Override
public DBFField[] getDBFHeaders() {
List<DBFField> dbfFields = new LinkedList<>();
Date date = new Date();
dbfFields.add(new DBFField("TP", DBFDataType.NUMERIC, 32, 18));
dbfFields.add(new DBFField("DT", DBFDataType.DATE));
dbfFields.add(new DBFField("TM", DBFDataType.DATE));
dbfFields.add(new DBFField("PR", DBFDataType.CHARACTER, 1));
return dbfFields.toArray(DBFField[]::new);
}
}

View file

@ -3,20 +3,22 @@ package ru.spcex.clearing.dbf.exporter.services.converters;
import com.linuxense.javadbf.DBFDataType;
import com.linuxense.javadbf.DBFField;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.sdf.SDf17;
import ru.clearing.classes.statics.data.sdf.SDf07;
import java.util.LinkedList;
import java.util.List;
@Service
public class S_DF17_Converter extends DFConverter<SDf17> {
public class S_DF07_Converter extends DFConverter<SDf07> {
@Override
public Object[] toObjectArray(SDf17 entity) {
public Object[] toObjectArray(SDf07 entity) {
List<Object> values = new LinkedList<>();
values.add(typeMatch(entity.getAccount()));
values.add(typeMatch(entity.getSum()));
values.add(typeMatch(entity.getMarket()));
values.add(typeMatch(entity.getType()));
values.add(typeMatch(entity.getDeal()));
values.add(typeMatch(entity.getClientN()));
values.add(typeMatch(entity.getInn()));
values.add(typeMatch(entity.getBic()));
values.add(typeMatch(entity.getSpec()));
@ -32,11 +34,13 @@ public class S_DF17_Converter extends DFConverter<SDf17> {
dbfFields.add(new DBFField("SUM", DBFDataType.NUMERIC, 32, 18));
dbfFields.add(new DBFField("MARKET", DBFDataType.CHARACTER, 1));
dbfFields.add(new DBFField("TYPE", DBFDataType.CHARACTER, 1));
dbfFields.add(new DBFField("DEAL", DBFDataType.CHARACTER, 10));
dbfFields.add(new DBFField("CLIENT_N", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("_I_N_N", DBFDataType.NUMERIC, 32, 18));
dbfFields.add(new DBFField("_B_I_C", DBFDataType.NUMERIC, 32, 18));
dbfFields.add(new DBFField("_S_P_E_C", DBFDataType.CHARACTER, 254));
dbfFields.add(new DBFField("NUMBER", DBFDataType.NUMERIC, 32, 18));
dbfFields.add(new DBFField("RESULT", DBFDataType.NUMERIC, 1));
dbfFields.add(new DBFField("RESULT", DBFDataType.NUMERIC, 32, 18));
return dbfFields.toArray(DBFField[]::new);
}

View file

@ -1,39 +0,0 @@
package ru.spcex.clearing.dbf.exporter.services.converters;
import com.linuxense.javadbf.DBFDataType;
import com.linuxense.javadbf.DBFField;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.sdf.SDf10;
import java.util.LinkedList;
import java.util.List;
@Service
public class S_DF10_Converter extends DFConverter<SDf10> {
@Override
public Object[] toObjectArray(SDf10 entity) {
List<Object> values = new LinkedList<>();
// values.add(typeMatch(entity.getAccount()));
// values.add(typeMatch(entity.getSum()));
// values.add(typeMatch(entity.getMarket()));
// values.add(typeMatch(entity.getType()));
// values.add(typeMatch(entity.getNumber()));
// values.add(typeMatch(entity.getInn()));
// values.add(typeMatch(entity.getResult()));
return values.toArray(Object[]::new);
}
@Override
public DBFField[] getDBFHeaders() {
List<DBFField> dbfFields = new LinkedList<>();
dbfFields.add(new DBFField("ACCOUNT", DBFDataType.CHARACTER, 20));
dbfFields.add(new DBFField("SUM", DBFDataType.NUMERIC, 32, 18));
dbfFields.add(new DBFField("MARKET", DBFDataType.CHARACTER, 1));
dbfFields.add(new DBFField("TYPE", DBFDataType.CHARACTER, 1));
dbfFields.add(new DBFField("NUMBER", DBFDataType.NUMERIC, 32, 18));
dbfFields.add(new DBFField("_I_N_N", DBFDataType.NUMERIC, 32, 18));
dbfFields.add(new DBFField("RESULT", DBFDataType.CHARACTER, 3));
return dbfFields.toArray(DBFField[]::new);
}
}

View file

@ -1,115 +0,0 @@
package ru.spcex.clearing.dbf.exporter.services.converters;
import com.linuxense.javadbf.DBFDataType;
import com.linuxense.javadbf.DBFField;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.sdf.SDf11;
import java.util.LinkedList;
import java.util.List;
@Service
public class S_DF11_Converter extends DFConverter<SDf11> {
@Override
public Object[] toObjectArray(SDf11 entity) {
List<Object> values = new LinkedList<>();
// values.add(typeMatch(entity.getSeg_type()));
// values.add(typeMatch(entity.getDoc_type()));
// values.add(typeMatch(entity.getDocnm_ref()));
// values.add(typeMatch(entity.getDocnmprev()));
// values.add(typeMatch(entity.getPriority()));
// values.add(typeMatch(entity.getSbankcode()));
// values.add(typeMatch(entity.getC_acc_deb()));
// values.add(typeMatch(entity.getSbanknam1()));
// values.add(typeMatch(entity.getSbanknam2()));
// values.add(typeMatch(entity.getSbanknam3()));
// values.add(typeMatch(entity.getSbanknam4()));
// values.add(typeMatch(entity.getSbanknam5()));
// values.add(typeMatch(entity.getRbankcode()));
// values.add(typeMatch(entity.getC_acc_cred()));
// values.add(typeMatch(entity.getRbanknam1()));
// values.add(typeMatch(entity.getRbanknam2()));
// values.add(typeMatch(entity.getRbanknam3()));
// values.add(typeMatch(entity.getRbanknam4()));
// values.add(typeMatch(entity.getRbanknam5()));
// values.add(typeMatch(entity.getPay_date()));
// values.add(typeMatch(entity.getExt_date()));
// values.add(typeMatch(entity.getPay_val()));
// values.add(typeMatch(entity.getSum_deb()));
// values.add(typeMatch(entity.getSclientn1()));
// values.add(typeMatch(entity.getSclientn2()));
// values.add(typeMatch(entity.getSclientn3()));
// values.add(typeMatch(entity.getSclientn4()));
// values.add(typeMatch(entity.getSc_code()));
// values.add(typeMatch(entity.getAcc_deb()));
// values.add(typeMatch(entity.getRclientn1()));
// values.add(typeMatch(entity.getRclientn2()));
// values.add(typeMatch(entity.getRclientn3()));
// values.add(typeMatch(entity.getRclientn4()));
// values.add(typeMatch(entity.getAcc_kr_1()));
// values.add(typeMatch(entity.getAcc_kr_2()));
// values.add(typeMatch(entity.getSp_code()));
// values.add(typeMatch(entity.getSpecif_1()));
// values.add(typeMatch(entity.getSpecif_2()));
// values.add(typeMatch(entity.getSpecif_3()));
// values.add(typeMatch(entity.getSpecif_4()));
// values.add(typeMatch(entity.getSpecif_5()));
// values.add(typeMatch(entity.getSpecif_6()));
// values.add(typeMatch(entity.getSend_type()));
// values.add(typeMatch(entity.getServdate()));
// values.add(typeMatch(entity.getDoc_result()));
return values.toArray(Object[]::new);
}
@Override
public DBFField[] getDBFHeaders() {
List<DBFField> dbfFields = new LinkedList<>();
dbfFields.add(new DBFField("SEG_TYPE", DBFDataType.CHARACTER, 1));
dbfFields.add(new DBFField("DOC_TYPE", DBFDataType.CHARACTER, 4));
dbfFields.add(new DBFField("DOCNM_REF", DBFDataType.CHARACTER, 16));
dbfFields.add(new DBFField("DOCNMPREV", DBFDataType.CHARACTER, 16));
dbfFields.add(new DBFField("PRIORITY", DBFDataType.CHARACTER, 1));
dbfFields.add(new DBFField("SBANKCODE", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("C_ACC_DEB", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM5", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKCODE", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("C_ACC_CRED", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM5", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("PAY_DATE", DBFDataType.CHARACTER, 8));
dbfFields.add(new DBFField("EXT_DATE", DBFDataType.CHARACTER, 8));
dbfFields.add(new DBFField("PAY_VAL", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("SUM_DEB", DBFDataType.CHARACTER, 22));
dbfFields.add(new DBFField("SCLIENTN1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SCLIENTN2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SCLIENTN3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SCLIENTN4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SC_CODE", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("ACC_DEB", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RCLIENTN1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RCLIENTN2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RCLIENTN3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RCLIENTN4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("ACC_KR_1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("ACC_KR_2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SP_CODE", DBFDataType.CHARACTER, 2));
dbfFields.add(new DBFField("SPECIF_1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SPECIF_2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SPECIF_3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SPECIF_4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SPECIF_5", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SPECIF_6", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SEND_TYPE", DBFDataType.CHARACTER, 10));
dbfFields.add(new DBFField("SERVDATE", DBFDataType.CHARACTER, 8));
dbfFields.add(new DBFField("DOC_RESULT", DBFDataType.CHARACTER, 2));
return dbfFields.toArray(DBFField[]::new);
}
}

View file

@ -3,35 +3,30 @@ package ru.spcex.clearing.dbf.exporter.services.converters;
import com.linuxense.javadbf.DBFDataType;
import com.linuxense.javadbf.DBFField;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.sdf.SDf08;
import ru.clearing.classes.statics.data.sdf.SDf51;
import java.time.format.DateTimeFormatter;
import java.util.LinkedList;
import java.util.List;
@Service
public class S_DF08_Converter extends DFConverter<SDf08> {
public class S_DF51_Converter extends DFConverter<SDf51> {
@Override
public Object[] toObjectArray(SDf08 entity) {
public Object[] toObjectArray(SDf51 entity) {
List<Object> values = new LinkedList<>();
// values.add(convertStrToLong(entity.getNumber()));
// values.add(typeMatch(convertStrToLong(entity.getDatetime()))); // UNIX TIME
values.add(typeMatch(entity.getNumber()));
values.add(typeMatch(convertStrToLong(entity.getDatetime()))); // UNIX TIME
return values.toArray(Object[]::new);
}
@Override
public DBFField[] getDBFHeaders() {
List<DBFField> dbfFields = new LinkedList<>();
dbfFields.add(new DBFField("NUMBER", DBFDataType.NUMERIC, 10));
dbfFields.add(new DBFField("NUMBER", DBFDataType.CHARACTER, 10));
dbfFields.add(new DBFField("DATETIME", DBFDataType.NUMERIC, 13)); // UNIX TIME
return dbfFields.toArray(DBFField[]::new);
}
Long convertStrToLong(String s) {
if (s == null) return null;
return Long.valueOf(s);
}
private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("dd.MM.yyyy");
private static final DateTimeFormatter DATE_TIME_FMT = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");

View file

@ -3,22 +3,20 @@ package ru.spcex.clearing.dbf.exporter.services.converters;
import com.linuxense.javadbf.DBFDataType;
import com.linuxense.javadbf.DBFField;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.sdf.SDf18;
import ru.clearing.classes.statics.data.sdf.SDf53;
import java.util.LinkedList;
import java.util.List;
@Service
public class S_DF18_Converter extends DFConverter<SDf18> {
public class S_DF53_Converter extends DFConverter<SDf53> {
@Override
public Object[] toObjectArray(SDf18 entity) {
public Object[] toObjectArray(SDf53 entity) {
List<Object> values = new LinkedList<>();
values.add(typeMatch(entity.getAccount()));
values.add(typeMatch(entity.getDeal()));
values.add(typeMatch(entity.getStatus()));
values.add(typeMatch(entity.getResult()));
values.add(typeMatch(entity.getGenerationTime()));
values.add(typeMatch(entity.getGenerationId()));
return values.toArray(Object[]::new);
}
@ -29,8 +27,6 @@ public class S_DF18_Converter extends DFConverter<SDf18> {
dbfFields.add(new DBFField("DEAL", DBFDataType.CHARACTER, 4));
dbfFields.add(new DBFField("STATUS", DBFDataType.NUMERIC, 32, 18));
dbfFields.add(new DBFField("RESULT", DBFDataType.NUMERIC, 32, 18));
dbfFields.add(new DBFField("GEN_TIME", DBFDataType.DATE));
dbfFields.add(new DBFField("GEN_ID", DBFDataType.NUMERIC));
return dbfFields.toArray(DBFField[]::new);
}

View file

@ -0,0 +1,105 @@
package ru.spcex.clearing.dbf.exporter.services.converters;
import com.linuxense.javadbf.DBFDataType;
import com.linuxense.javadbf.DBFField;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.sdf.SDf54;
import java.util.LinkedList;
import java.util.List;
@Service
public class S_DF54_Converter extends DFConverter<SDf54> {
@Override
public Object[] toObjectArray(SDf54 entity) {
List<Object> values = new LinkedList<>();
values.add(typeMatch(entity.getSeg_type()));
values.add(typeMatch(entity.getDoc_type()));
values.add(typeMatch(entity.getDocnm_ref()));
values.add(typeMatch(entity.getDocnmprev()));
values.add(typeMatch(entity.getSbankcode()));
values.add(typeMatch(entity.getC_acc_deb()));
values.add(typeMatch(entity.getSbanknam1()));
values.add(typeMatch(entity.getSbanknam2()));
values.add(typeMatch(entity.getSbanknam3()));
values.add(typeMatch(entity.getSbanknam4()));
values.add(typeMatch(entity.getSbanknam5()));
values.add(typeMatch(entity.getRbankcode()));
values.add(typeMatch(entity.getC_acc_cred()));
values.add(typeMatch(entity.getRbanknam1()));
values.add(typeMatch(entity.getRbanknam2()));
values.add(typeMatch(entity.getRbanknam3()));
values.add(typeMatch(entity.getRbanknam4()));
values.add(typeMatch(entity.getRbanknam5()));
values.add(typeMatch(entity.getOp_type()));
values.add(typeMatch(entity.getOp_order()));
values.add(typeMatch(entity.getPay_date()));
values.add(typeMatch(entity.getPay_val()));
values.add(typeMatch(entity.getSum_deb()));
values.add(typeMatch(entity.getSclientn1()));
values.add(typeMatch(entity.getSclientn2()));
values.add(typeMatch(entity.getSclientn3()));
values.add(typeMatch(entity.getSclientn4()));
values.add(typeMatch(entity.getInn_deb()));
values.add(typeMatch(entity.getKpp_deb()));
values.add(typeMatch(entity.getAcc_deb()));
values.add(typeMatch(entity.getRclientn1()));
values.add(typeMatch(entity.getRclientn2()));
values.add(typeMatch(entity.getRclientn3()));
values.add(typeMatch(entity.getRclientn4()));
values.add(typeMatch(entity.getInn_cred()));
values.add(typeMatch(entity.getKpp_cred()));
values.add(typeMatch(entity.getAcc_kr_1()));
values.add(typeMatch(entity.getSpecif_1()));
values.add(typeMatch(entity.getSend_type()));
values.add(typeMatch(entity.getDoc_result()));
return values.toArray(Object[]::new);
}
@Override
public DBFField[] getDBFHeaders() {
List<DBFField> dbfFields = new LinkedList<>();
dbfFields.add(new DBFField("SEG_TYPE", DBFDataType.CHARACTER, 1));
dbfFields.add(new DBFField("DOC_TYPE", DBFDataType.CHARACTER, 13));
dbfFields.add(new DBFField("DOCNM_REF", DBFDataType.CHARACTER, 16));
dbfFields.add(new DBFField("DOCNMPREV", DBFDataType.CHARACTER, 16));
dbfFields.add(new DBFField("SBANKCODE", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("C_ACC_DEB", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SBANKNAM5", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKCODE", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("C_ACC_CRED", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RBANKNAM5", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("OP_TYPE", DBFDataType.CHARACTER, 2));
dbfFields.add(new DBFField("OP_ORDER", DBFDataType.CHARACTER, 1));
dbfFields.add(new DBFField("PAY_DATE", DBFDataType.CHARACTER, 8));
dbfFields.add(new DBFField("PAY_VAL", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("SUM_DEB", DBFDataType.CHARACTER, 22));
dbfFields.add(new DBFField("SCLIENTN1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SCLIENTN2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SCLIENTN3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SCLIENTN4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("INN_DEB", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("KPP_DEB", DBFDataType.CHARACTER, 9));
dbfFields.add(new DBFField("ACC_DEB", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RCLIENTN1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RCLIENTN2", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RCLIENTN3", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("RCLIENTN4", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("INN_CRED", DBFDataType.CHARACTER, 12));
dbfFields.add(new DBFField("KPP_CRED", DBFDataType.CHARACTER, 9));
dbfFields.add(new DBFField("ACC_KR1", DBFDataType.CHARACTER, 35));
dbfFields.add(new DBFField("SPECIF1", DBFDataType.CHARACTER, 254));
dbfFields.add(new DBFField("SEND_TYPE", DBFDataType.CHARACTER, 10));
dbfFields.add(new DBFField("DOC_RESULT", DBFDataType.CHARACTER, 2));
return dbfFields.toArray(DBFField[]::new);
}
}

View file

@ -0,0 +1,35 @@
package ru.spcex.clearing.dbf.exporter.services.converters;
import com.linuxense.javadbf.DBFDataType;
import com.linuxense.javadbf.DBFField;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.sdf.SDf56;
import java.util.LinkedList;
import java.util.List;
@Service
public class S_DF56_Converter extends DFConverter<SDf56> {
@Override
public Object[] toObjectArray(SDf56 entity) {
List<Object> values = new LinkedList<>();
values.add(typeMatch(entity.getNumber()));
values.add(convertStrToBigDecimal(entity.getStart_datetime())); // UNIX DATE TIME
values.add(convertStrToBigDecimal(entity.getEnd_datetime())); // UNIX DATE TIME
values.add(typeMatch(entity.getAccount()));
values.add(typeMatch(entity.getDeal()));
return values.toArray(Object[]::new);
}
@Override
public DBFField[] getDBFHeaders() {
List<DBFField> dbfFields = new LinkedList<>();
dbfFields.add(new DBFField("NUMBER", DBFDataType.CHARACTER, 10));
dbfFields.add(new DBFField("SDATETIME", DBFDataType.NUMERIC, 10));
dbfFields.add(new DBFField("EDATETIME", DBFDataType.NUMERIC, 10));
dbfFields.add(new DBFField("ACCOUNT", DBFDataType.CHARACTER, 25));
dbfFields.add(new DBFField("DEAL", DBFDataType.CHARACTER, 4));
return dbfFields.toArray(DBFField[]::new);
}
}

View file

@ -1,6 +1,4 @@
server.port=8080
server.servlet.context-path=/exporter
spring.main.web-application-type=servlet
spring.main.web-application-type=none
export-dbf-service.hazelcast.cluster-members=10.200.200.181:5701
export-dbf-service.hazelcast.login=dev
@ -9,7 +7,12 @@ export-dbf-service.hazelcast.password=dev-pass
export-dbf-service.common.encoding=cp866
export-dbf-service.common.threads-count=10
export-dbf-service.store.out-dir=d:\\trash\\clearing\\exporter\\out\\
export-dbf-service.store.local-temp-dir=D:\\docs and T3\\clearing\\dbf\\
export-dbf-service.store.out-dir=DocOut
export-dbf-service.store.user:tester
export-dbf-service.store.password=password
export-dbf-service.store.server-ip=10.230.238.53
export-dbf-service.store.server-port=2222
export-dbf-service.kafka-consumer.bootstrap-servers=localhost:9092
export-dbf-service.kafka-consumer.group-id=dev-group-balance-service
@ -18,3 +21,10 @@ export-dbf-service.kafka-consumer.session-timeout-ms=30000
export-dbf-service.kafka-consumer.auto-offset-reset=latest
export-dbf-service.kafka-consumer.linger-ms=1
export-dbf-service.kafka-consumer.buffer-memory=33554432
export-dbf-service.kafka-producer.bootstrap-servers=localhost:9092
export-dbf-service.kafka-producer.acks=all
export-dbf-service.kafka-producer.retries=0
export-dbf-service.kafka-producer.batch-size=16384
export-dbf-service.kafka-producer.linger-ms=1
export-dbf-service.kafka-producer.buffer-memory=33554432

View file

@ -0,0 +1,73 @@
package ru.spcex.clearing.dbf.exporter;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.spcex.clearing.dbf.exporter.config.ExportDBFServiceSettingsTest;
import ru.spcex.clearing.dbf.exporter.config.PipelineConfig;
import ru.spcex.clearing.dbf.exporter.config.SFTPTestConfig;
import ru.spcex.clearing.dbf.exporter.logic.Processor;
import ru.spcex.clearing.dbf.exporter.logic.stages.ExportFromHazelcast;
import ru.spcex.clearing.dbf.exporter.logic.stages.Journal;
import ru.spcex.clearing.dbf.exporter.logic.stages.PrepareDBFFile;
import ru.spcex.clearing.dbf.exporter.services.CommandService;
import ru.spcex.clearing.dbf.exporter.services.converters.*;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.nio.file.Path;
import java.nio.file.Paths;
import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
ExportDBFServiceSettingsTest.class,
SFTPTestConfig.class,
PipelineConfig.class,
ExportFromHazelcast.class,
Journal.class,
PrepareDBFFile.class,
Processor.class,
CommandService.class,
S_DF02_Converter.class,
S_DF03_Converter.class,
S_DF05_Converter.class,
S_DF07_Converter.class,
S_DF51_Converter.class,
S_DF53_Converter.class,
S_DF54_Converter.class,
S_DF56_Converter.class,
ImdgTestConfig.class,
KafkaTestConfig.class})
public abstract class AbstractServiceTest {
protected static final long generationId = 21L;
@Autowired
@Qualifier("kafkaTestTemplate")
protected KafkaTemplate<String, Object> kafkaTemplate;
@Autowired
@Qualifier("hazelcastServiceTest")
protected ImdgProvider imdgProvider;
@Autowired
protected CommandService commandService;
@BeforeAll
static void setProperty() {
Path path = Paths.get("src", "main", "resources");
String currentPath = path.toAbsolutePath().toString();
System.setProperty("spring.config.location", currentPath);
// Hazelcast.shutdownAll();
}
protected void init() {
waitAvailableImdgProviderAndAddAdminWithDefaultId();
}
}

View file

@ -0,0 +1,24 @@
package ru.spcex.clearing.dbf.exporter.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.dbf.exporter.config.settings.Common;
import ru.spcex.clearing.dbf.exporter.config.settings.ExportDBFServiceSettings;
import ru.spcex.clearing.dbf.exporter.config.settings.Store;
@Configuration
public class ExportDBFServiceSettingsTest {
@Bean
public ExportDBFServiceSettings settings(){
ExportDBFServiceSettings settings = new ExportDBFServiceSettings();
Common common = new Common();
common.setEncoding("cp866");
settings.setCommon(common);
Store store = new Store();
store.setOutDir("DocOut");
store.setLocalTempDir("D:\\docs and T3\\clearing\\dbf");
settings.setStore(store);
return settings;
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.dbf.exporter.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.sftp.session.SftpFileInfo;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class SFTPTestConfig {
@Bean
public SFTPConfig.DbfGateway dbfGateway(){
return new DGateway();
}
public static class DGateway implements SFTPConfig.DbfGateway{
@Override
public void sendToSftp(File file) {
}
@Override
public List<SftpFileInfo> listFiles(String dir) {
return new ArrayList<>();
}
}
}

View file

@ -0,0 +1,28 @@
package ru.spcex.clearing.dbf.exporter.logic.data.enums;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import org.junit.jupiter.api.Test;
import org.springframework.integration.sftp.session.SftpFileInfo;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;
class FilenameTemplateTest {
@Test
void countSameFilesInDir() {
LsEntry lsEntry = mock(LsEntry.class);
doReturn("DF-02_S_PRC2305191321_1.DBF").when(lsEntry).getFilename();
SftpFileInfo sftpFileInfo = spy(new SftpFileInfo(lsEntry));
doReturn(false).when(sftpFileInfo).isDirectory();
List<SftpFileInfo> files = List.of(sftpFileInfo);
int count = FilenameTemplate.df_section_dateTime.countSameFilesInDir("DF-02", files);
assertEquals(1, count);
// doReturn("DF-02_S_PRC230").when(lsEntry).getFilename();
// count = FilenameTemplate.df_section_dateTime.countSameFilesInDir("DF-02", files);
// assertEquals(0, count);
}
}

View file

@ -0,0 +1,69 @@
package ru.spcex.clearing.dbf.exporter.services;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import ru.clearing.classes.statics.data.sdf.SDf02;
import ru.spcex.clearing.dbf.exporter.AbstractServiceTest;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SdfClearingRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.system.JournalSdf;
import ru.spcex.platform.imdg.api.Imdg;
import javax.annotation.PostConstruct;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.test.TestUtils.addRecordToKafka;
import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
import static ru.spcex.clearing.test.config.KafkaTestConfig.getCaptor;
class S_DF02_Test extends AbstractServiceTest {
@PostConstruct
public void init() {
super.init();
}
/**
* Тест проверяет создание строк документа DBF .<br>
*/
@Test
void cdeateSdf() {
Table table = Table.S_DF02;
Imdg<SDf02> map = imdgProvider.getImdg(table.getHazelcastMapName(), SDf02.class);
SDf02 sDf02 = new SDf02();
sDf02.setGenerationId(generationId);
sDf02.setCurr_code("curr_code");
sDf02.setAccount("account");
sDf02.setRemainder("remainder");
sDf02.setDeal("deal");
sDf02.setAcc_code("acc_code");
sDf02.setDat("dat");
sDf02.setMarket("market");
sDf02.setAcc_name("acc_name");
sDf02.setAcc_type("acc_type");
sDf02.setSumengage("sumengage");
sDf02.setSumunblock("sumunblock");
sDf02.setFile_type("file_type");
sDf02.setResult("result");
map.insert(sDf02);
SdfClearingRequest sdfClearingRequest = new SdfClearingRequest();
sdfClearingRequest.setGroupId(generationId);
String request = getJsonStringForNew(sdfClearingRequest, generationId);
addRecordToKafka((MockConsumer) commandService.getConsumer(), Consts.SDF02_PROCESS, 0, 0, request);
//waiting for kafka send message (finale event)
ArgumentCaptor<ProducerRecord> captor = getCaptor(kafkaTemplate);
verify(kafkaTemplate, timeout(30_000L).times(1))
.send(captor.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) captor.getValue().value();
JournalSdf journalSdf = (JournalSdf) baseRequestResult.getRequestPayload();
assertEquals(generationId, journalSdf.getRegistrationNumber());
}
}

View file

@ -0,0 +1,77 @@
package ru.spcex.clearing.dbf.exporter.services;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import ru.clearing.classes.statics.data.sdf.SDf03;
import ru.spcex.clearing.dbf.exporter.AbstractServiceTest;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SdfClearingRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.system.JournalSdf;
import ru.spcex.platform.imdg.api.Imdg;
import javax.annotation.PostConstruct;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.test.TestUtils.addRecordToKafka;
import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
import static ru.spcex.clearing.test.config.KafkaTestConfig.getCaptor;
class S_DF03_Test extends AbstractServiceTest {
@PostConstruct
public void init() {
super.init();
}
/**
* Тест проверяет создание строк документа DBF .<br>
*/
@Test
void cdeateSdf() {
Table table = Table.S_DF03;
Imdg<SDf03> map = imdgProvider.getImdg(table.getHazelcastMapName(), SDf03.class);
SDf03 sDf03 = new SDf03();
sDf03.setGenerationId(generationId);
sDf03.setSeg_type("seg_type");
sDf03.setDoc_type("doc_type");
sDf03.setDocnm_ref("docnm_ref");
sDf03.setDocnmprev("docnmprev");
sDf03.setC_acc_deb("c_acc_deb");
sDf03.setSbanknam1("sbanknam1");
sDf03.setSbanknam2("sbanknam2");
sDf03.setSbanknam3("sbanknam3");
sDf03.setSbanknam4("sbanknam4");
sDf03.setSbanknam5("sbanknam5");
sDf03.setC_acc_cred("c_acc_cred");
sDf03.setRbanknam1("rbanknam1");
sDf03.setRbanknam2("rbanknam2");
sDf03.setRbanknam3("rbanknam3");
sDf03.setRbanknam4("rbanknam4");
sDf03.setRbanknam5("rbanknam5");
sDf03.setPay_date("pay_date");
sDf03.setPay_val("pay_val");
sDf03.setSum_deb("sum_deb");
sDf03.setSpecif_1("specif_1");
sDf03.setImp_result("imp_result");
map.insert(sDf03);
SdfClearingRequest sdfClearingRequest = new SdfClearingRequest();
sdfClearingRequest.setGroupId(generationId);
String request = getJsonStringForNew(sdfClearingRequest, generationId);
addRecordToKafka((MockConsumer) commandService.getConsumer(), Consts.SDF03_PROCESS, 0, 0, request);
//waiting for kafka send message (finale event)
ArgumentCaptor<ProducerRecord> captor = getCaptor(kafkaTemplate);
verify(kafkaTemplate, timeout(30_000L).times(1))
.send(captor.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) captor.getValue().value();
JournalSdf journalSdf = (JournalSdf) baseRequestResult.getRequestPayload();
assertEquals(generationId, journalSdf.getRegistrationNumber());
}
}

View file

@ -0,0 +1,63 @@
package ru.spcex.clearing.dbf.exporter.services;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import ru.clearing.classes.statics.data.sdf.SDf05;
import ru.spcex.clearing.dbf.exporter.AbstractServiceTest;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SdfClearingRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.system.JournalSdf;
import ru.spcex.platform.imdg.api.Imdg;
import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.test.TestUtils.addRecordToKafka;
import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
import static ru.spcex.clearing.test.config.KafkaTestConfig.getCaptor;
class S_DF05_Test extends AbstractServiceTest {
@PostConstruct
public void init() {
super.init();
}
/**
* Тест проверяет создание строк документа DBF .<br>
*/
@Test
void cdeateSdf() {
Table table = Table.S_DF05;
Imdg<SDf05> map = imdgProvider.getImdg(table.getHazelcastMapName(), SDf05.class);
SDf05 sDf05 = new SDf05();
sDf05.setGenerationId(generationId);
sDf05.setTp(new BigDecimal(32));
sDf05.setDt(LocalDate.now());
sDf05.setTm(LocalTime.now());
sDf05.setPr("deal");
map.insert(sDf05);
SdfClearingRequest sdfClearingRequest = new SdfClearingRequest();
sdfClearingRequest.setGroupId(generationId);
String request = getJsonStringForNew(sdfClearingRequest, generationId);
addRecordToKafka((MockConsumer) commandService.getConsumer(), Consts.SDF05_PROCESS, 0, 0, request);
//waiting for kafka send message (finale event)
ArgumentCaptor<ProducerRecord> captor = getCaptor(kafkaTemplate);
verify(kafkaTemplate, timeout(30_000L).times(1))
.send(captor.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) captor.getValue().value();
JournalSdf journalSdf = (JournalSdf) baseRequestResult.getRequestPayload();
assertEquals(generationId, journalSdf.getRegistrationNumber());
}
}

View file

@ -0,0 +1,68 @@
package ru.spcex.clearing.dbf.exporter.services;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import ru.clearing.classes.statics.data.sdf.SDf07;
import ru.spcex.clearing.dbf.exporter.AbstractServiceTest;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SdfClearingRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.system.JournalSdf;
import ru.spcex.platform.imdg.api.Imdg;
import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.test.TestUtils.addRecordToKafka;
import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
import static ru.spcex.clearing.test.config.KafkaTestConfig.getCaptor;
class S_DF07_Test extends AbstractServiceTest {
@PostConstruct
public void init() {
super.init();
}
/**
* Тест проверяет создание строк документа DBF .<br>
*/
@Test
void cdeateSdf() {
Table table = Table.S_DF07;
Imdg<SDf07> map = imdgProvider.getImdg(table.getHazelcastMapName(), SDf07.class);
SDf07 sDf07 = new SDf07();
sDf07.setGenerationId(generationId);
sDf07.setAccount("curr_code");
sDf07.setSum(new BigDecimal(32));
sDf07.setMarket("remainder");
sDf07.setType("deal");
sDf07.setDeal("acc_code");
sDf07.setClientN("dat");
sDf07.setInn(new BigDecimal(2435));
sDf07.setBic(new BigDecimal(2435));
sDf07.setSpec("acc_type");
sDf07.setNumber(new BigDecimal(2435));
sDf07.setResult(new BigDecimal(2435));
map.insert(sDf07);
SdfClearingRequest sdfClearingRequest = new SdfClearingRequest();
sdfClearingRequest.setGroupId(generationId);
String request = getJsonStringForNew(sdfClearingRequest, generationId);
addRecordToKafka((MockConsumer) commandService.getConsumer(), Consts.SDF07_PROCESS, 0, 0, request);
//waiting for kafka send message (finale event)
ArgumentCaptor<ProducerRecord> captor = getCaptor(kafkaTemplate);
verify(kafkaTemplate, timeout(30_000L).times(1))
.send(captor.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) captor.getValue().value();
JournalSdf journalSdf = (JournalSdf) baseRequestResult.getRequestPayload();
assertEquals(generationId, journalSdf.getRegistrationNumber());
}
}

View file

@ -0,0 +1,58 @@
package ru.spcex.clearing.dbf.exporter.services;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import ru.clearing.classes.statics.data.sdf.SDf51;
import ru.spcex.clearing.dbf.exporter.AbstractServiceTest;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SdfClearingRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.system.JournalSdf;
import ru.spcex.platform.imdg.api.Imdg;
import javax.annotation.PostConstruct;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.test.TestUtils.addRecordToKafka;
import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
import static ru.spcex.clearing.test.config.KafkaTestConfig.getCaptor;
class S_DF51_Test extends AbstractServiceTest {
@PostConstruct
public void init() {
super.init();
}
/**
* Тест проверяет создание строк документа DBF .<br>
*/
@Test
void cdeateSdf() {
Table table = Table.S_DF51;
Imdg<SDf51> map = imdgProvider.getImdg(table.getHazelcastMapName(), SDf51.class);
SDf51 sDf51 = new SDf51();
sDf51.setGenerationId(generationId);
sDf51.setNumber("curr_code");
sDf51.setDatetime("245367");
map.insert(sDf51);
SdfClearingRequest sdfClearingRequest = new SdfClearingRequest();
sdfClearingRequest.setGroupId(generationId);
String request = getJsonStringForNew(sdfClearingRequest, generationId);
addRecordToKafka((MockConsumer) commandService.getConsumer(), Consts.SDF51_PROCESS, 0, 0, request);
//waiting for kafka send message (finale event)
ArgumentCaptor<ProducerRecord> captor = getCaptor(kafkaTemplate);
verify(kafkaTemplate, timeout(30_000L).times(1))
.send(captor.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) captor.getValue().value();
JournalSdf journalSdf = (JournalSdf) baseRequestResult.getRequestPayload();
assertEquals(generationId, journalSdf.getRegistrationNumber());
}
}

View file

@ -0,0 +1,61 @@
package ru.spcex.clearing.dbf.exporter.services;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import ru.clearing.classes.statics.data.sdf.SDf53;
import ru.spcex.clearing.dbf.exporter.AbstractServiceTest;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SdfClearingRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.system.JournalSdf;
import ru.spcex.platform.imdg.api.Imdg;
import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.test.TestUtils.addRecordToKafka;
import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
import static ru.spcex.clearing.test.config.KafkaTestConfig.getCaptor;
class S_DF53_Test extends AbstractServiceTest {
@PostConstruct
public void init() {
super.init();
}
/**
* Тест проверяет создание строк документа DBF .<br>
*/
@Test
void cdeateSdf() {
Table table = Table.S_DF53;
Imdg<SDf53> map = imdgProvider.getImdg(table.getHazelcastMapName(), SDf53.class);
SDf53 sDf53 = new SDf53();
sDf53.setGenerationId(generationId);
sDf53.setAccount("curr_code");
sDf53.setDeal("245367");
sDf53.setStatus(12345L);
sDf53.setResult(new BigDecimal(2345));
map.insert(sDf53);
SdfClearingRequest sdfClearingRequest = new SdfClearingRequest();
sdfClearingRequest.setGroupId(generationId);
String request = getJsonStringForNew(sdfClearingRequest, generationId);
addRecordToKafka((MockConsumer) commandService.getConsumer(), Consts.SDF53_PROCESS, 0, 0, request);
//waiting for kafka send message (finale event)
ArgumentCaptor<ProducerRecord> captor = getCaptor(kafkaTemplate);
verify(kafkaTemplate, timeout(30_000L).times(1))
.send(captor.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) captor.getValue().value();
JournalSdf journalSdf = (JournalSdf) baseRequestResult.getRequestPayload();
assertEquals(generationId, journalSdf.getRegistrationNumber());
}
}

View file

@ -0,0 +1,96 @@
package ru.spcex.clearing.dbf.exporter.services;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import ru.clearing.classes.statics.data.sdf.SDf54;
import ru.spcex.clearing.dbf.exporter.AbstractServiceTest;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SdfClearingRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.system.JournalSdf;
import ru.spcex.platform.imdg.api.Imdg;
import javax.annotation.PostConstruct;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.test.TestUtils.addRecordToKafka;
import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
import static ru.spcex.clearing.test.config.KafkaTestConfig.getCaptor;
class S_DF54_Test extends AbstractServiceTest {
@PostConstruct
public void init() {
super.init();
}
/**
* Тест проверяет создание строк документа DBF .<br>
*/
@Test
void cdeateSdf() {
Table table = Table.S_DF54;
Imdg<SDf54> map = imdgProvider.getImdg(table.getHazelcastMapName(), SDf54.class);
SDf54 sDf54 = new SDf54();
sDf54.setGenerationId(generationId);
sDf54.setSeg_type("seg_type");
sDf54.setDoc_type("doc_type");
sDf54.setDocnm_ref("docnm_ref");
sDf54.setDocnmprev("docnmprev");
sDf54.setSbankcode("sbankcode");
sDf54.setC_acc_deb("c_acc_deb");
sDf54.setSbanknam1("sbanknam1");
sDf54.setSbanknam2("sbanknam2");
sDf54.setSbanknam3("sbanknam3");
sDf54.setSbanknam4("sbanknam4");
sDf54.setSbanknam5("sbanknam5");
sDf54.setRbankcode("rbankcode");
sDf54.setC_acc_cred("c_acc_cred");
sDf54.setRbanknam1("rbanknam1");
sDf54.setRbanknam2("rbanknam2");
sDf54.setRbanknam3("rbanknam3");
sDf54.setRbanknam4("rbanknam4");
sDf54.setRbanknam5("rbanknam5");
sDf54.setOp_type("op_type");
sDf54.setOp_order("op_order");
sDf54.setPay_date("pay_date");
sDf54.setPay_val("pay_val");
sDf54.setSum_deb("sum_deb");
sDf54.setSclientn1("sclientn1");
sDf54.setSclientn2("sclientn2");
sDf54.setSclientn3("sclientn3");
sDf54.setSclientn4("sclientn4");
sDf54.setInn_deb("inn_deb");
sDf54.setKpp_deb("kpp_deb");
sDf54.setAcc_deb("acc_deb");
sDf54.setRclientn1("rclientn1");
sDf54.setRclientn2("rclientn2");
sDf54.setRclientn3("rclientn3");
sDf54.setRclientn4("rclientn4");
sDf54.setInn_cred("inn_cred");
sDf54.setKpp_cred("kpp_cred");
sDf54.setAcc_kr_1("acc_kr_1");
sDf54.setSpecif_1("specif_1");
sDf54.setSend_type("send_type");
sDf54.setDoc_result("doc_result");
map.insert(sDf54);
SdfClearingRequest sdfClearingRequest = new SdfClearingRequest();
sdfClearingRequest.setGroupId(generationId);
String request = getJsonStringForNew(sdfClearingRequest, generationId);
addRecordToKafka((MockConsumer) commandService.getConsumer(), Consts.SDF54_PROCESS, 0, 0, request);
//waiting for kafka send message (finale event)
ArgumentCaptor<ProducerRecord> captor = getCaptor(kafkaTemplate);
verify(kafkaTemplate, timeout(30_000L).times(1))
.send(captor.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) captor.getValue().value();
JournalSdf journalSdf = (JournalSdf) baseRequestResult.getRequestPayload();
assertEquals(generationId, journalSdf.getRegistrationNumber());
}
}

View file

@ -0,0 +1,61 @@
package ru.spcex.clearing.dbf.exporter.services;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import ru.clearing.classes.statics.data.sdf.SDf56;
import ru.spcex.clearing.dbf.exporter.AbstractServiceTest;
import ru.spcex.clearing.dbf.exporter.logic.data.enums.Table;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SdfClearingRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.system.JournalSdf;
import ru.spcex.platform.imdg.api.Imdg;
import javax.annotation.PostConstruct;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.test.TestUtils.addRecordToKafka;
import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
import static ru.spcex.clearing.test.config.KafkaTestConfig.getCaptor;
class S_DF56_Test extends AbstractServiceTest {
@PostConstruct
public void init() {
super.init();
}
/**
* Тест проверяет создание строк документа DBF .<br>
*/
@Test
void cdeateSdf() {
Table table = Table.S_DF56;
Imdg<SDf56> map = imdgProvider.getImdg(table.getHazelcastMapName(), SDf56.class);
SDf56 sDf56 = new SDf56();
sDf56.setGenerationId(generationId);
sDf56.setNumber("seg_type");
sDf56.setStart_datetime("23456");
sDf56.setEnd_datetime("345678");
sDf56.setAccount("docnmprev");
sDf56.setDeal("sbankcode");
map.insert(sDf56);
SdfClearingRequest sdfClearingRequest = new SdfClearingRequest();
sdfClearingRequest.setGroupId(generationId);
String request = getJsonStringForNew(sdfClearingRequest, generationId);
addRecordToKafka((MockConsumer) commandService.getConsumer(), Consts.SDF56_PROCESS, 0, 0, request);
//waiting for kafka send message (finale event)
ArgumentCaptor<ProducerRecord> captor = getCaptor(kafkaTemplate);
verify(kafkaTemplate, timeout(30_000L).times(1))
.send(captor.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) captor.getValue().value();
JournalSdf journalSdf = (JournalSdf) baseRequestResult.getRequestPayload();
assertEquals(generationId, journalSdf.getRegistrationNumber());
}
}

View file

@ -1,19 +1,14 @@
package ru.spcex.clearing.lim.exporter;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.Producer;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.test.TestUtils;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.imdg.api.Imdg;
@ -21,8 +16,6 @@ import ru.spcex.platform.imdg.api.ImdgProvider;
import java.time.LocalDate;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId;
@ -40,10 +33,10 @@ public abstract class AbstractServiceTest {
protected Long securityIdFirst = 12L;
protected Long securityIdSecond = 23L;
@Captor
protected ArgumentCaptor<ProducerRecord> producerRecord;
@MockBean
protected MockProducer<String, Object> mockProducer;
@Autowired
@Qualifier("mockProducer")
protected Producer<String, Object> mockProducer;
@Autowired
@Qualifier("hazelcastServiceTest")
protected ImdgProvider imdgProvider;
@ -52,8 +45,5 @@ public abstract class AbstractServiceTest {
waitAvailableImdgProviderAndAddAdminWithDefaultId();
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
TestUtils.FutureRecordMetadata future = spy(new TestUtils.FutureRecordMetadata());
doReturn(future).when(mockProducer).send(producerRecord.capture());
}
}

View file

@ -20,9 +20,9 @@ public class KafkaConfig {
return KafkaConsumerFactory.consumer(settings.getKafkaConsumer());
}
// @Autowired
// @Bean
// public Producer<String, Object> createProducer(ReportsServiceSettings settings) {
// return KafkaProducerFactory.producer(settings.getKafkaProducer());
// }
@Autowired
@Bean
public Producer<String, Object> createProducer(ReportsServiceSettings settings) {
return KafkaProducerFactory.producer(settings.getKafkaProducer());
}
}

View file

@ -68,4 +68,9 @@ public class ImdgTransactionProviderHazelcast implements ImdgTransaction {
public void setHz(HazelcastInstance hz) {
this.hz = hz;
}
@Override
public String toString() {
return "ImdgTransaction{" + (ctx == null ? null : ctx.getTxnId()) + "}";
}
}

View file

@ -105,12 +105,19 @@ public interface Consts {
String USER_SETTINGS_UPDATE = "user-settings-update";
String STATEMENT_PROCESS = "statement-process";
String SDF04_PROCESS = "sdf04-process";
String SDF02_PROCESS = "sdf02-process";
String SDF03_PROCESS = "sdf03-process";
String SDF04_PROCESS = "sdf04-process";
String SDF05_PROCESS = "sdf05-process";
String SDF07_PROCESS = "sdf07-process";
String SDF11_PROCESS = "sdf11-process";
String SDF51_PROCESS = "sdf51-process";
String SDF53_PROCESS = "sdf53-process";
String SDF54_PROCESS = "sdf54-process";
String SDF56_PROCESS = "sdf56-process";
String SDF57_PROCESS = "sdf57-process";
String EXPORT_PROCESS = "export-process";
String EXPORT_COMPLETED = "export_completed";
String S_TRADES_IMPORTED = "s_trades-imported";
String LIM_EXPORTED = "lim_exported";
String ACCOUNT_TERMINATION = "account-termination";