ialbert 2022-08-18 17:20:00 +03:00
parent 394bb7477c
commit a4de8e691b
6 changed files with 121 additions and 92 deletions

View file

@ -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<IAction<?>> 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;
}
}

View file

@ -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 <T> CudResponse processRequest(String destination, IAction<T> iAction) throws ExecutionException, InterruptedException {
CudResponse responseToClient = new CudResponse();
responseToClient.setPayload(operator.sendRequestToQueue(destination, iAction));
responseToClient.setCode(0);
responseToClient.setMessage("success");
return responseToClient;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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<MoneyMarketSecurityNewRequest> {
@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<MoneyMarketSecurity
return req;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.NEW;

View file

@ -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.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest;
@ -11,20 +12,27 @@ import ru.spcex.clearing.platform.messaging.domain.json.deserialize.InstantDeser
import java.time.Instant;
public class MoneyMarketSecurityUpdateAction implements IAction<MoneyMarketSecurityUpdateRequest> {
@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<MoneyMarketSecur
return req;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.UPDATE;