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.indic.PhoneService;
|
||||||
import ru.nbch.credit_tracker.service.scoring.AuthorizationService;
|
import ru.nbch.credit_tracker.service.scoring.AuthorizationService;
|
||||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
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.IXmlProcessor;
|
||||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
||||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||||
|
|
@ -48,8 +46,6 @@ public class SignalFacade {
|
||||||
private final AuthorizationService authorizationService;
|
private final AuthorizationService authorizationService;
|
||||||
private final SignalService signalService;
|
private final SignalService signalService;
|
||||||
private final SignalRestService signalRestService;
|
private final SignalRestService signalRestService;
|
||||||
private final FailureAnswerGenerator failureAnswerGenerator;
|
|
||||||
private final SuccessAnswerGenerator successAnswerGenerator;
|
|
||||||
private final XmlUtilService xmlUtilService;
|
private final XmlUtilService xmlUtilService;
|
||||||
|
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
|
|
@ -59,16 +55,12 @@ public class SignalFacade {
|
||||||
AuthorizationService authorizationService,
|
AuthorizationService authorizationService,
|
||||||
SignalService signalService,
|
SignalService signalService,
|
||||||
SignalRestService signalRestService,
|
SignalRestService signalRestService,
|
||||||
FailureAnswerGenerator failureAnswerGenerator,
|
|
||||||
SuccessAnswerGenerator successAnswerGenerator,
|
|
||||||
XmlUtilService xmlUtilService,
|
XmlUtilService xmlUtilService,
|
||||||
@Qualifier("executorService") ExecutorService executor) {
|
@Qualifier("executorService") ExecutorService executor) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.authorizationService = authorizationService;
|
this.authorizationService = authorizationService;
|
||||||
this.signalService = signalService;
|
this.signalService = signalService;
|
||||||
this.signalRestService = signalRestService;
|
this.signalRestService = signalRestService;
|
||||||
this.failureAnswerGenerator = failureAnswerGenerator;
|
|
||||||
this.successAnswerGenerator = successAnswerGenerator;
|
|
||||||
this.xmlUtilService = xmlUtilService;
|
this.xmlUtilService = xmlUtilService;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
@ -256,15 +248,6 @@ public class SignalFacade {
|
||||||
file.getOriginalFilename() != null && file.getOriginalFilename().toLowerCase().endsWith(".zip");
|
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) {
|
public ResponseEntity<MonitoringActivePackagesResponse> findActivePackages(MonitoringActivePackagesRequest activePackagesRequest) {
|
||||||
try {
|
try {
|
||||||
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(activePackagesRequest.getUserId(), activePackagesRequest.getPassword());
|
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(activePackagesRequest.getUserId(), activePackagesRequest.getPassword());
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,10 @@ public class MonitoringService {
|
||||||
for (PackageData packageData : packages) {
|
for (PackageData packageData : packages) {
|
||||||
SgnlOnlineReport onlineReports = signalRestService.getReports(packageData.getUserId().substring(0, 6) + "_" + packageData.getPackageName());
|
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)
|
List<String> fileNames = onlineReports.getOperationReport().getReports().getReports().stream().map(Report::getFilename)
|
||||||
.filter(fileName -> CTUtil.parseDateFromReportFileName(fileName) != null).toList(); // TODO оптимизировать
|
.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.util.MultiValueMap;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
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.response.online_report.SgnlOnlineReport;
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
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.IXmlProcessor;
|
||||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
||||||
|
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|
@ -64,13 +64,116 @@ public class SignalRestService {
|
||||||
// good response
|
// good response
|
||||||
return true;
|
return true;
|
||||||
} else if (response.getStatusCode().value() == 200 && response.getBody() != null) {
|
} else if (response.getStatusCode().value() == 200 && response.getBody() != null) {
|
||||||
// bad response
|
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
||||||
log.error("Ошибка при постановке пакета на мониторинг в официальный сервис сигналов: {}", response.getBody());
|
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;
|
||||||
}
|
}
|
||||||
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 {
|
private Resource compressFile(Signals signals) throws Exception {
|
||||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
||||||
String requestData = processor.asString(signals, false);
|
String requestData = processor.asString(signals, false);
|
||||||
|
|
@ -88,85 +191,9 @@ public class SignalRestService {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deletePackage(String username, String packageName) {
|
private boolean isXmlError(byte[] data) {
|
||||||
String packCode = username.substring(0, 6) + "_" + packageName;
|
if (data == null || data.length < 10) return false;
|
||||||
String url = DELETE_URI + "?packCode=" + packCode;
|
String start = new String(data, 0, 10).trim();
|
||||||
HttpHeaders headers = new HttpHeaders();
|
return start.startsWith("<?xml");
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.errors.MonitoringError;
|
||||||
import ru.nbch.credit_tracker.entities.response.monitoring_signal_response.MonitoringSignalResponse;
|
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_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.response.success.MonitoringResponse;
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
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.XMLConstants;
|
||||||
import javax.xml.stream.XMLInputFactory;
|
import javax.xml.stream.XMLInputFactory;
|
||||||
|
|
@ -22,6 +27,8 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
||||||
|
|
||||||
|
|
@ -33,6 +40,7 @@ public class XmlUtilService {
|
||||||
// unmarshalling classes
|
// unmarshalling classes
|
||||||
MonitoringRequest.class,
|
MonitoringRequest.class,
|
||||||
OnlineDownloadReport.class,
|
OnlineDownloadReport.class,
|
||||||
|
SgnlOnlineReport.class,
|
||||||
// marshalling classes
|
// marshalling classes
|
||||||
Signals.class,
|
Signals.class,
|
||||||
MonitoringError.class,
|
MonitoringError.class,
|
||||||
|
|
@ -40,6 +48,12 @@ public class XmlUtilService {
|
||||||
MonitoringSignalResponse.class);
|
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 {
|
public void validateXMLByXSD(InputStream xmlStream, String xsdPath) throws IOException, XMLStreamException, SAXException {
|
||||||
SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
|
SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
|
||||||
Schema schema = sf.newSchema(new File(xsdPath));
|
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