xml-importer http://jira.mfd.msk:8088/browse/CLS-824 валидация ключевых полей

This commit is contained in:
AKurakin 2025-04-17 12:37:49 +03:00
parent 9f3ed39ef3
commit c7bd6c17ad
4 changed files with 185 additions and 1 deletions

View file

@ -66,6 +66,12 @@
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-imdg-api</artifactId>

View file

@ -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<String> fields = new ArrayList<>();
public ValidationException(String message) {
super(message);
}
public ValidationException(String message, List<String> fields) {
super(message + ": " + fields.stream().collect(Collectors.joining(", ")));
this.fields = Objects.requireNonNull(fields);
}
public ValidationException(String message, Throwable cause) {
super(message, cause);
}
public List<String> getFields() {
return fields;
}
}

View file

@ -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<String> 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;
}
}
}

View file

@ -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) {