diff --git a/clearing-parent/imdg/pom.xml b/clearing-parent/imdg/pom.xml
index 5a35a391a..cb06f2437 100644
--- a/clearing-parent/imdg/pom.xml
+++ b/clearing-parent/imdg/pom.xml
@@ -71,6 +71,10 @@
ru.spcex.platform
platform-imdg-api-hazelcast-impl
+
+ ru.spcex.platform
+ platform-enum
+
diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/AbstractHazelcastLifecycleSupport.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/AbstractHazelcastLifecycleSupport.java
index 53a6dd15a..8b9ea7df8 100644
--- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/AbstractHazelcastLifecycleSupport.java
+++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/AbstractHazelcastLifecycleSupport.java
@@ -19,17 +19,17 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
-import static ru.spcex.clearing.imdg.util.Util.makeSchedulerAllTodayMap;
-
//todo почистить класс
public abstract class AbstractHazelcastLifecycleSupport implements InitializingBean, DisposableBean {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private final HazelcastInstance hazelcastServerInstance;
private final JdbcTemplate jdbcTemplate;
+ private final PlannerAllTodayMaker plannerAllTodayMaker;
- public AbstractHazelcastLifecycleSupport(HazelcastInstance hazelcastServerInstance, JdbcTemplate jdbcTemplate) {
+ public AbstractHazelcastLifecycleSupport(HazelcastInstance hazelcastServerInstance, JdbcTemplate jdbcTemplate, PlannerAllTodayMaker plannerAllTodayMaker) {
this.hazelcastServerInstance = hazelcastServerInstance;
this.jdbcTemplate = jdbcTemplate;
+ this.plannerAllTodayMaker = plannerAllTodayMaker;
}
/**
@@ -103,7 +103,7 @@ public abstract class AbstractHazelcastLifecycleSupport implements InitializingB
boolean generatorResult = generator.init(maxKey);
if (generatorResult) {
log.info("IDGenerator {} success init by {}", IMDGDistributedNames.MAP_SEQUENCE_NAME, maxKey);
- makeSchedulerAllTodayMap(hazelcastServerInstance);
+ plannerAllTodayMaker.makeSchedulerAllTodayMap();
} else {
log.info("IDGenerator {} already initialized in other node", IMDGDistributedNames.MAP_SEQUENCE_NAME);
}
diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/HazelcastLifecycleSupport.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/HazelcastLifecycleSupport.java
index e248a2054..bf249777b 100644
--- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/HazelcastLifecycleSupport.java
+++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/HazelcastLifecycleSupport.java
@@ -19,8 +19,8 @@ public class HazelcastLifecycleSupport extends AbstractHazelcastLifecycleSupport
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
- public HazelcastLifecycleSupport(HazelcastInstance hazelcastServerInstance, JdbcTemplate jdbcTemplate) {
- super(hazelcastServerInstance, jdbcTemplate);
+ public HazelcastLifecycleSupport(HazelcastInstance hazelcastServerInstance, JdbcTemplate jdbcTemplate, PlannerAllTodayMaker plannerAllTodayMaker) {
+ super(hazelcastServerInstance, jdbcTemplate, plannerAllTodayMaker);
}
@Override
diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/PlannerAllTodayMaker.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/PlannerAllTodayMaker.java
new file mode 100644
index 000000000..81e9c8dc8
--- /dev/null
+++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/PlannerAllTodayMaker.java
@@ -0,0 +1,117 @@
+package ru.spcex.clearing.imdg.services;
+
+import com.hazelcast.core.HazelcastInstance;
+import com.hazelcast.core.IMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import ru.clearing.classes.statics.data.scheduler.ClearingCalendar;
+import ru.clearing.classes.statics.data.scheduler.Planner;
+import ru.clearing.classes.statics.data.scheduler.PlannerAllToday;
+import ru.clearing.classes.statics.data.scheduler.PlannerTemplate;
+import ru.spcex.platform.enumeration.DayStatus;
+import ru.spcex.platform.enumeration.Parent;
+import ru.spcex.platform.enumeration.Status;
+
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import static ru.spcex.clearing.imdg.IMDGDistributedNames.*;
+
+@Service
+public class PlannerAllTodayMaker {
+ private final HazelcastInstance hazelcastInstance;
+ private final IMap plannerMap;
+ private final IMap clearingCalendarMap;
+ private final IMap plannerTemplateMap;
+ private final IMap plannerAllTodayMap;
+
+ @Autowired
+ public PlannerAllTodayMaker(HazelcastInstance hazelcastInstance) {
+ this.hazelcastInstance = hazelcastInstance;
+ plannerMap = hazelcastInstance.getMap(Map_Planner);
+ clearingCalendarMap = hazelcastInstance.getMap(Map_ClearingCalendar);
+ plannerTemplateMap = hazelcastInstance.getMap(Map_PlannerTemplate);
+ plannerAllTodayMap = hazelcastInstance.getMap(Map_PlannerAllToday);
+ }
+
+ public void makeSchedulerAllTodayMap() {
+ LocalDate currentDate = LocalDate.now();
+ List listOfPlannerAllToday = new ArrayList<>();
+
+ if (!plannerMap.isEmpty()) listOfPlannerAllToday.addAll(getPlannersAllTodayToDate(currentDate));
+
+ plannerMap.values().stream()
+ .filter(x -> x.getTaskStatus() != null)
+ .filter((x) -> x.getClearingDate() == null || x.getClearingDate().isEqual(currentDate)).forEach((x) -> {
+ if (x.getTaskStatus().equalsIgnoreCase(Status.Active.getKey())) {
+ listOfPlannerAllToday.add(createPlannerAllTodayFromPlanner(x));
+ }
+
+ if (x.getTaskStatus().equalsIgnoreCase(Status.Cancel.getKey()) || x.getTaskStatus().equalsIgnoreCase(Status.Blocked.getKey())) {
+ listOfPlannerAllToday.removeIf((allToday) -> x.getTaskTime().equals(allToday.getTaskTime()) &&
+ x.getTask().equalsIgnoreCase(allToday.getTask()));
+ }
+ });
+ for (PlannerAllToday plannerAllToday : listOfPlannerAllToday) {
+ plannerAllToday.setId(hazelcastInstance.getIdGenerator(MAP_SEQUENCE_NAME).newId());
+ plannerAllTodayMap.put(plannerAllToday.getId(), plannerAllToday);
+ }
+ }
+
+ private List getPlannersAllTodayToDate(LocalDate currentDate) {
+ boolean weekend = Arrays.asList(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY).contains(currentDate.getDayOfWeek());
+ List res = new ArrayList<>();
+ if (clearingCalendarMap == null || clearingCalendarMap.isEmpty()) {
+ if (!weekend) {
+ for (PlannerTemplate plannerTemplate : plannerTemplateMap.values()) {
+ res.add(createPlannerAllTodayFromPlannerTemplate(plannerTemplate));
+ }
+ }
+ } else {
+ Optional clearingCalendarOptional = clearingCalendarMap.values().stream()
+ .filter((calendar) -> calendar.getClearingDate().isEqual(currentDate))
+ .findFirst();
+ if (clearingCalendarOptional.isPresent()) {
+ ClearingCalendar calendar = clearingCalendarOptional.get();
+ if (calendar.getDayStatus().equalsIgnoreCase(DayStatus.Workday.getKey())) {
+ if (calendar.getCompanyId() != null && calendar.getCompanyId() != 0) {
+ for (PlannerTemplate plannerTemplate : plannerTemplateMap.values()) {
+ res.add(createPlannerAllTodayFromPlannerTemplate(plannerTemplate));
+ }
+ }
+ }
+ }
+ }
+
+ return res;
+ }
+
+ private PlannerAllToday createPlannerAllTodayFromPlanner(Planner planner) {
+ PlannerAllToday res = new PlannerAllToday();
+ res.setTask(planner.getTask());
+ res.setTaskTime(planner.getTaskTime());
+ res.setClearingDate(planner.getClearingDate());
+ res.setMarket(planner.getMarket());
+ res.setTaskStatus(planner.getTaskStatus());
+ res.setCompanyId(planner.getCompanyId());
+ res.setSecurityId(planner.getSecurityId());
+ res.setParent(Parent.Planner.getKey());
+ res.setParentId(planner.getId());
+ return res;
+ }
+
+ private PlannerAllToday createPlannerAllTodayFromPlannerTemplate(PlannerTemplate plannerTemplate) {
+ PlannerAllToday res = new PlannerAllToday();
+ res.setTask(plannerTemplate.getTask());
+ res.setTaskTime(plannerTemplate.getTaskTime());
+ res.setTaskStatus(plannerTemplate.getTaskStatus());
+ res.setParent(Parent.Template.getKey());
+ res.setParentId(plannerTemplate.getId());
+ return res;
+ }
+
+}
diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/util/Util.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/util/Util.java
deleted file mode 100644
index 8ed0e6696..000000000
--- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/util/Util.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package ru.spcex.clearing.imdg.util;
-
-import com.hazelcast.core.HazelcastInstance;
-import com.hazelcast.core.IMap;
-import ru.clearing.classes.statics.data.scheduler.ClearingCalendar;
-import ru.clearing.classes.statics.data.scheduler.Planner;
-import ru.clearing.classes.statics.data.scheduler.PlannerAllToday;
-import ru.clearing.classes.statics.data.scheduler.PlannerTemplate;
-
-import java.time.LocalDate;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-import static ru.spcex.clearing.imdg.IMDGDistributedNames.*;
-
-public class Util {
-
- public static void makeSchedulerAllTodayMap(HazelcastInstance hazelcastInstance) {
- IMap plannerMap = hazelcastInstance.getMap(Map_Planner);
- IMap clearingCalendarMap = hazelcastInstance.getMap(Map_ClearingCalendar);
- IMap plannerTemplateMap = hazelcastInstance.getMap(Map_PlannerTemplate);
- IMap plannerAllTodayMap = hazelcastInstance.getMap(Map_PlannerAllToday);
- LocalDate currentDate = LocalDate.now();
- List listOfPlannerAllToday = new ArrayList<>();
-
-
- if (!plannerMap.isEmpty()) {
- switch (currentDate.getDayOfWeek()) {
- case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> listOfPlannerAllToday.addAll(getPlannersOnMonday2Friday(currentDate, clearingCalendarMap, plannerTemplateMap));
- case SUNDAY, SATURDAY -> listOfPlannerAllToday.addAll(getPlannersOnSunday2Saturday(currentDate, clearingCalendarMap, plannerTemplateMap));
- }
- }
-
- plannerMap.values().stream()
- .filter(x -> x.getTaskStatus() != null)
- .filter((x) -> x.getClearingDate() == null || x.getClearingDate().isEqual(currentDate)).forEach((x) -> {
- if (x.getTaskStatus().equalsIgnoreCase("ACTV")) {
- listOfPlannerAllToday.add(createPlannerAllTodayFromPlanner(x));
- }
-
- if (x.getTaskStatus().equalsIgnoreCase("CNCL") || x.getTaskStatus().equalsIgnoreCase("BLKD")) {
- listOfPlannerAllToday.removeIf((allToday) -> !x.getTaskTime().equals(allToday.getTaskTime()) ||
- !x.getTask().equalsIgnoreCase(allToday.getTask()));
- }
- });
- for (PlannerAllToday plannerAllToday : listOfPlannerAllToday) {
- plannerAllToday.setId(hazelcastInstance.getIdGenerator(MAP_SEQUENCE_NAME).newId());
- plannerAllTodayMap.put(plannerAllToday.getId(), plannerAllToday);
- }
- }
-
- private static List getPlannersOnMonday2Friday(LocalDate currentDate, IMap clearingCalendarMap, IMap plannerTemplateMap) {
- List res = new ArrayList<>();
- if (clearingCalendarMap == null || clearingCalendarMap.isEmpty()) {
- for (PlannerTemplate plannerTemplate : plannerTemplateMap.values()) {
- res.add(createPlannerAllTodayFromPlannerTemplate(plannerTemplate));
- }
- } else {
- Optional clearingCalendarOptional = clearingCalendarMap.values().stream().filter((calendar) -> calendar.getClearingDate().isEqual(currentDate)).findFirst();
- if (clearingCalendarOptional.isPresent()) {
- ClearingCalendar calendar = clearingCalendarOptional.get();
- if (calendar.getDayStatus().equalsIgnoreCase("BDAY")) {
- if (calendar.getCompanyId() != null && calendar.getCompanyId() != 0) {
- for (PlannerTemplate plannerTemplate :
- plannerTemplateMap.values()) {
- res.add(createPlannerAllTodayFromPlannerTemplate(plannerTemplate));
- }
- }
- }
- }
- }
-
- return res;
- }
-
- private static List getPlannersOnSunday2Saturday(LocalDate currentDate, IMap clearingCalendarMap, IMap plannerTemplateMap) {
- List res = new ArrayList<>();
- Optional clearingCalendarOptional = clearingCalendarMap.values().stream().filter((calendar) -> calendar.getClearingDate().isEqual(currentDate)).findFirst();
- if (clearingCalendarOptional.isPresent()) {
- ClearingCalendar clearingCalendar = clearingCalendarOptional.get();
- if (clearingCalendar.getDayStatus().equalsIgnoreCase("BDAY")) {
- for (PlannerTemplate plannerTemplate : plannerTemplateMap.values()) {
- res.add(createPlannerAllTodayFromPlannerTemplate(plannerTemplate));
- }
- }
- }
- return res;
- }
-
- private static PlannerAllToday createPlannerAllTodayFromPlanner(Planner planner) {
- PlannerAllToday res = new PlannerAllToday();
- res.setTask(planner.getTask());
- res.setTaskTime(planner.getTaskTime());
- res.setClearingDate(planner.getClearingDate());
- res.setMarket(planner.getMarket());
- res.setTaskStatus(planner.getTaskStatus());
- res.setCompanyId(planner.getCompanyId());
- res.setSecurityId(planner.getSecurityId());
- res.setParent("PLNR");
- res.setParentId(planner.getId());
- return res;
- }
-
- private static PlannerAllToday createPlannerAllTodayFromPlannerTemplate(PlannerTemplate plannerTemplate) {
- PlannerAllToday res = new PlannerAllToday();
- res.setTask(plannerTemplate.getTask());
- res.setTaskTime(plannerTemplate.getTaskTime());
- res.setTaskStatus(plannerTemplate.getTaskStatus());
- res.setParent("TMPL");
- res.setParentId(plannerTemplate.getId());
- return res;
- }
-
-}
diff --git a/clearing-parent/scheduler-service/pom.xml b/clearing-parent/scheduler-service/pom.xml
index 04774fd14..cb13c4eef 100644
--- a/clearing-parent/scheduler-service/pom.xml
+++ b/clearing-parent/scheduler-service/pom.xml
@@ -28,6 +28,10 @@
ru.spcex.platform
platform-imdg-api-hazelcast-impl
+
+ ru.spcex.clearing
+ dictionary
+
ru.spcex.clearing
classes
diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/ErrorResolverConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/ErrorResolverConfig.java
new file mode 100644
index 000000000..c64e7c10e
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/ErrorResolverConfig.java
@@ -0,0 +1,14 @@
+package ru.spcex.clearing.scheduler.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import ru.spcex.platform.utils.enumeration.IMessageResolver;
+import ru.spcex.platform.utils.enumeration.SimpleMessageResolver;
+
+@Configuration
+public class ErrorResolverConfig {
+ @Bean
+ public IMessageResolver messageResolver() {
+ return new SimpleMessageResolver();
+ }
+}
diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/ClearingCalendarValidationConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/ClearingCalendarValidationConfig.java
new file mode 100644
index 000000000..c16595d10
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/ClearingCalendarValidationConfig.java
@@ -0,0 +1,100 @@
+package ru.spcex.clearing.scheduler.config.validation;
+
+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.scheduler.ClearingCalendar;
+import ru.clearing.platform.dictionary.DayStatusDictionary;
+import ru.spcex.clearing.imdg.IMDGDistributedNames;
+import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
+import ru.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendarNewRequest;
+import ru.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendarUpdateRequest;
+import ru.spcex.clearing.scheduler.error.ValidationError;
+import ru.spcex.clearing.scheduler.validation.rules.common.DateNotBeforeRule;
+import ru.spcex.clearing.scheduler.validation.rules.common.DictionaryPresentRule;
+import ru.spcex.clearing.scheduler.validation.rules.common.IdPresentRule;
+import ru.spcex.platform.classes.base.SpcexObjectBase;
+import ru.spcex.platform.enumeration.WorkflowStatus;
+import ru.spcex.platform.imdg.api.Imdg;
+import ru.spcex.platform.imdg.validation.ImdgValidationContext;
+import ru.spcex.platform.utils.validation.IValidator;
+import ru.spcex.platform.utils.validation.ValidatorImpl;
+
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+@Configuration
+public class ClearingCalendarValidationConfig {
+
+ @Bean("clearingCalendarNewRequestValidator")
+ public Function clearingCalendarNewRequestValidator(Map> imdgForValidation) {
+ return clearingCalendarNewRequest -> {
+ ImdgValidationContext context = new ImdgValidationContext<>();
+ context.setValidatedObject(clearingCalendarNewRequest);
+ Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
+ addImdg.accept(IMDGDistributedNames.Map_Company);
+ addImdg.accept(IMDGDistributedNames.Map_DayStatusDictionary);
+ return new ValidatorImpl<>(context,
+ DateNotBeforeRule.instance("clearingDate",
+ ClearingCalendarNewRequest::getClearingDate),
+ IdPresentRule.instance("companyId",
+ ClearingCalendarNewRequest::getCompanyId,
+ IMDGDistributedNames.Map_Company,
+ Company.class,
+ ValidationError.CompanyNotFound,
+ company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
+ DictionaryPresentRule.instance("dayStatus",
+ ClearingCalendarNewRequest::getDayStatus,
+ IMDGDistributedNames.Map_DayStatusDictionary,
+ DayStatusDictionary.class)
+ );
+ };
+ }
+
+ @Bean("clearingCalendarUpdateRequestValidator")
+ public Function clearingCalendarUpdateRequestValidator(Map> imdgForValidation) {
+ return clearingCalendarUpdateRequest -> {
+ ImdgValidationContext context = new ImdgValidationContext<>();
+ context.setValidatedObject(clearingCalendarUpdateRequest);
+ Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
+ addImdg.accept(IMDGDistributedNames.Map_Company);
+ addImdg.accept(IMDGDistributedNames.Map_DayStatusDictionary);
+ return new ValidatorImpl<>(context,
+ IdPresentRule.instance("id",
+ ClearingCalendarUpdateRequest::getId,
+ IMDGDistributedNames.Map_ClearingCalendar,
+ ClearingCalendar.class,
+ ValidationError.RecordNotFound),
+ DateNotBeforeRule.instance("clearingDate",
+ ClearingCalendarUpdateRequest::getClearingDate),
+ IdPresentRule.instance("companyId",
+ ClearingCalendarUpdateRequest::getCompanyId,
+ IMDGDistributedNames.Map_Company,
+ Company.class,
+ ValidationError.CompanyNotFound,
+ company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
+ DictionaryPresentRule.instance("dayStatus",
+ ClearingCalendarUpdateRequest::getDayStatus,
+ IMDGDistributedNames.Map_DayStatusDictionary,
+ DayStatusDictionary.class)
+ );
+ };
+ }
+
+ @Bean("clearingCalendarDeleteRequestValidator")
+ public Function clearingCalendarDeleteRequestValidator() {
+ return clearingCalendarDeleteRequest -> {
+ ImdgValidationContext context = new ImdgValidationContext<>();
+ context.setValidatedObject(clearingCalendarDeleteRequest);
+ return new ValidatorImpl<>(context,
+ IdPresentRule.instance("id",
+ CommonDeleteRequest::getId,
+ IMDGDistributedNames.Map_ClearingCalendar,
+ ClearingCalendar.class,
+ ValidationError.RecordNotFound)
+ );
+ };
+ }
+
+}
diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerTemplateValidationConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerTemplateValidationConfig.java
new file mode 100644
index 000000000..56c9f706f
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerTemplateValidationConfig.java
@@ -0,0 +1,132 @@
+package ru.spcex.clearing.scheduler.config.validation;
+
+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.scheduler.PlannerTemplate;
+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.common.CommonDeleteRequest;
+import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerTemplateNewRequest;
+import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerTemplateUpdateRequest;
+import ru.spcex.clearing.scheduler.error.ValidationError;
+import ru.spcex.clearing.scheduler.validation.rules.common.DictionaryPresentRule;
+import ru.spcex.clearing.scheduler.validation.rules.common.IdPresentRule;
+import ru.spcex.clearing.scheduler.validation.rules.common.TimeNotBeforeRule;
+import ru.spcex.platform.classes.base.SpcexObjectBase;
+import ru.spcex.platform.enumeration.WorkflowStatus;
+import ru.spcex.platform.imdg.api.Imdg;
+import ru.spcex.platform.imdg.validation.ImdgValidationContext;
+import ru.spcex.platform.utils.validation.IValidator;
+import ru.spcex.platform.utils.validation.ValidatorImpl;
+
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+@Configuration
+public class PlannerTemplateValidationConfig {
+
+ @Bean("plannerTemplateNewRequestValidator")
+ public Function plannerNewRequestValidator(Map> imdgForValidation) {
+ return plannerNewRequest -> {
+ ImdgValidationContext context = new ImdgValidationContext<>();
+ context.setValidatedObject(plannerNewRequest);
+ Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
+ addImdg.accept(IMDGDistributedNames.Map_TaskDictionary);
+ addImdg.accept(IMDGDistributedNames.Map_TaskStatusDictionary);
+ addImdg.accept(IMDGDistributedNames.Map_Company);
+ addImdg.accept(IMDGDistributedNames.Map_Security);
+ return new ValidatorImpl<>(context,
+ DictionaryPresentRule.instance("task",
+ PlannerTemplateNewRequest::getTask,
+ IMDGDistributedNames.Map_TaskDictionary,
+ TaskDictionary.class),
+ TimeNotBeforeRule.instance("taskTime",
+ PlannerTemplateNewRequest::getTaskTime),
+ DictionaryPresentRule.instance("taskStatus",
+ PlannerTemplateNewRequest::getTaskStatus,
+ IMDGDistributedNames.Map_TaskStatusDictionary,
+ TaskStatusDictionary.class),
+ IdPresentRule.instance("companyId",
+ PlannerTemplateNewRequest::getCompanyId,
+ IMDGDistributedNames.Map_Company,
+ Company.class,
+ ValidationError.CompanyNotFound,
+ company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
+ IdPresentRule.instance("securityId",
+ PlannerTemplateNewRequest::getSecurityId,
+ IMDGDistributedNames.Map_Security,
+ Security.class,
+ ValidationError.SecurityNotFound,
+ security -> WorkflowStatus.Active.getKey().equals(security.getWorkflowStatus()) ? null : ValidationError.SecurityNotActive)
+ );
+ };
+ }
+
+ @Bean("plannerTemplateUpdateRequestValidator")
+ public Function plannerUpdateRequestValidator(Map> imdgForValidation) {
+ return plannerUpdateRequest -> {
+ ImdgValidationContext context = new ImdgValidationContext<>();
+ context.setValidatedObject(plannerUpdateRequest);
+ Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
+ addImdg.accept(IMDGDistributedNames.Map_TaskDictionary);
+ addImdg.accept(IMDGDistributedNames.Map_TaskStatusDictionary);
+ addImdg.accept(IMDGDistributedNames.Map_Company);
+ addImdg.accept(IMDGDistributedNames.Map_Security);
+ return new ValidatorImpl<>(context,
+ IdPresentRule.instance("id",
+ PlannerTemplateUpdateRequest::getId,
+ IMDGDistributedNames.Map_PlannerTemplate,
+ PlannerTemplate.class,
+ ValidationError.RecordNotFound),
+ DictionaryPresentRule.instance("task",
+ PlannerTemplateNewRequest::getTask,
+ IMDGDistributedNames.Map_TaskDictionary,
+ TaskDictionary.class,
+ false),
+ TimeNotBeforeRule.instance("taskTime",
+ PlannerTemplateNewRequest::getTaskTime,
+ false),
+ DictionaryPresentRule.instance("taskStatus",
+ PlannerTemplateNewRequest::getTaskStatus,
+ IMDGDistributedNames.Map_TaskStatusDictionary,
+ TaskStatusDictionary.class,
+ false),
+ IdPresentRule.instance("companyId",
+ PlannerTemplateNewRequest::getCompanyId,
+ IMDGDistributedNames.Map_Company,
+ Company.class,
+ ValidationError.CompanyNotFound,
+ false,
+ company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
+ IdPresentRule.instance("securityId",
+ PlannerTemplateNewRequest::getSecurityId,
+ IMDGDistributedNames.Map_Security,
+ Security.class,
+ ValidationError.SecurityNotFound,
+ false,
+ security -> WorkflowStatus.Active.getKey().equals(security.getWorkflowStatus()) ? null : ValidationError.SecurityNotActive)
+ );
+ };
+ }
+
+
+ @Bean("plannerTemplateDeleteRequestValidator")
+ public Function plannerTemplateDeleteRequestValidator() {
+ return plannerTemplateDeleteRequest -> {
+ ImdgValidationContext context = new ImdgValidationContext<>();
+ context.setValidatedObject(plannerTemplateDeleteRequest);
+ return new ValidatorImpl<>(context,
+ IdPresentRule.instance("id",
+ CommonDeleteRequest::getId,
+ IMDGDistributedNames.Map_PlannerTemplate,
+ PlannerTemplate.class,
+ ValidationError.RecordNotFound)
+ );
+ };
+ }
+
+}
diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerValidationConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerValidationConfig.java
new file mode 100644
index 000000000..16a4e8501
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerValidationConfig.java
@@ -0,0 +1,143 @@
+package ru.spcex.clearing.scheduler.config.validation;
+
+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.scheduler.Planner;
+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.common.CommonDeleteRequest;
+import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest;
+import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerUpdateRequest;
+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.validation.ImdgValidationContext;
+import ru.spcex.platform.utils.validation.IValidator;
+import ru.spcex.platform.utils.validation.ValidatorImpl;
+
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+@Configuration
+public class PlannerValidationConfig {
+
+ @Bean("plannerNewRequestValidator")
+ public Function plannerNewRequestValidator(Map> imdgForValidation) {
+ return plannerNewRequest -> {
+ ImdgValidationContext context = new ImdgValidationContext<>();
+ context.setValidatedObject(plannerNewRequest);
+ Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
+ addImdg.accept(IMDGDistributedNames.Map_TaskDictionary);
+ addImdg.accept(IMDGDistributedNames.Map_TaskStatusDictionary);
+ addImdg.accept(IMDGDistributedNames.Map_Company);
+ addImdg.accept(IMDGDistributedNames.Map_Security);
+ return new ValidatorImpl<>(context,
+ DictionaryPresentRule.instance("task",
+ PlannerNewRequest::getTask,
+ IMDGDistributedNames.Map_TaskDictionary,
+ 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)
+ );
+ };
+ }
+
+ @Bean("plannerUpdateRequestValidator")
+ public Function plannerUpdateRequestValidator(Map> imdgForValidation) {
+ return plannerUpdateRequest -> {
+ ImdgValidationContext context = new ImdgValidationContext<>();
+ context.setValidatedObject(plannerUpdateRequest);
+ Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
+ addImdg.accept(IMDGDistributedNames.Map_TaskDictionary);
+ addImdg.accept(IMDGDistributedNames.Map_TaskStatusDictionary);
+ addImdg.accept(IMDGDistributedNames.Map_Company);
+ addImdg.accept(IMDGDistributedNames.Map_Security);
+ return new ValidatorImpl<>(context,
+ IdPresentRule.instance("id",
+ PlannerUpdateRequest::getId,
+ IMDGDistributedNames.Map_Planner,
+ Planner.class,
+ ValidationError.RecordNotFound),
+ DictionaryPresentRule.instance("task",
+ PlannerUpdateRequest::getTask,
+ IMDGDistributedNames.Map_TaskDictionary,
+ TaskDictionary.class,
+ false),
+ TimeNotBeforeRule.instance("taskTime",
+ PlannerUpdateRequest::getTaskTime,
+ false),
+ DateNotBeforeRule.instance("clearingDate",
+ PlannerUpdateRequest::getClearingDate,
+ false),
+ EnumPresentRule.instance("market",
+ PlannerUpdateRequest::getMarket,
+ Market.values(),
+ false),
+ DictionaryPresentRule.instance("taskStatus",
+ PlannerUpdateRequest::getTaskStatus,
+ IMDGDistributedNames.Map_TaskStatusDictionary,
+ TaskStatusDictionary.class,
+ false),
+ IdPresentRule.instance("companyId",
+ PlannerUpdateRequest::getCompanyId,
+ IMDGDistributedNames.Map_Company,
+ Company.class,
+ ValidationError.CompanyNotFound,
+ false,
+ company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
+ IdPresentRule.instance("securityId",
+ PlannerUpdateRequest::getSecurityId,
+ IMDGDistributedNames.Map_Security,
+ Security.class,
+ ValidationError.SecurityNotFound,
+ false,
+ security -> WorkflowStatus.Active.getKey().equals(security.getWorkflowStatus()) ? null : ValidationError.SecurityNotActive)
+ );
+ };
+ }
+
+ @Bean("plannerDeleteRequestValidator")
+ public Function plannerDeleteRequestValidator() {
+ return plannerDeleteRequest -> {
+ ImdgValidationContext context = new ImdgValidationContext<>();
+ context.setValidatedObject(plannerDeleteRequest);
+ return new ValidatorImpl<>(context,
+ IdPresentRule.instance("id",
+ CommonDeleteRequest::getId,
+ IMDGDistributedNames.Map_Planner,
+ Planner.class,
+ ValidationError.RecordNotFound)
+ );
+ };
+ }
+
+}
diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/ValidationConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/ValidationConfig.java
new file mode 100644
index 000000000..d12745c9e
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/ValidationConfig.java
@@ -0,0 +1,34 @@
+package ru.spcex.clearing.scheduler.config.validation;
+
+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.DayStatusDictionary;
+import ru.clearing.platform.dictionary.TaskDictionary;
+import ru.clearing.platform.dictionary.TaskStatusDictionary;
+import ru.spcex.clearing.imdg.IMDGDistributedNames;
+import ru.spcex.platform.classes.base.SpcexObjectBase;
+import ru.spcex.platform.imdg.api.Imdg;
+import ru.spcex.platform.imdg.api.ImdgProvider;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiConsumer;
+
+@Configuration
+public class ValidationConfig {
+
+ @Bean("imdgForValidation")
+ public Map> imdgForValidation(ImdgProvider imdgProvider) {
+ final Map> imdg = new HashMap<>();
+ BiConsumer> addImdg = (s, aClass) -> imdg.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);
+ addImdg.accept(IMDGDistributedNames.Map_DayStatusDictionary, DayStatusDictionary.class);
+ return imdg;
+ }
+
+}
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..ea04bfa3a
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/ValidationError.java
@@ -0,0 +1,29 @@
+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
+ RecordNotFound(7006L),
+ 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 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 3a86684b7..adbf15094 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
@@ -6,6 +6,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.scheduler.ClearingCalendar;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
@@ -15,40 +16,58 @@ 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.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
+import ru.spcex.platform.utils.enumeration.IMessageResolver;
+import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant;
+import java.util.function.Function;
@Service
public class ClearingCalendarService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg clearingCalendarMap;
+ private final IMessageResolver messageResolver;
+ private final Function clearingCalendarDeleteRequestValidation;
+ private final Function clearingCalendarNewRequestValidation;
+ private final Function clearingCalendarUpdateRequestValidation;
@Autowired
public ClearingCalendarService(Consumer kafkaQueue, Producer kafkaProducer,
- ImdgProvider imdgProvider) {
+ ImdgProvider imdgProvider,
+ IMessageResolver messageResolver,
+ @Qualifier("clearingCalendarDeleteRequestValidator") Function clearingCalendarDeleteRequestValidator,
+ @Qualifier("clearingCalendarNewRequestValidator") Function clearingCalendarNewRequestValidator,
+ @Qualifier("clearingCalendarUpdateRequestValidator") Function clearingCalendarUpdateRequestValidator) {
super(kafkaQueue, kafkaProducer);
this.clearingCalendarMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingCalendar, ClearingCalendar.class);
+ this.clearingCalendarDeleteRequestValidation = clearingCalendarDeleteRequestValidator;
+ this.clearingCalendarNewRequestValidation = clearingCalendarNewRequestValidator;
+ this.clearingCalendarUpdateRequestValidation = clearingCalendarUpdateRequestValidator;
+ this.messageResolver = messageResolver;
}
@Override
public void afterPropertiesSet() {
callback(ClearingCalendarNewRequest.class)
- .setConsumer(this::newClearingCalendar)
+ .setFunction(this::newClearingCalendar)
.forDestination(Consts.DESTINATION_CLEARING_CALENDAR_NEW, callbacks::put);
callback(ClearingCalendarUpdateRequest.class)
- .setConsumer(this::updateClearingCalendar)
+ .setFunction(this::updateClearingCalendar)
.forDestination(Consts.DESTINATION_CLEARING_CALENDAR_UPDATE, callbacks::put);
callback(CommonDeleteRequest.class)
- .setConsumer(this::deleteClearingCalendar)
+ .setFunction(this::deleteClearingCalendar)
.forDestination(Consts.DESTINATION_CLEARING_CALENDAR_DELETE, callbacks::put);
init();
}
- private void newClearingCalendar(BaseRequest userRequest) {
+ private RequestInfoUpdate newClearingCalendar(BaseRequest userRequest) {
ClearingCalendarNewRequest req = userRequest.getRequestPayload();
log.debug("ClearingCalendarNewRequest received");
+ RequestInfoUpdate requestInfoUpdate = validate(userRequest, clearingCalendarNewRequestValidation, messageResolver);
+ if (requestInfoUpdate != null) return requestInfoUpdate;
ClearingCalendar clearingCalendar = new ClearingCalendar();
Instant created = Instant.now();
clearingCalendar.setCreated(created);
@@ -57,11 +76,14 @@ public class ClearingCalendarService extends QueueConsumer implements Initializi
clearingCalendar.setDayStatus(req.getDayStatus());
clearingCalendarMap.insert(clearingCalendar);
log.debug("successfully processed, new id {}", clearingCalendar.getId());
+ return null;
}
- private void updateClearingCalendar(BaseRequest userRequest) {
+ private RequestInfoUpdate updateClearingCalendar(BaseRequest userRequest) {
ClearingCalendarUpdateRequest req = userRequest.getRequestPayload();
log.debug("ClearingCalendarUpdateRequest received");
+ RequestInfoUpdate requestInfoUpdate = validate(userRequest, clearingCalendarUpdateRequestValidation, messageResolver);
+ if (requestInfoUpdate != null) return requestInfoUpdate;
Instant updated = Instant.now();
ClearingCalendar clearingCalendar = clearingCalendarMap.getSingleObjectByID(req.getId());
clearingCalendar.setClearingDate(req.getClearingDate());
@@ -70,12 +92,16 @@ public class ClearingCalendarService extends QueueConsumer implements Initializi
clearingCalendar.setUpdated(updated);
clearingCalendarMap.update(clearingCalendar);
log.debug("successfully processed, new id {}", clearingCalendar.getId());
+ return null;
}
- private void deleteClearingCalendar(BaseRequest userRequest) {
+ private RequestInfoUpdate deleteClearingCalendar(BaseRequest userRequest) {
CommonDeleteRequest req = userRequest.getRequestPayload();
+ RequestInfoUpdate requestInfoUpdate = validate(userRequest, clearingCalendarDeleteRequestValidation, messageResolver);
+ if (requestInfoUpdate != null) return requestInfoUpdate;
log.debug("CommonDeleteRequest received id = {}", req.getId());
ClearingCalendar clearingCalendar = clearingCalendarMap.getSingleObjectByID(req.getId());
clearingCalendarMap.delete(clearingCalendar);
+ 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 199c12ab4..4f0870dbc 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
@@ -6,6 +6,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.scheduler.Planner;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
@@ -15,40 +16,59 @@ import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteReques
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerUpdateRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
+import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
+import ru.spcex.platform.utils.enumeration.IMessageResolver;
+import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant;
+import java.util.function.Function;
@Service
public class PlannerService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg plannerMap;
+ private final IMessageResolver messageResolver;
+ private final Function plannerDeleteRequestValidation;
+ private final Function plannerNewRequestValidation;
+ private final Function plannerUpdateRequestValidation;
@Autowired
- public PlannerService(Consumer kafkaQueue, Producer kafkaProducer,
- ImdgProvider imdgProvider) {
+ public PlannerService(Consumer kafkaQueue,
+ Producer kafkaProducer,
+ ImdgProvider imdgProvider,
+ IMessageResolver messageResolver,
+ @Qualifier("plannerDeleteRequestValidator") Function plannerDeleteRequestValidator,
+ @Qualifier("plannerNewRequestValidator") Function plannerNewRequestValidator,
+ @Qualifier("plannerUpdateRequestValidator") Function plannerUpdateRequestValidator) {
super(kafkaQueue, kafkaProducer);
this.plannerMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Planner, Planner.class);
+ this.messageResolver = messageResolver;
+ this.plannerDeleteRequestValidation = plannerDeleteRequestValidator;
+ this.plannerNewRequestValidation = plannerNewRequestValidator;
+ this.plannerUpdateRequestValidation = plannerUpdateRequestValidator;
}
@Override
public void afterPropertiesSet() {
callback(PlannerNewRequest.class)
- .setConsumer(this::newScheduler)
+ .setFunction(this::newScheduler)
.forDestination(Consts.DESTINATION_PLANNER_NEW, callbacks::put);
callback(PlannerUpdateRequest.class)
- .setConsumer(this::updateScheduler)
+ .setFunction(this::updateScheduler)
.forDestination(Consts.DESTINATION_PLANNER_UPDATE, callbacks::put);
callback(CommonDeleteRequest.class)
- .setConsumer(this::deleteScheduler)
+ .setFunction(this::deleteScheduler)
.forDestination(Consts.DESTINATION_PLANNER_DELETE, callbacks::put);
init();
}
- private void newScheduler(BaseRequest userRequest) {
+ private RequestInfoUpdate newScheduler(BaseRequest userRequest) {
PlannerNewRequest req = userRequest.getRequestPayload();
log.debug("PlannerNewRequest received");
+ RequestInfoUpdate requestInfoUpdate = validate(userRequest, plannerNewRequestValidation, messageResolver);
+ if (requestInfoUpdate != null) return requestInfoUpdate;
Planner planner = new Planner();
planner.setCreated(Instant.now());
planner.setTask(req.getTask());
@@ -60,11 +80,14 @@ public class PlannerService extends QueueConsumer implements InitializingBean {
planner.setSecurityId(req.getSecurityId());
plannerMap.insert(planner);
log.debug("successfully processed, new id {}", planner.getId());
+ return null;
}
- private void updateScheduler(BaseRequest userRequest) {
+ private RequestInfoUpdate updateScheduler(BaseRequest userRequest) {
PlannerUpdateRequest req = userRequest.getRequestPayload();
log.debug("PlannerUpdateRequest received id = {}", req.getId());
+ RequestInfoUpdate requestInfoUpdate = validate(userRequest, plannerUpdateRequestValidation, messageResolver);
+ if (requestInfoUpdate != null) return requestInfoUpdate;
Planner planner = plannerMap.getSingleObjectByID(req.getId());
planner.setUpdated(Instant.now());
planner.setTask(req.getTask());
@@ -75,13 +98,17 @@ public class PlannerService extends QueueConsumer implements InitializingBean {
planner.setCompanyId(req.getCompanyId());
planner.setSecurityId(req.getSecurityId());
plannerMap.update(planner);
+ return null;
}
- private void deleteScheduler(BaseRequest userRequest) {
+ private RequestInfoUpdate deleteScheduler(BaseRequest userRequest) {
CommonDeleteRequest req = userRequest.getRequestPayload();
log.debug("CommonDeleteRequest received id = {}", req.getId());
+ RequestInfoUpdate requestInfoUpdate = validate(userRequest, plannerDeleteRequestValidation, messageResolver);
+ if (requestInfoUpdate != null) return requestInfoUpdate;
Planner planner = plannerMap.getSingleObjectByID(req.getId());
plannerMap.delete(planner);
+ return null;
}
}
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 77a1466a0..2b7c7c76a 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
@@ -6,6 +6,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.scheduler.PlannerTemplate;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
@@ -15,40 +16,58 @@ 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.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
+import ru.spcex.platform.utils.enumeration.IMessageResolver;
+import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant;
+import java.util.function.Function;
@Service
public class PlannerTemplateService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg plannerTemplateMap;
+ private final IMessageResolver messageResolver;
+ private final Function plannerTemplateDeleteRequestValidation;
+ private final Function plannerTemplateNewRequestValidation;
+ private final Function plannerTemplateUpdateRequestValidation;
@Autowired
public PlannerTemplateService(Consumer kafkaQueue, Producer kafkaProducer,
- ImdgProvider imdgProvider) {
+ ImdgProvider imdgProvider,
+ IMessageResolver messageResolver,
+ @Qualifier("plannerTemplateDeleteRequestValidator") Function plannerTemplateDeleteRequestValidator,
+ @Qualifier("plannerTemplateNewRequestValidator") Function plannerTemplateNewRequestValidator,
+ @Qualifier("plannerTemplateUpdateRequestValidator") Function plannerTemplateUpdateRequestValidator) {
super(kafkaQueue, kafkaProducer);
this.plannerTemplateMap = imdgProvider.getImdg(IMDGDistributedNames.Map_PlannerTemplate, PlannerTemplate.class);
+ this.plannerTemplateDeleteRequestValidation = plannerTemplateDeleteRequestValidator;
+ this.plannerTemplateNewRequestValidation = plannerTemplateNewRequestValidator;
+ this.plannerTemplateUpdateRequestValidation = plannerTemplateUpdateRequestValidator;
+ this.messageResolver = messageResolver;
}
@Override
public void afterPropertiesSet() {
callback(PlannerTemplateNewRequest.class)
- .setConsumer(this::newTimetable)
+ .setFunction(this::newTimetable)
.forDestination(Consts.DESTINATION_PLANNER_TEMPLATE_NEW, callbacks::put);
callback(PlannerTemplateUpdateRequest.class)
- .setConsumer(this::updateTimetable)
+ .setFunction(this::updateTimetable)
.forDestination(Consts.DESTINATION_PLANNER_TEMPLATE_UPDATE, callbacks::put);
callback(CommonDeleteRequest.class)
- .setConsumer(this::deleteTimetable)
+ .setFunction(this::deleteTimetable)
.forDestination(Consts.DESTINATION_PLANNER_TEMPLATE_DELETE, callbacks::put);
init();
}
- private void newTimetable(BaseRequest userRequest) {
+ private RequestInfoUpdate newTimetable(BaseRequest userRequest) {
PlannerTemplateNewRequest req = userRequest.getRequestPayload();
log.debug("PlannerTemplateNewRequest received");
+ RequestInfoUpdate requestInfoUpdate = validate(userRequest, plannerTemplateNewRequestValidation, messageResolver);
+ if (requestInfoUpdate != null) return requestInfoUpdate;
PlannerTemplate plannerTemplate = new PlannerTemplate();
Instant created = Instant.now();
plannerTemplate.setCreated(created);
@@ -59,11 +78,14 @@ public class PlannerTemplateService extends QueueConsumer implements Initializin
plannerTemplate.setSecurityId(req.getSecurityId());
plannerTemplateMap.insert(plannerTemplate);
log.debug("successfully processed, new id {}", plannerTemplate.getId());
+ return null;
}
- private void updateTimetable(BaseRequest userRequest) {
+ private RequestInfoUpdate updateTimetable(BaseRequest userRequest) {
PlannerTemplateUpdateRequest req = userRequest.getRequestPayload();
log.debug("PlannerTemplateUpdateRequest received");
+ RequestInfoUpdate requestInfoUpdate = validate(userRequest, plannerTemplateUpdateRequestValidation, messageResolver);
+ if (requestInfoUpdate != null) return requestInfoUpdate;
PlannerTemplate plannerTemplate = plannerTemplateMap.getSingleObjectByID(req.getId());
Instant updated = Instant.now();
plannerTemplate.setUpdated(updated);
@@ -74,12 +96,16 @@ public class PlannerTemplateService extends QueueConsumer implements Initializin
plannerTemplate.setSecurityId(req.getSecurityId());
plannerTemplateMap.update(plannerTemplate);
log.debug("successfully processed, new id {}", plannerTemplate.getId());
+ return null;
}
- private void deleteTimetable(BaseRequest userRequest) {
+ private RequestInfoUpdate deleteTimetable(BaseRequest userRequest) {
CommonDeleteRequest req = userRequest.getRequestPayload();
log.debug("CommonDeleteRequest received id = {}", req.getId());
+ RequestInfoUpdate requestInfoUpdate = validate(userRequest, plannerTemplateDeleteRequestValidation, messageResolver);
+ if (requestInfoUpdate != null) return requestInfoUpdate;
PlannerTemplate plannerTemplate = plannerTemplateMap.getSingleObjectByID(req.getId());
plannerTemplateMap.delete(plannerTemplate);
+ return null;
}
}
diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/TaskManager.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/TaskManager.java
index b0a8708d5..bcc7fbc07 100644
--- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/TaskManager.java
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/TaskManager.java
@@ -18,6 +18,7 @@ import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.enumeration.Task;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
+import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast;
import java.time.*;
import java.util.ArrayList;
@@ -75,6 +76,9 @@ public class TaskManager implements EntryAddedListener,
public void afterPropertiesSet() {
this.launcherMap = imdgProvider.getImdg(Map_Launcher, Launcher.class);
this.plannerAllTodayMap = imdgProvider.getImdg(Map_PlannerAllToday, PlannerAllToday.class);
+ if (plannerAllTodayMap instanceof ImdgHazelcast plannerAllTodayImdgHazelcast) {
+ plannerAllTodayImdgHazelcast.getMap().addEntryListener(this, true);
+ }
scheduledJobs = new ConcurrentHashMap<>();
updateScheduler();
}
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..b1df393c6
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/DateNotBeforeRule.java
@@ -0,0 +1,45 @@
+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;
+
+/**
+ * Проверка поля с LocalDate. Условие проверки: поверяемая дата >= текущая дата
+ * @param Класс проверяемого объекта
+ */
+public record DateNotBeforeRule(String fieldName, Function getter, boolean required) implements IValidationRule> {
+
+ /**
+ * @param fieldName Название поля класса, используется для передачи ошибки
+ * @param getter Метод получения проверяемой даты
+ * @param required Флаг обязательности поля
+ * @param Класс проверяемого объекта
+ */
+ public static DateNotBeforeRule instance(String fieldName, Function getter, boolean required) {
+ return new DateNotBeforeRule<>(fieldName, getter, required);
+ }
+
+ /**
+ * @param fieldName Название поля класса, используется для передачи ошибки
+ * @param getter Метод получения проверяемой даты
+ * @param Класс проверяемого объекта
+ */
+ 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/common/DictionaryPresentRule.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/DictionaryPresentRule.java
new file mode 100644
index 000000000..999f484bb
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/DictionaryPresentRule.java
@@ -0,0 +1,81 @@
+package ru.spcex.clearing.scheduler.validation.rules.common;
+
+import ru.clearing.platform.dictionary.AbstractDictionary;
+import ru.spcex.clearing.scheduler.error.ValidationError;
+import ru.spcex.platform.imdg.api.Imdg;
+import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
+import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
+import ru.spcex.platform.imdg.validation.ImdgValidationContext;
+import ru.spcex.platform.utils.enumeration.EnumMessage;
+import ru.spcex.platform.utils.validation.IValidationRule;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.function.Function;
+
+/**
+ * Проверка поля с кодом из словаря (таблицы *_dictionary)
+ * @param Класс проверяемого объекта
+ * @param Класс словаря
+ */
+public record DictionaryPresentRule(String fieldName,
+ Function getter,
+ String dictionaryName,
+ Class dictionaryClass,
+ boolean required) implements IValidationRule> {
+
+ /**
+ * @param fieldName Название поля
+ * @param getter Метод получения проверяемого значения
+ * @param dictionaryName Название словаря (см. IMDGDistributedNames)
+ * @param dictionaryClass Класс словаря (классы *Dictionary.class)
+ * @param required Флаг обязательности
+ * @param Класс проверяемого объекта
+ * @param Класс словаря
+ */
+ public static DictionaryPresentRule instance(String fieldName,
+ Function getter,
+ String dictionaryName,
+ Class dictionaryClass,
+ boolean required) {
+ return new DictionaryPresentRule<>(fieldName, getter, dictionaryName, dictionaryClass, required);
+ }
+
+ /**
+ * @param fieldName Название поля
+ * @param getter Метод получения проверяемого значения
+ * @param dictionaryName Название словаря (см. IMDGDistributedNames)
+ * @param dictionaryClass Класс словаря (классы *Dictionary.class)
+ * @param Класс проверяемого объекта
+ * @param Класс словаря
+ */
+ 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 = getter.apply(validatedObject);
+ if (enumCode == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : empty();
+ Imdg dictImdg = context.obtainMap(
+ dictionaryName,
+ dictionaryClass
+ );
+ ImdgPredicateBuilder imdgPredicateBuilder = dictImdg.predicateBuilder();
+ ImdgPredicate imdgPredicate = imdgPredicateBuilder.equals("code", enumCode);
+ Collection fromMap = dictImdg.getCollectionObjectsByPredicate(imdgPredicate);
+ if (fromMap.isEmpty()) {
+ return of(ValidationError.WrongDictionaryValue, fieldName);
+ }
+ assert fromMap.size() == 1;
+ D dictionaryFromMap = fromMap.iterator().next();
+ if (dictionaryFromMap == null) {
+ 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..a8ab3cd4f
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/EnumPresentRule.java
@@ -0,0 +1,60 @@
+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;
+
+/**
+ * Проверка поля со значением из множества (enum)
+ * @param Класс проверяемого объекта
+ * @param Enum
+ */
+public record EnumPresentRule(String fieldName,
+ Function getter,
+ E[] enumValues,
+ boolean required) implements IValidationRule> {
+
+ /**
+ * @param fieldName Название поля
+ * @param getter Метод получения проверяемого значения
+ * @param enumValues Значения из проверяемого множества (Enum.values())
+ * @param required Флаг обязательности
+ * @param Класс проверяемого объекта
+ * @param Enum
+ */
+ public static EnumPresentRule instance(String fieldName,
+ Function getter,
+ E[] enumValues,
+ boolean required) {
+ return new EnumPresentRule<>(fieldName, getter, enumValues, required);
+ }
+
+ /**
+ * @param fieldName Название поля
+ * @param getter Метод получения проверяемого значения
+ * @param enumValues Значения из проверяемого множества (Enum.values())
+ * @param Класс проверяемого объекта
+ * @param Enum
+ */
+ 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/common/FieldRequiredRule.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/FieldRequiredRule.java
new file mode 100644
index 000000000..4abc90b45
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/FieldRequiredRule.java
@@ -0,0 +1,35 @@
+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.util.Optional;
+import java.util.function.Function;
+
+/**
+ * Проверка обязательности поля (not null)
+ * @param Класс проверяемого объекта
+ * @param Класс проверяемого значения
+ */
+public record FieldRequiredRule(String fieldName, Function getter) implements IValidationRule> {
+
+ /**
+ * @param fieldName Название поля
+ * @param getter Метод получения значения
+ * @param Класс проверяемого объекта
+ * @param Класс проверяемого значения
+ */
+ 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(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..e87377b56
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/IdPresentRule.java
@@ -0,0 +1,77 @@
+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.Optional;
+import java.util.function.Function;
+
+/**
+ * Проверка наличия связанного по Id объекта в базе
+ * @param Класс проверяемого объекта
+ * @param Класс связанного объекта
+ */
+public record IdPresentRule(
+ String fieldName,
+ Function idGetter,
+ Function[] additionalChecks,
+ String mapName,
+ Class mapClass,
+ ValidationError idNotPresentError,
+ boolean required
+) implements IValidationRule> {
+
+ /**
+ * @param fieldName Название поля, содержащего Id
+ * @param idGetter Метод получения Id
+ * @param mapName Название мапы связанного объекта (см. IMDGDistributedNames)
+ * @param mapClass Класс связанного объекта
+ * @param idNotPresentError Ошибка, которая будет возвращена, если Id не найден
+ * @param required Флаг обязательности
+ * @param additionalChecks Дополнительные проверки, которые можно провести со связанным объектом
+ * @param Класс проверяемого объекта
+ * @param Класс связанного объекта
+ */
+ @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.getSingleObjectByID(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..90287864e
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/TimeNotBeforeRule.java
@@ -0,0 +1,45 @@
+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;
+
+/**
+ * Проверка поля с LocalTime. Условие проверки: проверяемое время >= текущее время
+ * @param Класс проверяемого объекта
+ */
+public record TimeNotBeforeRule(String fieldName, Function getter, boolean required) implements IValidationRule> {
+
+ /**
+ * @param fieldName Название поля класса, используется для передачи ошибки
+ * @param getter Метод получения проверяемого времени
+ * @param required Флаг обязательности поля
+ * @param Класс проверяемого объекта
+ */
+ public static TimeNotBeforeRule instance(String fieldName, Function getter, boolean required) {
+ return new TimeNotBeforeRule<>(fieldName, getter, required);
+ }
+
+ /**
+ * @param fieldName Название поля класса, используется для передачи ошибки
+ * @param getter Метод получения проверяемого времени
+ * @param Класс проверяемого объекта
+ */
+ 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/config/HazelcastServiceTestConfiguration.java b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/config/HazelcastServiceTestConfiguration.java
index af55150d0..48b9644d4 100644
--- a/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/config/HazelcastServiceTestConfiguration.java
+++ b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/config/HazelcastServiceTestConfiguration.java
@@ -10,6 +10,8 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper;
+import ru.spcex.platform.utils.enumeration.IMessageResolver;
+import ru.spcex.platform.utils.enumeration.SimpleMessageResolver;
import java.util.List;
import java.util.Random;
@@ -65,4 +67,9 @@ public class HazelcastServiceTestConfiguration {
params.setNearCacheConfig(new NearCacheConfig());
return params;
}
+
+ @Bean
+ public IMessageResolver messageResolver() {
+ return new SimpleMessageResolver();
+ }
}
diff --git a/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/service/ClearingCalendarServiceTest.java b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/service/ClearingCalendarServiceTest.java
index 7307966f9..258f6e1a3 100644
--- a/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/service/ClearingCalendarServiceTest.java
+++ b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/service/ClearingCalendarServiceTest.java
@@ -17,25 +17,40 @@ 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.profile.Contact;
import ru.clearing.classes.statics.data.scheduler.ClearingCalendar;
+import ru.clearing.platform.dictionary.DayStatusDictionary;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
+import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendarNewRequest;
+import ru.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendarUpdateRequest;
+import ru.spcex.clearing.scheduler.config.validation.ClearingCalendarValidationConfig;
+import ru.spcex.clearing.scheduler.config.validation.ValidationConfig;
import ru.spcex.clearing.scheduler.service.ClearingCalendarService;
+import ru.spcex.platform.enumeration.DayStatus;
+import ru.spcex.platform.enumeration.WorkflowStatus;
+import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
+import ru.spcex.platform.utils.enumeration.IMessageResolver;
+import ru.spcex.platform.utils.validation.IValidator;
import ru.specx.clearing.scheduler.config.HazelcastServiceTestConfiguration;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Collections;
import java.util.HashMap;
+import java.util.function.Function;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
- HazelcastServiceTestConfiguration.class})
+ HazelcastServiceTestConfiguration.class,
+ ValidationConfig.class,
+ ClearingCalendarValidationConfig.class
+})
class ClearingCalendarServiceTest {
private static final int PARTITION = 0;
@@ -48,6 +63,18 @@ class ClearingCalendarServiceTest {
private MockConsumer mockConsumer;
private MockProducer mockProducer;
+ @Autowired
+ private IMessageResolver messageResolver;
+
+ @Autowired
+ private Function clearingCalendarDeleteRequestValidation;
+
+ @Autowired
+ private Function clearingCalendarNewRequestValidation;
+
+ @Autowired
+ private Function clearingCalendarUpdateRequestValidation;
+
@BeforeEach
void setUp() {
mockConsumer = new MockConsumer<>(OffsetResetStrategy.EARLIEST);
@@ -61,14 +88,28 @@ class ClearingCalendarServiceTest {
*/
@Test
public void newClearingCalendarInQueue() throws InterruptedException {
- //ARRANGE
+ // Prepare test objects
+ hazelcastServiceTest.waitAvailable();
+ Company company = new Company();
+ company.setId(0L);
+ company.setWorkflowStatus(WorkflowStatus.Active.getKey());
+ Imdg companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class);
+ companyImdg.insert(company);
+ DayStatus dayStatus = DayStatus.Workday;
+ DayStatusDictionary dayStatusDictionary = new DayStatusDictionary();
+ dayStatusDictionary.setId(0L);
+ dayStatusDictionary.setCode(dayStatus.getKey());
+ Imdg dayStatusDictionaryImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_DayStatusDictionary, DayStatusDictionary.class);
+ dayStatusDictionaryImdg.insert(dayStatusDictionary);
+
+ //ARRANGE
ClearingCalendar clearingCalendar = new ClearingCalendar();
Instant created = Instant.now();
clearingCalendar.setCreated(created);
- clearingCalendar.setClearingDate(LocalDate.now());
+ clearingCalendar.setClearingDate(LocalDate.now().plusDays(1));
clearingCalendar.setCompanyId(0L);
- clearingCalendar.setDayStatus("STATUS");
+ clearingCalendar.setDayStatus(DayStatus.Workday.getKey());
ClearingCalendarNewRequest clearingCalendarNewRequest = new ClearingCalendarNewRequest();
clearingCalendarNewRequest.setClearingDate(clearingCalendar.getClearingDate());
@@ -89,10 +130,23 @@ class ClearingCalendarServiceTest {
//ACT
//service set up
- ClearingCalendarService clearingCalendarService = new ClearingCalendarService(mockConsumer, mockProducer, hazelcastServiceTest);
+ ClearingCalendarService clearingCalendarService = new ClearingCalendarService(mockConsumer,
+ mockProducer,
+ hazelcastServiceTest,
+ messageResolver,
+ clearingCalendarDeleteRequestValidation,
+ clearingCalendarNewRequestValidation,
+ clearingCalendarUpdateRequestValidation);
//callbacks set up
clearingCalendarService.afterPropertiesSet();
+
+ BaseRequest baseRequest = new BaseRequest<>();
+ baseRequest.setId(1L);
+ baseRequest.setActionType(ActionType.NEW);
+ ClearingCalendarNewRequest newRequest = new ClearingCalendarNewRequest();
+ baseRequest.setRequestPayload(newRequest);
+
IMap iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_ClearingCalendar);
//KAFKA
HashMap startOffsetsUpdating = new HashMap<>();
diff --git a/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/service/PlannerTemplateServiceTest.java b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/service/PlannerTemplateServiceTest.java
index ff5ac8109..7fd0b0d66 100644
--- a/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/service/PlannerTemplateServiceTest.java
+++ b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/service/PlannerTemplateServiceTest.java
@@ -17,25 +17,44 @@ 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.profile.Contact;
import ru.clearing.classes.statics.data.scheduler.PlannerTemplate;
+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.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
+import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerTemplateNewRequest;
+import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerTemplateUpdateRequest;
+import ru.spcex.clearing.scheduler.config.validation.PlannerTemplateValidationConfig;
+import ru.spcex.clearing.scheduler.config.validation.ValidationConfig;
import ru.spcex.clearing.scheduler.service.PlannerTemplateService;
+import ru.spcex.platform.enumeration.Status;
+import ru.spcex.platform.enumeration.Task;
+import ru.spcex.platform.enumeration.WorkflowStatus;
+import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
+import ru.spcex.platform.utils.enumeration.IMessageResolver;
+import ru.spcex.platform.utils.validation.IValidator;
import ru.specx.clearing.scheduler.config.HazelcastServiceTestConfiguration;
import java.time.Instant;
import java.time.LocalTime;
+import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.HashMap;
+import java.util.function.Function;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
- HazelcastServiceTestConfiguration.class})
+ HazelcastServiceTestConfiguration.class,
+ ValidationConfig.class,
+ PlannerTemplateValidationConfig.class
+})
class PlannerTemplateServiceTest {
private static final int PARTITION = 0;
@@ -48,6 +67,18 @@ class PlannerTemplateServiceTest {
private MockConsumer mockConsumer;
private MockProducer mockProducer;
+ @Autowired
+ private IMessageResolver messageResolver;
+
+ @Autowired
+ private Function plannerTemplateDeleteRequestValidation;
+
+ @Autowired
+ private Function plannerTemplateNewRequestValidation;
+
+ @Autowired
+ private Function plannerTemplateUpdateRequestValidation;
+
@BeforeEach
void setUp() {
mockConsumer = new MockConsumer<>(OffsetResetStrategy.EARLIEST);
@@ -61,14 +92,42 @@ class PlannerTemplateServiceTest {
*/
@Test
public void newPlannerTemplateInQueue() throws InterruptedException {
+ Task testTask = Task.accountBlock;
+ TaskDictionary taskDictionary = new TaskDictionary();
+ taskDictionary.setId(0L);
+ taskDictionary.setCode(testTask.getKey());
+ Imdg taskDictionaryImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_TaskDictionary, TaskDictionary.class);
+ taskDictionaryImdg.insert(taskDictionary);
+
+ Status testTaskStatus = Status.Active;
+ TaskStatusDictionary taskStatusDictionary = new TaskStatusDictionary();
+ taskStatusDictionary.setId(0L);
+ taskStatusDictionary.setCode(testTaskStatus.getKey());
+ Imdg taskStatusDictionaryImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_TaskStatusDictionary, TaskStatusDictionary.class);
+ taskStatusDictionaryImdg.insert(taskStatusDictionary);
+
+ long testCompanyId = 0L;
+ Company company = new Company();
+ company.setId(testCompanyId);
+ company.setWorkflowStatus(WorkflowStatus.Active.getKey());
+ Imdg companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class);
+ companyImdg.insert(company);
+
+ long testSecurityId = 0L;
+ Security security = new Security();
+ security.setId(testSecurityId);
+ security.setWorkflowStatus(WorkflowStatus.Active.getKey());
+ Imdg securityImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Security, Security.class);
+ securityImdg.insert(security);
+
//ARRANGE
Instant created = Instant.now();
PlannerTemplate plannerTemplate = new PlannerTemplate();
- plannerTemplate.setTask("TASK");
- plannerTemplate.setTaskTime(LocalTime.MIDNIGHT);
- plannerTemplate.setTaskStatus("TASK_STATUS");
- plannerTemplate.setCompanyId(0L);
- plannerTemplate.setSecurityId(10L);
+ plannerTemplate.setTask(testTask.getKey());
+ plannerTemplate.setTaskTime(LocalTime.now().plusHours(1));
+ plannerTemplate.setTaskStatus(testTaskStatus.getKey());
+ plannerTemplate.setCompanyId(testCompanyId);
+ plannerTemplate.setSecurityId(testSecurityId);
PlannerTemplateNewRequest plannerTemplateNewRequest = new PlannerTemplateNewRequest();
plannerTemplateNewRequest.setTask(plannerTemplate.getTask());
@@ -91,7 +150,13 @@ class PlannerTemplateServiceTest {
//ACT
//service set up
- PlannerTemplateService plannerTemplateService = new PlannerTemplateService(mockConsumer, mockProducer, hazelcastServiceTest);
+ PlannerTemplateService plannerTemplateService = new PlannerTemplateService(mockConsumer,
+ mockProducer,
+ hazelcastServiceTest,
+ messageResolver,
+ plannerTemplateDeleteRequestValidation,
+ plannerTemplateNewRequestValidation,
+ plannerTemplateUpdateRequestValidation);
//callbacks set up
plannerTemplateService.afterPropertiesSet();
@@ -131,7 +196,7 @@ class PlannerTemplateServiceTest {
Assertions.assertNotNull(plannerTemplateRes.getCreated());
Assertions.assertEquals(plannerTemplate.getTask(), plannerTemplateRes.getTask());
- Assertions.assertEquals(plannerTemplate.getTaskTime(), plannerTemplateRes.getTaskTime());
+ Assertions.assertEquals(plannerTemplate.getTaskTime().truncatedTo(ChronoUnit.SECONDS), plannerTemplateRes.getTaskTime().truncatedTo(ChronoUnit.SECONDS));
Assertions.assertEquals(plannerTemplate.getTaskStatus(), plannerTemplateRes.getTaskStatus());
Assertions.assertEquals(plannerTemplate.getCompanyId(), plannerTemplateRes.getCompanyId());
Assertions.assertEquals(plannerTemplate.getSecurityId(), plannerTemplateRes.getSecurityId());
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
new file mode 100644
index 000000000..3cbcf6698
--- /dev/null
+++ b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/validation/DictionaryPresentRuleTest.java
@@ -0,0 +1,115 @@
+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.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;
+
+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 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",
+ Task.values(),
+ PlannerNewRequest::getTask,
+ PlannerNewRequest::setTask);
+ testDictionary(IMDGDistributedNames.Map_TaskStatusDictionary,
+ TaskStatusDictionary.class,
+ PlannerNewRequest.class,
+ "taskStatus",
+ Status.values(),
+ PlannerNewRequest::getTaskStatus,
+ PlannerNewRequest::setTaskStatus);
+ testDictionary(IMDGDistributedNames.Map_DayStatusDictionary,
+ DayStatusDictionary.class,
+ ClearingCalendarNewRequest.class,
+ "dayStatus",
+ DayStatus.values(),
+ ClearingCalendarNewRequest::getDayStatus,
+ ClearingCalendarNewRequest::setDayStatus);
+
+ }
+
+ 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);
+ long idIdx = 0;
+ for (E enumValue : enumValues) {
+ D td = dictionaryClass.getConstructor().newInstance();
+ td.setId(idIdx++);
+ td.setCode(enumValue.getKey());
+ dictionaryImdg.insert(td);
+ }
+
+ Function validatorBuilder = request -> {
+ ImdgValidationContext context = new ImdgValidationContext<>();
+ context.setValidatedObject(request);
+ context.addImdg(dictionaryKey, dictionaryImdg);
+ return new ValidatorImpl<>(context,
+ DictionaryPresentRule.instance(fieldName,
+ getter,
+ dictionaryKey,
+ dictionaryClass)
+ );
+ };
+ R record = recordClass.getConstructor().newInstance();
+ IValidator validator = validatorBuilder.apply(record);
+
+ Collection enumMessages;
+ for (E enumValue : enumValues) {
+ setter.accept(record, enumValue.getKey());
+ enumMessages = validator.validateAll();
+ assertTrue(enumMessages.isEmpty());
+ }
+
+ setter.accept(record, "BAD_VALUE");
+ enumMessages = validator.validateAll();
+ assertEquals(1, enumMessages.size());
+ 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
new file mode 100644
index 000000000..78cbec5d0
--- /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.common.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
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/DayStatus.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/DayStatus.java
new file mode 100644
index 000000000..2028f093c
--- /dev/null
+++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/DayStatus.java
@@ -0,0 +1,18 @@
+package ru.spcex.platform.enumeration;
+
+import ru.spcex.platform.utils.enumeration.IEnumKey;
+
+public enum DayStatus implements IEnumKey {
+ Workday("BDAY"), DayOff("DOFF");
+
+ private final String key;
+
+ DayStatus(String key) {
+ this.key = key;
+ }
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+}
diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Parent.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Parent.java
new file mode 100644
index 000000000..523bba0bf
--- /dev/null
+++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Parent.java
@@ -0,0 +1,18 @@
+package ru.spcex.platform.enumeration;
+
+import ru.spcex.platform.utils.enumeration.IEnumKey;
+
+public enum Parent implements IEnumKey {
+ Template("TMPL"), Planner("PLNR"), Calendar("CLND");
+
+ private final String key;
+
+ Parent(String key) {
+ this.key = key;
+ }
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+}
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;
+ }
+}
diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java
index 2730b70a5..8fffd91e8 100644
--- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java
+++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java
@@ -16,16 +16,21 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.logic.functional.BuilderConsumerStep;
import ru.spcex.clearing.platform.messaging.logic.functional.ConsumerSpecificClass;
+import ru.spcex.platform.utils.enumeration.EnumMessage;
+import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.log.ExceptionUtils;
+import ru.spcex.platform.utils.validation.IValidator;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
/**
* утилитный класс для обработки сообщений из очереди
@@ -155,6 +160,31 @@ public class QueueConsumer implements AutoCloseable {
return ConsumerSpecificClass.build(clazz);
}
+
+ /**
+ * Валидация запроса
+ * @param Класс проверяемого запроса
+ * @return null если ошибок нет
+ */
+ public RequestInfoUpdate validate(BaseRequest userRequest,
+ Function validatorBuilder,
+ IMessageResolver messageResolver) {
+ if (validatorBuilder != null) {
+ R req = userRequest.getRequestPayload();
+ IValidator validator = validatorBuilder.apply(req);
+ Optional validationError = validator.tillFirstError();
+ if (validationError.isPresent()) {
+ String errorMsg = messageResolver.resolve(validationError.get());
+ log.error("validation error for {} error={}, id={}: {}", req.getClass().getSimpleName(), validationError.get().getSubject(), userRequest.getId(), errorMsg);
+ return new RequestInfoUpdate()
+ .setId(userRequest.getId())
+ .setStatus(Status.Error)
+ .setMessage(errorMsg);
+ }
+ }
+ return null;
+ }
+
@Override
public void close() {
log.debug("Closing queue consumer {}", getClass().getSimpleName());
diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/RequestInfoUpdate.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/RequestInfoUpdate.java
index 24e8a1562..fd0610311 100644
--- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/RequestInfoUpdate.java
+++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/RequestInfoUpdate.java
@@ -39,4 +39,13 @@ public class RequestInfoUpdate {
this.message = message;
return this;
}
+
+ @Override
+ public String toString() {
+ return "RequestInfoUpdate{" +
+ "id=" + id +
+ ", status=" + status +
+ ", message='" + message + '\'' +
+ '}';
+ }
}