diff --git a/clearing-parent/xml-importer/pom.xml b/clearing-parent/xml-importer/pom.xml index fa9aa21b7..726099b7a 100644 --- a/clearing-parent/xml-importer/pom.xml +++ b/clearing-parent/xml-importer/pom.xml @@ -66,6 +66,12 @@ com.fasterxml.jackson.datatype jackson-datatype-jsr310 + + + org.apache.commons + commons-lang3 + 3.7 + ru.spcex.platform platform-imdg-api diff --git a/clearing-parent/xml-importer/src/main/java/ru/spcex/clearing/xml/importer/logic/data/error/ValidationException.java b/clearing-parent/xml-importer/src/main/java/ru/spcex/clearing/xml/importer/logic/data/error/ValidationException.java new file mode 100644 index 000000000..49212bbd4 --- /dev/null +++ b/clearing-parent/xml-importer/src/main/java/ru/spcex/clearing/xml/importer/logic/data/error/ValidationException.java @@ -0,0 +1,27 @@ +package ru.spcex.clearing.xml.importer.logic.data.error; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class ValidationException extends Exception { + protected List fields = new ArrayList<>(); + + public ValidationException(String message) { + super(message); + } + + public ValidationException(String message, List fields) { + super(message + ": " + fields.stream().collect(Collectors.joining(", "))); + this.fields = Objects.requireNonNull(fields); + } + + public ValidationException(String message, Throwable cause) { + super(message, cause); + } + + public List getFields() { + return fields; + } +} diff --git a/clearing-parent/xml-importer/src/main/java/ru/spcex/clearing/xml/importer/logic/steps/ReadXMLFile.java b/clearing-parent/xml-importer/src/main/java/ru/spcex/clearing/xml/importer/logic/steps/ReadXMLFile.java index 12b22b9c8..c91d8db43 100644 --- a/clearing-parent/xml-importer/src/main/java/ru/spcex/clearing/xml/importer/logic/steps/ReadXMLFile.java +++ b/clearing-parent/xml-importer/src/main/java/ru/spcex/clearing/xml/importer/logic/steps/ReadXMLFile.java @@ -1,7 +1,12 @@ package ru.spcex.clearing.xml.importer.logic.steps; import com.fasterxml.jackson.dataformat.xml.XmlMapper; + import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedHashSet; + +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; @@ -10,9 +15,14 @@ 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.error.ValidationException; import ru.spcex.clearing.xml.importer.logic.data.tags.lks.AccountListCur; import ru.spcex.clearing.xml.importer.logic.data.tags.lks.AccountListRub; import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.DocumentTag; +import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF01ObjectTag; +import ru.spcex.clearing.xml.importer.logic.data.tags.sdf.objects.DF06ObjectTag; +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.utils.log.ExceptionUtils; @Component @@ -32,6 +42,7 @@ public class ReadXMLFile { try { if (resultContainer.getXmlTable().getFileType().equals(FileType.SDF)) { resultContainer.setXmlFile(xmlMapper.readValue(resultContainer.getXmlFilePath(), DocumentTag.class)); + validateXml(resultContainer); } else if (resultContainer.getXmlTable().getFileType().equals(FileType.LKS)) { if (resultContainer.getXmlTable().equals(ETable.ACCOUNT_LIST_RUB)) { resultContainer.setXmlFile(xmlMapper.readValue(resultContainer.getXmlFilePath(), AccountListRub.class)); @@ -46,6 +57,138 @@ public class ReadXMLFile { kafkaMessenger.notifyUserAboutErrorParsing(e, resultContainer); log.info("uuid {}. Stage reading from XML file finished with status {}", resultContainer.getUuid(), StageResult.ERROR); return StageResult.ERROR; + } catch (ValidationException e) { + log.warn("Validation error for file \"{}\": {}", resultContainer.getXmlFilePath(), e.getMessage()); + kafkaMessenger.notifyUserAboutErrorParsing(e, resultContainer); + log.info("uuid {}. Stage reading from XML file finished with status {}", resultContainer.getUuid(), StageResult.ERROR); + return StageResult.ERROR; } } + + protected void validateXml(ResultContainer container) throws ValidationException { + LinkedHashSet lostField = new LinkedHashSet<>(); + if (ETable.DF_01 == container.getXmlTable()) { + log.trace("Validate DF01"); + DocumentTag sdf01 = (DocumentTag) container.getXmlFile(); + for (Object rawrow : sdf01.getObjects()) { + if (rawrow instanceof DF01ObjectTag row) { + if (row.getCurrCode() == null) + lostField.add("CURR_CODE"); + if (row.getAccount() == null) + lostField.add("ACCOUNT"); + if (row.getRemainder() == null) + lostField.add("REMAINDER"); + if (row.getDat() == null) + lostField.add("DAT"); + if (row.getMarket() == null) + lostField.add("MARKET"); + if (row.getAccType() == null) + lostField.add("ACC_TYPE"); + } else { + log.warn("Unexpected row type: {}", rawrow); + throw new ValidationException("DF01: wrong row format"); + } + } + } else if (ETable.DF_06 == container.getXmlTable()) { + log.trace("Validate DF06"); + DocumentTag sdf06 = (DocumentTag) container.getXmlFile(); + for (Object rawrow : sdf06.getObjects()) { + if (rawrow instanceof DF06ObjectTag row) { + if (row.getAccount() == null) + lostField.add("Account"); + if (row.getSum() == null) + lostField.add("Sum"); + if (row.getMarket() == null) + lostField.add("Market"); + if (row.getDeal() == null) + lostField.add("DEAL"); + if (row.getSpec() == null) + lostField.add("SPEC"); + if (row.getNumber() == null) + lostField.add("Number"); + if (row.getDocNum() == null) + lostField.add("Doc_Num"); + if (row.getDocDate() == null) + lostField.add("Doc_Date"); + if (row.getPayVal() == null) + lostField.add("Pay_Val"); + } else { + log.warn("Unexpected row type: {}", rawrow); + throw new ValidationException("DF06: wrong row format"); + } + } + } else if (ETable.DF_55 == container.getXmlTable()) { + log.trace("Validate DF55"); + DocumentTag sdf55 = (DocumentTag) container.getXmlFile(); + for (Object rawrow : sdf55.getObjects()) { + if (rawrow instanceof DF55ObjectTag row) { + if (row.getDocnmRef() == null) + lostField.add("DOCNM_REF"); + if (row.getDocnmprev() == null) + lostField.add("DOCNMPREV"); + if (row.getPayVal() == null) + lostField.add("PAY_VAL"); + if (row.getSumDeb() == null) + lostField.add("SUM_DEB"); + if (row.getSpecif1() == null) + lostField.add("SPECIF_1"); + if (row.getDocResult() == null) + lostField.add("DOC_RESULT"); + } else { + log.warn("Unexpected row type: {}", rawrow); + throw new ValidationException("DF55: wrong row format"); + } + } + } else if (ETable.DF_57 == container.getXmlTable()) { + log.trace("Validate DF57"); + DocumentTag sdf57 = (DocumentTag) container.getXmlFile(); + for (Object rawrow : sdf57.getObjects()) { + if (rawrow instanceof DF57ObjectTag row) { + if (row.getId() == null) + lostField.add("ID"); + if (row.getDealDeb() == null && StringUtils.isNotEmpty(row.getAccDeb())) + lostField.add("DEAL_DEB"); + if (row.getDealCred() == null && StringUtils.isNotEmpty(row.getAccKr())) + lostField.add("DEAL_CRED"); + if (row.getPayDate() == null) + lostField.add("PAY_DATE"); + if (row.getExtDate() == null) + lostField.add("EXT_DATE"); + if (row.getPayVal() == null) + lostField.add("PAY_VAL"); + if (row.getSumDeb() == null) + lostField.add("SUM_DEB"); + if (row.getAccDeb() == null) + lostField.add("ACC_DEB"); + if (row.getAccKr() == null) + lostField.add("ACC_KR"); + if (row.getSpecif() == null) + lostField.add("SPECIF"); + if (row.getDocNum() == null) + lostField.add("DOC_NUM"); + if (row.getDocDate() == null) + lostField.add("DOC_DATE"); + if (row.getDtIn() == null) + lostField.add("DT_IN"); + if (row.getKtIn() == null) + lostField.add("KT_IN"); + if (row.getDtOut() == null) + lostField.add("DT_OUT"); + if (row.getKtOut() == null) + lostField.add("KT_OUT"); + } else { + log.warn("Unexpected row type: {}", rawrow); + throw new ValidationException("DF57: wrong row format"); + } + } + } else { + log.trace("No need validate {}", container.getXmlTable()); + } + if (!lostField.isEmpty()) { + ValidationException validateResult = new ValidationException("Cross validate of " + container.getXmlTable().name(), new ArrayList<>(lostField)); + log.debug("Cross validate error: {}", validateResult.toString()); + throw validateResult; + } + } + } diff --git a/clearing-parent/xml-importer/src/main/java/ru/spcex/clearing/xml/importer/logic/steps/XmlImportKafkaMessenger.java b/clearing-parent/xml-importer/src/main/java/ru/spcex/clearing/xml/importer/logic/steps/XmlImportKafkaMessenger.java index 374c785b8..1e602d4a2 100644 --- a/clearing-parent/xml-importer/src/main/java/ru/spcex/clearing/xml/importer/logic/steps/XmlImportKafkaMessenger.java +++ b/clearing-parent/xml-importer/src/main/java/ru/spcex/clearing/xml/importer/logic/steps/XmlImportKafkaMessenger.java @@ -6,6 +6,8 @@ import java.util.EnumMap; import java.util.Map; import java.util.function.Consumer; import java.util.function.Supplier; +import java.util.stream.Collectors; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; @@ -22,6 +24,7 @@ import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; 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.error.ValidationException; import ru.spcex.platform.enumeration.ObjectType; import ru.spcex.platform.enumeration.Priority; import ru.spcex.platform.enumeration.SdfTable; @@ -75,7 +78,12 @@ public class XmlImportKafkaMessenger implements InitializingBean { String fileName = resultContainer.getXmlFilePath().getName(); log.debug("Notify user about error {} \"{}\"", resultContainer.getXmlTable(), fileName); - sendUserNotification(ObjectType.rgst, String.format("Файл \"%s\" не сохранен", fileName), Priority.HIGH); + String message = String.format("Файл \"%s\" не сохранен", fileName); + if (error instanceof ValidationException validationException) { + message = String.format("Файл \"%s\" не загружен. Не заполнены ключевые поля : %s", fileName, + validationException.getFields().stream().collect(Collectors.joining(", "))); + } + sendUserNotification(ObjectType.rgst, message, Priority.HIGH); } public void notifyUserAboutSuccessLoad(ResultContainer resultContainer) {