http://jira.mfd.msk:8088/browse/CLS-213 добавил словари в мету

This commit is contained in:
ialbert 2022-12-26 20:20:04 +03:00
parent a5320f36f3
commit 1d63a859c6
9 changed files with 158 additions and 23 deletions

View file

@ -9,25 +9,34 @@ import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ApiModel(description = "Ответ при получении объектов словаря.")
public class DictionaryBackendGetAll extends BasicSpcexResponse {
@JsonProperty
@ApiModelProperty(value = "Полезная нагрузка")
private DictionaryBackendPayload payload = new DictionaryBackendPayload();
private IDictionaryPayload payload;
public void fromEntity(Collection<AbstractDictionary> dictionaryValues) {
var payload = this.getPayload();
this.payload = new GeneralDictionaryBackendPayload();
GeneralDictionaryBackendPayload castedPayload = (GeneralDictionaryBackendPayload) payload;
for (AbstractDictionary dictionaryValue : dictionaryValues) {
var singleItem = new DictionaryBackendGetFields();
singleItem.fromEntity(dictionaryValue);
payload.getItems().add(singleItem);
castedPayload.getItems().add(singleItem);
}
}
public void addMap(Map<String, Object> m) {
if (this.payload == null) {
this.payload = new SpecificDictionaryBackendPayload();
}
SpecificDictionaryBackendPayload payloadCasted = (SpecificDictionaryBackendPayload) this.payload;
payloadCasted.getItems().add(m);
}
private static class DictionaryBackendPayload {
public static class GeneralDictionaryBackendPayload implements IDictionaryPayload {
private List<DictionaryBackendGetFields> items = new ArrayList<>();
public List<DictionaryBackendGetFields> getItems() {
@ -39,11 +48,24 @@ public class DictionaryBackendGetAll extends BasicSpcexResponse {
}
}
public DictionaryBackendPayload getPayload() {
public static class SpecificDictionaryBackendPayload implements IDictionaryPayload {
@JsonProperty
private List<Map<String, Object>> items = new ArrayList<>();
public List<Map<String, Object>> getItems() {
return items;
}
public void setItems(List<Map<String, Object>> items) {
this.items = items;
}
}
public IDictionaryPayload getPayload() {
return payload;
}
public void setPayload(DictionaryBackendPayload payload) {
public void setPayload(IDictionaryPayload payload) {
this.payload = payload;
}
}

View file

@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import ru.clearing.platform.dictionary.AbstractDictionary;
public class DictionaryBackendGetFields {
public class DictionaryBackendGetFields implements IDictionaryPayload {
@JsonProperty
@ApiModelProperty(value = "Идентификатор", example = "1234")
private Long id;

View file

@ -0,0 +1,25 @@
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.spcex.clearing.backendapi.controller.response.BasicSpcexResponse;
import java.util.HashMap;
import java.util.Map;
@ApiModel(description = "Ответ при получении объекта словаря.")
public class DictionaryBackendGetSingleValueV2 extends BasicSpcexResponse {
@JsonProperty
@ApiModelProperty(value = "Поля объекта")
private Map<String, Object> payload = new HashMap<>();
public Map<String, Object> getPayload() {
return payload;
}
public void setPayload(Map<String, Object> payload) {
this.payload = payload;
}
}

View file

@ -0,0 +1,4 @@
package ru.spcex.clearing.backendapi.controller.response.entity.dictionary;
public interface IDictionaryPayload {
}

View file

@ -13,10 +13,11 @@ 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.controller.response.entity.dictionary.DictionaryBackendGetSingleValueV2;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.backendapi.errors.BackEndError;
import ru.spcex.clearing.backendapi.errors.NotFound404Exception;
import ru.spcex.clearing.backendapi.meta.GetResponseFactory;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
@ -33,10 +34,12 @@ public class DictionaryController {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Map<String, Imdg<?>> allDictionaryMaps;
private final ImdgProvider imdgProvider;
private final GetResponseFactory responseFactory;
@Autowired
public DictionaryController(ImdgProvider imdgProvider) {
public DictionaryController(ImdgProvider imdgProvider, GetResponseFactory responseFactory) {
this.imdgProvider = imdgProvider;
this.responseFactory = responseFactory;
this.allDictionaryMaps = new ConcurrentHashMap<>();
}
@ -49,39 +52,42 @@ public class DictionaryController {
Imdg<AbstractDictionary> dictionary = extractDictionaryImdgFromUrlParameter(dictionaryName, AbstractDictionary.class);
Collection<AbstractDictionary> allValues = dictionary.getAllValues();
DictionaryBackendGetAll response = new DictionaryBackendGetAll();
response.fromEntity(allValues);
for (AbstractDictionary val : allValues) {
Map<String, Object> fromMeta = responseFactory.responseFromDictionary(dictionaryName, val);
response.addMap(fromMeta);
}
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)})
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = DictionaryBackendGetSingleValueV2.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")
public DictionaryBackendGetSingleValueV2 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);
DictionaryBackendGetSingleValueV2 response = new DictionaryBackendGetSingleValueV2();
response.setPayload(responseFactory.responseFromDictionary(dictionaryName, 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)})
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = DictionaryBackendGetSingleValueV2.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(value = "/{dictionary-name}/code/{code}", method = RequestMethod.GET)
@ResponseBody
public DictionaryBackendGetSingleValue getByCode(@ApiParam(value = "Название словаря", required = true, example = "moneyFlowSide")
public DictionaryBackendGetSingleValueV2 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);
DictionaryBackendGetSingleValueV2 response = new DictionaryBackendGetSingleValueV2();
response.setPayload(responseFactory.responseFromDictionary(dictionaryName, value));
return response;
}

View file

@ -0,0 +1,22 @@
package ru.spcex.clearing.backendapi.meta;
import java.util.List;
public class ClearingDictionaryExtracted extends ObjectExtracted {
public ClearingDictionaryExtracted(String clazz, List<ActionField> actionFields) {
for (ActionField field : actionFields) {
if (field.getVirtual() != null && field.isVirtual()){
continue;
}
FieldExtracted fe = getImplFieldExtracted(field);
fields.add(fe);
fieldByCode.put(field.getCode(), fe);
}
}
@Override
public FieldExtracted getImplFieldExtracted(ActionField field) {
return new ClearingFieldExtracted(field);
}
}

View file

@ -31,11 +31,26 @@ public class GetResponseFactory {
.collect(Collectors.toList());
}
/**
* dictionaryName - это имя тэга внутри <enum>
*/
public Map<String, Object> responseFromDictionary(String dictionaryName, Object o) {
ObjectExtracted objectExtracted = meta.getEnumsExtractedByTagName().get(dictionaryName);
if (objectExtracted == null) {
throw new RuntimeException("cannot find dictionary in meta for " + dictionaryName);
}
return responseFromObjectExtracted(o, objectExtracted);
}
public Map<String, Object> responseFromObject(Object o) {
ObjectExtracted objExtr = meta.getObjectsExtractedByClazz().get(o.getClass().getCanonicalName());
if (objExtr == null) {
throw new RuntimeException("cannot find object in meta for " + o.getClass().getCanonicalName());
}
return responseFromObjectExtracted(o, objExtr);
}
private Map<String, Object> responseFromObjectExtracted(Object o, ObjectExtracted objExtr) {
Map<String, Object> r = new LinkedHashMap<>();
FieldExtracted currentField = null;
try {

View file

@ -2,6 +2,7 @@ package ru.spcex.clearing.backendapi.meta;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.spcex.platform.utils.log.ExceptionUtils;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
@ -17,6 +18,8 @@ public class MetaServer extends MetaBase {
private Map<String, ObjectExtracted> objectsExtractedByDestination;
private Map<String, ObjectExtracted> actionObjectsExtracted;
private Map<String, ObjectElement> objectElementByDestination;
private Map<String, ObjectExtracted> enumsExtractedByTagName;
private final static Set<String> dictionaryDefaultFields = Set.of("id", "code", "name");
protected ObjectExtracted getImplInstanceObjectExtracted(String clazz, List<ActionField> actionFields) {
return new ClearingObjectExtracted(clazz, actionFields);
@ -31,6 +34,7 @@ public class MetaServer extends MetaBase {
objectsExtractedByClazz = new ConcurrentHashMap<>();
objectsExtractedByDestination = new ConcurrentHashMap<>();
objectElementByDestination = new ConcurrentHashMap<>();
enumsExtractedByTagName = new ConcurrentHashMap<>();
try {
Map<String, ObjectElement> objects = getObjects();
log.info("Meta objects:\n{}",
@ -84,6 +88,37 @@ public class MetaServer extends MetaBase {
} catch (Throwable e) {
throw new ClearingMetaServerValidationException(e.getLocalizedMessage());
}
try {
Map<String, ObjectEnumElement> enums = getEnums();
for (String key : enums.keySet()) {
ObjectExtracted oe;
ObjectEnumElement objectElement = enums.get(key);
try {
oe = new ClearingDictionaryExtracted(objectElement.getClazz(), objectElement.getFields());
} catch (Throwable e) {
log.warn("{} {}", key, ExceptionUtils.getStackTrace(e));
continue;
}
/**
* можно было бы хранить только для нестандартных словарей (где не только id, name, code)
*/
// List<FieldExtracted> dictFields = oe.getFields();
// boolean add = false;
// for (FieldExtracted dictField : dictFields) {
// if (!dictionaryDefaultFields.contains(dictField.getMemberName())) {
// add = true;
// break;
// }
// }
// if (add) {
// enumsExtractedByTagName.put(key, oe);
// }
enumsExtractedByTagName.put(key, oe);
}
} catch (Throwable e) {
throw new ClearingMetaServerValidationException(e.getLocalizedMessage());
}
}
for (ObjectExtracted o : this.objectsExtracted) {
try {
@ -196,4 +231,8 @@ public class MetaServer extends MetaBase {
}
return partSize;
}
public Map<String, ObjectExtracted> getEnumsExtractedByTagName() {
return enumsExtractedByTagName;
}
}

View file

@ -5,12 +5,14 @@ import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public abstract class ObjectExtracted {
private String className;
private Class<?> clazz;
private List<FieldExtracted> fields = new LinkedList<>();
private Map<String, FieldExtracted> fieldByCode = new ConcurrentHashMap<>();
private boolean isArray = false;
protected String className;
protected Class<?> clazz;
protected List<FieldExtracted> fields = new LinkedList<>();
protected Map<String, FieldExtracted> fieldByCode = new ConcurrentHashMap<>();
protected boolean isArray = false;
public ObjectExtracted() {
}
public ObjectExtracted(String clazz, List<ActionField> actionFields) {
this.className = clazz;