Merge remote-tracking branch 'refs/remotes/origin/new' into dev

This commit is contained in:
etreschenkov 2024-09-24 12:27:09 +03:00
commit b61f3956f3
73 changed files with 18982 additions and 10216 deletions

View file

@ -26,6 +26,7 @@ preflight:
only:
- dev
- /^dev_.*$/
- new
resource_group: clearing-test
build:
@ -41,6 +42,7 @@ build:
only:
- dev
- /^dev_.*$/
- new
resource_group: clearing-test
test:
@ -62,4 +64,5 @@ test:
only:
- dev
- /^dev_.*$/
- new
resource_group: clearing-test

View file

@ -793,7 +793,7 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
}
if (returnTrigger) {
log.debug("Remove from waiting list accountId={} (list groupId={})", accountId, inWaitingLst.getGroupId());
waitingList.remove(inWaitingLst);
waitingList.remove(accountId);
}
if (returnTrigger)
return inWaitingLst;

View file

@ -132,7 +132,7 @@ public class ClientCodeMessageListener extends QueueConsumer implements Initiali
clientCodeNewRequest.setCompanyId(company.getId());
clientCodeNewRequest.setCode(tkrAccount.getClientCode());
clientCodeNewRequest.setDepoAccountId(depoAccountId);
Account moneyAccount = accountByCurrency.get(CurrencyCode.RUB);
Account moneyAccount = accountByCurrency.get(CurrencyCode.RUB.getKey());
clientCodeNewRequest.setMoneyAccountId(moneyAccount.getId());
List<Long> foreignCurrencyList = accountByCurrency.entrySet()

View file

@ -4,6 +4,8 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.nio.file.Files;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
@ -12,9 +14,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import ru.spcex.clearing.backendapi.meta.MetaServer;
import java.io.IOException;
import java.nio.file.Files;
@Configuration
public class MetaConfiguration {
@Value("file:${spring.config.location}/meta.json")

View file

@ -53,6 +53,51 @@ public class BankAccountNewAction implements IAction<BankAccountNewRequest> {
@ApiModelProperty(value = "Код SWIFT посредника", example = "ABCDE")
@JsonProperty
private String intermediarySwiftCode;
@ApiModelProperty(value = "Наименование владельца счета", example = "ABCDE")
@JsonProperty
private String name;
@ApiModelProperty(value = "Адрес владельца счета", example = "ABCDE")
@JsonProperty
private String address;
@ApiModelProperty(value = "Место нахождения банка получателя средств", example = "ABCDE")
@JsonProperty
private String bankAddress;
@ApiModelProperty(value = "SWIFT банка получателя средств", example = "ABCDE")
@JsonProperty
private String bankSwiftCode;
@ApiModelProperty(value = "Номер счета банка получателя средств", example = "ABCDE")
@JsonProperty
private String bankAccount;
@ApiModelProperty(value = "Наименование банка-посредника 1", example = "ABCDE")
@JsonProperty
private String bankName1;
@ApiModelProperty(value = "Место нахождения банка-посредника 1", example = "ABCDE")
@JsonProperty
private String bankAddress1;
@ApiModelProperty(value = "Номер счета банка-посредника 1", example = "ABCDE")
@JsonProperty
private String bankAccount1;
@ApiModelProperty(value = "Наименование банка-посредника 2", example = "ABCDE")
@JsonProperty
private String bankName2;
@ApiModelProperty(value = "Место нахождения банка-посредника 2", example = "ABCDE")
@JsonProperty
private String bankAddress2;
@ApiModelProperty(value = "SWIFT банка-посредника 2", example = "ABCDE")
@JsonProperty
private String intermediarySwiftCode2;
@ApiModelProperty(value = "Номер счета банка-посредника 2", example = "ABCDE")
@JsonProperty
private String bankAccount2;
@ApiModelProperty(value = "Лицевой счет получателя", example = "ABCDE")
@JsonProperty
private String personalAccount;
@ApiModelProperty(value = "КБК", example = "ABCDE")
@JsonProperty
private String budgetClassificationCode;
@ApiModelProperty(value = "ОКТМО получателя средств", example = "ABCDE")
@JsonProperty
private String oktmo;
@Override
public BankAccountNewRequest toRequest() {
@ -69,6 +114,21 @@ public class BankAccountNewAction implements IAction<BankAccountNewRequest> {
req.setCompanyId(this.companyId);
req.setSwiftCode(swiftCode);
req.setIntermediarySwiftCode(intermediarySwiftCode);
req.setName(name);
req.setAddress(address);
req.setBankAddress(bankAddress);
req.setBankSwiftCode(bankSwiftCode);
req.setBankAccount(bankAccount);
req.setBankName1(bankName1);
req.setBankAddress1(bankAddress1);
req.setBankAccount1(bankAccount1);
req.setBankName2(bankName2);
req.setBankAddress2(bankAddress2);
req.setIntermediarySwiftCode2(intermediarySwiftCode2);
req.setBankAccount2(bankAccount2);
req.setPersonalAccount(personalAccount);
req.setBudgetClassificationCode(budgetClassificationCode);
req.setOktmo(oktmo);
return req;
}
@ -173,4 +233,124 @@ public class BankAccountNewAction implements IAction<BankAccountNewRequest> {
public void setIntermediarySwiftCode(String intermediarySwiftCode) {
this.intermediarySwiftCode = intermediarySwiftCode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getBankAddress() {
return bankAddress;
}
public void setBankAddress(String bankAddress) {
this.bankAddress = bankAddress;
}
public String getBankSwiftCode() {
return bankSwiftCode;
}
public void setBankSwiftCode(String bankSwiftCode) {
this.bankSwiftCode = bankSwiftCode;
}
public String getBankAccount() {
return bankAccount;
}
public void setBankAccount(String bankAccount) {
this.bankAccount = bankAccount;
}
public String getBankName1() {
return bankName1;
}
public void setBankName1(String bankName1) {
this.bankName1 = bankName1;
}
public String getBankAddress1() {
return bankAddress1;
}
public void setBankAddress1(String bankAddress1) {
this.bankAddress1 = bankAddress1;
}
public String getBankAccount1() {
return bankAccount1;
}
public void setBankAccount1(String bankAccount1) {
this.bankAccount1 = bankAccount1;
}
public String getBankName2() {
return bankName2;
}
public void setBankName2(String bankName2) {
this.bankName2 = bankName2;
}
public String getBankAddress2() {
return bankAddress2;
}
public void setBankAddress2(String bankAddress2) {
this.bankAddress2 = bankAddress2;
}
public String getIntermediarySwiftCode2() {
return intermediarySwiftCode2;
}
public void setIntermediarySwiftCode2(String intermediarySwiftCode2) {
this.intermediarySwiftCode2 = intermediarySwiftCode2;
}
public String getBankAccount2() {
return bankAccount2;
}
public void setBankAccount2(String bankAccount2) {
this.bankAccount2 = bankAccount2;
}
public String getPersonalAccount() {
return personalAccount;
}
public void setPersonalAccount(String personalAccount) {
this.personalAccount = personalAccount;
}
public String getBudgetClassificationCode() {
return budgetClassificationCode;
}
public void setBudgetClassificationCode(String budgetClassificationCode) {
this.budgetClassificationCode = budgetClassificationCode;
}
public String getOktmo() {
return oktmo;
}
public void setOktmo(String oktmo) {
this.oktmo = oktmo;
}
}

View file

@ -48,6 +48,52 @@ public class BankAccountUpdateAction implements IAction<BankAccountUpdateRequest
@ApiModelProperty(value = "Номер счета", example = "11111222223333344444")
private String account;
@ApiModelProperty(value = "Наименование владельца счета", example = "ABCDE")
@JsonProperty
private String name;
@ApiModelProperty(value = "Адрес владельца счета", example = "ABCDE")
@JsonProperty
private String address;
@ApiModelProperty(value = "Место нахождения банка получателя средств", example = "ABCDE")
@JsonProperty
private String bankAddress;
@ApiModelProperty(value = "SWIFT банка получателя средств", example = "ABCDE")
@JsonProperty
private String bankSwiftCode;
@ApiModelProperty(value = "Номер счета банка получателя средств", example = "ABCDE")
@JsonProperty
private String bankAccount;
@ApiModelProperty(value = "Наименование банка-посредника 1", example = "ABCDE")
@JsonProperty
private String bankName1;
@ApiModelProperty(value = "Место нахождения банка-посредника 1", example = "ABCDE")
@JsonProperty
private String bankAddress1;
@ApiModelProperty(value = "Номер счета банка-посредника 1", example = "ABCDE")
@JsonProperty
private String bankAccount1;
@ApiModelProperty(value = "Наименование банка-посредника 2", example = "ABCDE")
@JsonProperty
private String bankName2;
@ApiModelProperty(value = "Место нахождения банка-посредника 2", example = "ABCDE")
@JsonProperty
private String bankAddress2;
@ApiModelProperty(value = "SWIFT банка-посредника 2", example = "ABCDE")
@JsonProperty
private String intermediarySwiftCode2;
@ApiModelProperty(value = "Номер счета банка-посредника 2", example = "ABCDE")
@JsonProperty
private String bankAccount2;
@ApiModelProperty(value = "Лицевой счет получателя", example = "ABCDE")
@JsonProperty
private String personalAccount;
@ApiModelProperty(value = "КБК", example = "ABCDE")
@JsonProperty
private String budgetClassificationCode;
@ApiModelProperty(value = "ОКТМО получателя средств", example = "ABCDE")
@JsonProperty
private String oktmo;
@Override
public BankAccountUpdateRequest toRequest() {
var req = new BankAccountUpdateRequest();
@ -63,6 +109,21 @@ public class BankAccountUpdateAction implements IAction<BankAccountUpdateRequest
req.setAccount(this.account);
req.setSwiftCode(swiftCode);
req.setIntermediarySwiftCode(intermediarySwiftCode);
req.setName(name);
req.setAddress(address);
req.setBankAddress(bankAddress);
req.setBankSwiftCode(bankSwiftCode);
req.setBankAccount(bankAccount);
req.setBankName1(bankName1);
req.setBankAddress1(bankAddress1);
req.setBankAccount1(bankAccount1);
req.setBankName2(bankName2);
req.setBankAddress2(bankAddress2);
req.setIntermediarySwiftCode2(intermediarySwiftCode2);
req.setBankAccount2(bankAccount2);
req.setPersonalAccount(personalAccount);
req.setBudgetClassificationCode(budgetClassificationCode);
req.setOktmo(oktmo);
return req;
}
@ -167,4 +228,124 @@ public class BankAccountUpdateAction implements IAction<BankAccountUpdateRequest
public void setIntermediarySwiftCode(String intermediarySwiftCode) {
this.intermediarySwiftCode = intermediarySwiftCode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getBankAddress() {
return bankAddress;
}
public void setBankAddress(String bankAddress) {
this.bankAddress = bankAddress;
}
public String getBankSwiftCode() {
return bankSwiftCode;
}
public void setBankSwiftCode(String bankSwiftCode) {
this.bankSwiftCode = bankSwiftCode;
}
public String getBankAccount() {
return bankAccount;
}
public void setBankAccount(String bankAccount) {
this.bankAccount = bankAccount;
}
public String getBankName1() {
return bankName1;
}
public void setBankName1(String bankName1) {
this.bankName1 = bankName1;
}
public String getBankAddress1() {
return bankAddress1;
}
public void setBankAddress1(String bankAddress1) {
this.bankAddress1 = bankAddress1;
}
public String getBankAccount1() {
return bankAccount1;
}
public void setBankAccount1(String bankAccount1) {
this.bankAccount1 = bankAccount1;
}
public String getBankName2() {
return bankName2;
}
public void setBankName2(String bankName2) {
this.bankName2 = bankName2;
}
public String getBankAddress2() {
return bankAddress2;
}
public void setBankAddress2(String bankAddress2) {
this.bankAddress2 = bankAddress2;
}
public String getIntermediarySwiftCode2() {
return intermediarySwiftCode2;
}
public void setIntermediarySwiftCode2(String intermediarySwiftCode2) {
this.intermediarySwiftCode2 = intermediarySwiftCode2;
}
public String getBankAccount2() {
return bankAccount2;
}
public void setBankAccount2(String bankAccount2) {
this.bankAccount2 = bankAccount2;
}
public String getPersonalAccount() {
return personalAccount;
}
public void setPersonalAccount(String personalAccount) {
this.personalAccount = personalAccount;
}
public String getBudgetClassificationCode() {
return budgetClassificationCode;
}
public void setBudgetClassificationCode(String budgetClassificationCode) {
this.budgetClassificationCode = budgetClassificationCode;
}
public String getOktmo() {
return oktmo;
}
public void setOktmo(String oktmo) {
this.oktmo = oktmo;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?-->
<meta version="3.14.105.103">
<meta version="3.14.105.104">
<!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" -->
<!--Здесь словари-->
<enums>
@ -1159,6 +1159,21 @@
<status field="accountId" type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" searchable="true" sortable="true" visible="true" linkKeyCode="id" linkCode="status" link="account" extends="account"/>
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<intermediarySwiftCode type="2" length="255" name="Код SWIFT посредника" shortname="SWIFT посредника" searchable="true" sortable="true" visible="true"/>
<name type="2" length="255" name="Наименование владельца счета" shortname="Владелец счета" searchable="true" sortable="true" visible="true"/>
<address type="2" length="255" name="Адрес владельца счета" shortname="Адрес владельца" searchable="true" sortable="true" visible="true"/>
<bankAddress type="2" length="255" name="Место нахождения банка получателя средств" shortname="Место нахождение банка" searchable="true" sortable="true" visible="true"/>
<bankSwiftCode type="2" length="12" name="SWIFT банка получателя средств" shortname="SWIFT банка" searchable="true" sortable="true" visible="true"/>
<bankAccount type="2" length="35" name="Номер счета банка получателя средств" shortname="Номер счёта получателя" searchable="true" sortable="true" visible="true"/>
<bankName1 type="2" length="255" name="Наименование банка-посредника 1" shortname="Банк посредник 1" searchable="true" sortable="true" visible="true"/>
<bankAddress1 type="2" length="255" name="Место нахождения банка-посредника 1" shortname="Место нахождения банка-посредника 1" searchable="true" sortable="true" visible="true"/>
<bankAccount1 type="2" length="35" name="Номер счета банка-посредника 1" shortname="Счет банка-посредника 1" searchable="true" sortable="true" visible="true"/>
<bankName2 type="2" length="255" name="Наименование банка-посредника 2" shortname="Банк посредник 2" searchable="true" sortable="true" visible="true"/>
<bankAddress2 type="2" length="255" name="Место нахождения банка-посредника 2" shortname="Место нахождения банка-посредника 2" searchable="true" sortable="true" visible="true"/>
<intermediarySwiftCode2 type="2" length="12" name="SWIFT банка-посредника 2" shortname="Счет банка-посредника 2" searchable="true" sortable="true" visible="true"/>
<bankAccount2 type="2" length="35" name="Номер счета банка-посредника 2" shortname="Счет банка-посредника 2" searchable="true" sortable="true" visible="true"/>
<personalAccount type="2" length="20" name="Лицевой счет получателя" shortname="Счет получателя" searchable="true" sortable="true" visible="true"/>
<budgetClassificationCode type="2" length="20" name="КБК" shortname="КБК" searchable="true" sortable="true" visible="true"/>
<oktmo type="2" length="20" name="ОКТМО получателя средств" shortname="ОКТМО" searchable="true" sortable="true" visible="true"/>
<actions>
<post name="Добавление счета вывода средств" confirmation="currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account" class="ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountNewAction">
<currency type="12" name="Код валюты" shortname="Валюта" required="true" link="currencyCode" linkCode="code"/>
@ -1173,6 +1188,21 @@
<companyId type="1" name="Компания" shortname="Компания" link="company" linkCode="shortName" visible="false"/>
<destination type="2" length="255" name="Назначение платежа" shortname="Назначение платежа" visible="true"/>
<intermediarySwiftCode type="2" length="255" name="Код SWIFT посредника" shortname="SWIFT посредника" searchable="true" sortable="true" visible="true"/>
<name type="2" length="255" name="Наименование владельца счета" shortname="Владелец счета" searchable="true" sortable="true" visible="true" required="true"/>
<address type="2" length="255" name="Адрес владельца счета" shortname="Адрес владельца" searchable="true" sortable="true" visible="true" required="true"/>
<bankAddress type="2" length="255" name="Место нахождения банка получателя средств" shortname="Место нахождение банка" searchable="true" sortable="true" visible="true" required="true"/>
<bankSwiftCode type="2" length="12" name="SWIFT банка получателя средств" shortname="SWIFT банка" searchable="true" sortable="true" visible="true" required="true"/>
<bankAccount type="2" length="35" name="Номер счета банка получателя средств" shortname="Номер счёта получателя" searchable="true" sortable="true" visible="true" required="true"/>
<bankName1 type="2" length="255" name="Наименование банка-посредника 1" shortname="Банк посредник 1" searchable="true" sortable="true" visible="true"/>
<bankAddress1 type="2" length="255" name="Место нахождения банка-посредника 1" shortname="Место нахождения банка-посредника 1" searchable="true" sortable="true" visible="true"/>
<bankAccount1 type="2" length="35" name="Номер счета банка-посредника 1" shortname="Счет банка-посредника 1" searchable="true" sortable="true" visible="true"/>
<bankName2 type="2" length="255" name="Наименование банка-посредника 2" shortname="Банк посредник 2" searchable="true" sortable="true" visible="true"/>
<bankAddress2 type="2" length="255" name="Место нахождения банка-посредника 2" shortname="Место нахождения банка-посредника 2" searchable="true" sortable="true" visible="true"/>
<intermediarySwiftCode2 type="2" length="12" name="SWIFT банка-посредника 2" shortname="Счет банка-посредника 2" searchable="true" sortable="true" visible="true"/>
<bankAccount2 type="2" length="35" name="Номер счета банка-посредника 2" shortname="Счет банка-посредника 2" searchable="true" sortable="true" visible="true"/>
<personalAccount type="2" length="20" name="Лицевой счет получателя" shortname="Счет получателя" searchable="true" sortable="true" visible="true"/>
<budgetClassificationCode type="2" length="20" name="КБК" shortname="КБК" searchable="true" sortable="true" visible="true"/>
<oktmo type="2" length="20" name="ОКТМО получателя средств" shortname="ОКТМО" searchable="true" sortable="true" visible="true"/>
</post>
<put name="Изменение счета вывода средств" confirmation="currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account" class="ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountUpdateAction">
<id type="1" name="Идентификатор записи" shortname="ID" link="bankAccount" linkCode="id" required="true"/>
@ -1187,6 +1217,21 @@
<account type="2" length="50" name="Номер счета" shortname="Счет"/>
<destination type="2" length="255" name="Назначение платежа" shortname="Назначение платежа" visible="true"/>
<intermediarySwiftCode type="2" length="255" name="Код SWIFT посредника" shortname="SWIFT посредника" searchable="true" sortable="true" visible="true"/>
<name type="2" length="255" name="Наименование владельца счета" shortname="Владелец счета" searchable="true" sortable="true" visible="true" required="true"/>
<address type="2" length="255" name="Адрес владельца счета" shortname="Адрес владельца" searchable="true" sortable="true" visible="true" required="true"/>
<bankAddress type="2" length="255" name="Место нахождения банка получателя средств" shortname="Место нахождение банка" searchable="true" sortable="true" visible="true" required="true"/>
<bankSwiftCode type="2" length="12" name="SWIFT банка получателя средств" shortname="SWIFT банка" searchable="true" sortable="true" visible="true" required="true"/>
<bankAccount type="2" length="35" name="Номер счета банка получателя средств" shortname="Номер счёта получателя" searchable="true" sortable="true" visible="true" required="true"/>
<bankName1 type="2" length="255" name="Наименование банка-посредника 1" shortname="Банк посредник 1" searchable="true" sortable="true" visible="true"/>
<bankAddress1 type="2" length="255" name="Место нахождения банка-посредника 1" shortname="Место нахождения банка-посредника 1" searchable="true" sortable="true" visible="true"/>
<bankAccount1 type="2" length="35" name="Номер счета банка-посредника 1" shortname="Счет банка-посредника 1" searchable="true" sortable="true" visible="true"/>
<bankName2 type="2" length="255" name="Наименование банка-посредника 2" shortname="Банк посредник 2" searchable="true" sortable="true" visible="true"/>
<bankAddress2 type="2" length="255" name="Место нахождения банка-посредника 2" shortname="Место нахождения банка-посредника 2" searchable="true" sortable="true" visible="true"/>
<intermediarySwiftCode2 type="2" length="12" name="SWIFT банка-посредника 2" shortname="Счет банка-посредника 2" searchable="true" sortable="true" visible="true"/>
<bankAccount2 type="2" length="35" name="Номер счета банка-посредника 2" shortname="Счет банка-посредника 2" searchable="true" sortable="true" visible="true"/>
<personalAccount type="2" length="20" name="Лицевой счет получателя" shortname="Счет получателя" searchable="true" sortable="true" visible="true"/>
<budgetClassificationCode type="2" length="20" name="КБК" shortname="КБК" searchable="true" sortable="true" visible="true"/>
<oktmo type="2" length="20" name="ОКТМО получателя средств" shortname="ОКТМО" searchable="true" sortable="true" visible="true"/>
</put>
<delete name="Блокировка счета вывода средств" confirmation="currency,bankIdentificationCode,correspondentAccount,taxpayerIdentificationNumber,taxRegistrationReasonCode,account" class="ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction">
<id type="1" name="Идентификатор записи" shortname="ID" link="bankAccount" linkCode="id" required="true"/>

View file

@ -1,6 +1,6 @@
{
"version": "3.12.8.101",
"version": "3.14.105.104",
"enums": {
@ -1523,7 +1523,7 @@
"destination": "db-versions",
"class": "",
"class": "ru.clearing.classes.statics.data.misc.DbVersion",
"table": "db_version",
@ -1535,6 +1535,10 @@
{"code": "version",
"type": 2,"length": 50,"name": "Версия базы данных, привязанная к релизу","shortname": "Версия БД","searchable": true,"sortable": true,"visible": true
}
,
{"code": "dictionaryVersion",
"type": 2,"length": 100,"name": "Версия справочника","shortname": "Версия справочника","searchable": true,"sortable": true,"visible": true
}
]
}
@ -4984,6 +4988,66 @@
{"code": "intermediarySwiftCode",
"type": 2,"length": 255,"name": "Код SWIFT посредника","shortname": "SWIFT посредника","searchable": true,"sortable": true,"visible": true
}
,
{"code": "name",
"type": 2,"length": 255,"name": "Наименование владельца счета","shortname": "Владелец счета","searchable": true,"sortable": true,"visible": true
}
,
{"code": "address",
"type": 2,"length": 255,"name": "Адрес владельца счета","shortname": "Адрес владельца","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAddress",
"type": 2,"length": 255,"name": "Место нахождения банка получателя средств","shortname": "Место нахождение банка","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankSwiftCode",
"type": 2,"length": 12,"name": "SWIFT банка получателя средств","shortname": "SWIFT банка","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAccount",
"type": 2,"length": 35,"name": "Номер счета банка получателя средств","shortname": "Номер счёта получателя","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankName1",
"type": 2,"length": 255,"name": "Наименование банка-посредника 1","shortname": "Банк посредник 1","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAddress1",
"type": 2,"length": 255,"name": "Место нахождения банка-посредника 1","shortname": "Место нахождения банка-посредника 1","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAccount1",
"type": 2,"length": 35,"name": "Номер счета банка-посредника 1","shortname": "Счет банка-посредника 1","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankName2",
"type": 2,"length": 255,"name": "Наименование банка-посредника 2","shortname": "Банк посредник 2","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAddress2",
"type": 2,"length": 255,"name": "Место нахождения банка-посредника 2","shortname": "Место нахождения банка-посредника 2","searchable": true,"sortable": true,"visible": true
}
,
{"code": "intermediarySwiftCode2",
"type": 2,"length": 12,"name": "SWIFT банка-посредника 2","shortname": "Счет банка-посредника 2","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAccount2",
"type": 2,"length": 35,"name": "Номер счета банка-посредника 2","shortname": "Счет банка-посредника 2","searchable": true,"sortable": true,"visible": true
}
,
{"code": "personalAccount",
"type": 2,"length": 20,"name": "Лицевой счет получателя","shortname": "Счет получателя","searchable": true,"sortable": true,"visible": true
}
,
{"code": "budgetClassificationCode",
"type": 2,"length": 20,"name": "КБК","shortname": "КБК","searchable": true,"sortable": true,"visible": true
}
,
{"code": "oktmo",
"type": 2,"length": 20,"name": "ОКТМО получателя средств","shortname": "ОКТМО","searchable": true,"sortable": true,"visible": true
}
]
,"actions":[
{"method":"post",
@ -5042,6 +5106,66 @@
{"code": "intermediarySwiftCode",
"type": 2,"length": 255,"name": "Код SWIFT посредника","shortname": "SWIFT посредника","searchable": true,"sortable": true,"visible": true
}
,
{"code": "name",
"type": 2,"length": 255,"name": "Наименование владельца счета","shortname": "Владелец счета","searchable": true,"sortable": true,"visible": true,"required": true
}
,
{"code": "address",
"type": 2,"length": 255,"name": "Адрес владельца счета","shortname": "Адрес владельца","searchable": true,"sortable": true,"visible": true,"required": true
}
,
{"code": "bankAddress",
"type": 2,"length": 255,"name": "Место нахождения банка получателя средств","shortname": "Место нахождение банка","searchable": true,"sortable": true,"visible": true,"required": true
}
,
{"code": "bankSwiftCode",
"type": 2,"length": 12,"name": "SWIFT банка получателя средств","shortname": "SWIFT банка","searchable": true,"sortable": true,"visible": true,"required": true
}
,
{"code": "bankAccount",
"type": 2,"length": 35,"name": "Номер счета банка получателя средств","shortname": "Номер счёта получателя","searchable": true,"sortable": true,"visible": true,"required": true
}
,
{"code": "bankName1",
"type": 2,"length": 255,"name": "Наименование банка-посредника 1","shortname": "Банк посредник 1","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAddress1",
"type": 2,"length": 255,"name": "Место нахождения банка-посредника 1","shortname": "Место нахождения банка-посредника 1","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAccount1",
"type": 2,"length": 35,"name": "Номер счета банка-посредника 1","shortname": "Счет банка-посредника 1","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankName2",
"type": 2,"length": 255,"name": "Наименование банка-посредника 2","shortname": "Банк посредник 2","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAddress2",
"type": 2,"length": 255,"name": "Место нахождения банка-посредника 2","shortname": "Место нахождения банка-посредника 2","searchable": true,"sortable": true,"visible": true
}
,
{"code": "intermediarySwiftCode2",
"type": 2,"length": 12,"name": "SWIFT банка-посредника 2","shortname": "Счет банка-посредника 2","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAccount2",
"type": 2,"length": 35,"name": "Номер счета банка-посредника 2","shortname": "Счет банка-посредника 2","searchable": true,"sortable": true,"visible": true
}
,
{"code": "personalAccount",
"type": 2,"length": 20,"name": "Лицевой счет получателя","shortname": "Счет получателя","searchable": true,"sortable": true,"visible": true
}
,
{"code": "budgetClassificationCode",
"type": 2,"length": 20,"name": "КБК","shortname": "КБК","searchable": true,"sortable": true,"visible": true
}
,
{"code": "oktmo",
"type": 2,"length": 20,"name": "ОКТМО получателя средств","shortname": "ОКТМО","searchable": true,"sortable": true,"visible": true
}
]
}
,
@ -5101,6 +5225,66 @@
{"code": "intermediarySwiftCode",
"type": 2,"length": 255,"name": "Код SWIFT посредника","shortname": "SWIFT посредника","searchable": true,"sortable": true,"visible": true
}
,
{"code": "name",
"type": 2,"length": 255,"name": "Наименование владельца счета","shortname": "Владелец счета","searchable": true,"sortable": true,"visible": true,"required": true
}
,
{"code": "address",
"type": 2,"length": 255,"name": "Адрес владельца счета","shortname": "Адрес владельца","searchable": true,"sortable": true,"visible": true,"required": true
}
,
{"code": "bankAddress",
"type": 2,"length": 255,"name": "Место нахождения банка получателя средств","shortname": "Место нахождение банка","searchable": true,"sortable": true,"visible": true,"required": true
}
,
{"code": "bankSwiftCode",
"type": 2,"length": 12,"name": "SWIFT банка получателя средств","shortname": "SWIFT банка","searchable": true,"sortable": true,"visible": true,"required": true
}
,
{"code": "bankAccount",
"type": 2,"length": 35,"name": "Номер счета банка получателя средств","shortname": "Номер счёта получателя","searchable": true,"sortable": true,"visible": true,"required": true
}
,
{"code": "bankName1",
"type": 2,"length": 255,"name": "Наименование банка-посредника 1","shortname": "Банк посредник 1","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAddress1",
"type": 2,"length": 255,"name": "Место нахождения банка-посредника 1","shortname": "Место нахождения банка-посредника 1","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAccount1",
"type": 2,"length": 35,"name": "Номер счета банка-посредника 1","shortname": "Счет банка-посредника 1","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankName2",
"type": 2,"length": 255,"name": "Наименование банка-посредника 2","shortname": "Банк посредник 2","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAddress2",
"type": 2,"length": 255,"name": "Место нахождения банка-посредника 2","shortname": "Место нахождения банка-посредника 2","searchable": true,"sortable": true,"visible": true
}
,
{"code": "intermediarySwiftCode2",
"type": 2,"length": 12,"name": "SWIFT банка-посредника 2","shortname": "Счет банка-посредника 2","searchable": true,"sortable": true,"visible": true
}
,
{"code": "bankAccount2",
"type": 2,"length": 35,"name": "Номер счета банка-посредника 2","shortname": "Счет банка-посредника 2","searchable": true,"sortable": true,"visible": true
}
,
{"code": "personalAccount",
"type": 2,"length": 20,"name": "Лицевой счет получателя","shortname": "Счет получателя","searchable": true,"sortable": true,"visible": true
}
,
{"code": "budgetClassificationCode",
"type": 2,"length": 20,"name": "КБК","shortname": "КБК","searchable": true,"sortable": true,"visible": true
}
,
{"code": "oktmo",
"type": 2,"length": 20,"name": "ОКТМО получателя средств","shortname": "ОКТМО","searchable": true,"sortable": true,"visible": true
}
]
}
,
@ -10332,6 +10516,32 @@
]
}
,
"blacklistMarket": {
"name": "blacklist площадок",
"destination": "blacklist-market",
"class": "ru.clearing.classes.statics.data.misc.BlacklistMarket",
"table": "blacklist_market",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"visible": true
}
,
{"code": "code",
"name": "Код рынка","shortname": "Код рынка","type": 2,"length": 12
}
,
{"code": "section",
"name": "Секция","shortname": "Секция","type": 12
}
]
}
}

View file

@ -26,6 +26,21 @@ public class BankAccount extends SpcexObjectBase {
private String account;
private Long companyId;
private String intermediarySwiftCode;
private String name;
private String address;
private String bankAddress;
private String bankSwiftCode;
private String bankAccount;
private String bankName1;
private String bankAddress1;
private String bankAccount1;
private String bankName2;
private String bankAddress2;
private String intermediarySwiftCode2;
private String bankAccount2;
private String personalAccount;
private String budgetClassificationCode;
private String oktmo;
public Long getAccountId() {
return accountId;
@ -143,7 +158,128 @@ public class BankAccount extends SpcexObjectBase {
return intermediarySwiftCode;
}
public void setIntermediarySwiftCode(String intermediarySwiftCode) {
this.intermediarySwiftCode = intermediarySwiftCode;
public void setIntermediarySwiftCode(String value) {
this.intermediarySwiftCode = value;
}
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public String getAddress() {
return address;
}
public void setAddress(String value) {
this.address = value;
}
public String getBankAddress() {
return bankAddress;
}
public void setBankAddress(String value) {
this.bankAddress = value;
}
public String getBankSwiftCode() {
return bankSwiftCode;
}
public void setBankSwiftCode(String value) {
this.bankSwiftCode = value;
}
public String getBankAccount() {
return bankAccount;
}
public void setBankAccount(String value) {
this.bankAccount = value;
}
public String getBankName1() {
return bankName1;
}
public void setBankName1(String value) {
this.bankName1 = value;
}
public String getBankAddress1() {
return bankAddress1;
}
public void setBankAddress1(String value) {
this.bankAddress1 = value;
}
public String getBankAccount1() {
return bankAccount1;
}
public void setBankAccount1(String value) {
this.bankAccount1 = value;
}
public String getBankName2() {
return bankName2;
}
public void setBankName2(String value) {
this.bankName2 = value;
}
public String getBankAddress2() {
return bankAddress2;
}
public void setBankAddress2(String value) {
this.bankAddress2 = value;
}
public String getIntermediarySwiftCode2() {
return intermediarySwiftCode2;
}
public void setIntermediarySwiftCode2(String value) {
this.intermediarySwiftCode2 = value;
}
public String getBankAccount2() {
return bankAccount2;
}
public void setBankAccount2(String value) {
this.bankAccount2 = value;
}
public String getPersonalAccount() {
return personalAccount;
}
public void setPersonalAccount(String value) {
this.personalAccount = value;
}
public String getBudgetClassificationCode() {
return budgetClassificationCode;
}
public void setBudgetClassificationCode(String value) {
this.budgetClassificationCode = value;
}
public String getOktmo() {
return oktmo;
}
public void setOktmo(String value) {
this.oktmo = value;
}
}

View file

@ -1,5 +1,8 @@
package ru.spcex.clearing.service.payment;
import static ru.spcex.clearing.session.stage.impl.GatewayRequester.mapError;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.Locale;
@ -40,7 +43,6 @@ import ru.spcex.clearing.service.registry.RegistryManager;
import ru.spcex.clearing.service.schedule.TradingTimeService;
import ru.spcex.clearing.service.validation.ValidationStored;
import ru.spcex.clearing.session.stage.impl.GatewayRequester;
import static ru.spcex.clearing.session.stage.impl.GatewayRequester.mapError;
import ru.spcex.clearing.util.LocaleUtil;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.platform.enumeration.CurrencyCode;
@ -55,7 +57,6 @@ import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumId;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.localization.SpringPropertiesLocalizer;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
import ru.spcex.platform.utils.text.TextUtil;
import ru.spcex.platform.utils.validation.IValidator;
@ -189,8 +190,8 @@ public class PaymentInstructionOutboundService {
sDf54.setGenerationId(pmt.getId());
if (time.isTradingTime()) {
Supplier<AssetOperationRequest> builder = () -> GatewayRequestCreator.from(pmt,
assets.get().a__b().getTradingCode(),
tcr.getCode());
assets.get().a__b().getTradingCode(),
tcr == null ? null : tcr.getCode());
Optional<Boolean> gatewayOk = gateway.gatewayRequestAndWait(builder);
if (gatewayOk.isEmpty() || gatewayOk.get().equals(Boolean.FALSE)) {
String gtwErrMsg = msgs.resolve(mapError(gatewayOk));

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
-- DB version: 3.13
-- DB version: 3.14
/* Dictionaries */
-- allowed - Справочник признаков допустимости использования объектов
@ -2381,7 +2381,7 @@ GRANT ALL PRIVILEGES ON TABLE RELATION_HISTORY TO clearing;
-- bankAccount - Счета вывода средств
DROP TABLE IF EXISTS BANK_ACCOUNT;
CREATE TABLE BANK_ACCOUNT(ACCOUNT_ID bigint, BANK_IDENTIFICATION_CODE varchar(255), BANK_NAME varchar(255), CORRESPONDENT_ACCOUNT varchar(255), CORRESPONDENT_ACCOUNT_NAME varchar(255), CURRENCY varchar(4), DESTINATION varchar(255), IBAN varchar(255), INTERNATIONAL_TRANSFER_SIGN varchar(4), SWIFT_CODE varchar(255), TAXPAYER_IDENTIFICATION_NUMBER varchar(255), TAX_REGISTRATION_REASON_CODE varchar(255), ACCOUNT varchar(50), COMPANY_ID bigint, ID bigint PRIMARY KEY, INTERMEDIARY_SWIFT_CODE varchar(255));
CREATE TABLE BANK_ACCOUNT(ACCOUNT_ID bigint, BANK_IDENTIFICATION_CODE varchar(255), BANK_NAME varchar(255), CORRESPONDENT_ACCOUNT varchar(255), CORRESPONDENT_ACCOUNT_NAME varchar(255), CURRENCY varchar(4), DESTINATION varchar(255), IBAN varchar(255), INTERNATIONAL_TRANSFER_SIGN varchar(4), SWIFT_CODE varchar(255), TAXPAYER_IDENTIFICATION_NUMBER varchar(255), TAX_REGISTRATION_REASON_CODE varchar(255), ACCOUNT varchar(50), COMPANY_ID bigint, ID bigint PRIMARY KEY, INTERMEDIARY_SWIFT_CODE varchar(255), NAME varchar(255), ADDRESS varchar(255), BANK_ADDRESS varchar(255), BANK_SWIFT_CODE varchar(12), BANK_ACCOUNT varchar(35), BANK_NAME1 varchar(255), BANK_ADDRESS1 varchar(255), BANK_ACCOUNT1 varchar(35), BANK_NAME2 varchar(255), BANK_ADDRESS2 varchar(255), INTERMEDIARY_SWIFT_CODE2 varchar(12), BANK_ACCOUNT2 varchar(35), PERSONAL_ACCOUNT varchar(20), BUDGET_CLASSIFICATION_CODE varchar(20), OKTMO varchar(20));
COMMENT ON TABLE BANK_ACCOUNT IS 'Счета вывода средств';
COMMENT ON COLUMN BANK_ACCOUNT.ACCOUNT_ID IS 'Идентификатор счета (linked to account)';
@ -2416,12 +2416,42 @@ COMMENT ON COLUMN BANK_ACCOUNT.ID IS 'Идентификатор записи';
COMMENT ON COLUMN BANK_ACCOUNT.INTERMEDIARY_SWIFT_CODE IS 'Код SWIFT посредника';
COMMENT ON COLUMN BANK_ACCOUNT.NAME IS 'Наименование владельца счета';
COMMENT ON COLUMN BANK_ACCOUNT.ADDRESS IS 'Адрес владельца счета';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_ADDRESS IS 'Место нахождения банка получателя средств';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_SWIFT_CODE IS 'SWIFT банка получателя средств';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_ACCOUNT IS 'Номер счета банка получателя средств';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_NAME1 IS 'Наименование банка-посредника 1';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_ADDRESS1 IS 'Место нахождения банка-посредника 1';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_ACCOUNT1 IS 'Номер счета банка-посредника 1';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_NAME2 IS 'Наименование банка-посредника 2';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_ADDRESS2 IS 'Место нахождения банка-посредника 2';
COMMENT ON COLUMN BANK_ACCOUNT.INTERMEDIARY_SWIFT_CODE2 IS 'SWIFT банка-посредника 2';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_ACCOUNT2 IS 'Номер счета банка-посредника 2';
COMMENT ON COLUMN BANK_ACCOUNT.PERSONAL_ACCOUNT IS 'Лицевой счет получателя';
COMMENT ON COLUMN BANK_ACCOUNT.BUDGET_CLASSIFICATION_CODE IS 'КБК';
COMMENT ON COLUMN BANK_ACCOUNT.OKTMO IS 'ОКТМО получателя средств';
GRANT ALL PRIVILEGES ON TABLE BANK_ACCOUNT TO clearing;
-- History log of bankAccount - Счета вывода средств
DROP TABLE IF EXISTS BANK_ACCOUNT_HISTORY;
CREATE TABLE BANK_ACCOUNT_HISTORY(BANK_ACCOUNT_ID BIGINT NOT NULL, EVENT_TIME timestamp, EVENT_USER_ID BIGINT, EVENT_TYPE VARCHAR(4), ACCOUNT_ID bigint, BANK_IDENTIFICATION_CODE varchar(255), BANK_NAME varchar(255), CORRESPONDENT_ACCOUNT varchar(255), CORRESPONDENT_ACCOUNT_NAME varchar(255), CURRENCY varchar(4), DESTINATION varchar(255), IBAN varchar(255), INTERNATIONAL_TRANSFER_SIGN varchar(4), SWIFT_CODE varchar(255), TAXPAYER_IDENTIFICATION_NUMBER varchar(255), TAX_REGISTRATION_REASON_CODE varchar(255), ACCOUNT varchar(50), COMPANY_ID bigint, ID bigint PRIMARY KEY, INTERMEDIARY_SWIFT_CODE varchar(255));
CREATE TABLE BANK_ACCOUNT_HISTORY(BANK_ACCOUNT_ID BIGINT NOT NULL, EVENT_TIME timestamp, EVENT_USER_ID BIGINT, EVENT_TYPE VARCHAR(4), ACCOUNT_ID bigint, BANK_IDENTIFICATION_CODE varchar(255), BANK_NAME varchar(255), CORRESPONDENT_ACCOUNT varchar(255), CORRESPONDENT_ACCOUNT_NAME varchar(255), CURRENCY varchar(4), DESTINATION varchar(255), IBAN varchar(255), INTERNATIONAL_TRANSFER_SIGN varchar(4), SWIFT_CODE varchar(255), TAXPAYER_IDENTIFICATION_NUMBER varchar(255), TAX_REGISTRATION_REASON_CODE varchar(255), ACCOUNT varchar(50), COMPANY_ID bigint, ID bigint PRIMARY KEY, INTERMEDIARY_SWIFT_CODE varchar(255), NAME varchar(255), ADDRESS varchar(255), BANK_ADDRESS varchar(255), BANK_SWIFT_CODE varchar(12), BANK_ACCOUNT varchar(35), BANK_NAME1 varchar(255), BANK_ADDRESS1 varchar(255), BANK_ACCOUNT1 varchar(35), BANK_NAME2 varchar(255), BANK_ADDRESS2 varchar(255), INTERMEDIARY_SWIFT_CODE2 varchar(12), BANK_ACCOUNT2 varchar(35), PERSONAL_ACCOUNT varchar(20), BUDGET_CLASSIFICATION_CODE varchar(20), OKTMO varchar(20));
COMMENT ON TABLE BANK_ACCOUNT_HISTORY IS 'История изменений таблицы bankAccount';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.BANK_ACCOUNT_ID IS 'Идентификатор записи в таблице BANK_ACCOUNT';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.EVENT_TIME IS 'Дата и время изменения';
@ -2460,6 +2490,36 @@ COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.ID IS 'Идентификатор зап
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.INTERMEDIARY_SWIFT_CODE IS 'Код SWIFT посредника';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.NAME IS 'Наименование владельца счета';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.ADDRESS IS 'Адрес владельца счета';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.BANK_ADDRESS IS 'Место нахождения банка получателя средств';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.BANK_SWIFT_CODE IS 'SWIFT банка получателя средств';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.BANK_ACCOUNT IS 'Номер счета банка получателя средств';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.BANK_NAME1 IS 'Наименование банка-посредника 1';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.BANK_ADDRESS1 IS 'Место нахождения банка-посредника 1';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.BANK_ACCOUNT1 IS 'Номер счета банка-посредника 1';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.BANK_NAME2 IS 'Наименование банка-посредника 2';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.BANK_ADDRESS2 IS 'Место нахождения банка-посредника 2';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.INTERMEDIARY_SWIFT_CODE2 IS 'SWIFT банка-посредника 2';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.BANK_ACCOUNT2 IS 'Номер счета банка-посредника 2';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.PERSONAL_ACCOUNT IS 'Лицевой счет получателя';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.BUDGET_CLASSIFICATION_CODE IS 'КБК';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.OKTMO IS 'ОКТМО получателя средств';
GRANT ALL PRIVILEGES ON TABLE BANK_ACCOUNT_HISTORY TO clearing;
-- informationAccount - Регистр КС
@ -5121,4 +5181,4 @@ GRANT ALL PRIVILEGES ON TABLE BLACKLIST_MARKET TO clearing;
-- Data types
INSERT INTO DB_VERSION(ID, VERSION) values (1, '3.13') ON CONFLICT (ID) DO UPDATE SET VERSION = EXCLUDED.VERSION
INSERT INTO DB_VERSION(ID, VERSION) values (1, '3.14') ON CONFLICT (ID) DO UPDATE SET VERSION = EXCLUDED.VERSION

View file

@ -3,4 +3,36 @@
-- == alter exist tables ==
ALTER TABLE BLACKLIST_MARKET ALTER COLUMN CODE TYPE varchar(12);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS NAME varchar(255);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS ADDRESS varchar(255);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS BANK_ADDRESS varchar(255);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS BANK_SWIFT_CODE varchar(12);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS BANK_ACCOUNT varchar(35);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS BANK_NAME1 varchar(255);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS BANK_ADDRESS1 varchar(255);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS BANK_ACCOUNT1 varchar(35);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS BANK_NAME2 varchar(255);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS BANK_ADDRESS2 varchar(255);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS INTERMEDIARY_SWIFT_CODE2 varchar(12);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS BANK_ACCOUNT2 varchar(35);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS PERSONAL_ACCOUNT varchar(20);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS BUDGET_CLASSIFICATION_CODE varchar(20);
ALTER TABLE BANK_ACCOUNT ADD COLUMN IF NOT EXISTS OKTMO varchar(20);
COMMENT ON COLUMN BANK_ACCOUNT.NAME IS 'Íàèìåíîâàíèå âëàäåëüöà ñ÷åòà';
COMMENT ON COLUMN BANK_ACCOUNT.ADDRESS IS 'Àäðåñ âëàäåëüöà ñ÷åòà (ïîëó÷àòåëÿ ñðåäñòâ)';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_ADDRESS IS 'Ìåñòî íàõîæäåíèÿ áàíêà ïîëó÷àòåëÿ ñðåäñòâ';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_SWIFT_CODE IS 'SWIFT áàíêà ïîëó÷àòåëÿ ñðåäñòâ';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_ACCOUNT IS 'Íîìåð ñ÷åòà áàíêà ïîëó÷àòåëÿ ñðåäñòâ';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_NAME1 IS 'Íàèìåíîâàíèå áàíêà-ïîñðåäíèêà 1 (ïðè íàëè÷èè)';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_ADDRESS1 IS 'Ìåñòî íàõîæäåíèÿ áàíêà-ïîñðåäíèêà 1 (ïðè íàëè÷èè)';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_ACCOUNT1 IS 'Íîìåð ñ÷åòà áàíêà-ïîñðåäíèêà 1';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_NAME2 IS 'Íàèìåíîâàíèå áàíêà-ïîñðåäíèêà 2';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_ADDRESS2 IS 'Ìåñòî íàõîæäåíèÿ áàíêà-ïîñðåäíèêà 2';
COMMENT ON COLUMN BANK_ACCOUNT.INTERMEDIARY_SWIFT_CODE2 IS 'SWIFT áàíêà-ïîñðåäíèêà 2';
COMMENT ON COLUMN BANK_ACCOUNT.BANK_ACCOUNT2 IS 'Íîìåð ñ÷åòà áàíêà-ïîñðåäíèêà 2';
COMMENT ON COLUMN BANK_ACCOUNT.PERSONAL_ACCOUNT IS 'Ëèöåâîé ñ÷åò ïîëó÷àòåëÿ';
COMMENT ON COLUMN BANK_ACCOUNT.BUDGET_CLASSIFICATION_CODE IS 'ÊÁÊ';
COMMENT ON COLUMN BANK_ACCOUNT.OKTMO IS 'ÎÊÒÌÎ ïîëó÷àòåëÿ ñðåäñòâ';
INSERT INTO DB_VERSION(ID, VERSION) values (1, '3.14') ON CONFLICT (ID) DO UPDATE SET VERSION = EXCLUDED.VERSION

View file

@ -60,12 +60,12 @@ public class DbfImportKafkaMessenger implements InitializingBean {
}
public void notifyUserAboutErrorParsing(Throwable error, ResultContainer resultContainer) {
if (resultContainer == null || resultContainer.getDbfFile() == null || resultContainer.getDbfFile() == null)
if (resultContainer == null || resultContainer.getDbfFile() == null)
return;
ETable currTable = resultContainer.getDbfTable();
String fileName = resultContainer.getDbfFile().getName();
log.debug("Notify user about error {} \"{}\"",
resultContainer.getDbfTable(), fileName);
currTable, fileName);
sendUserNotification(ObjectType.rgst, String.format("Файл \"%s\" не сохранен", fileName), Priority.HIGH);
}

View file

@ -1,6 +1,22 @@
package ru.spcex.clearing.imdg.base;
import com.hazelcast.core.MapStore;
import java.math.BigDecimal;
import java.sql.ParameterMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -8,18 +24,11 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SqlTypeValue;
import org.springframework.jdbc.core.StatementCreatorUtils;
import org.springframework.lang.NonNull;
import ru.spcex.clearing.imdg.util.ColumnMetaData;
import ru.spcex.clearing.imdg.util.PostgresColumnTypeUtil;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.utils.text.TextUtil;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
/**
* MapStore для выгрузки обычных объектов
*
@ -29,7 +38,7 @@ public abstract class SimpleObjectMapStore<T extends SpcexObjectBase> implements
private final static int BATCH_SIZE = 1000;
protected final Logger log = LoggerFactory.getLogger(this.getClass());
protected final JdbcTemplate jdbcTemplate;
protected SimpleDateFormat DB_DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
protected Map<String, ColumnMetaData> columnMetaDataMap;
protected SimpleObjectMapStore(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
@ -149,10 +158,12 @@ public abstract class SimpleObjectMapStore<T extends SpcexObjectBase> implements
}
protected void batchInsertUpdate(@NonNull String insertStatement, @NonNull List<Object[]> args) {
readMetaData();
try {
int[][] ret = jdbcTemplate.batchUpdate(insertStatement, args, BATCH_SIZE, (ps, params) -> {
for (int i = 0; i < params.length; i++) {
Object value = params[i];
value = normalizeValue(value, ps.getParameterMetaData(), columnMetaDataMap, i, insertStatement, params);
try {
StatementCreatorUtils.setParameterValue(ps, i + 1, SqlTypeValue.TYPE_UNKNOWN, value);
} catch (SQLException e) {
@ -168,6 +179,113 @@ public abstract class SimpleObjectMapStore<T extends SpcexObjectBase> implements
}
}
Object normalizeValue(Object value, ParameterMetaData metaData, Map<String, ColumnMetaData> columnMetaDataMap, int i,
String insertStatement, Object[] params) throws SQLException {
if (value == null)
return null;
i++; // нумерация в ParameterMetaData начинается с 1
final int type = metaData.getParameterType(i);
final String fieldName = getFields()[i - 1].toLowerCase();
if (columnMetaDataMap == null) {
log.trace("Column metadata was empty, can not verify {}.{}", getTableName(), fieldName);
}
if ((type == Types.VARCHAR || type == Types.CHAR) && value instanceof String stringValue) {
int length;
if (columnMetaDataMap == null) {
length = metaData.getPrecision(i + 1);
} else {
// в postgresql для String ParameterMetaData.getPrecision возвращает 0, используется columnMetaDataMap
length = columnMetaDataMap.get(fieldName).getPrecision();
}
if (length > 0 && stringValue.length() > length) {
value = stringValue.substring(0, length);
log.error("String value is too large [insertSql: {}, params: {}, i: {}, incorrect value: {}, normalized value: {}]",
insertStatement, Arrays.toString(params), i, stringValue, value);
}
} else if ((type == Types.DECIMAL || type == Types.NUMERIC || type == Types.BIGINT || type == Types.INTEGER) &&
(value instanceof BigDecimal || value instanceof Long || value instanceof Integer)) {
if (value instanceof Integer && (type == Types.INTEGER || type == Types.BIGINT)) {
return value; // ok
}
if (value instanceof Long vl) {
if (type == Types.BIGINT) {
return value; // ok
}
if (type == Types.INTEGER) {
if (vl > Integer.MAX_VALUE) {
value = Integer.MAX_VALUE;
log.error("Long value for insert is too large [insertSql: {}, params: {}, i: {}, incorrect value: {}, normalized value: {}]",
insertStatement, Arrays.toString(params), i, vl, value);
}
if (vl < Integer.MIN_VALUE) {
value = Integer.MIN_VALUE;
log.error("Long value for insert is too large [insertSql: {}, params: {}, i: {}, incorrect value: {}, normalized value: {}]",
insertStatement, Arrays.toString(params), i, vl, value);
}
return value;
}
}
BigDecimal bigDecimalValue;
if (value instanceof Integer intValue) {
bigDecimalValue = BigDecimal.valueOf(intValue);
} else if (value instanceof Long longValue) {
bigDecimalValue = BigDecimal.valueOf(longValue);
} else {
bigDecimalValue = (BigDecimal) value;
}
if (type == Types.BIGINT) {
if (bigDecimalValue.compareTo(BigDecimal.valueOf(Long.MAX_VALUE)) > 0) {
Object oldValue = value;
value = Long.MAX_VALUE;
log.error("Double value as BIGINT is too large [insertSql: {}, params: {}, i: {}, incorrect value: {}, normalized value: {}]",
insertStatement, Arrays.toString(params), i, oldValue, value);
} else if (bigDecimalValue.compareTo(BigDecimal.valueOf(Long.MIN_VALUE)) < 0) {
Object oldValue = value;
value = Long.MIN_VALUE;
log.error("Double value as BIGINT is too large [insertSql: {}, params: {}, i: {}, incorrect value: {}, normalized value: {}]",
insertStatement, Arrays.toString(params), i, oldValue, value);
}
return value; // value ok
}
if (type == Types.INTEGER) {
if (bigDecimalValue.compareTo(BigDecimal.valueOf(Integer.MAX_VALUE)) > 0) {
Object oldValue = value;
value = Integer.MAX_VALUE;
log.error("Double value as INTEGER is too large [insertSql: {}, params: {}, i: {}, incorrect value: {}, normalized value: {}]",
insertStatement, Arrays.toString(params), i, oldValue, value);
} else if (bigDecimalValue.compareTo(BigDecimal.valueOf(Integer.MIN_VALUE)) < 0) {
Object oldValue = value;
value = Integer.MIN_VALUE;
log.error("Double value as INTEGER is too large [insertSql: {}, params: {}, i: {}, incorrect value: {}, normalized value: {}]",
insertStatement, Arrays.toString(params), i, oldValue, value);
}
return value; // value ok
}
int dbScalePartLength;
int precision;
if (columnMetaDataMap == null) {
dbScalePartLength = metaData.getScale(i);
precision = metaData.getPrecision(i);
} else {
dbScalePartLength = columnMetaDataMap.get(fieldName).getScale();
precision = columnMetaDataMap.get(fieldName).getPrecision();
}
if (!checkBigDecimalSize(bigDecimalValue, precision, dbScalePartLength)) {
boolean negative = bigDecimalValue.signum() < 0;
value = new BigDecimal(BigDecimal.valueOf(Math.pow(10, precision - dbScalePartLength)).longValue() - 1);
if (negative)
value = ((BigDecimal) value).negate();
log.error("BigDecimal value is too large [insertSql: {}, params: {}, i: {}, incorrect value: {}, normalized value: {}]",
insertStatement, Arrays.toString(params), i, bigDecimalValue, value);
}
}
return value;
}
protected Instant getInstantFromTimestamp(ResultSet rs, String column) throws SQLException {
Timestamp date = rs.getTimestamp(column);
return date != null ? date.toInstant() : null;
@ -191,4 +309,16 @@ public abstract class SimpleObjectMapStore<T extends SpcexObjectBase> implements
return TextUtil.format(INSERT_TEMPLATE, params);
}
private void readMetaData() {
if (columnMetaDataMap == null) synchronized (this) {
columnMetaDataMap = PostgresColumnTypeUtil.extractTableMetadata(jdbcTemplate, getTableName());
}
}
private boolean checkBigDecimalSize(BigDecimal value, int dbSize, int dbScale) {
if (value == null)
return true;
return value.precision() - value.scale() <= dbSize - dbScale;
}
}

View file

@ -27,8 +27,8 @@ public class BankAccountHistoryMapStore extends TemplateEventMapStore<BankAccoun
@Override
public String[] getFields() {
return new String[]{"ID", "EVENT_TIME", "EVENT_TYPE", "EVENT_USER_ID",
"BANK_ACCOUNT_ID", "ACCOUNT_ID", "BANK_IDENTIFICATION_CODE", "BANK_NAME", "CORRESPONDENT_ACCOUNT", "CORRESPONDENT_ACCOUNT_NAME", "CURRENCY", "DESTINATION", "IBAN", "INTERNATIONAL_TRANSFER_SIGN", "SWIFT_CODE", "TAXPAYER_IDENTIFICATION_NUMBER", "TAX_REGISTRATION_REASON_CODE", "ACCOUNT", "COMPANY_ID", "INTERMEDIARY_SWIFT_CODE"
return new String[]{"ID", "EVENT_TIME", "EVENT_USER_ID", "EVENT_TYPE",
"BANK_ACCOUNT_ID", "ACCOUNT_ID", "BANK_IDENTIFICATION_CODE", "BANK_NAME", "CORRESPONDENT_ACCOUNT", "CORRESPONDENT_ACCOUNT_NAME", "CURRENCY", "DESTINATION", "IBAN", "INTERNATIONAL_TRANSFER_SIGN", "SWIFT_CODE", "TAXPAYER_IDENTIFICATION_NUMBER", "TAX_REGISTRATION_REASON_CODE", "ACCOUNT", "COMPANY_ID", "INTERMEDIARY_SWIFT_CODE", "NAME", "ADDRESS", "BANK_ADDRESS", "BANK_SWIFT_CODE", "BANK_ACCOUNT", "BANK_NAME1", "BANK_ADDRESS1", "BANK_ACCOUNT1", "BANK_NAME2", "BANK_ADDRESS2", "INTERMEDIARY_SWIFT_CODE2", "BANK_ACCOUNT2", "PERSONAL_ACCOUNT", "BUDGET_CLASSIFICATION_CODE", "OKTMO"
};
}
@ -38,8 +38,8 @@ public class BankAccountHistoryMapStore extends TemplateEventMapStore<BankAccoun
Object[] args = new Object[]{
historyLog.getId(),
TimeUtil.toDateFromInstant(historyLog.getEventTime()),
historyLog.getEventType(),
historyLog.getUserId(),
historyLog.getEventType(),
object.getId(),
object.getAccountId(),
@ -56,7 +56,22 @@ public class BankAccountHistoryMapStore extends TemplateEventMapStore<BankAccoun
object.getTaxRegistrationReasonCode(),
object.getAccount(),
object.getCompanyId(),
object.getIntermediarySwiftCode()
object.getIntermediarySwiftCode(),
object.getName(),
object.getAddress(),
object.getBankAddress(),
object.getBankSwiftCode(),
object.getBankAccount(),
object.getBankName1(),
object.getBankAddress1(),
object.getBankAccount1(),
object.getBankName2(),
object.getBankAddress2(),
object.getIntermediarySwiftCode2(),
object.getBankAccount2(),
object.getPersonalAccount(),
object.getBudgetClassificationCode(),
object.getOktmo()
};
return args;
}

View file

@ -33,7 +33,7 @@ public class BankAccountMapStore extends TemplateMapStore<BankAccount> {
@Override
public String[] getFields() {
return new String[]{
"ID", "ACCOUNT_ID", "BANK_IDENTIFICATION_CODE", "BANK_NAME", "CORRESPONDENT_ACCOUNT", "CORRESPONDENT_ACCOUNT_NAME", "CURRENCY", "DESTINATION", "IBAN", "INTERNATIONAL_TRANSFER_SIGN", "SWIFT_CODE", "TAXPAYER_IDENTIFICATION_NUMBER", "TAX_REGISTRATION_REASON_CODE", "ACCOUNT", "COMPANY_ID", "INTERMEDIARY_SWIFT_CODE"
"ID", "ACCOUNT_ID", "BANK_IDENTIFICATION_CODE", "BANK_NAME", "CORRESPONDENT_ACCOUNT", "CORRESPONDENT_ACCOUNT_NAME", "CURRENCY", "DESTINATION", "IBAN", "INTERNATIONAL_TRANSFER_SIGN", "SWIFT_CODE", "TAXPAYER_IDENTIFICATION_NUMBER", "TAX_REGISTRATION_REASON_CODE", "ACCOUNT", "COMPANY_ID", "INTERMEDIARY_SWIFT_CODE", "NAME", "ADDRESS", "BANK_ADDRESS", "BANK_SWIFT_CODE", "BANK_ACCOUNT", "BANK_NAME1", "BANK_ADDRESS1", "BANK_ACCOUNT1", "BANK_NAME2", "BANK_ADDRESS2", "INTERMEDIARY_SWIFT_CODE2", "BANK_ACCOUNT2", "PERSONAL_ACCOUNT", "BUDGET_CLASSIFICATION_CODE", "OKTMO"
};
}
@ -56,6 +56,21 @@ public class BankAccountMapStore extends TemplateMapStore<BankAccount> {
object.setAccount(resultSet.getObject("ACCOUNT", String.class));
object.setCompanyId(resultSet.getObject("COMPANY_ID", Long.class));
object.setIntermediarySwiftCode(resultSet.getObject("INTERMEDIARY_SWIFT_CODE", String.class));
object.setName(resultSet.getObject("NAME", String.class));
object.setAddress(resultSet.getObject("ADDRESS", String.class));
object.setBankAddress(resultSet.getObject("BANK_ADDRESS", String.class));
object.setBankSwiftCode(resultSet.getObject("BANK_SWIFT_CODE", String.class));
object.setBankAccount(resultSet.getObject("BANK_ACCOUNT", String.class));
object.setBankName1(resultSet.getObject("BANK_NAME1", String.class));
object.setBankAddress1(resultSet.getObject("BANK_ADDRESS1", String.class));
object.setBankAccount1(resultSet.getObject("BANK_ACCOUNT1", String.class));
object.setBankName2(resultSet.getObject("BANK_NAME2", String.class));
object.setBankAddress2(resultSet.getObject("BANK_ADDRESS2", String.class));
object.setIntermediarySwiftCode2(resultSet.getObject("INTERMEDIARY_SWIFT_CODE2", String.class));
object.setBankAccount2(resultSet.getObject("BANK_ACCOUNT2", String.class));
object.setPersonalAccount(resultSet.getObject("PERSONAL_ACCOUNT", String.class));
object.setBudgetClassificationCode(resultSet.getObject("BUDGET_CLASSIFICATION_CODE", String.class));
object.setOktmo(resultSet.getObject("OKTMO", String.class));
return object;
}
@ -77,7 +92,22 @@ public class BankAccountMapStore extends TemplateMapStore<BankAccount> {
object.getTaxRegistrationReasonCode(),
object.getAccount(),
object.getCompanyId(),
object.getIntermediarySwiftCode()
object.getIntermediarySwiftCode(),
object.getName(),
object.getAddress(),
object.getBankAddress(),
object.getBankSwiftCode(),
object.getBankAccount(),
object.getBankName1(),
object.getBankAddress1(),
object.getBankAccount1(),
object.getBankName2(),
object.getBankAddress2(),
object.getIntermediarySwiftCode2(),
object.getBankAccount2(),
object.getPersonalAccount(),
object.getBudgetClassificationCode(),
object.getOktmo()
};
return args;
}

View file

@ -4,6 +4,14 @@ import com.hazelcast.config.MapStoreConfig;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.core.IdGenerator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
@ -16,10 +24,6 @@ import ru.spcex.clearing.imdg.base.SimpleObjectMapStore;
import ru.spcex.clearing.imdg.object.DbVersionMapStore;
import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
//todo почистить класс
public abstract class AbstractHazelcastLifecycleSupport implements InitializingBean, DisposableBean {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@ -48,7 +52,7 @@ public abstract class AbstractHazelcastLifecycleSupport implements InitializingB
@Override
public void afterPropertiesSet() {
// HazelcastCommon.loadClassesVersionsByStorage(hazelcastServerInstance, getSerialVersionUIDClasses());
// databaseVersionCheck();
databaseVersionCheck();
long loadTime = System.currentTimeMillis();
@ -119,11 +123,38 @@ public abstract class AbstractHazelcastLifecycleSupport implements InitializingB
HazelcastHelper.imdgSystem_setStorageState(true, hazelcastServerInstance);
loadTime = System.currentTimeMillis() - loadTime;
log.info("All map load time {} ms", loadTime);
}
@Override
public void destroy() {
hazelcastServerInstance.shutdown();
}
private void databaseVersionCheck() {
log.debug("Validating database version, expected \"{}\"", getCheckDbVersion());
String dbVersion = jdbcTemplate.queryForObject("SELECT version FROM db_version", String.class);
log.trace("Database version is \"{}\"", dbVersion);
if (dbVersion == null || dbVersion.isBlank()) {
log.error("Database version is empty");
System.exit(1);
} else {
List<Integer> expectedVersion = Arrays.stream(getCheckDbVersion().split("\\."))
.map(Integer::parseInt)
.toList();
List<Integer> actualVersion = Arrays.stream(dbVersion.split("\\."))
.map(Integer::parseInt)
.toList();
if (expectedVersion.size() < 2 || actualVersion.size() < 2) {
log.error("Database version have wrong format, expected = {}, actual = {}", expectedVersion, actualVersion);
System.exit(1);
}
if (!expectedVersion.get(0).equals(actualVersion.get(0)) || expectedVersion.get(1) > actualVersion.get(1)) {
log.error("Database version is older than expected version, expected = {}, actual = {}", expectedVersion, actualVersion);
System.exit(1);
}
}
}
}

View file

@ -0,0 +1,40 @@
package ru.spcex.clearing.imdg.util;
public class ColumnMetaData {
private final String name;
private final String dataType;
private final int characterMaximumLength;
private final int numericPrecision;
private final int numericScale;
public ColumnMetaData(String name, String dataType, int characterMaximumLength, int numericPrecision, int numericScale) {
this.name = name;
this.dataType = dataType;
this.characterMaximumLength = characterMaximumLength;
this.numericPrecision = numericPrecision;
this.numericScale = numericScale;
}
public String getName() {
return name;
}
public String getDataType() {
return dataType;
}
public int getPrecision() {
return switch (dataType) {
case "smallint", "integer", "real", "numeric", "bigint", "double precision" -> numericPrecision;
case "character varying" -> characterMaximumLength;
default -> 0;
};
}
public int getScale() {
return switch (dataType) {
case "smallint", "integer", "real", "numeric", "bigint", "double precision" -> numericScale;
default -> 0;
};
}
}

View file

@ -0,0 +1,28 @@
package ru.spcex.clearing.imdg.util;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
public final class PostgresColumnTypeUtil {
static Logger log = LoggerFactory.getLogger(PostgresColumnTypeUtil.class);
static String SELECT_METADATA_LIKE = "SELECT * FROM information_schema.columns WHERE table_name=?";
static String SELECT_METADATA_ILIKE = "SELECT * FROM information_schema.columns WHERE table_name ilike ?";
public static Map<String, ColumnMetaData> extractTableMetadata(JdbcTemplate template, String tableName) {
List<ColumnMetaData> columnMetaDataList = template.query(tableName.contains("\"") ? SELECT_METADATA_LIKE
: SELECT_METADATA_ILIKE, (rs, rn) -> new ColumnMetaData(
rs.getString("column_name"),
rs.getString("data_type"),
rs.getInt("character_maximum_length"),
rs.getInt("numeric_precision"), rs.getInt("numeric_scale")
), tableName.replace("\"", ""));
log.debug("metadata of table \"{}\" is {}", tableName, columnMetaDataList);
return columnMetaDataList.isEmpty() ? null :
columnMetaDataList.stream().collect(Collectors.toMap(ColumnMetaData::getName, Function.identity()));
}
}

View file

@ -213,8 +213,7 @@ public class TradeImporterService {
private boolean isValidTrades(STrades trades) {
return trades.getTradeDate() != null
&& trades.getTradeNum() != null
&& StringUtils.hasText(trades.getOperation())
&& trades.getTradeNum() != null;
&& StringUtils.hasText(trades.getOperation());
}
public STrades readSTrades(ResultSet resultSet) throws SQLException {

View file

@ -6,7 +6,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import ru.spcex.clearing.xml.importer.config.settings.ImportXMLServiceSettings;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@Configuration
@ -33,8 +32,8 @@ public class ImporterImdgConfig {
}
@Autowired
@Bean
public HazelcastService imdgProvider(
@Bean(name = "hazelcastService")
public HazelcastService hazelcastService(
@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
@Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
ImportXMLServiceSettings settings

View file

@ -3,55 +3,50 @@ package ru.spcex.clearing.xml.importer.config;
import java.util.function.Supplier;
import org.apache.kafka.clients.consumer.Consumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.config.KafkaConsumerFactory;
import ru.spcex.clearing.platform.messaging.config.KafkaProducerFactory;
import ru.spcex.clearing.platform.messaging.config.element.KafkaProducerSettings;
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.xml.importer.config.settings.ImportXMLServiceSettings;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@Configuration
public class KafkaConfig {
@Bean
public ProducerFactory<String, Object> pf(ImportXMLServiceSettings settings) {
@Bean(name = "producerFactory")
public ProducerFactory<String, Object> producerFactory(ImportXMLServiceSettings settings) {
KafkaProducerSettings kafkaSettings = settings.getKafkaProducer();
return KafkaProducerFactory.producerFactory(kafkaSettings);
}
@Bean("kafkaTemplate")
public KafkaTemplate<String, Object> kafkaTemplate(ProducerFactory<String, Object> pf) {
@Bean(name = "kafkaTemplate")
public KafkaTemplate<String, Object> kafkaTemplate(@Qualifier("producerFactory") ProducerFactory<String, Object> pf) {
return new KafkaTemplate<>(pf);
}
@Autowired
@Bean
public Supplier<KafkaSender> kafkaSender(KafkaTemplate<String, Object> kafkaTemplate,
ImdgProvider imdgProvider) {
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
@Bean(name = "kafkaSender")
public Supplier<KafkaSender> kafkaSender(@Qualifier("kafkaTemplate") KafkaTemplate<String, Object> kafkaTemplate,
@Qualifier("hazelcastService") HazelcastService hazelcastService) {
ImdgId imdgIdGenerator = hazelcastService.getImdgIdGenerator();
return () -> KafkaSender
.setup()
.setKafkaTemplate(kafkaTemplate)
.idGenerator(imdgIdGenerator::nextId)
.imdgProvider(s -> {
Imdg<RequestInfo> imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class);
return imdg::insert;
})
.saveRequestInfo(false)
.build();
}
@Autowired
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean
@Bean(name = "createConsumer")
public Consumer<String, Object> createConsumer(ImportXMLServiceSettings settings) {
return KafkaConsumerFactory.consumer(settings.getKafkaConsumer());
}

View file

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

View file

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

View file

@ -13,8 +13,9 @@ import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@ -28,22 +29,19 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.xml.importer.config.settings.ImportXMLServiceSettings;
import ru.spcex.clearing.xml.importer.logic.data.enums.ETable;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@Configuration
@EnableConfigurationProperties
public class XMLImporterConfig {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ImportXMLServiceSettings settings;
private final ApplicationContext context;
private final ImdgProvider hazelcastService;
private final HazelcastService hazelcastService;
public XMLImporterConfig(ImportXMLServiceSettings settings,
ApplicationContext context,
ImdgProvider hazelcastService) {
@Qualifier("hazelcastService") HazelcastService hazelcastService) {
this.settings = settings;
this.context = context;
this.hazelcastService = hazelcastService;
}
@ -62,6 +60,7 @@ public class XMLImporterConfig {
}
@Bean("mapOfTable")
@ConditionalOnProperty(value = "import-xml-service.process-sdf-files", havingValue = "true")
public Map<ETable, ImdgHazelcast<? extends SpcexObjectBase>> getMapOfTables() {
Map<ETable, ImdgHazelcast<? extends SpcexObjectBase>> map = new HashMap<>();
map.put(ETable.DF_01, (ImdgHazelcast<? extends SpcexObjectBase>) hazelcastService.getImdg(IMDGDistributedNames.Map_SDf01, SDf01.class));

View file

@ -1,6 +1,7 @@
package ru.spcex.clearing.xml.importer.config.settings;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.platform.messaging.config.element.KafkaConsumerSettings;
@ -11,13 +12,26 @@ import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
@PropertySource("file:${spring.config.location}/application.properties")
@ConfigurationProperties("import-xml-service")
public class ImportXMLServiceSettings {
@NestedConfigurationProperty
private HazelcastClientParams hazelcast;
@NestedConfigurationProperty
private KafkaProducerSettings kafkaProducer;
@NestedConfigurationProperty
private KafkaConsumerSettings kafkaConsumer;
@NestedConfigurationProperty
private StoreSettings storeSdf;
@NestedConfigurationProperty
private StoreSettings storeLks;
@NestedConfigurationProperty
private Common common;
private Store store;
@NestedConfigurationProperty
private Cron cron;
private boolean processSdfFiles;
private boolean processLksFiles;
public HazelcastClientParams getHazelcast() {
return hazelcast;
}
@ -42,6 +56,22 @@ public class ImportXMLServiceSettings {
this.kafkaConsumer = kafkaConsumer;
}
public StoreSettings getStoreSdf() {
return storeSdf;
}
public void setStoreSdf(StoreSettings storeSdf) {
this.storeSdf = storeSdf;
}
public StoreSettings getStoreLks() {
return storeLks;
}
public void setStoreLks(StoreSettings storeLks) {
this.storeLks = storeLks;
}
public Common getCommon() {
return common;
}
@ -50,14 +80,6 @@ public class ImportXMLServiceSettings {
this.common = common;
}
public Store getStore() {
return store;
}
public void setStore(Store store) {
this.store = store;
}
public Cron getCron() {
return cron;
}
@ -65,4 +87,20 @@ public class ImportXMLServiceSettings {
public void setCron(Cron cron) {
this.cron = cron;
}
public boolean isProcessSdfFiles() {
return processSdfFiles;
}
public void setProcessSdfFiles(boolean processSdfFiles) {
this.processSdfFiles = processSdfFiles;
}
public boolean isProcessLksFiles() {
return processLksFiles;
}
public void setProcessLksFiles(boolean processLksFiles) {
this.processLksFiles = processLksFiles;
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,13 +2,19 @@ package ru.spcex.clearing.xml.importer.logic.steps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.sdf.SDf57;
import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewRequest;
import ru.spcex.clearing.xml.importer.logic.data.ResultContainer;
import ru.spcex.clearing.xml.importer.logic.data.enums.ETable;
import ru.spcex.clearing.xml.importer.logic.data.enums.StageResult;
import ru.spcex.clearing.xml.importer.logic.data.tags.DocumentTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.objects.ObjectTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.AccountListCur;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.AccountListRub;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account.AccountTagCur;
import ru.spcex.clearing.xml.importer.logic.data.tags.lks.registrator.client.account.AccountTagRub;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.DocumentTag;
import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.ObjectTag;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.ObjectType;
import ru.spcex.platform.enumeration.Priority;
@ -20,7 +26,7 @@ public class ImportToDB {
private final HazelcastService hazelcastService;
private final XmlImportKafkaMessenger kafkaMessenger;
public ImportToDB(HazelcastService hazelcastService,
public ImportToDB(@Qualifier("hazelcastService") HazelcastService hazelcastService,
XmlImportKafkaMessenger kafkaMessenger) {
this.hazelcastService = hazelcastService;
this.kafkaMessenger = kafkaMessenger;
@ -28,10 +34,18 @@ public class ImportToDB {
public StageResult process(ResultContainer resultContainer) {
log.info("uuid {}. Stage: Import to DB", resultContainer.getUuid());
ETable currTable = resultContainer.getXmlTable();
DocumentTag documentTag = resultContainer.getDocumentTag();
String fileName = resultContainer.getXmlFile().getName();
return switch (resultContainer.getXmlTable().getFileType()) {
case SDF -> processSdfFile(resultContainer);
case LKS -> processLksFile(resultContainer);
};
}
private StageResult processSdfFile(ResultContainer resultContainer) {
ETable currTable = resultContainer.getXmlTable();
DocumentTag documentTag = (DocumentTag) resultContainer.getXmlFile();
String fileName = resultContainer.getXmlFilePath().getName();
Long fileId = hazelcastService.getImdgIdGenerator().nextId();
for (ObjectTag o : documentTag.getObjects()) {
o.setHazelcastService(hazelcastService);
@ -49,7 +63,7 @@ public class ImportToDB {
}
if (ETable.DF_01.equals(currTable)) {
kafkaMessenger.sendPairSdfRequest(fileName, fileId, currTable.getPrefix());
kafkaMessenger.sendPairSdfRequest(fileName, fileId, currTable.name());
}
kafkaMessenger.notifySystemIfNeeded(currTable, fileId);
kafkaMessenger.notifyUserAboutSuccessLoad(resultContainer);
@ -57,4 +71,65 @@ public class ImportToDB {
log.info("uuid {}. Stage import to DB finished with status {}", resultContainer.getUuid(), StageResult.OK);
return StageResult.OK;
}
private StageResult processLksFile(ResultContainer resultContainer) {
if (resultContainer.getXmlTable().equals(ETable.ACCOUNT_LIST_RUB)) {
AccountTagRub accountTagRub = ((AccountListRub) resultContainer.getXmlFile())
.getRegistrator()
.getClient()
.getAccount();
BankAccountNewRequest bankAccountNewRequest = new BankAccountNewRequest();
bankAccountNewRequest.setBankIdentificationCode(accountTagRub.getBic());
bankAccountNewRequest.setBankName(accountTagRub.getBankName());
bankAccountNewRequest.setCorrespondentAccount(accountTagRub.getCorrespondentAccount());
bankAccountNewRequest.setCurrency(accountTagRub.getCurrency());
bankAccountNewRequest.setDestination(accountTagRub.getDestination());
bankAccountNewRequest.setTaxpayerIdentificationNumber(accountTagRub.getTin());
bankAccountNewRequest.setTaxRegistrationReasonCode(accountTagRub.getTrrc());
bankAccountNewRequest.setAccount(accountTagRub.getAccount());
bankAccountNewRequest.setName(accountTagRub.getName());
bankAccountNewRequest.setBankAddress(accountTagRub.getBankAddress());
bankAccountNewRequest.setPersonalAccount(accountTagRub.getPersonalAccount());
bankAccountNewRequest.setBudgetClassificationCode(accountTagRub.getBudgetClassificationCode());
bankAccountNewRequest.setOktmo(accountTagRub.getOktmo());
// No DISCONTINUATION_DATE in BankAccountNewAction
boolean sendResult = kafkaMessenger.sendToBankAccount(bankAccountNewRequest);
return sendResult ? StageResult.OK : StageResult.ERROR;
} else if (resultContainer.getXmlTable().equals(ETable.ACCOUNT_LIST_CUR)) {
AccountTagCur accountTagCur = ((AccountListCur) resultContainer.getXmlFile())
.getRegistrator()
.getClient()
.getAccount();
BankAccountNewRequest bankAccountNewRequest = new BankAccountNewRequest();
bankAccountNewRequest.setBankName(accountTagCur.getBankName());
bankAccountNewRequest.setCurrency(accountTagCur.getCurrency());
bankAccountNewRequest.setDestination(accountTagCur.getDestination());
bankAccountNewRequest.setAccount(accountTagCur.getAccount());
bankAccountNewRequest.setSwiftCode(accountTagCur.getSwiftCode());
bankAccountNewRequest.setIntermediarySwiftCode(accountTagCur.getIntermediarySwiftCode1());
bankAccountNewRequest.setName(accountTagCur.getName());
bankAccountNewRequest.setAddress(accountTagCur.getAddress());
bankAccountNewRequest.setBankAddress(accountTagCur.getBankAddress());
bankAccountNewRequest.setBankSwiftCode(accountTagCur.getBankSwiftCode());
bankAccountNewRequest.setBankAccount(accountTagCur.getBankAccount());
bankAccountNewRequest.setBankName1(accountTagCur.getBankName1());
bankAccountNewRequest.setBankAddress1(accountTagCur.getBankAddress1());
bankAccountNewRequest.setBankAccount1(accountTagCur.getBankAccount1());
bankAccountNewRequest.setBankName2(accountTagCur.getBankName2());
bankAccountNewRequest.setBankAddress2(accountTagCur.getBankAddress2());
bankAccountNewRequest.setIntermediarySwiftCode2(accountTagCur.getIntermediarySwiftCode2());
bankAccountNewRequest.setBankAccount2(accountTagCur.getBankAccount2());
boolean sendResult = kafkaMessenger.sendToBankAccount(bankAccountNewRequest);
return sendResult ? StageResult.OK : StageResult.ERROR;
}
log.error("Table type {} is not supported", resultContainer.getXmlTable());
return StageResult.ERROR;
}
}

View file

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

View file

@ -2,15 +2,17 @@ package ru.spcex.clearing.xml.importer.logic.steps;
import static ru.spcex.clearing.platform.messaging.domain.Consts.PAIR_SDF;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.Sdf04Request;
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.NotificationNewRequest;
@ -28,11 +30,10 @@ import ru.spcex.platform.enumeration.SdfTable;
public class XmlImportKafkaMessenger implements InitializingBean {
final Logger log = LoggerFactory.getLogger(getClass());
private final Supplier<KafkaSender> kafka;
private final Map<ETable, Consumer<Long>> messengers;
private final Map<ETable, Consumer<Long>> messengers = new EnumMap<>(ETable.class);
public XmlImportKafkaMessenger(Supplier<KafkaSender> kafka) {
public XmlImportKafkaMessenger(@Qualifier("kafkaSender") Supplier<KafkaSender> kafka) {
this.kafka = kafka;
this.messengers = new HashMap<>();
}
@Override
@ -45,6 +46,18 @@ public class XmlImportKafkaMessenger implements InitializingBean {
messengers.put(ETable.DF_57, groupId -> messageStatement(groupId, SdfTable.SDF_57));
}
public boolean sendToBankAccount(BankAccountNewRequest bankAccountNewRequest) {
try {
kafka.get().sendRequestToQueue(Consts.DESTINATION_BANK_ACCOUNT_NEW, bankAccountNewRequest);
} catch (Exception e) {
log.error("Error occurred on sending message to kafka {}", e.getMessage(), e);
return false;
}
log.info("Message to {} was sent {}", Consts.DESTINATION_BANK_ACCOUNT_NEW, bankAccountNewRequest);
return true;
}
/**
* отправляет в кафку сообщение, при необходимости
* (обрабатывается, например, в balance-service, clearing-service)
@ -57,9 +70,9 @@ public class XmlImportKafkaMessenger implements InitializingBean {
}
public void notifyUserAboutErrorParsing(Throwable error, ResultContainer resultContainer) {
if (resultContainer == null || resultContainer.getXmlFile() == null)
if (resultContainer == null || resultContainer.getXmlFilePath() == null)
return;
String fileName = resultContainer.getXmlFile().getName();
String fileName = resultContainer.getXmlFilePath().getName();
log.debug("Notify user about error {} \"{}\"",
resultContainer.getXmlTable(), fileName);
sendUserNotification(ObjectType.rgst, String.format("Файл \"%s\" не сохранен", fileName), Priority.HIGH);
@ -70,7 +83,7 @@ public class XmlImportKafkaMessenger implements InitializingBean {
if (!(StageResult.OK == resultContainer.getLastStageStatus() || StageResult.COMPLETE == resultContainer.getLastStageStatus())) {
return;
}
String fileName = resultContainer.getXmlFile().getName();
String fileName = resultContainer.getXmlFilePath().getName();
log.debug("Notify user about success {} \"{}\"",
resultContainer.getXmlTable(), fileName);
sendUserNotification(ObjectType.rgst, String.format("Загружен \"%s\" - успешно", fileName), Priority.LOW);
@ -84,8 +97,9 @@ public class XmlImportKafkaMessenger implements InitializingBean {
request.setPriority(priority.getKey());
request.setComment(comment);
log.debug("Send message to kafka \"{}\": {}", destination, LogFormatter.toStringWrapper(request));
Long rKey = kafka.get().sendRequestToQueue(destination, request);
log.trace("For user send message, request id={}", rKey);
log.trace("For user send message to kafka, request id={}", rKey);
}
private void messageStatement(Long groupId, SdfTable table) {
@ -96,6 +110,7 @@ public class XmlImportKafkaMessenger implements InitializingBean {
StatementRequest statementRequest = new StatementRequest();
statementRequest.setGroupId(groupId);
statementRequest.setTable(table);
Long msgId = kafka.get().sendRequestToQueue(destination, statementRequest);
log.debug("Send StatementRequest({}, {}) message id={} to kafka \"{}\"",
groupId, table, msgId, destination);
@ -106,13 +121,15 @@ public class XmlImportKafkaMessenger implements InitializingBean {
request.setFileNameSDf(fileName);
request.setGenerationId(fileId);
request.setTableSDf(tableSdf);
Long msgId = kafka.get().sendRequestToQueue(PAIR_SDF, request);
log.info("Send PairSdfRequest={} message id={} to kafka \"{}\"", LogFormatter.toString(request), msgId, PAIR_SDF);
log.info("Send PairSdfRequest={} message id={} to SDF kafka \"{}\"", LogFormatter.toString(request), msgId, PAIR_SDF);
}
private void messageDf04(Long groupId) {
Sdf04Request sdf04ImportNotification = new Sdf04Request();
sdf04ImportNotification.setGroupId(groupId);
kafka.get().sendRequestToQueue(Consts.SDF04_PROCESS, sdf04ImportNotification);
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -112,7 +112,11 @@ public abstract class HazelcastServiceBase
break;
}
});
} catch (Throwable e) {
} catch (InterruptedException e) {
log.info("Hazelcast: event interrupted");
Thread.currentThread().interrupt();
}
catch (Throwable e) {
log.error("reinitializeHazelcastClient() has error: {}", ExceptionUtils.getStackTrace(e));
}
}

View file

@ -29,6 +29,37 @@ public class BankAccountNewRequest {
public String swiftCode;
@JsonProperty
private String intermediarySwiftCode;
@JsonProperty
private String name;
@JsonProperty
private String address;
@JsonProperty
private String bankAddress;
@JsonProperty
private String bankSwiftCode;
@JsonProperty
private String bankAccount;
@JsonProperty
private String bankName1;
@JsonProperty
private String bankAddress1;
@JsonProperty
private String bankAccount1;
@JsonProperty
private String bankName2;
@JsonProperty
private String bankAddress2;
@JsonProperty
private String intermediarySwiftCode2;
@JsonProperty
private String bankAccount2;
@JsonProperty
private String personalAccount;
@JsonProperty
private String budgetClassificationCode;
@JsonProperty
private String oktmo;
public String getBankIdentificationCode() {
return bankIdentificationCode;
@ -133,4 +164,124 @@ public class BankAccountNewRequest {
public void setIntermediarySwiftCode(String intermediarySwiftCode) {
this.intermediarySwiftCode = intermediarySwiftCode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getBankAddress() {
return bankAddress;
}
public void setBankAddress(String bankAddress) {
this.bankAddress = bankAddress;
}
public String getBankSwiftCode() {
return bankSwiftCode;
}
public void setBankSwiftCode(String bankSwiftCode) {
this.bankSwiftCode = bankSwiftCode;
}
public String getBankAccount() {
return bankAccount;
}
public void setBankAccount(String bankAccount) {
this.bankAccount = bankAccount;
}
public String getBankName1() {
return bankName1;
}
public void setBankName1(String bankName1) {
this.bankName1 = bankName1;
}
public String getBankAddress1() {
return bankAddress1;
}
public void setBankAddress1(String bankAddress1) {
this.bankAddress1 = bankAddress1;
}
public String getBankAccount1() {
return bankAccount1;
}
public void setBankAccount1(String bankAccount1) {
this.bankAccount1 = bankAccount1;
}
public String getBankName2() {
return bankName2;
}
public void setBankName2(String bankName2) {
this.bankName2 = bankName2;
}
public String getBankAddress2() {
return bankAddress2;
}
public void setBankAddress2(String bankAddress2) {
this.bankAddress2 = bankAddress2;
}
public String getIntermediarySwiftCode2() {
return intermediarySwiftCode2;
}
public void setIntermediarySwiftCode2(String intermediarySwiftCode2) {
this.intermediarySwiftCode2 = intermediarySwiftCode2;
}
public String getBankAccount2() {
return bankAccount2;
}
public void setBankAccount2(String bankAccount2) {
this.bankAccount2 = bankAccount2;
}
public String getPersonalAccount() {
return personalAccount;
}
public void setPersonalAccount(String personalAccount) {
this.personalAccount = personalAccount;
}
public String getBudgetClassificationCode() {
return budgetClassificationCode;
}
public void setBudgetClassificationCode(String budgetClassificationCode) {
this.budgetClassificationCode = budgetClassificationCode;
}
public String getOktmo() {
return oktmo;
}
public void setOktmo(String oktmo) {
this.oktmo = oktmo;
}
}

View file

@ -27,6 +27,36 @@ public class BankAccountUpdateRequest {
public String swiftCode;
@JsonProperty
private String intermediarySwiftCode;
@JsonProperty
private String name;
@JsonProperty
private String address;
@JsonProperty
private String bankAddress;
@JsonProperty
private String bankSwiftCode;
@JsonProperty
private String bankAccount;
@JsonProperty
private String bankName1;
@JsonProperty
private String bankAddress1;
@JsonProperty
private String bankAccount1;
@JsonProperty
private String bankName2;
@JsonProperty
private String bankAddress2;
@JsonProperty
private String intermediarySwiftCode2;
@JsonProperty
private String bankAccount2;
@JsonProperty
private String personalAccount;
@JsonProperty
private String budgetClassificationCode;
@JsonProperty
private String oktmo;
public Long getId() {
return id;
@ -123,4 +153,124 @@ public class BankAccountUpdateRequest {
public void setIntermediarySwiftCode(String intermediarySwiftCode) {
this.intermediarySwiftCode = intermediarySwiftCode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getBankAddress() {
return bankAddress;
}
public void setBankAddress(String bankAddress) {
this.bankAddress = bankAddress;
}
public String getBankSwiftCode() {
return bankSwiftCode;
}
public void setBankSwiftCode(String bankSwiftCode) {
this.bankSwiftCode = bankSwiftCode;
}
public String getBankAccount() {
return bankAccount;
}
public void setBankAccount(String bankAccount) {
this.bankAccount = bankAccount;
}
public String getBankName1() {
return bankName1;
}
public void setBankName1(String bankName1) {
this.bankName1 = bankName1;
}
public String getBankAddress1() {
return bankAddress1;
}
public void setBankAddress1(String bankAddress1) {
this.bankAddress1 = bankAddress1;
}
public String getBankAccount1() {
return bankAccount1;
}
public void setBankAccount1(String bankAccount1) {
this.bankAccount1 = bankAccount1;
}
public String getBankName2() {
return bankName2;
}
public void setBankName2(String bankName2) {
this.bankName2 = bankName2;
}
public String getBankAddress2() {
return bankAddress2;
}
public void setBankAddress2(String bankAddress2) {
this.bankAddress2 = bankAddress2;
}
public String getIntermediarySwiftCode2() {
return intermediarySwiftCode2;
}
public void setIntermediarySwiftCode2(String intermediarySwiftCode2) {
this.intermediarySwiftCode2 = intermediarySwiftCode2;
}
public String getBankAccount2() {
return bankAccount2;
}
public void setBankAccount2(String bankAccount2) {
this.bankAccount2 = bankAccount2;
}
public String getPersonalAccount() {
return personalAccount;
}
public void setPersonalAccount(String personalAccount) {
this.personalAccount = personalAccount;
}
public String getBudgetClassificationCode() {
return budgetClassificationCode;
}
public void setBudgetClassificationCode(String budgetClassificationCode) {
this.budgetClassificationCode = budgetClassificationCode;
}
public String getOktmo() {
return oktmo;
}
public void setOktmo(String oktmo) {
this.oktmo = oktmo;
}
}

View file

@ -2,6 +2,17 @@ package ru.spcex.clearing.platform.messaging.service;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
@ -24,17 +35,6 @@ import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.log.ExceptionUtils;
import ru.spcex.platform.utils.validation.IValidator;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
/**
* утилитный класс для обработки сообщений из очереди
*/
@ -129,6 +129,7 @@ public class QueueConsumer implements AutoCloseable {
try {
Thread.sleep(1000L);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
log.info("Thread interrupted. {}", ExceptionUtils.getStackTrace(ie));
break;
}
@ -196,7 +197,10 @@ public class QueueConsumer implements AutoCloseable {
}
send = producer.send(respRec);
send.get();
} catch (Exception e) {
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error(ExceptionUtils.getStackTrace(e));
} catch (ExecutionException e) {
log.error(ExceptionUtils.getStackTrace(e));
}
});

View file

@ -1,19 +1,20 @@
package ru.spcex.clearing.platform.messaging.service;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
@ -103,7 +104,8 @@ public class QueueConsumerV2 implements AutoCloseable {
log.warn("Too many error at row, {}. Sleep.", lastErrors);
try {
Thread.sleep(1000L);
} catch (InterruptedException e){
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.info("Thread interrupted. {}", ExceptionUtils.getStackTrace(e));
break;
}
@ -215,7 +217,10 @@ public class QueueConsumerV2 implements AutoCloseable {
}
send = producer.send(respRec);
send.get();
} catch (Exception e) {
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error(ExceptionUtils.getStackTrace(e));
} catch (ExecutionException e) {
log.error(ExceptionUtils.getStackTrace(e));
}
});