new exception
This commit is contained in:
parent
307f43f49b
commit
392b99aca4
13 changed files with 325 additions and 66 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
package ru.nbch.credit_tracker.config.rest;
|
package ru.nbch.credit_tracker.config.rest;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
|
@ -7,13 +8,19 @@ import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
import ru.nbch.credit_tracker.entities.response.errors.CommonError;
|
import ru.nbch.credit_tracker.entities.response.errors.CommonError;
|
||||||
|
import ru.nbch.credit_tracker.entities.response.errors.MonitoringActivePackagesError;
|
||||||
|
import ru.nbch.credit_tracker.entities.response.errors.MonitoringDownloadError;
|
||||||
|
import ru.nbch.credit_tracker.entities.response.errors.MonitoringError;
|
||||||
|
import ru.nbch.credit_tracker.entities.response.errors.MonitoringPackageDeleteError;
|
||||||
|
import ru.nbch.credit_tracker.entities.response.errors.MonitoringReportListError;
|
||||||
|
import ru.nbch.credit_tracker.exceptions.SignalClientException;
|
||||||
import ru.nbch.credit_tracker.exceptions.SignalErrorException;
|
import ru.nbch.credit_tracker.exceptions.SignalErrorException;
|
||||||
|
import ru.nbch.credit_tracker.utils.error.SimpleMessageResolver;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
|
|
||||||
@RestControllerAdvice
|
@RestControllerAdvice
|
||||||
public class GlobalExceptionHandler {
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
private final SimpleMessageResolver messageResolver = new SimpleMessageResolver();
|
||||||
@ExceptionHandler(value = SignalErrorException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
@ExceptionHandler(value = SignalErrorException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
||||||
public ResponseEntity<CommonError> handleInvalidUser(SignalErrorException ex) {
|
public ResponseEntity<CommonError> handleInvalidUser(SignalErrorException ex) {
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
|
@ -24,4 +31,29 @@ public class GlobalExceptionHandler {
|
||||||
return new ResponseEntity<>(ex.getError(), headers, HttpStatus.INTERNAL_SERVER_ERROR);
|
return new ResponseEntity<>(ex.getError(), headers, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(value = SignalClientException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
||||||
|
public ResponseEntity<CommonError> handleClientException(SignalClientException ex) {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(new MediaType("application", "xml", Charset.forName("windows-1251")));
|
||||||
|
CommonError commonError = getCommonError(ex);
|
||||||
|
commonError.setStatus("error");
|
||||||
|
commonError.setErrorCode(ex.getErrorMessage().getSubject().getErrorCode());
|
||||||
|
commonError.setErrorText(messageResolver.resolve(ex.getErrorMessage()));
|
||||||
|
|
||||||
|
return new ResponseEntity<>(commonError, headers, HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CommonError getCommonError(SignalClientException ex) {
|
||||||
|
CommonError commonError;
|
||||||
|
switch (ex.getErrorFormat()) {
|
||||||
|
case MonitoringError -> commonError = new MonitoringError();
|
||||||
|
case MonitoringActivePackagesError -> commonError = new MonitoringActivePackagesError();
|
||||||
|
case MonitoringDownloadError -> commonError = new MonitoringDownloadError();
|
||||||
|
case MonitoringReportListError -> commonError = new MonitoringReportListError();
|
||||||
|
case MonitoringPackageDeleteError -> commonError = new MonitoringPackageDeleteError();
|
||||||
|
default -> throw new IllegalStateException("Unsupported error format: " + ex.getErrorFormat());
|
||||||
|
}
|
||||||
|
return commonError;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package ru.nbch.credit_tracker.entities.dto;
|
package ru.nbch.credit_tracker.entities.dto;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
@ -11,6 +12,7 @@ import java.time.LocalDateTime;
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
public class SubjectData {
|
public class SubjectData {
|
||||||
private Integer id;
|
private Integer id;
|
||||||
private Integer packageId;
|
private Integer packageId;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package ru.nbch.credit_tracker.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
public class EnumKeyMessage {
|
||||||
|
private final IEnumKeyCode subject;
|
||||||
|
/**
|
||||||
|
* Параметры для подстановки в текст сообщения. Все Serializable.
|
||||||
|
* args not null.
|
||||||
|
*/
|
||||||
|
private Object[] args;
|
||||||
|
|
||||||
|
public EnumKeyMessage(IEnumKeyCode subject) {
|
||||||
|
this.subject = subject;
|
||||||
|
this.args = Collections.emptyList().toArray(new Object[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public EnumKeyMessage(IEnumKeyCode subject, Object... args) {
|
||||||
|
this.subject = subject;
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumKeyCode getSubject() {
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] getArgs() {
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArgs(Object[] args) {
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "EnumKeyMessage{subject=" + subject + ", args: " + Arrays.toString(args) + "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
102
src/main/java/ru/nbch/credit_tracker/enums/IEnumKeyCode.java
Normal file
102
src/main/java/ru/nbch/credit_tracker/enums/IEnumKeyCode.java
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
package ru.nbch.credit_tracker.enums;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public interface IEnumKeyCode extends Serializable {
|
||||||
|
String getKey();
|
||||||
|
String getCode();
|
||||||
|
|
||||||
|
default boolean equalsByKey(String key) {
|
||||||
|
return key != null && getKey().equalsIgnoreCase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Проверяет что среди данного набора Enum, присутствует элемент с данным id
|
||||||
|
* id может быть null
|
||||||
|
*/
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> boolean contains(String id, T... enumSet) {
|
||||||
|
for (T e : enumSet) {
|
||||||
|
if (Objects.equals(id, e.getKey()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> boolean containsIgnoreCase(String id, T... enumSet) {
|
||||||
|
for (T e : enumSet) {
|
||||||
|
if (e.getKey() != null && e.getKey().equalsIgnoreCase(id)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> boolean contains(T e, T... enumSet) {
|
||||||
|
for (T enumEl : enumSet) {
|
||||||
|
if (enumEl.equals(e))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Проверяет что среди всех Enum данного класса, присутствует элемент с данным id
|
||||||
|
* id может быть null
|
||||||
|
*/
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> boolean contains(String key, Class<T> enumClass) {
|
||||||
|
for (T e : enumClass.getEnumConstants()) {
|
||||||
|
if (Objects.equals(key, e.getKey()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает Enum по id, если в заданном классе такой определен
|
||||||
|
* id может быть null
|
||||||
|
*
|
||||||
|
* @return Enum если нашел, иначе <tt>null</tt>
|
||||||
|
*/
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> T getEnumByKey(Class<T> enumClass, String key) {
|
||||||
|
for (T e : enumClass.getEnumConstants()) {
|
||||||
|
if (Objects.equals(key, e.getKey()))
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> T getEnumByKeyOrUndefined(Class<T> enumClass, String key) {
|
||||||
|
T enumByKey = getEnumByKey(enumClass, key);
|
||||||
|
return enumByKey == null ? getUndefined(enumClass) : enumByKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> T getUndefined(Class<T> enumClass) {
|
||||||
|
T enumByKey = getEnumByKey(enumClass, UNDEFINED_VALUE);
|
||||||
|
if (enumByKey == null) {
|
||||||
|
throw new IllegalArgumentException("Undefined value not found in enum " + enumClass);
|
||||||
|
}
|
||||||
|
return enumByKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean theSameAs(Object other) {
|
||||||
|
if (!(other instanceof IEnumKeyCode otherCasted)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.getKey().equalsIgnoreCase(otherCasted.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getErrorCode() {
|
||||||
|
String key = getKey();
|
||||||
|
String[] split = key.split("\\.");
|
||||||
|
if (split.length < 1) return null;
|
||||||
|
String s = split[split.length - 1];
|
||||||
|
if (!s.matches("\\d+")) return null;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getKeyOrNull(IEnumKeyCode enumVal) {
|
||||||
|
return enumVal == null ? null : enumVal.getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
String UNDEFINED_VALUE = "_Undefined";
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
package ru.nbch.credit_tracker.enums;
|
package ru.nbch.credit_tracker.enums;
|
||||||
|
|
||||||
import lombok.Getter;
|
public enum SignalError implements IEnumKeyCode {
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum SignalError {
|
|
||||||
ERROR_001("001", "Ошибка распаковки архива"),
|
ERROR_001("001", "Ошибка распаковки архива"),
|
||||||
ERROR_002("002", "Отсутствует обязательный элемент: "),
|
ERROR_002("002", "Отсутствует обязательный элемент: "),
|
||||||
ERROR_003("003", "Элемент ClientId не соответствует формату XXXXXXXXX"),
|
ERROR_003("003", "Элемент ClientId не соответствует формату XXXXXXXXX"),
|
||||||
|
|
@ -31,4 +28,16 @@ public enum SignalError {
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ru.nbch.credit_tracker.enums;
|
||||||
|
|
||||||
|
public enum XmlErrorFormat {
|
||||||
|
MonitoringActivePackagesError,
|
||||||
|
MonitoringDownloadError,
|
||||||
|
MonitoringError,
|
||||||
|
MonitoringPackageDeleteError,
|
||||||
|
MonitoringReportListError
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package ru.nbch.credit_tracker.exceptions;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import ru.nbch.credit_tracker.enums.EnumKeyMessage;
|
||||||
|
import ru.nbch.credit_tracker.enums.XmlErrorFormat;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class SignalClientException extends RuntimeException {
|
||||||
|
|
||||||
|
private final EnumKeyMessage errorMessage;
|
||||||
|
private final XmlErrorFormat errorFormat;
|
||||||
|
|
||||||
|
public SignalClientException(EnumKeyMessage errorMessage,
|
||||||
|
XmlErrorFormat errorFormat) {
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
this.errorFormat = errorFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,9 +19,9 @@ public class SignalErrorException extends RuntimeException {
|
||||||
errorMessage.setStatus("error");
|
errorMessage.setStatus("error");
|
||||||
errorMessage.setErrorCode(error.getCode());
|
errorMessage.setErrorCode(error.getCode());
|
||||||
if (tag != null) {
|
if (tag != null) {
|
||||||
errorMessage.setErrorText(error.getMessage() + " " + tag);
|
errorMessage.setErrorText(error.getKey() + " " + tag);
|
||||||
} else {
|
} else {
|
||||||
errorMessage.setErrorText(error.getMessage());
|
errorMessage.setErrorText(error.getKey());
|
||||||
}
|
}
|
||||||
return errorMessage;
|
return errorMessage;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,14 @@
|
||||||
package ru.nbch.credit_tracker.facade;
|
package ru.nbch.credit_tracker.facade;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.core.io.FileUrlResource;
|
import org.springframework.core.io.FileUrlResource;
|
||||||
|
|
@ -12,13 +21,19 @@ import ru.nbch.credit_tracker.entities.request.active_packages.MonitoringActiveP
|
||||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
|
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
|
||||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject;
|
import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject;
|
||||||
import ru.nbch.credit_tracker.entities.response.active_packages.MonitoringActivePackagesResponse;
|
import ru.nbch.credit_tracker.entities.response.active_packages.MonitoringActivePackagesResponse;
|
||||||
import ru.nbch.credit_tracker.entities.response.errors.*;
|
import ru.nbch.credit_tracker.entities.response.errors.MonitoringActivePackagesError;
|
||||||
|
import ru.nbch.credit_tracker.entities.response.errors.MonitoringDownloadError;
|
||||||
|
import ru.nbch.credit_tracker.entities.response.errors.MonitoringError;
|
||||||
|
import ru.nbch.credit_tracker.entities.response.errors.MonitoringPackageDeleteError;
|
||||||
|
import ru.nbch.credit_tracker.entities.response.errors.MonitoringReportListError;
|
||||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringPackageDeleteResponse;
|
import ru.nbch.credit_tracker.entities.response.success.MonitoringPackageDeleteResponse;
|
||||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringReportListResponse;
|
import ru.nbch.credit_tracker.entities.response.success.MonitoringReportListResponse;
|
||||||
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.enums.SignalError;
|
import ru.nbch.credit_tracker.enums.SignalError;
|
||||||
import ru.nbch.credit_tracker.enums.Status;
|
import ru.nbch.credit_tracker.enums.Status;
|
||||||
|
import ru.nbch.credit_tracker.enums.XmlErrorFormat;
|
||||||
|
import ru.nbch.credit_tracker.exceptions.SignalClientException;
|
||||||
import ru.nbch.credit_tracker.exceptions.SignalErrorException;
|
import ru.nbch.credit_tracker.exceptions.SignalErrorException;
|
||||||
import ru.nbch.credit_tracker.service.SignalService;
|
import ru.nbch.credit_tracker.service.SignalService;
|
||||||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
||||||
|
|
@ -28,14 +43,8 @@ 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;
|
||||||
import ru.nbch.credit_tracker.utils.ValidationUtil;
|
import ru.nbch.credit_tracker.utils.ValidationUtil;
|
||||||
|
import ru.nbch.credit_tracker.utils.ZipUtils;
|
||||||
import java.io.File;
|
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.excp;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipInputStream;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
|
@ -76,64 +85,44 @@ public class SignalFacade {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Валидация Архива на количетсво файлов, размер и расширение
|
// Валидация Архива на количетсво файлов, размер и расширение
|
||||||
try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
|
|
||||||
int fileCount = 0;
|
|
||||||
ZipEntry xmlEntry = null;
|
|
||||||
|
|
||||||
ZipEntry entry = zipInputStream.getNextEntry();
|
|
||||||
while (entry != null) {
|
|
||||||
if (!entry.isDirectory()) {
|
|
||||||
fileCount++;
|
|
||||||
if (fileCount > 1) { // Архив должен содержать ровно один XML-файл
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!entry.getName().toLowerCase().endsWith(".xml")) { // Файл должен быть с расширением xml
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlEntry = entry;
|
|
||||||
} else {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true); // Архив должен содержать ровно один XML-файл. Никаких доп директорий
|
|
||||||
}
|
|
||||||
zipInputStream.closeEntry();
|
|
||||||
entry = zipInputStream.getNextEntry();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileCount == 0) { // Архив должен содержать ровно один XML-файл
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlEntry.getSize() > MAX_XML_FILE_SIZE) { // максимально 2 Гб до запаковки
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_009, null, new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (e instanceof SignalErrorException) {
|
|
||||||
throw (SignalErrorException) e;
|
|
||||||
}
|
|
||||||
log.error(e.getMessage(), e);
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_100, null, new MonitoringError(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Теперь знаем, что в архиве лежит ровно один файл с раширением xml и он весит меньше 2гб. Можно валидировать сам xml
|
|
||||||
// Пробуем распарсить xml
|
|
||||||
MonitoringRequest monitoringRequest;
|
MonitoringRequest monitoringRequest;
|
||||||
Integer packageId;
|
Integer packageId;
|
||||||
try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
|
ZipInputStream zipInputStream = null;
|
||||||
|
try {
|
||||||
|
zipInputStream = new ZipInputStream(file.getInputStream());
|
||||||
|
Optional<ZipEntry> xmlFileEntry = ZipUtils.extractValidEntry(zipInputStream);
|
||||||
|
if (xmlFileEntry.isEmpty()) {
|
||||||
|
throw excp(SignalError.ERROR_001, XmlErrorFormat.MonitoringError);
|
||||||
|
}
|
||||||
|
if (xmlFileEntry.get().getSize() > MAX_XML_FILE_SIZE) {
|
||||||
|
throw excp(SignalError.ERROR_009, XmlErrorFormat.MonitoringError);
|
||||||
|
}
|
||||||
|
|
||||||
|
zipInputStream.close();
|
||||||
|
zipInputStream = new ZipInputStream(file.getInputStream());
|
||||||
zipInputStream.getNextEntry();
|
zipInputStream.getNextEntry();
|
||||||
|
|
||||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
||||||
monitoringRequest = processor.read(zipInputStream, MonitoringRequest.class);
|
monitoringRequest = processor.read(zipInputStream, MonitoringRequest.class);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalErrorException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
throw new SignalErrorException(SignalError.ERROR_100, null, new MonitoringError(), false);
|
//todo throw new SignalServerException(e);
|
||||||
|
throw excp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError);
|
||||||
|
} finally {
|
||||||
|
if (zipInputStream != null) {
|
||||||
|
try {
|
||||||
|
zipInputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
//todo throw new SignalServerException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// валидация xml
|
// валидация xml
|
||||||
try {
|
try {
|
||||||
validateMonitoringRequest(monitoringRequest);
|
validateMonitoringRequest(monitoringRequest);
|
||||||
|
|
@ -247,8 +236,8 @@ public class SignalFacade {
|
||||||
|
|
||||||
private boolean isZipFile(MultipartFile file) {
|
private boolean isZipFile(MultipartFile file) {
|
||||||
return file.getContentType() != null &&
|
return file.getContentType() != null &&
|
||||||
(file.getContentType().equals("application/zip") || file.getContentType().equals("application/x-zip-compressed")) ||
|
(file.getContentType().equals("application/zip") || file.getContentType().equals("application/x-zip-compressed")) ||
|
||||||
file.getOriginalFilename() != null && file.getOriginalFilename().toLowerCase().endsWith(".zip");
|
file.getOriginalFilename() != null && file.getOriginalFilename().toLowerCase().endsWith(".zip");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseEntity<MonitoringActivePackagesResponse> findActivePackages(MonitoringActivePackagesRequest activePackagesRequest) {
|
public ResponseEntity<MonitoringActivePackagesResponse> findActivePackages(MonitoringActivePackagesRequest activePackagesRequest) {
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
||||||
@Service
|
@Service
|
||||||
public class XmlUtilService {
|
public class XmlUtilService {
|
||||||
|
|
||||||
|
//сделать бином
|
||||||
public IXmlProcessor createJaxbProcessor() throws JAXBException {
|
public IXmlProcessor createJaxbProcessor() throws JAXBException {
|
||||||
return new XmlProcessorImplAnyClasses(Charset.forName("windows-1251"),
|
return new XmlProcessorImplAnyClasses(Charset.forName("windows-1251"),
|
||||||
// unmarshalling classes
|
// unmarshalling classes
|
||||||
|
|
|
||||||
28
src/main/java/ru/nbch/credit_tracker/utils/ZipUtils.java
Normal file
28
src/main/java/ru/nbch/credit_tracker/utils/ZipUtils.java
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
package ru.nbch.credit_tracker.utils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class ZipUtils {
|
||||||
|
public static Optional<ZipEntry> extractValidEntry(ZipInputStream inputStream) throws IOException {
|
||||||
|
Optional<ZipEntry> zipEntry = Optional.empty();
|
||||||
|
ZipEntry entry;
|
||||||
|
while ((entry = inputStream.getNextEntry()) != null) {
|
||||||
|
if (!entry.isDirectory()) {
|
||||||
|
if (zipEntry.isPresent()) {
|
||||||
|
//если мы уже нашли валидный xml файл, то обработка всего файла недоступна, возвращаем пустой entry
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
if (entry.getName().toLowerCase().endsWith(".xml")) { // Файл должен быть с расширением xml
|
||||||
|
zipEntry = Optional.of(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inputStream.closeEntry();
|
||||||
|
}
|
||||||
|
return zipEntry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package ru.nbch.credit_tracker.utils.error;
|
||||||
|
|
||||||
|
import ru.nbch.credit_tracker.enums.EnumKeyMessage;
|
||||||
|
import ru.nbch.credit_tracker.enums.IEnumKeyCode;
|
||||||
|
import ru.nbch.credit_tracker.enums.XmlErrorFormat;
|
||||||
|
import ru.nbch.credit_tracker.exceptions.SignalClientException;
|
||||||
|
|
||||||
|
public class ExceptionUtils {
|
||||||
|
// public static SignalClientException excp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat) {
|
||||||
|
// return new SignalClientException(new EnumKeyMessage(enumKeyCode), xmlErrorFormat);
|
||||||
|
// }
|
||||||
|
public static SignalClientException excp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat, Object... args) {
|
||||||
|
return new SignalClientException(new EnumKeyMessage(enumKeyCode, args), xmlErrorFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package ru.nbch.credit_tracker.utils.error;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import ru.nbch.credit_tracker.enums.EnumKeyMessage;
|
||||||
|
|
||||||
|
|
||||||
|
public class SimpleMessageResolver {
|
||||||
|
public String resolve(EnumKeyMessage errorMessage) {
|
||||||
|
if (errorMessage == null) return "null";
|
||||||
|
return String.format("(%s) args %s", errorMessage.getSubject().getKey(), Arrays.toString(errorMessage.getArgs()));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue