Added GlobalExceptionHandler; Added finding active packages by membercode;

This commit is contained in:
Mikhail Trofimov 2025-06-17 16:48:47 +03:00
parent 7a4290ad0b
commit b9a98d9e0b
20 changed files with 252 additions and 33 deletions

View file

@ -0,0 +1,17 @@
package ru.nbch.credit_tracker.config.rest;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import ru.nbch.credit_tracker.entities.response.errors.CommonError;
import ru.nbch.credit_tracker.exceptions.SignalErrorException;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = SignalErrorException.class, produces = MediaType.APPLICATION_XML_VALUE)
public ResponseEntity<CommonError> handleInvalidUser(SignalErrorException ex) {
return ResponseEntity.badRequest().body(ex.getError());
}
}

View file

@ -3,11 +3,10 @@ package ru.nbch.credit_tracker.controller;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import ru.nbch.credit_tracker.entities.request.active_packages.MonitoringActivePackagesRequest;
import ru.nbch.credit_tracker.entities.response.active_packages.MonitoringActivePackagesResponse;
import ru.nbch.credit_tracker.facade.SignalFacade;
@RestController
@ -25,5 +24,10 @@ public class SignalController {
return signalFacade.setupMonitoring(file);
}
@PostMapping(value = "active_packages", consumes = MediaType.APPLICATION_XML_VALUE, produces = MediaType.APPLICATION_XML_VALUE)
public ResponseEntity<MonitoringActivePackagesResponse> findActivePackages(@RequestBody MonitoringActivePackagesRequest activePackagesRequest) {
return signalFacade.findActivePackages(activePackagesRequest);
}
}

View file

@ -0,0 +1,21 @@
package ru.nbch.credit_tracker.entities.request.active_packages;
import jakarta.xml.bind.annotation.*;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"userId",
"password"
})
@XmlRootElement(name = "MonitoringActivePackagesRequest")
public class MonitoringActivePackagesRequest {
@XmlElement(name = "UserId", required = true)
protected String userId;
@XmlElement(name = "Password", required = true)
protected String password;
}

View file

@ -1,5 +1,5 @@
package ru.nbch.credit_tracker.entities.monitoring_request;
package ru.nbch.credit_tracker.entities.request.monitoring_request;
import jakarta.xml.bind.annotation.*;
import lombok.Getter;

View file

@ -1,5 +1,5 @@
package ru.nbch.credit_tracker.entities.monitoring_request;
package ru.nbch.credit_tracker.entities.request.monitoring_request;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;

View file

@ -1,4 +1,4 @@
package ru.nbch.credit_tracker.entities.monitoring_request;
package ru.nbch.credit_tracker.entities.request.monitoring_request;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;

View file

@ -0,0 +1,24 @@
package ru.nbch.credit_tracker.entities.response.active_packages;
import jakarta.xml.bind.annotation.*;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"status",
"membercode",
"packages"
})
@XmlRootElement(name = "MonitoringRequest")
public class MonitoringActivePackagesResponse {
@XmlElement(name = "Status", required = true)
protected String status;
@XmlElement(name = "Membercode", required = true)
protected String membercode;
@XmlElement(name = "Packages", required = true)
protected Packages packages;
}

View file

@ -0,0 +1,23 @@
package ru.nbch.credit_tracker.entities.response.active_packages;
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 = {
"packageName",
"createdAt"
})
public class Package {
@XmlElement(name = "PackageName", required = true)
protected String packageName;
@XmlElement(name = "CreatedAt", required = true)
protected String createdAt;
}

View file

@ -0,0 +1,26 @@
package ru.nbch.credit_tracker.entities.response.active_packages;
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 java.util.ArrayList;
import java.util.List;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"packages"
})
public class Packages {
@XmlElement(name = "Package", required = true)
protected List<Package> packages;
public List<Package> getPackages() {
if (packages == null) {
packages = new ArrayList<>();
}
return this.packages;
}
}

View file

@ -0,0 +1,7 @@
package ru.nbch.credit_tracker.entities.response.errors;
public interface CommonError {
void setStatus(String status);
void setErrorCode(String errorCode);
void setErrorText(String errorText);
}

View file

@ -0,0 +1,25 @@
package ru.nbch.credit_tracker.entities.response.errors;
import jakarta.xml.bind.annotation.*;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MonitoringActivePackagesResponse", propOrder = {
"status",
"errorCode",
"errorText"
})
@XmlRootElement(name = "MonitoringActivePackagesResponse")
public class MonitoringActivePackagesError implements CommonError {
@XmlElement(name = "Status", required = true)
protected String status;
@XmlElement(name = "ErrorCode",required = true)
protected String errorCode;
@XmlElement(name = "ErrorText",required = true)
protected String errorText;
}

View file

@ -13,7 +13,7 @@ import lombok.Setter;
"errorText"
})
@XmlRootElement(name = "MonitoringErrorResponse")
public class MonitoringError {
public class MonitoringError implements CommonError {
@XmlElement(name = "Status", required = true)
protected String status;

View file

@ -15,6 +15,10 @@ public enum SignalError {
ERROR_009("009", "Превышен допустимый размер пакета"),
ERROR_010("010", "Идентификатор субъекта (Id) не соответствует допустимому формату"),
ERROR_011("011", "Получен невалидный XML"),
ERROR_013("013", "На стороне сервиса произошла ошибка, попробуйте повторить запрос позже или сообщите в техническую поддержку"),
ERROR_015("015", "Клиент с указанным membercode не найден"),
ERROR_100("100", "Непредвиденная ошибка");
private final String code;

View file

@ -0,0 +1,27 @@
package ru.nbch.credit_tracker.exceptions;
import lombok.Getter;
import ru.nbch.credit_tracker.entities.response.errors.CommonError;
import ru.nbch.credit_tracker.enums.SignalError;
@Getter
public class SignalErrorException extends RuntimeException {
private final CommonError error;
public SignalErrorException(SignalError signalError, String tag, CommonError error) {
this.error = createErrorMessage(error, signalError, tag);
}
private CommonError createErrorMessage(CommonError errorMessage, SignalError error, String tag) {
errorMessage.setStatus("error");
errorMessage.setErrorCode(error.getCode());
if (tag != null) {
errorMessage.setErrorText(error.getMessage() + " " + tag);
} else {
errorMessage.setErrorText(error.getMessage());
}
return errorMessage;
}
}

View file

@ -1,17 +0,0 @@
package ru.nbch.credit_tracker.exceptions;
import lombok.Getter;
@Getter
public class ValidationException extends Exception {
private String elementName;
public ValidationException() {
}
public ValidationException(String elementName) {
super();
this.elementName = elementName;
}
}

View file

@ -7,12 +7,16 @@ import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
import ru.nbch.credit_tracker.entities.monitoring_request.MonitoringRequest;
import ru.nbch.credit_tracker.entities.monitoring_request.Subject;
import ru.nbch.credit_tracker.entities.request.active_packages.MonitoringActivePackagesRequest;
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.response.active_packages.MonitoringActivePackagesResponse;
import ru.nbch.credit_tracker.entities.response.errors.MonitoringActivePackagesError;
import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse;
import ru.nbch.credit_tracker.entities.signal_package.Signals;
import ru.nbch.credit_tracker.enums.SignalError;
import ru.nbch.credit_tracker.enums.Status;
import ru.nbch.credit_tracker.exceptions.SignalErrorException;
import ru.nbch.credit_tracker.service.SignalService;
import ru.nbch.credit_tracker.service.indic.PhoneService;
import ru.nbch.credit_tracker.service.scoring.AuthorizationService;
@ -255,4 +259,25 @@ public class SignalFacade {
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());
if (!authResult.isSuccess()) {
throw new SignalErrorException(authResult.getError(), null, new MonitoringActivePackagesError());
}
MonitoringActivePackagesResponse response = signalService.findActivePackages(activePackagesRequest.getUserId());
if (response != null) {
return ResponseEntity.ok(response);
} else {
throw new SignalErrorException(SignalError.ERROR_015, null, new MonitoringActivePackagesError());
}
} catch (Exception e) {
if (e instanceof SignalErrorException) {
throw (SignalErrorException) e;
}
log.error(e.getMessage(), e);
throw new SignalErrorException(SignalError.ERROR_013, null, new MonitoringActivePackagesError());
}
}
}

View file

@ -2,8 +2,8 @@ package ru.nbch.credit_tracker.mapper.signal;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import ru.nbch.credit_tracker.entities.monitoring_request.MonitoringRequest;
import ru.nbch.credit_tracker.entities.monitoring_request.Subject;
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.service.SignalService;
import java.time.LocalDateTime;
@ -27,4 +27,6 @@ public interface SignalMapper {
List<SignalService.SubjectData> findSubjectsData(@Param("packageId") Integer packageId);
SignalService.PackageData findPackageData(@Param("id") Integer id);
List<SignalService.PackageData> findPackageDataList(@Param("userId") String userId);
}

View file

@ -5,7 +5,10 @@ import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
import ru.nbch.credit_tracker.entities.monitoring_request.MonitoringRequest;
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
import ru.nbch.credit_tracker.entities.response.active_packages.MonitoringActivePackagesResponse;
import ru.nbch.credit_tracker.entities.response.active_packages.Package;
import ru.nbch.credit_tracker.entities.response.active_packages.Packages;
import ru.nbch.credit_tracker.entities.signal_package.Auth;
import ru.nbch.credit_tracker.entities.signal_package.Person;
import ru.nbch.credit_tracker.entities.signal_package.Signals;
@ -155,11 +158,32 @@ public class SignalService {
return Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
public MonitoringActivePackagesResponse findActivePackages(String userId) {
String memberCode = userId.substring(0, 6);
MonitoringActivePackagesResponse activePackages = new MonitoringActivePackagesResponse();
activePackages.setStatus("OK");
activePackages.setMembercode(memberCode);
Packages packages = new Packages();
mapper.findPackageDataList(memberCode).forEach(data -> {
Package pack = new Package();
pack.setPackageName(data.getPackageName());
pack.setCreatedAt(data.getCreatedAt() != null ? data.getCreatedAt().toString() : null);
packages.getPackages().add(pack);
});
activePackages.setPackages(packages);
if (packages.getPackages() == null || packages.getPackages().isEmpty()) {
return null;
}
return activePackages;
}
@Getter
@Setter
public static class PackageData {
private String userId;
private String packageName;
private LocalDateTime createdAt;
}
@Getter

View file

@ -3,7 +3,7 @@ package ru.nbch.credit_tracker.service.xml.jaxb;
import jakarta.xml.bind.JAXBException;
import org.springframework.stereotype.Service;
import org.xml.sax.SAXException;
import ru.nbch.credit_tracker.entities.monitoring_request.MonitoringRequest;
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
import ru.nbch.credit_tracker.entities.response.errors.MonitoringError;
import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse;
import ru.nbch.credit_tracker.entities.signal_package.Signals;

View file

@ -14,6 +14,7 @@
<resultMap id="packageDataResultMap" type="ru.nbch.credit_tracker.service.SignalService$PackageData">
<result property="userId" column="membercode" />
<result property="packageName" column="package_name" />
<result property="createdAt" column="created_at"/>
</resultMap>
<select id="isPackageNotUnique" resultType="boolean">
@ -22,13 +23,13 @@
WHERE membercode IS NOT NULL AND LEFT(membercode, 6) = #{userId} AND package_name = #{packageName}
</select>
<select id="registerPackage" resultType="java.lang.Integer" parameterType="ru.nbch.credit_tracker.entities.monitoring_request.MonitoringRequest" >
<select id="registerPackage" resultType="java.lang.Integer" parameterType="ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest" >
INSERT INTO signals_user_packages (membercode, package_name, created_at, status)
values (#{request.userId}, #{request.packageName}, #{creadedAt}, #{status})
RETURNING id
</select>
<insert id="insertPackage" parameterType="ru.nbch.credit_tracker.entities.monitoring_request.MonitoringRequest" >
<insert id="insertPackage" parameterType="ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest" >
INSERT INTO signals_user_packages (membercode, package_name, created_at, status)
values (#{request.userId}, #{request.packageName}, #{creadedAt}, #{status})
</insert>
@ -65,4 +66,10 @@
WHERE id = #{id} LIMIT 1
</select>
<select id="findPackageDataList" resultMap="packageDataResultMap" resultType="ru.nbch.credit_tracker.service.SignalService$PackageData">
SELECT package_name, created_at
FROM signals_user_packages
WHERE membercode IS NOT NULL AND LEFT(membercode, 6) = #{userId}
</select>
</mapper>