Removed FailureAnswerGenerator and SuccessAnswerGenerator; Added staxReader for exceptions handling from nbki service; Minor refactoring
This commit is contained in:
parent
d85f97a025
commit
16bb8eb723
14 changed files with 397 additions and 195 deletions
|
|
@ -0,0 +1,23 @@
|
|||
package ru.nbch.credit_tracker.entities.response.external_errors;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import jakarta.xml.bind.annotation.XmlType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"name",
|
||||
"description"
|
||||
})
|
||||
public class Error {
|
||||
|
||||
@XmlElement(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlElement(name = "description", required = true)
|
||||
protected String description;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package ru.nbch.credit_tracker.entities.response.external_errors;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import jakarta.xml.bind.annotation.XmlType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"memberCode",
|
||||
"packCode"
|
||||
})
|
||||
public class InputParams {
|
||||
|
||||
@XmlElement(name = "memberCode", required = true)
|
||||
protected String memberCode;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package ru.nbch.credit_tracker.entities.response.external_errors;
|
||||
|
||||
import jakarta.xml.bind.annotation.*;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"inputParams",
|
||||
"error"
|
||||
})
|
||||
@XmlRootElement(name = "SgnlReport")
|
||||
public class SgnlReport {
|
||||
|
||||
@XmlElement(name = "InputParams", required = true)
|
||||
protected InputParams inputParams;
|
||||
@XmlElement(name = "Error", required = true)
|
||||
protected Error error;
|
||||
}
|
||||
|
|
@ -24,8 +24,6 @@ import ru.nbch.credit_tracker.service.SignalService;
|
|||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
||||
import ru.nbch.credit_tracker.service.scoring.AuthorizationService;
|
||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
||||
import ru.nbch.credit_tracker.service.xml.FailureAnswerGenerator;
|
||||
import ru.nbch.credit_tracker.service.xml.SuccessAnswerGenerator;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||
|
|
@ -48,8 +46,6 @@ public class SignalFacade {
|
|||
private final AuthorizationService authorizationService;
|
||||
private final SignalService signalService;
|
||||
private final SignalRestService signalRestService;
|
||||
private final FailureAnswerGenerator failureAnswerGenerator;
|
||||
private final SuccessAnswerGenerator successAnswerGenerator;
|
||||
private final XmlUtilService xmlUtilService;
|
||||
|
||||
private final ExecutorService executor;
|
||||
|
|
@ -59,16 +55,12 @@ public class SignalFacade {
|
|||
AuthorizationService authorizationService,
|
||||
SignalService signalService,
|
||||
SignalRestService signalRestService,
|
||||
FailureAnswerGenerator failureAnswerGenerator,
|
||||
SuccessAnswerGenerator successAnswerGenerator,
|
||||
XmlUtilService xmlUtilService,
|
||||
@Qualifier("executorService") ExecutorService executor) {
|
||||
this.config = config;
|
||||
this.authorizationService = authorizationService;
|
||||
this.signalService = signalService;
|
||||
this.signalRestService = signalRestService;
|
||||
this.failureAnswerGenerator = failureAnswerGenerator;
|
||||
this.successAnswerGenerator = successAnswerGenerator;
|
||||
this.xmlUtilService = xmlUtilService;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
|
@ -256,15 +248,6 @@ public class SignalFacade {
|
|||
file.getOriginalFilename() != null && file.getOriginalFilename().toLowerCase().endsWith(".zip");
|
||||
}
|
||||
|
||||
private ResponseEntity<Resource> getBadResponse(SignalError error, String tag) {
|
||||
Resource answer = failureAnswerGenerator.generateFailureAnswer(error, tag);
|
||||
return ResponseEntity.badRequest().body(answer);
|
||||
}
|
||||
|
||||
private ResponseEntity<Resource> getBadResponse(SignalError error) {
|
||||
return getBadResponse(error, null);
|
||||
}
|
||||
|
||||
public ResponseEntity<MonitoringActivePackagesResponse> findActivePackages(MonitoringActivePackagesRequest activePackagesRequest) {
|
||||
try {
|
||||
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(activePackagesRequest.getUserId(), activePackagesRequest.getPassword());
|
||||
|
|
|
|||
|
|
@ -60,6 +60,10 @@ public class MonitoringService {
|
|||
for (PackageData packageData : packages) {
|
||||
SgnlOnlineReport onlineReports = signalRestService.getReports(packageData.getUserId().substring(0, 6) + "_" + packageData.getPackageName());
|
||||
|
||||
if (onlineReports == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<String> fileNames = onlineReports.getOperationReport().getReports().getReports().stream().map(Report::getFilename)
|
||||
.filter(fileName -> CTUtil.parseDateFromReportFileName(fileName) != null).toList(); // TODO оптимизировать
|
||||
|
||||
|
|
|
|||
|
|
@ -11,18 +11,18 @@ import org.springframework.util.LinkedMultiValueMap;
|
|||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||
import ru.nbch.credit_tracker.entities.response.external_errors.SgnlReport;
|
||||
import ru.nbch.credit_tracker.entities.response.online_report.SgnlOnlineReport;
|
||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
||||
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Base64;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
@Slf4j
|
||||
|
|
@ -64,13 +64,116 @@ public class SignalRestService {
|
|||
// good response
|
||||
return true;
|
||||
} else if (response.getStatusCode().value() == 200 && response.getBody() != null) {
|
||||
// bad response
|
||||
log.error("Ошибка при постановке пакета на мониторинг в официальный сервис сигналов: {}", response.getBody());
|
||||
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
||||
SgnlReport error = staxXmlProcessor.read(response.getBody(), SgnlReport.class);
|
||||
if (error.getError().getDescription() != null) {
|
||||
log.error("Ошибка при постановке пакета на мониторинг в официальный сервис сигналов: {}", error.getError().getDescription());
|
||||
} else {
|
||||
log.error("неизвестная ошибка при постановке пакета на мониторинг в официальный сервис сигналов: {}", response.getBody());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void deletePackage(String username, String packageName) {
|
||||
String packCode = username.substring(0, 6) + "_" + packageName;
|
||||
String url = DELETE_URI + "?packCode=" + packCode;
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBasicAuth(authToken);
|
||||
|
||||
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
|
||||
|
||||
ResponseEntity<String> response = restTemplate.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
requestEntity,
|
||||
String.class
|
||||
);
|
||||
String answer = response.getBody();
|
||||
|
||||
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
||||
SgnlReport error = staxXmlProcessor.read(answer, SgnlReport.class);
|
||||
if (error.getError().getDescription() != null) {
|
||||
log.error("Ошибка при удалении пакета из сервиса НБКИ. packCode={}. Описание: {}", packCode, error.getError().getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
public SgnlOnlineReport getReports(String packCode) {
|
||||
String url = GET_REPORTS_URI + "?packCode=" + packCode;
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBasicAuth(authToken);
|
||||
|
||||
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
|
||||
|
||||
ResponseEntity<String> response = restTemplate.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
requestEntity,
|
||||
String.class
|
||||
);
|
||||
|
||||
String answer = response.getBody();
|
||||
|
||||
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
||||
SgnlReport error = staxXmlProcessor.read(answer, SgnlReport.class);
|
||||
if (error.getError().getDescription() != null) {
|
||||
log.error("Ошибка при получении пакета из сервиса НБКИ. packCode={}. Описание: {}", packCode, error.getError().getDescription());
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
||||
return processor.read(answer, SgnlOnlineReport.class);
|
||||
} catch (Exception e) {
|
||||
log.error("Ошибка при получении пакета из сервиса НБКИ. Код ошибки: {} packCode={}", response.getStatusCode().value(), packCode);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] downloadReport(String reportName) {
|
||||
String url = DOWNLOAD_REPORT_URI + "?fNameReport=" + reportName;
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBasicAuth(authToken);
|
||||
|
||||
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
|
||||
|
||||
ResponseEntity<byte[]> response = restTemplate.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
requestEntity,
|
||||
byte[].class
|
||||
);
|
||||
|
||||
byte[] answer = response.getBody();
|
||||
if (isXmlError(response.getBody())) {
|
||||
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
||||
SgnlReport error = staxXmlProcessor.read(answer, SgnlReport.class);
|
||||
if (error.getError().getDescription() != null) {
|
||||
log.error("Ошибка при скачивание отчета. fNameReport={}. Описание: {}", reportName, error.getError().getDescription());
|
||||
return null;
|
||||
}
|
||||
log.error("Неизвестная ошибка при скачивание отчета. fNameReport={}", reportName);
|
||||
return null;
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
private String buildToken(String signalsToken, String signalsuser) throws Exception {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] messageDigest = md.digest((signalsuser + "|" + signalsToken).getBytes(StandardCharsets.UTF_8));
|
||||
String hash = DatatypeConverter.printHexBinary(messageDigest).toLowerCase();
|
||||
Base64.Encoder encoder = Base64.getEncoder();
|
||||
return encoder.encodeToString((signalsuser + ":" + hash).getBytes(StandardCharsets.UTF_8));
|
||||
} catch (Exception e) {
|
||||
log.error("Error building token", e);
|
||||
throw new Exception("Error building token", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Resource compressFile(Signals signals) throws Exception {
|
||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
||||
String requestData = processor.asString(signals, false);
|
||||
|
|
@ -88,85 +191,9 @@ public class SignalRestService {
|
|||
};
|
||||
}
|
||||
|
||||
public void deletePackage(String username, String packageName) {
|
||||
String packCode = username.substring(0, 6) + "_" + packageName;
|
||||
String url = DELETE_URI + "?packCode=" + packCode;
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBasicAuth(authToken);
|
||||
|
||||
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
|
||||
|
||||
ResponseEntity<String> response = restTemplate.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
requestEntity,
|
||||
String.class
|
||||
);
|
||||
String answer = response.getBody();
|
||||
if (response.getStatusCode().value() == 200 && answer != null && answer.contains("<Error>")) {
|
||||
if (answer.contains("<description>")) {
|
||||
Pattern pattern = Pattern.compile("<description>(.*?)</description>");
|
||||
Matcher matcher = pattern.matcher(answer);
|
||||
if (matcher.find()) {
|
||||
String description = matcher.group(1);
|
||||
log.error("Ошибка при удалении пакета из сервиса НБКИ. packCode={}. Описание: {}", packCode, description);
|
||||
}
|
||||
} else {
|
||||
log.error("Ошибка при удалении пакета из сервиса НБКИ. packCode={}", packCode);
|
||||
}
|
||||
} else if (response.getStatusCode().value() != 200) {
|
||||
log.error("Ошибка при удалении пакета из сервиса НБКИ. Код ошибки: {} packCode={}", response.getStatusCode().value(), packCode);
|
||||
}
|
||||
}
|
||||
|
||||
public SgnlOnlineReport getReports(String packCode) {
|
||||
String url = GET_REPORTS_URI + "?packCode=" + packCode;
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBasicAuth(authToken);
|
||||
|
||||
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
|
||||
|
||||
ResponseEntity<SgnlOnlineReport> response = restTemplate.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
requestEntity,
|
||||
SgnlOnlineReport.class
|
||||
);
|
||||
|
||||
// TODO обработка ошибок
|
||||
|
||||
return response.getBody();
|
||||
}
|
||||
|
||||
public byte[] downloadReport(String reportName) {
|
||||
String url = DOWNLOAD_REPORT_URI + "?fNameReport=" + reportName;
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBasicAuth(authToken);
|
||||
|
||||
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
|
||||
|
||||
ResponseEntity<byte[]> response = restTemplate.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
requestEntity,
|
||||
byte[].class
|
||||
);
|
||||
|
||||
return response.getBody();
|
||||
}
|
||||
|
||||
private String buildToken(String signalsToken, String signalsuser) throws Exception {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] messageDigest = md.digest((signalsuser + "|" + signalsToken).getBytes(StandardCharsets.UTF_8));
|
||||
String hash = DatatypeConverter.printHexBinary(messageDigest).toLowerCase();
|
||||
Base64.Encoder encoder = Base64.getEncoder();
|
||||
return encoder.encodeToString((signalsuser + ":" + hash).getBytes(StandardCharsets.UTF_8));
|
||||
} catch (Exception e) {
|
||||
log.error("Error building token", e);
|
||||
throw new Exception("Error building token", e);
|
||||
}
|
||||
private boolean isXmlError(byte[] data) {
|
||||
if (data == null || data.length < 10) return false;
|
||||
String start = new String(data, 0, 10).trim();
|
||||
return start.startsWith("<?xml");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
package ru.nbch.credit_tracker.service.xml;
|
||||
|
||||
import jakarta.xml.bind.JAXBException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringError;
|
||||
import ru.nbch.credit_tracker.enums.SignalError;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class FailureAnswerGenerator {
|
||||
private final XmlUtilService xmlUtilService;
|
||||
|
||||
public FailureAnswerGenerator(XmlUtilService xmlUtilService) {
|
||||
this.xmlUtilService = xmlUtilService;
|
||||
}
|
||||
|
||||
public Resource generateFailureAnswer(SignalError error) {
|
||||
return generateFailureAnswer(error, null);
|
||||
}
|
||||
|
||||
// TODO extend with common errorResponse class
|
||||
public Resource generateFailureAnswer(SignalError error, String tag) {
|
||||
try {
|
||||
IXmlProcessor xmlProcessor = xmlUtilService.createJaxbProcessor();
|
||||
String errorMessage = xmlProcessor.asString(createErrorMessage(error, tag), false, StandardCharsets.UTF_8.name());
|
||||
byte[] xmlBytes = errorMessage.getBytes(StandardCharsets.UTF_8);
|
||||
return new ByteArrayResource(xmlBytes);
|
||||
} catch (JAXBException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private MonitoringError createErrorMessage(SignalError error, String tag) {
|
||||
MonitoringError errorMessage = new MonitoringError();
|
||||
errorMessage.setStatus("error");
|
||||
errorMessage.setErrorCode(error.getCode());
|
||||
if (tag != null) {
|
||||
errorMessage.setErrorText(error.getMessage() + " " + tag);
|
||||
} else {
|
||||
errorMessage.setErrorText(error.getMessage());
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
package ru.nbch.credit_tracker.service.xml;
|
||||
|
||||
import jakarta.xml.bind.JAXBException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SuccessAnswerGenerator {
|
||||
|
||||
private final XmlUtilService xmlUtilService;
|
||||
|
||||
public SuccessAnswerGenerator(XmlUtilService xmlUtilService) {
|
||||
this.xmlUtilService = xmlUtilService;
|
||||
}
|
||||
|
||||
// TODO extend with common successResponse class
|
||||
public Resource generateSuccessAnswer(Class clazz) {
|
||||
try {
|
||||
IXmlProcessor xmlProcessor = xmlUtilService.createJaxbProcessor();
|
||||
String errorMessage = xmlProcessor.asString(createSuccessMessage(), false, StandardCharsets.UTF_8.name());
|
||||
byte[] xmlBytes = errorMessage.getBytes(StandardCharsets.UTF_8);
|
||||
return new ByteArrayResource(xmlBytes);
|
||||
} catch (JAXBException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private MonitoringResponse createSuccessMessage() {
|
||||
return new MonitoringResponse();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,8 +7,13 @@ import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequ
|
|||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringError;
|
||||
import ru.nbch.credit_tracker.entities.response.monitoring_signal_response.MonitoringSignalResponse;
|
||||
import ru.nbch.credit_tracker.entities.response.online_download.OnlineDownloadReport;
|
||||
import ru.nbch.credit_tracker.entities.response.online_report.SgnlOnlineReport;
|
||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse;
|
||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
||||
import ru.nbch.credit_tracker.service.xml.stax.SgnlReportStatusStaxReader;
|
||||
import ru.nbch.credit_tracker.service.xml.stax.StaxReader;
|
||||
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
||||
import ru.nbch.credit_tracker.service.xml.stax.XmlProcessorStaxImpl;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
|
|
@ -22,6 +27,8 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
||||
|
||||
|
|
@ -33,6 +40,7 @@ public class XmlUtilService {
|
|||
// unmarshalling classes
|
||||
MonitoringRequest.class,
|
||||
OnlineDownloadReport.class,
|
||||
SgnlOnlineReport.class,
|
||||
// marshalling classes
|
||||
Signals.class,
|
||||
MonitoringError.class,
|
||||
|
|
@ -40,6 +48,12 @@ public class XmlUtilService {
|
|||
MonitoringSignalResponse.class);
|
||||
}
|
||||
|
||||
public StaxXmlProcessor staxXmlProcessor() {
|
||||
List<StaxReader<?>> staxReader = new ArrayList<>();
|
||||
staxReader.add(new SgnlReportStatusStaxReader());
|
||||
return new XmlProcessorStaxImpl(staxReader);
|
||||
}
|
||||
|
||||
public void validateXMLByXSD(InputStream xmlStream, String xsdPath) throws IOException, XMLStreamException, SAXException {
|
||||
SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
|
||||
Schema schema = sf.newSchema(new File(xsdPath));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
package ru.nbch.credit_tracker.service.xml.stax;
|
||||
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
|
||||
public abstract class BaseStaxReader<T> implements StaxReader<T> {
|
||||
private final Deque<String> stack = new ArrayDeque<>();
|
||||
protected final StringBuilder buffer = new StringBuilder();
|
||||
protected abstract T createObject();
|
||||
|
||||
@Override
|
||||
public T read(XMLStreamReader reader) throws XMLStreamException {
|
||||
T obj = createObject();
|
||||
while (reader.hasNext()) {
|
||||
boolean breakExecution = false;
|
||||
int ev = reader.next();
|
||||
switch (ev) {
|
||||
case XMLStreamConstants.START_ELEMENT -> {
|
||||
buffer.setLength(0);
|
||||
startElement(reader.getLocalName());
|
||||
}
|
||||
case XMLStreamConstants.CHARACTERS -> {
|
||||
String text = reader.getText().trim();
|
||||
if (!text.isEmpty()) buffer.append(text);
|
||||
}
|
||||
case XMLStreamConstants.END_ELEMENT -> {
|
||||
breakExecution = innerProcess(reader, obj);
|
||||
endElement();
|
||||
}
|
||||
default -> {}
|
||||
}
|
||||
if (breakExecution) break;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
protected abstract boolean innerProcess(XMLStreamReader reader, T obj) throws XMLStreamException;
|
||||
|
||||
|
||||
public void startElement(String localName) {
|
||||
localName = substringAfterColon(localName);
|
||||
stack.push(localName);
|
||||
}
|
||||
|
||||
public void endElement() {
|
||||
if (!stack.isEmpty()) {
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Iterator<String> it = stack.descendingIterator(); it.hasNext(); ) {
|
||||
String name = it.next();
|
||||
sb.append('/').append(name);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String substringAfterColon(String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
int idx = input.indexOf(':');
|
||||
if (idx == -1) {
|
||||
return input;
|
||||
}
|
||||
if (idx == input.length() - 1) {
|
||||
return "";
|
||||
}
|
||||
return input.substring(idx + 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package ru.nbch.credit_tracker.service.xml.stax;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.nbch.credit_tracker.entities.response.external_errors.Error;
|
||||
import ru.nbch.credit_tracker.entities.response.external_errors.InputParams;
|
||||
import ru.nbch.credit_tracker.entities.response.external_errors.SgnlReport;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
@Component
|
||||
public class SgnlReportStatusStaxReader extends BaseStaxReader<SgnlReport> {
|
||||
|
||||
@Override
|
||||
public Class<SgnlReport> type() {
|
||||
return SgnlReport.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SgnlReport createObject() {
|
||||
SgnlReport report = new SgnlReport();
|
||||
InputParams inputParams = new InputParams();
|
||||
report.setInputParams(inputParams);
|
||||
Error error = new Error();
|
||||
report.setError(error);
|
||||
return report;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean innerProcess(XMLStreamReader reader, SgnlReport obj) {
|
||||
String text = buffer.toString();
|
||||
String currPath = getPath();
|
||||
switch (currPath) {
|
||||
case "/SgnlReport/InputParams/memberCode" ->
|
||||
obj.getInputParams().setMemberCode(text);
|
||||
case "/SgnlReport/Error/name" ->
|
||||
obj.getError().setName(text);
|
||||
case "/SgnlReport/Error/description" ->
|
||||
obj.getError().setDescription(text);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package ru.nbch.credit_tracker.service.xml.stax;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
public interface StaxReader<T> {
|
||||
Class<T> type();
|
||||
T read(XMLStreamReader xmlStreamReader) throws XMLStreamException;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package ru.nbch.credit_tracker.service.xml.stax;
|
||||
|
||||
public interface StaxXmlProcessor {
|
||||
<Z> Z read(String xml, Class<Z> clazz);
|
||||
<Z> Z read(byte[] xml, Class<Z> clazz);
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
package ru.nbch.credit_tracker.service.xml.stax;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.StringReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class XmlProcessorStaxImpl implements StaxXmlProcessor {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
protected XMLInputFactory xmlInputFactory;
|
||||
protected Map<Class<?>, StaxReader<?>> staxReaders = new HashMap<>();
|
||||
|
||||
public XmlProcessorStaxImpl(List<StaxReader<?>> staxReaders) {
|
||||
this.xmlInputFactory = XMLInputFactory.newInstance();
|
||||
this.xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); // полностью выключить DOCTYPE Declaration
|
||||
// или выключить особо опасные возможности (менее строгое ограничение XXE, но достаточное):
|
||||
this.xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
|
||||
this.xmlInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false);
|
||||
this.xmlInputFactory.setXMLResolver((publicID, systemID, baseURI, namespace) -> {
|
||||
throw new XMLStreamException("External entities are disabled");
|
||||
});
|
||||
staxReaders.forEach(reader -> this.staxReaders.put(reader.type(), reader));
|
||||
}
|
||||
|
||||
public XmlProcessorStaxImpl(StaxReader<?>... staxReaders) {
|
||||
this(Arrays.asList(staxReaders));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <Z> Z read(String xml, Class<Z> clazz) {
|
||||
try {
|
||||
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new StringReader(xml));
|
||||
@SuppressWarnings("unchecked")
|
||||
StaxReader<Z> staxProcessor = (StaxReader<Z>) staxReaders.get(clazz);
|
||||
if (staxProcessor != null) {
|
||||
return staxProcessor.read(xmlStreamReader);
|
||||
}
|
||||
throw new IllegalStateException("no stax reader registered for " + clazz);
|
||||
} catch (Exception e) {
|
||||
log.error(ExceptionUtils.getStackTrace(e));
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <Z> Z read(byte[] xml, Class<Z> clazz) {
|
||||
try {
|
||||
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(xml));
|
||||
@SuppressWarnings("unchecked")
|
||||
StaxReader<Z> staxProcessor = (StaxReader<Z>) staxReaders.get(clazz);
|
||||
if (staxProcessor != null) {
|
||||
return staxProcessor.read(xmlStreamReader);
|
||||
}
|
||||
throw new IllegalStateException("no stax reader registered for " + clazz);
|
||||
} catch (Exception e) {
|
||||
log.error(ExceptionUtils.getStackTrace(e));
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue