From 299cbb1abe11f14d605707c7cf0360019edf207b Mon Sep 17 00:00:00 2001 From: akulikov Date: Tue, 17 Jan 2023 13:35:13 +0300 Subject: [PATCH] Some ValidatorRule and PlannerNewRequest validator --- .../scheduler/config/ValidationConfig.java | 41 ++++++- .../scheduler/error/PlannerErrors.java | 21 ---- .../scheduler/error/ValidationError.java | 28 +++++ .../scheduler/service/PlannerService.java | 3 +- .../validation/IRequestValidator.java | 2 +- .../rules/common/DateNotBeforeRule.java | 30 +++++ .../{ => common}/DictionaryPresentRule.java | 31 +++--- .../rules/common/EnumPresentRule.java | 40 +++++++ .../rules/{ => common}/FieldRequiredRule.java | 6 +- .../rules/common/IdPresentRule.java | 62 +++++++++++ .../rules/common/TimeNotBeforeRule.java | 30 +++++ .../validation/DateNotBeforeRuleTest.java | 49 ++++++++ .../validation/DictionaryPresentRuleTest.java | 77 ++++++------- .../validation/EnumPresentRuleTest.java | 97 ++++++++++++++++ .../validation/FieldRequiredRuleTest.java | 2 +- .../validation/IdPresentRuleTest.java | 105 ++++++++++++++++++ .../validation/TimeNotBeforeRuleTest.java | 49 ++++++++ .../platform/enumeration/WorkflowStatus.java | 19 ++++ 18 files changed, 599 insertions(+), 93 deletions(-) delete mode 100644 clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/PlannerErrors.java create mode 100644 clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/ValidationError.java create mode 100644 clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/DateNotBeforeRule.java rename clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/{ => common}/DictionaryPresentRule.java (58%) create mode 100644 clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/EnumPresentRule.java rename clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/{ => common}/FieldRequiredRule.java (79%) create mode 100644 clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/IdPresentRule.java create mode 100644 clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/TimeNotBeforeRule.java create mode 100644 clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/DateNotBeforeRuleTest.java create mode 100644 clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/EnumPresentRuleTest.java create mode 100644 clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/IdPresentRuleTest.java create mode 100644 clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/TimeNotBeforeRuleTest.java create mode 100644 platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/WorkflowStatus.java 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 fde7183b9..28bf7a2c4 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 @@ -2,11 +2,17 @@ package ru.spcex.clearing.scheduler.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.security.Security; 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.PlannerNewRequest; -import ru.spcex.clearing.scheduler.validation.rules.DictionaryPresentRule; +import ru.spcex.clearing.scheduler.error.ValidationError; +import ru.spcex.clearing.scheduler.validation.rules.common.*; import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.enumeration.Market; +import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.validation.ImdgValidationContext; @@ -27,11 +33,11 @@ public class ValidationConfig { this.imdgs = new HashMap<>(); BiConsumer> addImdg = (s, aClass) -> imdgs.put(s, imdgProvider.getImdg(s, aClass)); addImdg.accept(IMDGDistributedNames.Map_TaskDictionary, TaskDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_TaskStatusDictionary, TaskStatusDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_Company, Company.class); + addImdg.accept(IMDGDistributedNames.Map_Security, Security.class); } - /** - * чтобы во всех валидаторах был один экземпляр Imdg - */ private Imdg getImdg(String key) { return imdgs.get(key); } @@ -47,8 +53,31 @@ public class ValidationConfig { DictionaryPresentRule.instance("task", PlannerNewRequest::getTask, IMDGDistributedNames.Map_TaskDictionary, - TaskDictionary.class, - true) + TaskDictionary.class), + TimeNotBeforeRule.instance("taskTime", + PlannerNewRequest::getTaskTime), + DateNotBeforeRule.instance("clearingDate", + PlannerNewRequest::getClearingDate), + EnumPresentRule.instance("market", + PlannerNewRequest::getMarket, + Market.values(), + false), + DictionaryPresentRule.instance("taskStatus", + PlannerNewRequest::getTaskStatus, + IMDGDistributedNames.Map_TaskStatusDictionary, + TaskStatusDictionary.class), + IdPresentRule.instance("companyId", + PlannerNewRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + ValidationError.CompanyNotFound, + company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive), + IdPresentRule.instance("securityId", + PlannerNewRequest::getSecurityId, + IMDGDistributedNames.Map_Security, + Security.class, + ValidationError.SecurityNotFound, + security -> WorkflowStatus.Active.getKey().equals(security.getWorkflowStatus()) ? null : ValidationError.SecurityNotActive) ); }; } 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 deleted file mode 100644 index 8a52bc8f1..000000000 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/PlannerErrors.java +++ /dev/null @@ -1,21 +0,0 @@ -package ru.spcex.clearing.scheduler.error; - -import ru.spcex.platform.utils.enumeration.IEnumId; - -public enum PlannerErrors implements IEnumId { - WrongEnumValue(10003L), - EmptyRequiredValue(10002L) - ; - - private final Long id; - - PlannerErrors(Long id) { - this.id = id; - } - - - @Override - public Long getId() { - return null; - } -} diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/ValidationError.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/ValidationError.java new file mode 100644 index 000000000..bdc24ed06 --- /dev/null +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/ValidationError.java @@ -0,0 +1,28 @@ +package ru.spcex.clearing.scheduler.error; + +import ru.spcex.platform.utils.enumeration.IEnumId; + +public enum ValidationError implements IEnumId { + WrongDictionaryValue(10003L), + EmptyRequiredValue(10002L), + WrongEnumValue(777L), //todo set code + TaskForPastDate(7010L), + TaskForPastTime(7011L), + CompanyNotFound(7014L), + SecurityNotFound(7012L), + CompanyNotActive(7015L), + SecurityNotActive(7013L) + ; + + private final Long id; + + ValidationError(Long id) { + this.id = id; + } + + + @Override + public Long getId() { + return null; + } +} 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 bab9b5174..4a069ec79 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,7 +18,6 @@ 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.error.PlannerErrors; import ru.spcex.clearing.scheduler.validation.IRequestValidator; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -74,7 +73,7 @@ public class PlannerService extends QueueConsumer implements InitializingBean { IValidator validator = validationFactory.apply(req); Optional validationError = validator.tillFirstError(); if (validationError.isPresent()) { - String errorMsg = messageResolver.resolve(new EnumMessage(PlannerErrors.WrongEnumValue)); + String errorMsg = messageResolver.resolve(validationError.get()); log.error("cannot process PlannerNewRequest id={}: {}", userRequest.getId(), errorMsg); return new RequestInfoUpdate() .setId(userRequest.getId()) diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/IRequestValidator.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/IRequestValidator.java index 2651aeb30..baaee072d 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/IRequestValidator.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/IRequestValidator.java @@ -225,7 +225,7 @@ public interface IRequestValidator { */ static boolean checkErrorList(List errors, Logger log) { if (!errors.isEmpty()) { - log.error("Validation error: [{}]", + log.error("Validation idNotPresentError: [{}]", errors.stream().map(IRequestValidator.ValidationError::toString).collect(Collectors.joining(", ")) ); return true; diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/DateNotBeforeRule.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/DateNotBeforeRule.java new file mode 100644 index 000000000..aaa94d43e --- /dev/null +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/DateNotBeforeRule.java @@ -0,0 +1,30 @@ +package ru.spcex.clearing.scheduler.validation.rules.common; + +import ru.spcex.clearing.scheduler.error.ValidationError; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.time.LocalDate; +import java.util.Optional; +import java.util.function.Function; + +public record DateNotBeforeRule(String fieldName, Function getter, boolean required) implements IValidationRule> { + + public static DateNotBeforeRule instance(String fieldName, Function getter, boolean required) { + return new DateNotBeforeRule<>(fieldName, getter, required); + } + + public static DateNotBeforeRule instance(String fieldName, Function getter) { + return new DateNotBeforeRule<>(fieldName, getter, true); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + LocalDate date = getter.apply(validatedObject); + if (date == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : Optional.empty(); + if (date.isBefore(LocalDate.now())) return of(ValidationError.TaskForPastDate, fieldName); + return Optional.empty(); + } +} 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/common/DictionaryPresentRule.java similarity index 58% rename from clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/DictionaryPresentRule.java rename to clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/DictionaryPresentRule.java index b8c66a8cb..68301c308 100644 --- 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/common/DictionaryPresentRule.java @@ -1,7 +1,7 @@ -package ru.spcex.clearing.scheduler.validation.rules; +package ru.spcex.clearing.scheduler.validation.rules.common; import ru.clearing.platform.dictionary.AbstractDictionary; -import ru.spcex.clearing.scheduler.error.PlannerErrors; +import ru.spcex.clearing.scheduler.error.ValidationError; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; @@ -12,33 +12,38 @@ import java.util.Optional; import java.util.function.Function; public record DictionaryPresentRule(String fieldName, - Function getEnumCode, + Function getter, String dictionaryName, - Class enumClass, + Class dictionaryClass, boolean required) implements IValidationRule> { public static DictionaryPresentRule instance(String fieldName, - Function getEnumCode, + Function getter, String dictionaryName, - Class enumClass, + Class dictionaryClass, boolean required) { - return new DictionaryPresentRule<>(fieldName, getEnumCode, dictionaryName, enumClass, required); + return new DictionaryPresentRule<>(fieldName, getter, dictionaryName, dictionaryClass, required); + } + + public static DictionaryPresentRule instance(String fieldName, + Function getter, + String dictionaryName, + Class dictionaryClass) { + return new DictionaryPresentRule<>(fieldName, getter, dictionaryName, dictionaryClass, true); } @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(); - } + String enumCode = getter.apply(validatedObject); + if (enumCode == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : empty(); Imdg dictImdg = context.obtainMap( dictionaryName, - enumClass + dictionaryClass ); D dictionaryFromMap = dictImdg.getSingleObjectByFieldValues(Map.of("code", enumCode)); if (dictionaryFromMap == null) { - return of(PlannerErrors.WrongEnumValue, fieldName); + return of(ValidationError.WrongDictionaryValue, fieldName); } return empty(); } diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/EnumPresentRule.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/EnumPresentRule.java new file mode 100644 index 000000000..6a1cf9e58 --- /dev/null +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/EnumPresentRule.java @@ -0,0 +1,40 @@ +package ru.spcex.clearing.scheduler.validation.rules.common; + +import ru.spcex.clearing.scheduler.error.ValidationError; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumKey; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; +import java.util.function.Function; + +public record EnumPresentRule(String fieldName, + Function getter, + E[] enumValues, + boolean required) implements IValidationRule> { + + public static EnumPresentRule instance(String fieldName, + Function getter, + E[] enumValues, + boolean required) { + return new EnumPresentRule<>(fieldName, getter, enumValues, required); + } + + public static EnumPresentRule instance(String fieldName, + Function getter, + E[] enumValues) { + return new EnumPresentRule<>(fieldName, getter, enumValues, true); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + String enumCode = getter.apply(validatedObject); + if (enumCode == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : empty(); + for (E enumValue : enumValues) { + if (enumValue.getKey().equals(enumCode)) return empty(); + } + return of(ValidationError.WrongEnumValue, fieldName); + } +} 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/common/FieldRequiredRule.java similarity index 79% rename from clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/FieldRequiredRule.java rename to clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/FieldRequiredRule.java index 4c4701c5a..80c3e5600 100644 --- 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/common/FieldRequiredRule.java @@ -1,6 +1,6 @@ -package ru.spcex.clearing.scheduler.validation.rules; +package ru.spcex.clearing.scheduler.validation.rules.common; -import ru.spcex.clearing.scheduler.error.PlannerErrors; +import ru.spcex.clearing.scheduler.error.ValidationError; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.validation.IValidationRule; @@ -18,7 +18,7 @@ public record FieldRequiredRule(String fieldName, Function getter) i public Optional validate(ImdgValidationContext context) { R validatedObject = context.getValidatedObject(); V value = getter.apply(validatedObject); - if (value == null) return of(PlannerErrors.EmptyRequiredValue, fieldName); + if (value == null) return of(ValidationError.EmptyRequiredValue, fieldName); return empty(); } } diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/IdPresentRule.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/IdPresentRule.java new file mode 100644 index 000000000..dd71412e0 --- /dev/null +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/IdPresentRule.java @@ -0,0 +1,62 @@ +package ru.spcex.clearing.scheduler.validation.rules.common; + +import ru.spcex.clearing.scheduler.error.ValidationError; +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 record IdPresentRule( + String fieldName, + Function idGetter, + Function[] additionalChecks, + String mapName, + Class mapClass, + ValidationError idNotPresentError, + boolean required +) implements IValidationRule> { + + @SafeVarargs + public static IdPresentRule instance(String fieldName, + Function idGetter, + String mapName, + Class mapClass, + ValidationError idNotPresentError, + boolean required, + Function ... additionalChecks) { + return new IdPresentRule<>(fieldName, idGetter, additionalChecks, mapName, mapClass, idNotPresentError, required); + } + + @SafeVarargs + public static IdPresentRule instance(String fieldName, + Function idGetter, + String mapName, + Class mapClass, + ValidationError idNotPresentError, + Function ... additionalChecks) { + return new IdPresentRule<>(fieldName, idGetter, additionalChecks, mapName, mapClass, idNotPresentError, true); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + Long id = idGetter.apply(validatedObject); + if (id == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : empty(); + Imdg imdg = context.obtainMap(mapName, mapClass); + V fromMap = imdg.getSingleObjectByFieldValues(Map.of("id", id)); + if (fromMap == null) { + return of(idNotPresentError, fieldName); + } + for (Function additionalCheck : additionalChecks) { + ValidationError validationError = additionalCheck.apply(fromMap); + if (validationError != null) + return of(validationError, fieldName); + } + return empty(); + } +} diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/TimeNotBeforeRule.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/TimeNotBeforeRule.java new file mode 100644 index 000000000..9d172e0bd --- /dev/null +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/TimeNotBeforeRule.java @@ -0,0 +1,30 @@ +package ru.spcex.clearing.scheduler.validation.rules.common; + +import ru.spcex.clearing.scheduler.error.ValidationError; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.time.LocalTime; +import java.util.Optional; +import java.util.function.Function; + +public record TimeNotBeforeRule(String fieldName, Function getter, boolean required) implements IValidationRule> { + + public static TimeNotBeforeRule instance(String fieldName, Function getter, boolean required) { + return new TimeNotBeforeRule<>(fieldName, getter, required); + } + + public static TimeNotBeforeRule instance(String fieldName, Function getter) { + return new TimeNotBeforeRule<>(fieldName, getter, true); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + LocalTime date = getter.apply(validatedObject); + if (date == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : Optional.empty(); + if (date.isBefore(LocalTime.now())) return of(ValidationError.TaskForPastTime, fieldName); + return Optional.empty(); + } +} diff --git a/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/DateNotBeforeRuleTest.java b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/DateNotBeforeRuleTest.java new file mode 100644 index 000000000..311bf050c --- /dev/null +++ b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/DateNotBeforeRuleTest.java @@ -0,0 +1,49 @@ +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.common.DateNotBeforeRule; +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.time.LocalDate; +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 DateNotBeforeRuleTest { + + @Test + public void dateNotBeforeRuleTest() { + Function validatorBuilder = plannerNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(plannerNewRequest); + return new ValidatorImpl<>(context, + DateNotBeforeRule.instance("clearingDate", PlannerNewRequest::getClearingDate)); + }; + PlannerNewRequest plannerNewRequest = new PlannerNewRequest(); + + plannerNewRequest.setClearingDate(LocalDate.now().plusDays(1)); + IValidator validator = validatorBuilder.apply(plannerNewRequest); + Collection enumMessages = validator.validateAll(); + assertTrue(enumMessages.isEmpty()); + + plannerNewRequest.setClearingDate(LocalDate.now()); + validator = validatorBuilder.apply(plannerNewRequest); + enumMessages = validator.validateAll(); + assertTrue(enumMessages.isEmpty()); + + plannerNewRequest.setClearingDate(LocalDate.now().minusDays(1)); + validator = validatorBuilder.apply(plannerNewRequest); + enumMessages = validator.validateAll(); + assertEquals(1, enumMessages.size()); + } + +} \ No newline at end of file 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 index 897cb4a70..3cbcf6698 100644 --- 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 @@ -13,12 +13,16 @@ 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.clearing.scheduler.error.ValidationError; +import ru.spcex.clearing.scheduler.validation.rules.common.DictionaryPresentRule; +import ru.spcex.platform.enumeration.DayStatus; +import ru.spcex.platform.enumeration.Status; +import ru.spcex.platform.enumeration.Task; 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.enumeration.IEnumKey; import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.ValidatorImpl; import ru.specx.clearing.scheduler.config.HazelcastServiceTestConfiguration; @@ -26,7 +30,6 @@ 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; @@ -46,85 +49,67 @@ class DictionaryPresentRuleTest { TaskDictionary.class, PlannerNewRequest.class, "task", + Task.values(), PlannerNewRequest::getTask, PlannerNewRequest::setTask); testDictionary(IMDGDistributedNames.Map_TaskStatusDictionary, TaskStatusDictionary.class, PlannerNewRequest.class, "taskStatus", + Status.values(), 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", + DayStatus.values(), ClearingCalendarNewRequest::getDayStatus, ClearingCalendarNewRequest::setDayStatus); } - private void testDictionary(String dictionaryKey, + private void testDictionary(String dictionaryKey, Class dictionaryClass, Class recordClass, String fieldName, + E[] enumValues, 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); + long idIdx = 0; + for (E enumValue : enumValues) { + D td = dictionaryClass.getConstructor().newInstance(); + td.setId(idIdx++); + td.setCode(enumValue.getKey()); + dictionaryImdg.insert(td); + } - BiFunction validatorBuilder = (plannerNewRequest, required) -> { + Function validatorBuilder = request -> { ImdgValidationContext context = new ImdgValidationContext<>(); - context.setValidatedObject(plannerNewRequest); + context.setValidatedObject(request); context.addImdg(dictionaryKey, dictionaryImdg); return new ValidatorImpl<>(context, DictionaryPresentRule.instance(fieldName, getter, dictionaryKey, - dictionaryClass, - required) + dictionaryClass) ); }; R record = recordClass.getConstructor().newInstance(); - IValidator strictValidator = validatorBuilder.apply(record, true); - IValidator lazyValidator = validatorBuilder.apply(record, false); + IValidator validator = validatorBuilder.apply(record); - setter.accept(record, "CSD1"); - Collection enumMessages = strictValidator.validateAll(); - assertTrue(enumMessages.isEmpty()); + Collection enumMessages; + for (E enumValue : enumValues) { + setter.accept(record, enumValue.getKey()); + enumMessages = validator.validateAll(); + assertTrue(enumMessages.isEmpty()); + } - setter.accept(record, "CSD2"); - enumMessages = strictValidator.validateAll(); - assertTrue(enumMessages.isEmpty()); - - setter.accept(record, null); - enumMessages = strictValidator.validateAll(); + setter.accept(record, "BAD_VALUE"); + enumMessages = validator.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()); + assertEquals(ValidationError.WrongDictionaryValue, 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/EnumPresentRuleTest.java b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/EnumPresentRuleTest.java new file mode 100644 index 000000000..8303e0872 --- /dev/null +++ b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/EnumPresentRuleTest.java @@ -0,0 +1,97 @@ +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.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendarNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest; +import ru.spcex.clearing.scheduler.error.ValidationError; +import ru.spcex.clearing.scheduler.validation.rules.common.EnumPresentRule; +import ru.spcex.platform.enumeration.DayStatus; +import ru.spcex.platform.enumeration.Status; +import ru.spcex.platform.enumeration.Task; +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.enumeration.IEnumKey; +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 EnumPresentRuleTest { + @Autowired + @Qualifier("hazelcastServiceTest") + private HazelcastService hazelcastServiceTest; + + @Test + public void enumPresentRuleTest() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + testEnum( + PlannerNewRequest.class, + "task", + Task.values(), + PlannerNewRequest::getTask, + PlannerNewRequest::setTask); + testEnum( + PlannerNewRequest.class, + "taskStatus", + Status.values(), + PlannerNewRequest::getTaskStatus, + PlannerNewRequest::setTaskStatus); + testEnum( + ClearingCalendarNewRequest.class, + "dayStatus", + DayStatus.values(), + ClearingCalendarNewRequest::getDayStatus, + ClearingCalendarNewRequest::setDayStatus); + + } + + private void testEnum(Class recordClass, + String fieldName, + E[] enumValues, + Function getter, + BiConsumer setter) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + + BiFunction validatorBuilder = (request, required) -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(request); + return new ValidatorImpl<>(context, + EnumPresentRule.instance(fieldName, + getter, + enumValues, + required) + ); + }; + R record = recordClass.getConstructor().newInstance(); + IValidator strictValidator = validatorBuilder.apply(record, true); + + Collection enumMessages; + for (E enumValue : enumValues) { + setter.accept(record, enumValue.getKey()); + enumMessages = strictValidator.validateAll(); + assertTrue(enumMessages.isEmpty()); + } + + setter.accept(record, "BAD_VALUE"); + enumMessages = strictValidator.validateAll(); + assertEquals(1, enumMessages.size()); + assertEquals(ValidationError.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 index 3cfb9991d..78cbec5d0 100644 --- 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 @@ -4,7 +4,7 @@ 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.clearing.scheduler.validation.rules.common.FieldRequiredRule; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.validation.IValidator; diff --git a/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/IdPresentRuleTest.java b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/IdPresentRuleTest.java new file mode 100644 index 000000000..9bc738c22 --- /dev/null +++ b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/IdPresentRuleTest.java @@ -0,0 +1,105 @@ +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.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.security.Security; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest; +import ru.spcex.clearing.scheduler.error.ValidationError; +import ru.spcex.clearing.scheduler.validation.rules.common.IdPresentRule; +import ru.spcex.platform.classes.base.SpcexObjectBase; +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.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 IdPresentRuleTest { + private final static Long TEST_ID = 777L; + + @Autowired + @Qualifier("hazelcastServiceTest") + private HazelcastService hazelcastServiceTest; + + @Test + public void idPresentRuleTest() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + testIdPresentRule( + "companyId", + PlannerNewRequest::getCompanyId, + PlannerNewRequest::setCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + PlannerNewRequest.class, + ValidationError.CompanyNotFound, + ValidationError.CompanyNotActive + ); + testIdPresentRule( + "securityId", + PlannerNewRequest::getSecurityId, + PlannerNewRequest::setSecurityId, + IMDGDistributedNames.Map_Security, + Security.class, + PlannerNewRequest.class, + ValidationError.SecurityNotFound, + ValidationError.SecurityNotActive + ); + } + + private void testIdPresentRule(String fieldName, + Function getter, + BiConsumer setter, + String mapName, + Class mapClass, + Class objClass, + ValidationError notFoundExpectedError, + ValidationError notActiveExpectedError) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + Imdg imdg = hazelcastServiceTest.getImdg(mapName, mapClass); + Function validatorBuilder = request -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(request); + context.addImdg(mapName, imdg); + return new ValidatorImpl<>(context, IdPresentRule.instance(fieldName, + getter, + mapName, + mapClass, + notFoundExpectedError, + true, + company -> company.getId().equals(TEST_ID) ? null : notActiveExpectedError + )); + }; + + R obj = objClass.getConstructor().newInstance(); + setter.accept(obj, TEST_ID); + IValidator validator = validatorBuilder.apply(obj); + Collection enumMessages = validator.validateAll(); + assertEquals(1, enumMessages.size()); + assertEquals(notFoundExpectedError, enumMessages.iterator().next().getSubject()); + + D map = mapClass.getConstructor().newInstance(); + map.setId(TEST_ID); + imdg.insert(map); + + enumMessages = validator.validateAll(); + assertTrue(enumMessages.isEmpty()); + + } + +} \ No newline at end of file diff --git a/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/TimeNotBeforeRuleTest.java b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/TimeNotBeforeRuleTest.java new file mode 100644 index 000000000..32206cda7 --- /dev/null +++ b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/TimeNotBeforeRuleTest.java @@ -0,0 +1,49 @@ +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.common.TimeNotBeforeRule; +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.time.LocalTime; +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 TimeNotBeforeRuleTest { + + @Test + public void timeNotBeforeRuleTest() { + Function validatorBuilder = plannerNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(plannerNewRequest); + return new ValidatorImpl<>(context, + TimeNotBeforeRule.instance("taskTime", PlannerNewRequest::getTaskTime)); + }; + PlannerNewRequest plannerNewRequest = new PlannerNewRequest(); + + plannerNewRequest.setTaskTime(LocalTime.now().plusMinutes(1)); + IValidator validator = validatorBuilder.apply(plannerNewRequest); + Collection enumMessages = validator.validateAll(); + assertTrue(enumMessages.isEmpty()); + + plannerNewRequest.setTaskTime(LocalTime.now().plusSeconds(1)); + validator = validatorBuilder.apply(plannerNewRequest); + enumMessages = validator.validateAll(); + assertTrue(enumMessages.isEmpty()); + + plannerNewRequest.setTaskTime(LocalTime.now().minusMinutes(1)); + validator = validatorBuilder.apply(plannerNewRequest); + enumMessages = validator.validateAll(); + assertEquals(1, enumMessages.size()); + } + +} \ No newline at end of file diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/WorkflowStatus.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/WorkflowStatus.java new file mode 100644 index 000000000..0e1ccdd49 --- /dev/null +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/WorkflowStatus.java @@ -0,0 +1,19 @@ +package ru.spcex.platform.enumeration; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +public enum WorkflowStatus implements IEnumKey { + Active("ACTV"), + Blocked("BLKD"); + + private final String key; + + WorkflowStatus(String key) { + this.key = key; + } + + @Override + public String getKey() { + return key; + } +}