This commit is contained in:
parent
ab407edb8c
commit
7eaec47ad3
13 changed files with 313 additions and 15 deletions
|
|
@ -53,6 +53,10 @@
|
|||
<groupId>ru.spcex.clearing</groupId>
|
||||
<artifactId>classes</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.spcex.clearing</groupId>
|
||||
<artifactId>dictionary</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
package ru.spcex.clearing.backendapi.controller.response.entity.dictionary;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import ru.clearing.platform.dictionary.AbstractDictionary;
|
||||
import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel(description = "Ответ при получении объектов словаря.")
|
||||
public class DictionaryBackendGetAll extends BasicSpcexResponse {
|
||||
|
||||
@JsonProperty
|
||||
@ApiModelProperty(value = "Полезная нагрузка")
|
||||
private DictionaryBackendPayload payload = new DictionaryBackendPayload();
|
||||
|
||||
public void fromEntity(Collection<AbstractDictionary> dictionaryValues) {
|
||||
var payload = this.getPayload();
|
||||
for (AbstractDictionary dictionaryValue : dictionaryValues) {
|
||||
var singleItem = new DictionaryBackendGetFields();
|
||||
singleItem.fromEntity(dictionaryValue);
|
||||
payload.getItems().add(singleItem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class DictionaryBackendPayload {
|
||||
private List<DictionaryBackendGetFields> items = new ArrayList<>();
|
||||
|
||||
public List<DictionaryBackendGetFields> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(List<DictionaryBackendGetFields> items) {
|
||||
this.items = items;
|
||||
}
|
||||
}
|
||||
|
||||
public DictionaryBackendPayload getPayload() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
public void setPayload(DictionaryBackendPayload payload) {
|
||||
this.payload = payload;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package ru.spcex.clearing.backendapi.controller.response.entity.dictionary;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import ru.clearing.platform.dictionary.AbstractDictionary;
|
||||
|
||||
public class DictionaryBackendGetFields {
|
||||
@JsonProperty
|
||||
@ApiModelProperty(value = "Идентификатор", example = "1234")
|
||||
private Long id;
|
||||
@JsonProperty
|
||||
@ApiModelProperty(value = "", example = "")
|
||||
private String code;
|
||||
@JsonProperty
|
||||
@ApiModelProperty(value = "Имя банка", example = "Сбербанк")
|
||||
private String name;
|
||||
|
||||
public void fromEntity(AbstractDictionary dictionaryValue) {
|
||||
this.id = dictionaryValue.getId();
|
||||
this.code = dictionaryValue.getCode();
|
||||
this.name = dictionaryValue.getName();
|
||||
}
|
||||
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package ru.spcex.clearing.backendapi.controller.response.entity.dictionary;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import ru.clearing.platform.dictionary.AbstractDictionary;
|
||||
import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse;
|
||||
|
||||
@ApiModel(description = "Ответ при получении объекта BankAccount.")
|
||||
public class DictionaryBackendGetSingleValue extends BasicSpcexResponse {
|
||||
|
||||
@JsonProperty
|
||||
@ApiModelProperty(value = "Поля объекта")
|
||||
private DictionaryBackendGetFields payload;
|
||||
|
||||
public DictionaryBackendGetFields getPayload() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
public void fromEntity(AbstractDictionary dictionaryValue) {
|
||||
var payload = new DictionaryBackendGetFields();
|
||||
this.setPayload(payload);
|
||||
payload.fromEntity(dictionaryValue);
|
||||
}
|
||||
|
||||
|
||||
public void setPayload(DictionaryBackendGetFields payload) {
|
||||
this.payload = payload;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
package ru.spcex.clearing.backendapi.controller.system;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ru.clearing.platform.dictionary.AbstractDictionary;
|
||||
import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse;
|
||||
import ru.spcex.clearing.backendapi.controller.response.entity.dictionary.DictionaryBackendGetAll;
|
||||
import ru.spcex.clearing.backendapi.controller.response.entity.dictionary.DictionaryBackendGetSingleValue;
|
||||
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
|
||||
import ru.spcex.clearing.backendapi.errors.BackEndError;
|
||||
import ru.spcex.clearing.backendapi.errors.NotFound404Exception;
|
||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/dictionary")
|
||||
public class DictionaryController {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Map<String, Imdg<?>> allDictionaryMaps;
|
||||
private final ImdgProvider imdgProvider;
|
||||
|
||||
@Autowired
|
||||
public DictionaryController(ImdgProvider imdgProvider) {
|
||||
this.imdgProvider = imdgProvider;
|
||||
this.allDictionaryMaps = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "get all dictionary value.")
|
||||
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = DictionaryBackendGetAll.class)})
|
||||
@RequestMapping(value = "/{dictionary-name}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public DictionaryBackendGetAll getAll(@ApiParam(value = "Название словаря", required = true, example = "moneyFlowSide")
|
||||
@PathVariable("dictionary-name") String dictionaryName) {
|
||||
Imdg<AbstractDictionary> dictionary = extractDictionaryImdgFromUrlParameter(dictionaryName, AbstractDictionary.class);
|
||||
Collection<AbstractDictionary> allValues = dictionary.getAllValues();
|
||||
DictionaryBackendGetAll response = new DictionaryBackendGetAll();
|
||||
response.fromEntity(allValues);
|
||||
return response;
|
||||
}
|
||||
|
||||
@ApiOperation(value = "get dictionary value by id.")
|
||||
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = DictionaryBackendGetSingleValue.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
|
||||
@RequestMapping(value = "/{dictionary-name}/{id}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public DictionaryBackendGetSingleValue getById(@ApiParam(value = "Название словаря", required = true, example = "moneyFlowSide")
|
||||
@PathVariable("dictionary-name") String dictionaryName,
|
||||
@ApiParam(value = "Идентификатор объекта", required = true, example = "1234")
|
||||
@PathVariable("id") Long id) {
|
||||
Imdg<AbstractDictionary> dictionary = extractDictionaryImdgFromUrlParameter(dictionaryName, AbstractDictionary.class);
|
||||
AbstractDictionary value = dictionary.getSingleObjectByID(id);
|
||||
if (value == null) throw new NotFound404Exception(dictionaryName + " id='" + id + "'");
|
||||
DictionaryBackendGetSingleValue response = new DictionaryBackendGetSingleValue();
|
||||
response.fromEntity(value);
|
||||
return response;
|
||||
}
|
||||
|
||||
@ApiOperation(value = "get dictionary value by code.")
|
||||
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = DictionaryBackendGetSingleValue.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
|
||||
@RequestMapping(value = "/{dictionary-name}/{code}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public DictionaryBackendGetSingleValue getByCode(@ApiParam(value = "Название словаря", required = true, example = "moneyFlowSide")
|
||||
@PathVariable("dictionary-name") String dictionaryName,
|
||||
@ApiParam(value = "Код словаря", required = true, example = "1234")
|
||||
@PathVariable("code") String code) {
|
||||
Imdg<AbstractDictionary> dictionary = extractDictionaryImdgFromUrlParameter(dictionaryName, AbstractDictionary.class);
|
||||
AbstractDictionary value = dictionary.getSingleObjectByFieldValues(Map.of("code", code));
|
||||
if (value == null) throw new NotFound404Exception(dictionaryName + " code='" + code + "'");
|
||||
DictionaryBackendGetSingleValue response = new DictionaryBackendGetSingleValue();
|
||||
response.fromEntity(value);
|
||||
return response;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends SpcexObjectBase> Imdg<T> extractDictionaryImdgFromUrlParameter(String dictionaryNameFromUrl, Class<T> clazz) {
|
||||
if (dictionaryNameFromUrl == null || dictionaryNameFromUrl.length() < 1) {
|
||||
throw new ActionValidationException(BackEndError.ValidationError, "dictionary-name");
|
||||
}
|
||||
|
||||
String actualDictionaryName = "Map_"
|
||||
+ dictionaryNameFromUrl.substring(0, 1).toUpperCase()
|
||||
+ dictionaryNameFromUrl.substring(1)
|
||||
+ "Dictionary";
|
||||
|
||||
Imdg<T> dictionary = (Imdg<T>) allDictionaryMaps.computeIfAbsent(actualDictionaryName, (mapName1) -> {
|
||||
Imdg<T> potentialImdg = imdgProvider.getImdg(actualDictionaryName, clazz);
|
||||
if (potentialImdg.size() == 0) {
|
||||
log.warn("coudln't find dictionary {}", actualDictionaryName);
|
||||
return null;
|
||||
}
|
||||
return potentialImdg;
|
||||
});
|
||||
|
||||
if (dictionary == null) {
|
||||
throw new ActionValidationException(BackEndError.DictionaryNotFound, dictionaryNameFromUrl);
|
||||
}
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private IMessageResolver errorResolver;
|
||||
|
||||
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
|
||||
@ResponseBody
|
||||
@ExceptionHandler(ActionValidationException.class)
|
||||
public BasicSpcexResponse conflict(ActionValidationException ex) {
|
||||
BasicSpcexResponse response = new BasicSpcexResponse();
|
||||
EnumMessage message = ex.getErrors().stream().findFirst().orElseThrow();
|
||||
response.setCode(message.getSubject().getId());
|
||||
response.setMessage(errorResolver.resolve(message));
|
||||
return response;
|
||||
}
|
||||
|
||||
@ResponseStatus(value = HttpStatus.NOT_FOUND)
|
||||
@ResponseBody
|
||||
@ExceptionHandler(NotFound404Exception.class)
|
||||
public BasicSpcexResponse conflict(NotFound404Exception ex) {
|
||||
BasicSpcexResponse response = new BasicSpcexResponse();
|
||||
EnumMessage message = ex.getError();
|
||||
response.setCode(message.getSubject().getId());
|
||||
response.setMessage(errorResolver.resolve(message));
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package ru.spcex.clearing.backendapi.errors;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
|
@ -16,6 +17,10 @@ public class ActionValidationException extends RuntimeException {
|
|||
this.errors = List.of(error);
|
||||
}
|
||||
|
||||
public ActionValidationException(IEnumId subject, Object... args) {
|
||||
this.errors = List.of(new EnumMessage(subject, args));
|
||||
}
|
||||
|
||||
public Collection<EnumMessage> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@ public enum BackEndError implements IEnumId {
|
|||
ValidationError(3000L),
|
||||
UnknownJsonProperty(3001L),
|
||||
FailedToReadHttpMessage(3002L),
|
||||
KeycloakRepeatedRoles(3003L);
|
||||
KeycloakRepeatedRoles(3003L),
|
||||
DictionaryNotFound(3004L),
|
||||
ResourceNotFound(404L)
|
||||
;
|
||||
private final Long id;
|
||||
|
||||
BackEndError(Long id) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package ru.spcex.clearing.backendapi.errors;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
|
||||
public class NotFound404Exception extends RuntimeException {
|
||||
|
||||
private final EnumMessage error;
|
||||
|
||||
public NotFound404Exception(String comment) {
|
||||
this.error = new EnumMessage(BackEndError.ResourceNotFound, comment);
|
||||
}
|
||||
|
||||
public EnumMessage getError() {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
1=This is error example 1.
|
||||
3000=validation error field '%s'
|
||||
3001=unrecognized json property '%s'
|
||||
3002=failed to read http message
|
||||
3002=failed to read http message
|
||||
3004=couldn't find dictionary '%s'
|
||||
|
|
@ -55,6 +55,10 @@
|
|||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.spcex.platform</groupId>
|
||||
<artifactId>platform-classes-base</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
|||
|
|
@ -1,22 +1,12 @@
|
|||
package ru.clearing.platform.dictionary;
|
||||
|
||||
public abstract class AbstractDictionary implements Dictionary {
|
||||
static final long serialVersionUID = ConstDictionarySerializable.serialVersionUID;
|
||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||
|
||||
protected Long id;
|
||||
public abstract class AbstractDictionary extends SpcexObjectBase implements Dictionary {
|
||||
static final long serialVersionUID = ConstDictionarySerializable.serialVersionUID;
|
||||
protected String code;
|
||||
protected String name;
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return code;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ public class ImdgHazelcast<T extends SpcexObjectBase> implements Imdg<T> {
|
|||
return map.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(T paramT) {
|
||||
if (paramT.getId() == null) {
|
||||
|
|
|
|||
|
|
@ -57,4 +57,8 @@ public interface Imdg<T extends SpcexObjectBase> {
|
|||
default <A> Collection<A> projectionsAttributeBySql(String paramString, String... paramVarArgs) {
|
||||
throw new UnsupportedOperationException("not implemented projectionsAttributeBySql");
|
||||
}
|
||||
|
||||
default Integer size() {
|
||||
throw new UnsupportedOperationException("not implemented size");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue