diff --git a/clearing-parent/backend-api/pom.xml b/clearing-parent/backend-api/pom.xml
index 18b29f7d1..4a809e05a 100644
--- a/clearing-parent/backend-api/pom.xml
+++ b/clearing-parent/backend-api/pom.xml
@@ -53,6 +53,10 @@
ru.spcex.clearing
classes
+
+ ru.spcex.clearing
+ dictionary
+
diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetAll.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetAll.java
new file mode 100644
index 000000000..3d6c11aeb
--- /dev/null
+++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetAll.java
@@ -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 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 items = new ArrayList<>();
+
+ public List getItems() {
+ return items;
+ }
+
+ public void setItems(List items) {
+ this.items = items;
+ }
+ }
+
+ public DictionaryBackendPayload getPayload() {
+ return payload;
+ }
+
+ public void setPayload(DictionaryBackendPayload payload) {
+ this.payload = payload;
+ }
+}
\ No newline at end of file
diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetFields.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetFields.java
new file mode 100644
index 000000000..fa27898c9
--- /dev/null
+++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetFields.java
@@ -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;
+ }
+}
diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetSingleValue.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetSingleValue.java
new file mode 100644
index 000000000..b58ccd807
--- /dev/null
+++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetSingleValue.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/system/DictionaryController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/system/DictionaryController.java
new file mode 100644
index 000000000..ebbf91f79
--- /dev/null
+++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/system/DictionaryController.java
@@ -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> 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 dictionary = extractDictionaryImdgFromUrlParameter(dictionaryName, AbstractDictionary.class);
+ Collection 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 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 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 Imdg extractDictionaryImdgFromUrlParameter(String dictionaryNameFromUrl, Class 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 dictionary = (Imdg) allDictionaryMaps.computeIfAbsent(actualDictionaryName, (mapName1) -> {
+ Imdg 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;
+ }
+}
diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/ActionValidationException.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/ActionValidationException.java
index 251695991..b117f4c11 100644
--- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/ActionValidationException.java
+++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/ActionValidationException.java
@@ -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 getErrors() {
return errors;
}
diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/BackEndError.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/BackEndError.java
index 5808d3e7e..e84aeba69 100644
--- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/BackEndError.java
+++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/BackEndError.java
@@ -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) {
diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/NotFound404Exception.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/NotFound404Exception.java
new file mode 100644
index 000000000..1483749e5
--- /dev/null
+++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/NotFound404Exception.java
@@ -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;
+ }
+}
diff --git a/clearing-parent/backend-api/src/main/resources/messages/error.properties b/clearing-parent/backend-api/src/main/resources/messages/error.properties
index bd5831476..52320a63a 100644
--- a/clearing-parent/backend-api/src/main/resources/messages/error.properties
+++ b/clearing-parent/backend-api/src/main/resources/messages/error.properties
@@ -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
\ No newline at end of file
+3002=failed to read http message
+3004=couldn't find dictionary '%s'
\ No newline at end of file
diff --git a/clearing-parent/dictionary/pom.xml b/clearing-parent/dictionary/pom.xml
index cf6ecd958..323d95a0f 100644
--- a/clearing-parent/dictionary/pom.xml
+++ b/clearing-parent/dictionary/pom.xml
@@ -55,6 +55,10 @@
junit-jupiter
test
+
+ ru.spcex.platform
+ platform-classes-base
+
diff --git a/clearing-parent/dictionary/src/main/java/ru/clearing/platform/dictionary/AbstractDictionary.java b/clearing-parent/dictionary/src/main/java/ru/clearing/platform/dictionary/AbstractDictionary.java
index e5c970836..d7186440b 100644
--- a/clearing-parent/dictionary/src/main/java/ru/clearing/platform/dictionary/AbstractDictionary.java
+++ b/clearing-parent/dictionary/src/main/java/ru/clearing/platform/dictionary/AbstractDictionary.java
@@ -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;
diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java
index cb848122f..940adedcb 100644
--- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java
+++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java
@@ -29,6 +29,11 @@ public class ImdgHazelcast implements Imdg {
return map.values();
}
+ @Override
+ public Integer size() {
+ return map.size();
+ }
+
@Override
public void insert(T paramT) {
if (paramT.getId() == null) {
diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java
index 845eeb86f..ca765d5b5 100644
--- a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java
+++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java
@@ -57,4 +57,8 @@ public interface Imdg {
default Collection projectionsAttributeBySql(String paramString, String... paramVarArgs) {
throw new UnsupportedOperationException("not implemented projectionsAttributeBySql");
}
+
+ default Integer size() {
+ throw new UnsupportedOperationException("not implemented size");
+ }
}