diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/cud/CudController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/cud/CudController.java deleted file mode 100644 index d35857a74..000000000 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/cud/CudController.java +++ /dev/null @@ -1,88 +0,0 @@ -package ru.spcex.clearing.backendapi.controller.cud; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.*; -import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse; -import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse; -import ru.spcex.clearing.backendapi.domain.actions.IAction; -import ru.spcex.clearing.backendapi.meta.CudMetaService; -import ru.spcex.clearing.backendapi.service.IOperator; - -import java.util.concurrent.ExecutionException; - -@Controller -@RequestMapping("/cud") -public class CudController { - private final IOperator operator; - private final ObjectMapper json; - private final CudMetaService meta; - - @Autowired - public CudController(IOperator operator, CudMetaService meta) { - this.meta = meta; - this.json = new ObjectMapper(); - this.operator = operator; - } - - @ApiOperation(value = "create business objects. See meta.xml for field descriptions.") - @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) - @RequestMapping(value = "/{destination}", method = RequestMethod.POST) - @ResponseBody - public CudResponse add( - @ApiParam(value = "Последняя часть URL определяет 'направление', по которому пойдет запрос. " + - "Должно биться с форматом запроса.", required = true, example = "money-market-security-new") - @PathVariable("destination") - String destination, - @ApiParam(value = "Параметры команды в JSON формате, поля см. в meta.xml.", required = true) - @RequestBody String body) throws JsonProcessingException, ExecutionException, InterruptedException { - return processRequest(destination, body); - } - - @ApiOperation(value = "update business objects. See meta.xml for field descriptions.") - @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) - @RequestMapping(value = "/{destination}", method = RequestMethod.PUT) - @ResponseBody - public CudResponse update( - @ApiParam(value = "Последняя часть URL определяет 'направление', по которому пойдет запрос. " + - "Должно биться с форматом запроса.", required = true, example = "money-market-security-update") - @PathVariable("destination") - String destination, - @ApiParam(value = "Параметры команды в JSON формате, поля см. в meta.xml.", required = true) - @RequestBody String body) throws JsonProcessingException, ExecutionException, InterruptedException { - return processRequest(destination, body); - } - - @ApiOperation(value = "delete business objects. See meta.xml for field descriptions.") - @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) - @RequestMapping(value = "/{destination}", method = RequestMethod.DELETE) - @ResponseBody - public CudResponse delete( - @ApiParam(value = "Последняя часть URL определяет 'направление', по которому пойдет запрос. " + - "Должно биться с форматом запроса.", required = true, example = "money-market-security-delete") - @PathVariable("destination") - String destination, - @ApiParam(value = "Параметры команды в JSON формате, поля см. в meta.xml.", required = true) - @RequestBody String body) throws JsonProcessingException, ExecutionException, InterruptedException { - return processRequest(destination, body); - } - - private CudResponse processRequest(String destination, String body) throws ExecutionException, InterruptedException, JsonProcessingException { - Class> actionClazz = meta.byDestination(destination); - if (actionClazz == null) { - throw new UnsupportedOperationException("unsupported destination " + destination); - } - IAction iAction = json.readValue(body, actionClazz); - CudResponse responseToClient = new CudResponse(); - responseToClient.setPayload(operator.sendRequestToQueue(destination, iAction)); - responseToClient.setCode(0); - responseToClient.setMessage("success"); - return responseToClient; - } -} diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/AbstractQueueController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/AbstractQueueController.java new file mode 100644 index 000000000..6aa77ebba --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/AbstractQueueController.java @@ -0,0 +1,23 @@ +package ru.spcex.clearing.backendapi.controller.queue; + +import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse; +import ru.spcex.clearing.backendapi.domain.actions.IAction; +import ru.spcex.clearing.backendapi.service.IOperator; + +import java.util.concurrent.ExecutionException; + +public class AbstractQueueController { + private final IOperator operator; + + public AbstractQueueController(IOperator operator) { + this.operator = operator; + } + + protected CudResponse processRequest(String destination, IAction iAction) throws ExecutionException, InterruptedException { + CudResponse responseToClient = new CudResponse(); + responseToClient.setPayload(operator.sendRequestToQueue(destination, iAction)); + responseToClient.setCode(0); + responseToClient.setMessage("success"); + return responseToClient; + } +} diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/cud/CudExceptionHandler.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/QueueExceptionHandler.java similarity index 70% rename from clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/cud/CudExceptionHandler.java rename to clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/QueueExceptionHandler.java index a154197aa..e388793ef 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/cud/CudExceptionHandler.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/QueueExceptionHandler.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.backendapi.controller.cud; +package ru.spcex.clearing.backendapi.controller.queue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,14 +18,14 @@ import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.log.ExceptionUtils; -@ControllerAdvice("ru.spcex.clearing.backendapi.controller.cud") +@ControllerAdvice("ru.spcex.clearing.backendapi.controller.queue") @Order(Ordered.HIGHEST_PRECEDENCE) -public class CudExceptionHandler extends ResponseEntityExceptionHandler { +public class QueueExceptionHandler extends ResponseEntityExceptionHandler { private final Logger log = LoggerFactory.getLogger(getClass()); private final IMessageResolver errorResolver; @Autowired - public CudExceptionHandler(@Qualifier("errorResolver") IMessageResolver errorResolver) { + public QueueExceptionHandler(@Qualifier("errorResolver") IMessageResolver errorResolver) { this.errorResolver = errorResolver; } @@ -40,4 +40,15 @@ public class CudExceptionHandler extends ResponseEntityExceptionHandler { errorResponse.setMessage(errorResolver.resolve(firstError)); return errorResponse; } + + @ExceptionHandler(value = Throwable.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + @ResponseBody + public BasicSpcexResponse handleDefault(Throwable e) { + log.error("Default scoring exception handler: {}", ExceptionUtils.getStackTrace(e)); + BasicSpcexResponse errorResponse = new BasicSpcexResponse(); + errorResponse.setCode(-1); + errorResponse.setMessage("internal server error"); + return errorResponse; + } } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/securities/CudMoneyMarketSecurityController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/securities/CudMoneyMarketSecurityController.java new file mode 100644 index 000000000..b40917d34 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/securities/CudMoneyMarketSecurityController.java @@ -0,0 +1,64 @@ +package ru.spcex.clearing.backendapi.controller.queue.securities; + +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController; +import ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction; +import ru.spcex.clearing.backendapi.controller.request.cud.securities.MoneyMarketSecurityNewAction; +import ru.spcex.clearing.backendapi.controller.request.cud.securities.MoneyMarketSecurityUpdateAction; +import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse; +import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse; +import ru.spcex.clearing.backendapi.service.IOperator; +import ru.spcex.clearing.platform.messaging.domain.Consts; + +import java.util.concurrent.ExecutionException; + +@Controller +@RequestMapping("/securities/money-securities") +public class CudMoneyMarketSecurityController extends AbstractQueueController { + + @Autowired + public CudMoneyMarketSecurityController(IOperator operator) { + super(operator); + } + + @ApiOperation(value = "create money security.") + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) + @RequestMapping(value = "/", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + public CudResponse add( + @ApiParam(value = "Параметры команды в JSON формате.", required = true) + @RequestBody MoneyMarketSecurityNewAction moneySecurityNewAction) throws ExecutionException, InterruptedException { + return processRequest(Consts.DESTINATION_MONEY_MARKET_SECURITY_NEW, moneySecurityNewAction); + } + + @ApiOperation(value = "update money security.") + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) + @RequestMapping(value = "/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + public CudResponse update( + @ApiParam(value = "Идентификатор изменяего объекта.", required = true, example = "1234") + @PathVariable("id") Long id, + @ApiParam(value = "Новые значения полей объекта.", required = true) + @RequestBody MoneyMarketSecurityUpdateAction moneySecurityUpdateAction) throws ExecutionException, InterruptedException { + moneySecurityUpdateAction.setId(id); + return processRequest(Consts.DESTINATION_MONEY_MARKET_SECURITY_UPDATE, moneySecurityUpdateAction); + } + + @ApiOperation(value = "delete money security.") + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) + @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) + @ResponseBody + public CudResponse delete(@ApiParam(value = "Идентификатор удаляемого объекта", required = true, example = "1234") + @PathVariable("id") Long id) throws ExecutionException, InterruptedException { + CommonDeleteAction deleteAction = new CommonDeleteAction(); + deleteAction.setId(id); + return processRequest(Consts.DESTINATION_MONEY_MARKET_SECURITY_DELETE, deleteAction); + } +} diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java index 6b4d22120..66de901c0 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java @@ -3,6 +3,7 @@ package ru.spcex.clearing.backendapi.controller.request.cud.securities; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import io.swagger.annotations.ApiModelProperty; import ru.spcex.clearing.backendapi.domain.actions.IAction; import ru.spcex.clearing.backendapi.errors.BackEndError; import ru.spcex.clearing.platform.messaging.domain.ActionType; @@ -16,24 +17,32 @@ import java.util.Collections; import java.util.List; public class MoneyMarketSecurityNewAction implements IAction { + @ApiModelProperty(value = "Дата начала действия", example = "2022-01-20") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "Europe/Moscow") @JsonDeserialize(using = InstantDeserializer.class) @JsonProperty public Instant startDate; + @ApiModelProperty(value = "Дата окончания действия", example = "2022-02-21") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "Europe/Moscow") @JsonDeserialize(using = InstantDeserializer.class) @JsonProperty public Instant endDate; + @ApiModelProperty(value = "Номинал", example = "20.5") @JsonProperty public Double nominalValue; + @ApiModelProperty(value = "Идентификатор валюты номинала", example = "1000") @JsonProperty public Long nominalCurrencyId; + @ApiModelProperty(value = "Идентификатор типа инструмента", example = "ABCD") @JsonProperty public String instrumentType; + @ApiModelProperty(value = "Полное наименование инструмента", example = "Treasury bills") @JsonProperty public String fullName; + @ApiModelProperty(value = "Код инструмента", example = "ABSDEFJ") @JsonProperty public String securitySymbol; + @ApiModelProperty(value = "Размер лота", example = "300.5") @JsonProperty public Double lotSize; @@ -58,6 +67,7 @@ public class MoneyMarketSecurityNewAction implements IAction { + @ApiModelProperty(hidden = true) @JsonProperty public Long id; + @ApiModelProperty(value = "Дата окончания действия", example = "2022-02-21") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "Europe/Moscow") @JsonDeserialize(using = InstantDeserializer.class) @JsonProperty public Instant endDate; + @ApiModelProperty(value = "Номинал", example = "20.5") @JsonProperty public Double nominalValue; + @ApiModelProperty(value = "Идентификатор валюты номинала", example = "1000") @JsonProperty public Long nominalCurrencyId; + @ApiModelProperty(value = "Идентификатор типа инструмента", example = "ABCD") @JsonProperty public String instrumentType; + @ApiModelProperty(value = "Полное наименование инструмента", example = "Treasury bills") @JsonProperty public String fullName; + @ApiModelProperty(value = "Размер лота", example = "300.5") @JsonProperty public Double lotSize; @@ -41,6 +49,7 @@ public class MoneyMarketSecurityUpdateAction implements IAction