diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/config/MetaConfiguration.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/config/MetaConfiguration.java index 96e961be5..515707844 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/config/MetaConfiguration.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/config/MetaConfiguration.java @@ -1,9 +1,16 @@ package ru.spcex.clearing.backendapi.config; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; +import ru.spcex.clearing.backendapi.meta.MetaServer; import java.io.IOException; import java.nio.file.Files; @@ -18,4 +25,15 @@ public class MetaConfiguration { if (!meta.isReadable()) throw new IllegalStateException("cannot read meta.json from spring.config.location"); return Files.readString(meta.getFile().toPath()); } + + @Autowired + @Bean + public MetaServer metaServer(@Qualifier("metaJson") String metaJson) throws JsonProcessingException { + ObjectMapper jsonObjectMapper = new ObjectMapper(); + jsonObjectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); + jsonObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + MetaServer metaServer = jsonObjectMapper.readValue(metaJson, MetaServer.class); + metaServer.initAndValidate(); + return metaServer; + } } 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 index 3103aab14..e7585e1d1 100644 --- 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 @@ -16,6 +16,7 @@ import ru.spcex.clearing.backendapi.controller.request.cud.securities.MoneyMarke import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse; import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse; import ru.spcex.clearing.backendapi.controller.response.entity.securities.MoneyMarketSecurityBackendGetAll; +import ru.spcex.clearing.backendapi.meta.GetResponseFactory; import ru.spcex.clearing.backendapi.service.IOperator; import ru.spcex.clearing.backendapi.service.IStateLoader; import ru.spcex.clearing.imdg.IMDGDistributedNames; @@ -69,6 +70,9 @@ public class CudMoneyMarketSecurityController extends AbstractQueueController { return processRequest(Consts.DESTINATION_MONEY_MARKET_SECURITY_DELETE, deleteAction); } + @Autowired + private GetResponseFactory responseFactory; + @ApiOperation(value = "get all money market securities.") @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = MoneyMarketSecurityBackendGetAll.class)}) @RequestMapping(method = RequestMethod.GET) @@ -76,7 +80,7 @@ public class CudMoneyMarketSecurityController extends AbstractQueueController { public MoneyMarketSecurityBackendGetAll getAll() { Collection all = stateLoader.getAll(IMDGDistributedNames.Map_MoneyMarketSecurity, MoneyMarketSecurity.class); MoneyMarketSecurityBackendGetAll response = new MoneyMarketSecurityBackendGetAll(); - response.fromEntity(all); + response.fromEntity(responseFactory.responseFromObjectCollection(all)); return response; } } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/securities/MoneyMarketSecurityBackendGetAll.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/securities/MoneyMarketSecurityBackendGetAll.java index fecdc6a56..c19295725 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/securities/MoneyMarketSecurityBackendGetAll.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/securities/MoneyMarketSecurityBackendGetAll.java @@ -3,12 +3,12 @@ package ru.spcex.clearing.backendapi.controller.response.entity.securities; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; 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 = "Ответ при получении объектов MoneyMarketSecurity.") public class MoneyMarketSecurityBackendGetAll extends BasicSpcexResponse { @@ -18,13 +18,13 @@ public class MoneyMarketSecurityBackendGetAll extends BasicSpcexResponse { private MoneyMarketSecurityBackendPayload payload = new MoneyMarketSecurityBackendPayload(); private static class MoneyMarketSecurityBackendPayload { - private List items = new ArrayList<>(); + private List> items = new ArrayList<>(); - public List getItems() { + public List> getItems() { return items; } - public void setItems(List items) { + public void setItems(List> items) { this.items = items; } } @@ -37,22 +37,10 @@ public class MoneyMarketSecurityBackendGetAll extends BasicSpcexResponse { this.payload = payload; } - public void fromEntity(Collection moneyMarketSecurities) { + public void fromEntity(Collection> moneyMarketSecurities) { var payload = this.getPayload(); - for (MoneyMarketSecurity moneyMarketSecurity : moneyMarketSecurities) { - var singleItem = new MoneyMarketSecurityBackendGetFields(); - singleItem.setId(moneyMarketSecurity.getId()); - singleItem.setSecurityId(moneyMarketSecurity.getSecurityId()); - singleItem.setDescription(moneyMarketSecurity.getDescription()); - singleItem.setStartDate(moneyMarketSecurity.getStartDate()); - singleItem.setEndDate(moneyMarketSecurity.getEndDate()); - singleItem.setNominalValue(moneyMarketSecurity.getNominalValue()); - singleItem.setNominalCurrency(moneyMarketSecurity.getNominalCurrency()); - singleItem.setInstrumentType(moneyMarketSecurity.getInstrumentType()); - singleItem.setFullName(moneyMarketSecurity.getFullName()); - singleItem.setSecuritySymbol(moneyMarketSecurity.getSecuritySymbol()); - payload.getItems().add(singleItem); + for (Map moneyMarketSecurity : moneyMarketSecurities) { + payload.getItems().add(moneyMarketSecurity); } } - } \ No newline at end of file diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/securities/MoneyMarketSecurityBackendGetAllOld.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/securities/MoneyMarketSecurityBackendGetAllOld.java new file mode 100644 index 000000000..0f656b8a2 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/securities/MoneyMarketSecurityBackendGetAllOld.java @@ -0,0 +1,59 @@ +package ru.spcex.clearing.backendapi.controller.response.entity.securities; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Deprecated +@ApiModel(description = "Ответ при получении объектов MoneyMarketSecurity.") +public class MoneyMarketSecurityBackendGetAllOld extends BasicSpcexResponse { + + @JsonProperty + @ApiModelProperty(value = "Полезная нагрузка") + private MoneyMarketSecurityBackendPayload payload = new MoneyMarketSecurityBackendPayload(); + + private static class MoneyMarketSecurityBackendPayload { + private List items = new ArrayList<>(); + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + } + + public MoneyMarketSecurityBackendPayload getPayload() { + return payload; + } + + public void setPayload(MoneyMarketSecurityBackendPayload payload) { + this.payload = payload; + } + + public void fromEntity(Collection moneyMarketSecurities) { + var payload = this.getPayload(); + for (MoneyMarketSecurity moneyMarketSecurity : moneyMarketSecurities) { + var singleItem = new MoneyMarketSecurityBackendGetFields(); + singleItem.setId(moneyMarketSecurity.getId()); + singleItem.setSecurityId(moneyMarketSecurity.getSecurityId()); + singleItem.setDescription(moneyMarketSecurity.getDescription()); + singleItem.setStartDate(moneyMarketSecurity.getStartDate()); + singleItem.setEndDate(moneyMarketSecurity.getEndDate()); + singleItem.setNominalValue(moneyMarketSecurity.getNominalValue()); + singleItem.setNominalCurrency(moneyMarketSecurity.getNominalCurrency()); + singleItem.setInstrumentType(moneyMarketSecurity.getInstrumentType()); + singleItem.setFullName(moneyMarketSecurity.getFullName()); + singleItem.setSecuritySymbol(moneyMarketSecurity.getSecuritySymbol()); + payload.getItems().add(singleItem); + } + } + +} \ No newline at end of file diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ClearingFieldExtracted.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ClearingFieldExtracted.java new file mode 100644 index 000000000..bba9df903 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ClearingFieldExtracted.java @@ -0,0 +1,17 @@ +package ru.spcex.clearing.backendapi.meta; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ClearingFieldExtracted extends FieldExtracted { + static final Logger log = LoggerFactory.getLogger(ClearingFieldExtracted.class); + + public ClearingFieldExtracted(ActionField field) { + super(field); + } + + @Override + public Object getObjectRef(Object o) { + throw new IllegalStateException("unsupported operation"); + } +} diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ClearingObjectExtracted.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ClearingObjectExtracted.java new file mode 100644 index 000000000..ce103ed08 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ClearingObjectExtracted.java @@ -0,0 +1,14 @@ +package ru.spcex.clearing.backendapi.meta; + +import java.util.List; + +public class ClearingObjectExtracted extends ObjectExtracted { + public ClearingObjectExtracted(String clazz, List actionFields) { + super(clazz, actionFields); + } + + @Override + public FieldExtracted getImplFieldExtracted(ActionField field) { + return new ClearingFieldExtracted(field); + } +} diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/FieldExtracted.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/FieldExtracted.java index 033cded57..d3f1e4575 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/FieldExtracted.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/FieldExtracted.java @@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.time.LocalDate; import java.util.*; public abstract class FieldExtracted { @@ -58,6 +59,7 @@ public abstract class FieldExtracted { break; } + //fixme somehow externalize custom serialization for type // тут нужно вернуть список id объектов а не список самих объектов для случая // - add(r, "addresseeId", o.getAddressee() == null ? null : o.getAddressee().stream().map(OtcObjectBase::getId).collect(Collectors.toSet()), fieldFilter); if (result instanceof Set && ((Set) result).size() > 0) { @@ -70,6 +72,8 @@ public abstract class FieldExtracted { result = t; } catch (Throwable ignored) {// вернем сами объекты } + } else if (result instanceof LocalDate) { + result = result.toString(); } return result; } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/GetResponseFactory.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/GetResponseFactory.java new file mode 100644 index 000000000..11299df70 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/GetResponseFactory.java @@ -0,0 +1,125 @@ +package ru.spcex.clearing.backendapi.meta; + +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + +@Component +public class GetResponseFactory { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final MetaServer meta; + + @Autowired + public GetResponseFactory(MetaServer meta) { + this.meta = meta; + } + + public Collection> responseFromObjectCollection(Collection o) { + return o.stream() + .map(this::responseFromObject) + .collect(Collectors.toList()); + } + + public Map 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()); + } + Map r = new LinkedHashMap<>(); + FieldExtracted currentField = null; + try { + for (FieldExtracted field : objExtr.getFields()) { + if (field.getField().isVirtual() != null && field.getField().isVirtual()) { + continue; + } + currentField = field; +// if (fieldsToAdd.contains(field.getField().getCode())) { + try { + add(r, field.getField().getCode(), field.extractValue(o)); + } catch (Throwable e) { + log.warn(ExceptionUtils.getStackTrace( + new RuntimeException(String.format("Can't extract value for field='%s' of %s(%s): %s -> %s\n%s", + field.getField().getCode(), + o.getClass().getSimpleName(), objExtr.getClassName(), + e.getClass().getSimpleName(), e.getLocalizedMessage(), + currentField.toString() + ))) + ); + } +// } + } + } catch (Exception e) { + log.error(ExceptionUtils.getStackTrace(e)); + return null; + } + return r; + } + + private void add(Map response, String name, Object value) { + Object data; + if (value instanceof Date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+03:00"); + data = sdf.format(value); + } else if (value instanceof Instant) { + data = dateTimeFormatter.format((Instant) value); + } else { + data = value; + } + response.put(name, data); + } + + private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter + .ofPattern("yyyy-MM-dd'T'HH:mm:ss+03:00") + .withLocale(Locale.US) + .withZone(ZoneId.of("Europe/Moscow")); + + +// public Map newX(Object o, Collection fieldFilter, String destination) { +// ObjectExtracted targetClazz = getTargetClazz(o, destination); +// if (targetClazz == null) +// throw new FrontendException(String.format("Unknown response class: %s", o.getClass().getName())); +// Collection fieldsToAdd = getFilteredFields(targetClazz, fieldFilter); +// Map r = new LinkedHashMap<>(); +// FieldExtracted currentField = null; +// try { +// for (FieldExtracted field : targetClazz.getFields()) { +// if (field.getField().isVirtual() != null && field.getField().isVirtual()) { +// continue; +// } +// currentField = field; +// if (fieldsToAdd.contains(field.getField().getCode())) { +// try { +// add(r, field.getField().getCode(), field.extractValue(o)); +// } catch (Throwable e) { +// log.warn(ExceptionUtils.getStackTrace( +// new FrontendException(String.format("Can't extract value for field='%s' of %s(%s): %s -> %s\n%s", +// field.getField().getCode(), +// o.getClass().getSimpleName(), targetClazz.getClazz().getSimpleName(), +// e.getClass().getSimpleName(), e.getLocalizedMessage(), +// JsonHelper.writeAnyClassToLog(currentField) +// ))) +// ); +// } +// } +// } +// } catch (FrontendException e) { +// throw e; +// } catch (Throwable e) { +// throw new FrontendException(String.format("Can't get field of %s(%s): %s -> %s\n%s", +// o.getClass().getSimpleName(), targetClazz.getClazz().getSimpleName(), +// e.getClass().getSimpleName(), e.getLocalizedMessage(), +// JsonHelper.writeAnyClassToLog(currentField) +// )); +// } +// return r; +// } +} diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/MetaServer.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/MetaServer.java index 9dfb63789..be7392a9b 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/MetaServer.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/MetaServer.java @@ -9,7 +9,7 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; -public abstract class MetaServer extends MetaBase { +public class MetaServer extends MetaBase { private final Logger log = LoggerFactory.getLogger(this.getClass()); private Collection objectsExtracted; @@ -18,8 +18,11 @@ public abstract class MetaServer extends MetaBase { private Map actionObjectsExtracted; private Map objectElementByDestination; - protected abstract ObjectExtracted getImplInstanceObjectExtracted(String clazz, List actionFields); + protected ObjectExtracted getImplInstanceObjectExtracted(String clazz, List actionFields) { + return new ClearingObjectExtracted(clazz, actionFields); + } + private int classNameMock = 1; @SuppressWarnings("Duplicates") public void initAndValidate() throws ClearingMetaServerValidationException, OtcMetaServerGetterNotFoundException { if (objectsExtracted == null) { @@ -47,11 +50,17 @@ public abstract class MetaServer extends MetaBase { try { oe = getImplInstanceObjectExtracted(objectElement.getClazz(), objectElement.getFields()); } catch (Throwable e) { - log.warn("META SERVER >>> Класс {} не найден!", objects.get(key).getClazz()); + log.warn("META SERVER >>> Класс {} для {} не найден!", objects.get(key).getClazz(), key); continue; } objectsExtracted.add(oe); - objectsExtractedByClazz.put(oe.getClassName(), oe); + if (oe.getClassName() != null) { + ObjectExtracted previous = objectsExtractedByClazz.put(oe.getClassName(), oe); + if (previous != null) { + log.warn("!!! meta contains duplicate classes {}", oe.getClassName()); + } + } else + objectsExtractedByClazz.put(String.valueOf(classNameMock++), oe); if (objectElement.getSubscription() != null && objectElement.getSubscription().destination != null) { objectsExtractedByDestination.put(objectElement.getSubscription().destination, oe); } @@ -93,25 +102,24 @@ public abstract class MetaServer extends MetaBase { throw new ClearingMetaServerValidationException(e.getLocalizedMessage()); } } - - for (ObjectExtracted o : this.actionObjectsExtracted.values()) { - try { - if (!RfHelper.isAbstract(o.getClazz())) { - try { - Object instance = newInstance(o.getClassName()); - // создается успешно. - } catch (Throwable e) { - log.warn("META SERVER ACTION >>> Не удается создать класс {} !", o.getClassName()); - } - } - validateGetterForObject(o); - } catch (OtcMetaServerGetterNotFoundException e) { - throw e; - } catch (Throwable e) { - throw new ClearingMetaServerValidationException(e.getLocalizedMessage()); - } - } - +// +// for (ObjectExtracted o : this.actionObjectsExtracted.values()) { +// try { +// if (!RfHelper.isAbstract(o.getClazz())) { +// try { +// Object instance = newInstance(o.getClassName()); +// // создается успешно. +// } catch (Throwable e) { +// log.warn("META SERVER ACTION >>> Не удается создать класс {} !", o.getClassName()); +// } +// } +// validateGetterForObject(o); +// } catch (OtcMetaServerGetterNotFoundException e) { +// throw e; +// } catch (Throwable e) { +// throw new ClearingMetaServerValidationException(e.getLocalizedMessage()); +// } +// } } /** diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/meta/GetResponseFactoryTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/meta/GetResponseFactoryTest.java new file mode 100644 index 000000000..a408322a5 --- /dev/null +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/meta/GetResponseFactoryTest.java @@ -0,0 +1,66 @@ +package ru.spcex.clearing.backendapi.meta; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.*; +import java.util.stream.Collectors; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = GetResponseFactoryTestConfiguration.class) +public class GetResponseFactoryTest { + private final MetaServer meta; + + @Autowired + public GetResponseFactoryTest(@Qualifier("metaJsonTest") MetaServer meta) { + this.meta = meta; + } + + @Test + public void testAllObjectsFields() throws ClassNotFoundException, InstantiationException, IllegalAccessException { + Collection allMetaObjects = meta.getObjects().values(); + Set> allMetaObjects2 = meta.getObjects().entrySet(); + Map> error = new HashMap<>(); + for (Map.Entry ent : allMetaObjects2) { + ObjectElement objectElement = ent.getValue(); + String className = objectElement.getClazz(); + Class classByName = null; + if (className == null) { + error.computeIfAbsent(ent.getKey(), v -> new ArrayList<>()).add(ent.getKey() + " no class property"); + continue; + } + try { + classByName = Class.forName(className); + } catch (ClassNotFoundException e) { + error.computeIfAbsent(ent.getKey(), v -> new ArrayList<>()).add(ent.getKey() + " cannot find class " + className); + continue; + } + Object object = classByName.newInstance(); + ObjectExtracted objectExtracted = meta.getObjectsExtractedByClazz().get(className); + for (FieldExtracted fieldExtracted : objectExtracted.getFields()) { + try { + fieldExtracted.extractValue(object); + } catch (Exception e) { + error.computeIfAbsent(ent.getKey(), v -> new ArrayList<>()).add( + "memberName " + fieldExtracted.getMemberName() + "; code " + fieldExtracted.getField().getCode() + "; field " + fieldExtracted.getField().getField() + ); + } + } + } + + String errorIfPresent = error + .entrySet() + .stream() + .map(entry -> entry.getKey() + ": " + entry.getValue() + .stream() + .collect(Collectors.joining(" |\n", "[", "]"))) + .collect(Collectors.joining("\n\n\n")); + Assertions.assertEquals(0, error.size(), errorIfPresent); + } + +} diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/meta/GetResponseFactoryTestConfiguration.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/meta/GetResponseFactoryTestConfiguration.java new file mode 100644 index 000000000..f3a989d58 --- /dev/null +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/meta/GetResponseFactoryTestConfiguration.java @@ -0,0 +1,46 @@ +package ru.spcex.clearing.backendapi.meta; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.PathResource; +import org.springframework.core.io.Resource; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +@Configuration +public class GetResponseFactoryTestConfiguration { + @Bean("metaJsonTestPath") + public Resource metaJsonPath() { + Path path = Paths.get("src", "main", "resources", "meta.json"); + return new PathResource(path); + } + +// @Value("file:${spring.config.location}/meta.json") +// private Resource meta; +// + @Bean("metaJsonTestRaw") + public String metaJsonRawString(@Qualifier("metaJsonTestPath") Resource meta) throws IOException { + if (!meta.isReadable()) throw new IllegalStateException("cannot read meta.json from meta " + meta.getFile()); + return Files.readString(meta.getFile().toPath()); + } +// + @Autowired + @Bean("metaJsonTest") + public MetaServer metaServer(@Qualifier("metaJsonTestRaw") String metaJson) throws JsonProcessingException { + ObjectMapper jsonObjectMapper = new ObjectMapper(); + jsonObjectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); + jsonObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + MetaServer metaServer = jsonObjectMapper.readValue(metaJson, MetaServer.class); + metaServer.initAndValidate(); + return metaServer; + } +}