diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/ValidationConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/ValidationConfig.java index f11175789..fde7183b9 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/ValidationConfig.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/ValidationConfig.java @@ -5,7 +5,7 @@ import org.springframework.context.annotation.Configuration; import ru.clearing.platform.dictionary.TaskDictionary; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest; -import ru.spcex.clearing.scheduler.validation.rules.EnumPresentRule; +import ru.spcex.clearing.scheduler.validation.rules.DictionaryPresentRule; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -44,10 +44,11 @@ public class ValidationConfig { Consumer addImdg = (s) -> context.addImdg(s, getImdg(s)); addImdg.accept(IMDGDistributedNames.Map_TaskDictionary); return new ValidatorImpl<>(context, - EnumPresentRule.instance("task", + DictionaryPresentRule.instance("task", PlannerNewRequest::getTask, IMDGDistributedNames.Map_TaskDictionary, - TaskDictionary.class) + TaskDictionary.class, + true) ); }; } diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/PlannerErrors.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/PlannerErrors.java index fc15d5a5b..8a52bc8f1 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/PlannerErrors.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/PlannerErrors.java @@ -4,6 +4,7 @@ import ru.spcex.platform.utils.enumeration.IEnumId; public enum PlannerErrors implements IEnumId { WrongEnumValue(10003L), + EmptyRequiredValue(10002L) ; private final Long id; diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/ClearingCalendarService.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/ClearingCalendarService.java index efe225cd3..8131a9626 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/ClearingCalendarService.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/ClearingCalendarService.java @@ -15,7 +15,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteReques import ru.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendarNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendarUpdateRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; -import ru.spcex.clearing.scheduler.IRequestValidator; +import ru.spcex.clearing.scheduler.validation.IRequestValidator; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/PlannerService.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/PlannerService.java index 869168f21..bab9b5174 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/PlannerService.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/PlannerService.java @@ -18,8 +18,8 @@ import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerUpdateReq import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; -import ru.spcex.clearing.scheduler.IRequestValidator; import ru.spcex.clearing.scheduler.error.PlannerErrors; +import ru.spcex.clearing.scheduler.validation.IRequestValidator; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.EnumMessage; diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/PlannerTemplateService.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/PlannerTemplateService.java index d1eec0d90..6cf914e9b 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/PlannerTemplateService.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/PlannerTemplateService.java @@ -15,7 +15,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteReques import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerTemplateNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerTemplateUpdateRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; -import ru.spcex.clearing.scheduler.IRequestValidator; +import ru.spcex.clearing.scheduler.validation.IRequestValidator; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/IRequestValidator.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/IRequestValidator.java similarity index 99% rename from clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/IRequestValidator.java rename to clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/IRequestValidator.java index 78285922a..2651aeb30 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/IRequestValidator.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/IRequestValidator.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.scheduler; +package ru.spcex.clearing.scheduler.validation; import org.slf4j.Logger; import ru.clearing.platform.dictionary.AbstractDictionary; diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/DictionaryPresentRule.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/DictionaryPresentRule.java new file mode 100644 index 000000000..b8c66a8cb --- /dev/null +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/DictionaryPresentRule.java @@ -0,0 +1,45 @@ +package ru.spcex.clearing.scheduler.validation.rules; + +import ru.clearing.platform.dictionary.AbstractDictionary; +import ru.spcex.clearing.scheduler.error.PlannerErrors; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; + +public record DictionaryPresentRule(String fieldName, + Function getEnumCode, + String dictionaryName, + Class enumClass, + boolean required) implements IValidationRule> { + + public static DictionaryPresentRule instance(String fieldName, + Function getEnumCode, + String dictionaryName, + Class enumClass, + boolean required) { + return new DictionaryPresentRule<>(fieldName, getEnumCode, dictionaryName, enumClass, required); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + String enumCode = getEnumCode.apply(validatedObject); + if (enumCode == null) { + return required ? of(PlannerErrors.EmptyRequiredValue, fieldName) : empty(); + } + Imdg dictImdg = context.obtainMap( + dictionaryName, + enumClass + ); + D dictionaryFromMap = dictImdg.getSingleObjectByFieldValues(Map.of("code", enumCode)); + if (dictionaryFromMap == null) { + return of(PlannerErrors.WrongEnumValue, fieldName); + } + return empty(); + } +} diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/EnumPresentRule.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/EnumPresentRule.java deleted file mode 100644 index 36eda3401..000000000 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/EnumPresentRule.java +++ /dev/null @@ -1,48 +0,0 @@ -package ru.spcex.clearing.scheduler.validation.rules; - -import ru.spcex.clearing.scheduler.error.PlannerErrors; -import ru.spcex.platform.classes.base.SpcexObjectBase; -import ru.spcex.platform.imdg.api.Imdg; -import ru.spcex.platform.imdg.validation.ImdgValidationContext; -import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.validation.IValidationRule; - -import java.util.Map; -import java.util.Optional; -import java.util.function.Function; - -public class EnumPresentRule implements IValidationRule> { - protected final Function getEnumCode; - protected final String dictionaryName; - protected final String fieldName; - protected final Class enumClass; - - public EnumPresentRule(String fieldName, Function getEnumCode, String dictionaryName, Class enumClass) { - this.fieldName = fieldName; - this.getEnumCode = getEnumCode; - this.dictionaryName = dictionaryName; - this.enumClass = enumClass; - } - - public static EnumPresentRule instance(String fieldName, - Function getEnumCode, - String dictionaryName, - Class enumClass) { - return new EnumPresentRule<>(fieldName, getEnumCode, dictionaryName, enumClass); - } - - @Override - public Optional validate(ImdgValidationContext context) { - T validatedObject = context.getValidatedObject(); - String enumCode = getEnumCode.apply(validatedObject); - Imdg dictImdg = context.obtainMap( - dictionaryName, - enumClass - ); - D taskFromMap = dictImdg.getSingleObjectByFieldValues(Map.of("code", enumCode)); - if (taskFromMap == null) { - return of(PlannerErrors.WrongEnumValue, fieldName); - } - return empty(); - } -} diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/FieldRequiredRule.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/FieldRequiredRule.java new file mode 100644 index 000000000..4c4701c5a --- /dev/null +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/FieldRequiredRule.java @@ -0,0 +1,24 @@ +package ru.spcex.clearing.scheduler.validation.rules; + +import ru.spcex.clearing.scheduler.error.PlannerErrors; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; +import java.util.function.Function; + +public record FieldRequiredRule(String fieldName, Function getter) implements IValidationRule> { + + public static FieldRequiredRule instance(String fieldName, Function getter) { + return new FieldRequiredRule<>(fieldName, getter); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + V value = getter.apply(validatedObject); + if (value == null) return of(PlannerErrors.EmptyRequiredValue, fieldName); + return empty(); + } +} diff --git a/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/DictionaryPresentRuleTest.java b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/DictionaryPresentRuleTest.java new file mode 100644 index 000000000..897cb4a70 --- /dev/null +++ b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/DictionaryPresentRuleTest.java @@ -0,0 +1,130 @@ +package ru.specx.clearing.scheduler.validation; + +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 ru.clearing.platform.dictionary.AbstractDictionary; +import ru.clearing.platform.dictionary.DayStatusDictionary; +import ru.clearing.platform.dictionary.TaskDictionary; +import ru.clearing.platform.dictionary.TaskStatusDictionary; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendarNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest; +import ru.spcex.clearing.scheduler.error.PlannerErrors; +import ru.spcex.clearing.scheduler.validation.rules.DictionaryPresentRule; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidator; +import ru.spcex.platform.utils.validation.ValidatorImpl; +import ru.specx.clearing.scheduler.config.HazelcastServiceTestConfiguration; + +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + HazelcastServiceTestConfiguration.class}) +class DictionaryPresentRuleTest { + @Autowired + @Qualifier("hazelcastServiceTest") + private HazelcastService hazelcastServiceTest; + + @Test + public void dictionaryPresentRuleTest() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + testDictionary(IMDGDistributedNames.Map_TaskDictionary, + TaskDictionary.class, + PlannerNewRequest.class, + "task", + PlannerNewRequest::getTask, + PlannerNewRequest::setTask); + testDictionary(IMDGDistributedNames.Map_TaskStatusDictionary, + TaskStatusDictionary.class, + PlannerNewRequest.class, + "taskStatus", + PlannerNewRequest::getTaskStatus, + PlannerNewRequest::setTaskStatus); + testDictionary(IMDGDistributedNames.Map_TaskDictionary, + TaskDictionary.class, + PlannerNewRequest.class, + "task", + PlannerNewRequest::getTask, + PlannerNewRequest::setTask); + testDictionary(IMDGDistributedNames.Map_DayStatusDictionary, + DayStatusDictionary.class, + ClearingCalendarNewRequest.class, + "dayStatus", + ClearingCalendarNewRequest::getDayStatus, + ClearingCalendarNewRequest::setDayStatus); + + } + + private void testDictionary(String dictionaryKey, + Class dictionaryClass, + Class recordClass, + String fieldName, + Function getter, + BiConsumer setter) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + Imdg dictionaryImdg = hazelcastServiceTest.getImdg(dictionaryKey, dictionaryClass); + D td1 = dictionaryClass.getConstructor().newInstance(); + td1.setId(1L); + td1.setCode("CSD1"); + td1.setName("TEST NAME 1"); + dictionaryImdg.insert(td1); + D td2 = dictionaryClass.getConstructor().newInstance(); + td2.setId(2L); + td2.setCode("CSD2"); + td2.setName("TEST NAME 2"); + dictionaryImdg.insert(td2); + + BiFunction validatorBuilder = (plannerNewRequest, required) -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(plannerNewRequest); + context.addImdg(dictionaryKey, dictionaryImdg); + return new ValidatorImpl<>(context, + DictionaryPresentRule.instance(fieldName, + getter, + dictionaryKey, + dictionaryClass, + required) + ); + }; + R record = recordClass.getConstructor().newInstance(); + IValidator strictValidator = validatorBuilder.apply(record, true); + IValidator lazyValidator = validatorBuilder.apply(record, false); + + setter.accept(record, "CSD1"); + Collection enumMessages = strictValidator.validateAll(); + assertTrue(enumMessages.isEmpty()); + + setter.accept(record, "CSD2"); + enumMessages = strictValidator.validateAll(); + assertTrue(enumMessages.isEmpty()); + + setter.accept(record, null); + enumMessages = strictValidator.validateAll(); + assertEquals(1, enumMessages.size()); + assertEquals(PlannerErrors.EmptyRequiredValue, enumMessages.iterator().next().getSubject()); + enumMessages = lazyValidator.validateAll(); + assertTrue(enumMessages.isEmpty()); + + setter.accept(record, "NOT_CSD"); + enumMessages = strictValidator.validateAll(); + assertEquals(1, enumMessages.size()); + assertEquals(PlannerErrors.WrongEnumValue, enumMessages.iterator().next().getSubject()); + enumMessages = lazyValidator.validateAll(); + assertEquals(1, enumMessages.size()); + assertEquals(PlannerErrors.WrongEnumValue, enumMessages.iterator().next().getSubject()); + } + +} \ No newline at end of file diff --git a/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/FieldRequiredRuleTest.java b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/FieldRequiredRuleTest.java new file mode 100644 index 000000000..3cfb9991d --- /dev/null +++ b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/FieldRequiredRuleTest.java @@ -0,0 +1,44 @@ +package ru.specx.clearing.scheduler.validation; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest; +import ru.spcex.clearing.scheduler.validation.rules.FieldRequiredRule; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidator; +import ru.spcex.platform.utils.validation.ValidatorImpl; + +import java.util.Collection; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith(SpringExtension.class) +class FieldRequiredRuleTest { + + @Test + public void fieldRequiredRuleTest() { + Function validatorBuilder = plannerNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(plannerNewRequest); + return new ValidatorImpl<>(context, + new FieldRequiredRule<>("task", PlannerNewRequest::getTask) + ); + }; + PlannerNewRequest plannerNewRequest = new PlannerNewRequest(); + + plannerNewRequest.setTask("test"); + IValidator validator = validatorBuilder.apply(plannerNewRequest); + Collection enumMessages = validator.validateAll(); + assertTrue(enumMessages.isEmpty()); + + plannerNewRequest.setTask(null); + validator = validatorBuilder.apply(plannerNewRequest); + enumMessages = validator.validateAll(); + assertEquals(1, enumMessages.size()); + } + +} \ No newline at end of file