Merge branch 'CLS_51_57' into dev

This commit is contained in:
akulikov 2023-01-19 12:48:21 +03:00
commit 5685f95ce2
36 changed files with 1723 additions and 156 deletions

View file

@ -71,6 +71,10 @@
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-imdg-api-hazelcast-impl</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-enum</artifactId>
</dependency>
<!-- TEST -->
<dependency>

View file

@ -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);
}

View file

@ -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

View file

@ -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<Long, Planner> plannerMap;
private final IMap<Long, ClearingCalendar> clearingCalendarMap;
private final IMap<Long, PlannerTemplate> plannerTemplateMap;
private final IMap<Long, PlannerAllToday> 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<PlannerAllToday> 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<PlannerAllToday> getPlannersAllTodayToDate(LocalDate currentDate) {
boolean weekend = Arrays.asList(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY).contains(currentDate.getDayOfWeek());
List<PlannerAllToday> res = new ArrayList<>();
if (clearingCalendarMap == null || clearingCalendarMap.isEmpty()) {
if (!weekend) {
for (PlannerTemplate plannerTemplate : plannerTemplateMap.values()) {
res.add(createPlannerAllTodayFromPlannerTemplate(plannerTemplate));
}
}
} else {
Optional<ClearingCalendar> 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;
}
}

View file

@ -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<Long, Planner> plannerMap = hazelcastInstance.getMap(Map_Planner);
IMap<Long, ClearingCalendar> clearingCalendarMap = hazelcastInstance.getMap(Map_ClearingCalendar);
IMap<Long, PlannerTemplate> plannerTemplateMap = hazelcastInstance.getMap(Map_PlannerTemplate);
IMap<Long, PlannerAllToday> plannerAllTodayMap = hazelcastInstance.getMap(Map_PlannerAllToday);
LocalDate currentDate = LocalDate.now();
List<PlannerAllToday> 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<PlannerAllToday> getPlannersOnMonday2Friday(LocalDate currentDate, IMap<Long, ClearingCalendar> clearingCalendarMap, IMap<Long, PlannerTemplate> plannerTemplateMap) {
List<PlannerAllToday> res = new ArrayList<>();
if (clearingCalendarMap == null || clearingCalendarMap.isEmpty()) {
for (PlannerTemplate plannerTemplate : plannerTemplateMap.values()) {
res.add(createPlannerAllTodayFromPlannerTemplate(plannerTemplate));
}
} else {
Optional<ClearingCalendar> 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<PlannerAllToday> getPlannersOnSunday2Saturday(LocalDate currentDate, IMap<Long, ClearingCalendar> clearingCalendarMap, IMap<Long, PlannerTemplate> plannerTemplateMap) {
List<PlannerAllToday> res = new ArrayList<>();
Optional<ClearingCalendar> 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;
}
}

View file

@ -28,6 +28,10 @@
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-imdg-api-hazelcast-impl</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>dictionary</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>

View file

@ -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();
}
}

View file

@ -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<ClearingCalendarNewRequest, IValidator> clearingCalendarNewRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return clearingCalendarNewRequest -> {
ImdgValidationContext<ClearingCalendarNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(clearingCalendarNewRequest);
Consumer<String> 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<ClearingCalendarUpdateRequest, IValidator> clearingCalendarUpdateRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return clearingCalendarUpdateRequest -> {
ImdgValidationContext<ClearingCalendarUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(clearingCalendarUpdateRequest);
Consumer<String> 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<CommonDeleteRequest, IValidator> clearingCalendarDeleteRequestValidator() {
return clearingCalendarDeleteRequest -> {
ImdgValidationContext<CommonDeleteRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(clearingCalendarDeleteRequest);
return new ValidatorImpl<>(context,
IdPresentRule.instance("id",
CommonDeleteRequest::getId,
IMDGDistributedNames.Map_ClearingCalendar,
ClearingCalendar.class,
ValidationError.RecordNotFound)
);
};
}
}

View file

@ -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<PlannerTemplateNewRequest, IValidator> plannerNewRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return plannerNewRequest -> {
ImdgValidationContext<PlannerTemplateNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerNewRequest);
Consumer<String> 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<PlannerTemplateUpdateRequest, IValidator> plannerUpdateRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return plannerUpdateRequest -> {
ImdgValidationContext<PlannerTemplateUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerUpdateRequest);
Consumer<String> 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<CommonDeleteRequest, IValidator> plannerTemplateDeleteRequestValidator() {
return plannerTemplateDeleteRequest -> {
ImdgValidationContext<CommonDeleteRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerTemplateDeleteRequest);
return new ValidatorImpl<>(context,
IdPresentRule.instance("id",
CommonDeleteRequest::getId,
IMDGDistributedNames.Map_PlannerTemplate,
PlannerTemplate.class,
ValidationError.RecordNotFound)
);
};
}
}

View file

@ -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<PlannerNewRequest, IValidator> plannerNewRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return plannerNewRequest -> {
ImdgValidationContext<PlannerNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerNewRequest);
Consumer<String> 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<PlannerUpdateRequest, IValidator> plannerUpdateRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return plannerUpdateRequest -> {
ImdgValidationContext<PlannerUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerUpdateRequest);
Consumer<String> 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<CommonDeleteRequest, IValidator> plannerDeleteRequestValidator() {
return plannerDeleteRequest -> {
ImdgValidationContext<CommonDeleteRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerDeleteRequest);
return new ValidatorImpl<>(context,
IdPresentRule.instance("id",
CommonDeleteRequest::getId,
IMDGDistributedNames.Map_Planner,
Planner.class,
ValidationError.RecordNotFound)
);
};
}
}

View file

@ -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<String, Imdg<? extends SpcexObjectBase>> imdgForValidation(ImdgProvider imdgProvider) {
final Map<String, Imdg<? extends SpcexObjectBase>> imdg = new HashMap<>();
BiConsumer<String, Class<? extends SpcexObjectBase>> 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;
}
}

View file

@ -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;
}
}

View file

@ -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<ClearingCalendar> clearingCalendarMap;
private final IMessageResolver messageResolver;
private final Function<CommonDeleteRequest, IValidator> clearingCalendarDeleteRequestValidation;
private final Function<ClearingCalendarNewRequest, IValidator> clearingCalendarNewRequestValidation;
private final Function<ClearingCalendarUpdateRequest, IValidator> clearingCalendarUpdateRequestValidation;
@Autowired
public ClearingCalendarService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider) {
ImdgProvider imdgProvider,
IMessageResolver messageResolver,
@Qualifier("clearingCalendarDeleteRequestValidator") Function<CommonDeleteRequest, IValidator> clearingCalendarDeleteRequestValidator,
@Qualifier("clearingCalendarNewRequestValidator") Function<ClearingCalendarNewRequest, IValidator> clearingCalendarNewRequestValidator,
@Qualifier("clearingCalendarUpdateRequestValidator") Function<ClearingCalendarUpdateRequest, IValidator> 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<ClearingCalendarNewRequest> userRequest) {
private RequestInfoUpdate newClearingCalendar(BaseRequest<ClearingCalendarNewRequest> 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<ClearingCalendarUpdateRequest> userRequest) {
private RequestInfoUpdate updateClearingCalendar(BaseRequest<ClearingCalendarUpdateRequest> 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<CommonDeleteRequest> userRequest) {
private RequestInfoUpdate deleteClearingCalendar(BaseRequest<CommonDeleteRequest> 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;
}
}

View file

@ -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<Planner> plannerMap;
private final IMessageResolver messageResolver;
private final Function<CommonDeleteRequest, IValidator> plannerDeleteRequestValidation;
private final Function<PlannerNewRequest, IValidator> plannerNewRequestValidation;
private final Function<PlannerUpdateRequest, IValidator> plannerUpdateRequestValidation;
@Autowired
public PlannerService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider) {
public PlannerService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
IMessageResolver messageResolver,
@Qualifier("plannerDeleteRequestValidator") Function<CommonDeleteRequest, IValidator> plannerDeleteRequestValidator,
@Qualifier("plannerNewRequestValidator") Function<PlannerNewRequest, IValidator> plannerNewRequestValidator,
@Qualifier("plannerUpdateRequestValidator") Function<PlannerUpdateRequest, IValidator> 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<PlannerNewRequest> userRequest) {
private RequestInfoUpdate newScheduler(BaseRequest<PlannerNewRequest> 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<PlannerUpdateRequest> userRequest) {
private RequestInfoUpdate updateScheduler(BaseRequest<PlannerUpdateRequest> 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<CommonDeleteRequest> userRequest) {
private RequestInfoUpdate deleteScheduler(BaseRequest<CommonDeleteRequest> 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;
}
}

View file

@ -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<PlannerTemplate> plannerTemplateMap;
private final IMessageResolver messageResolver;
private final Function<CommonDeleteRequest, IValidator> plannerTemplateDeleteRequestValidation;
private final Function<PlannerTemplateNewRequest, IValidator> plannerTemplateNewRequestValidation;
private final Function<PlannerTemplateUpdateRequest, IValidator> plannerTemplateUpdateRequestValidation;
@Autowired
public PlannerTemplateService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider) {
ImdgProvider imdgProvider,
IMessageResolver messageResolver,
@Qualifier("plannerTemplateDeleteRequestValidator") Function<CommonDeleteRequest, IValidator> plannerTemplateDeleteRequestValidator,
@Qualifier("plannerTemplateNewRequestValidator") Function<PlannerTemplateNewRequest, IValidator> plannerTemplateNewRequestValidator,
@Qualifier("plannerTemplateUpdateRequestValidator") Function<PlannerTemplateUpdateRequest, IValidator> 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<PlannerTemplateNewRequest> userRequest) {
private RequestInfoUpdate newTimetable(BaseRequest<PlannerTemplateNewRequest> 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<PlannerTemplateUpdateRequest> userRequest) {
private RequestInfoUpdate updateTimetable(BaseRequest<PlannerTemplateUpdateRequest> 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<CommonDeleteRequest> userRequest) {
private RequestInfoUpdate deleteTimetable(BaseRequest<CommonDeleteRequest> 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;
}
}

View file

@ -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<Long, PlannerAllToday>,
public void afterPropertiesSet() {
this.launcherMap = imdgProvider.getImdg(Map_Launcher, Launcher.class);
this.plannerAllTodayMap = imdgProvider.getImdg(Map_PlannerAllToday, PlannerAllToday.class);
if (plannerAllTodayMap instanceof ImdgHazelcast<PlannerAllToday> plannerAllTodayImdgHazelcast) {
plannerAllTodayImdgHazelcast.getMap().addEntryListener(this, true);
}
scheduledJobs = new ConcurrentHashMap<>();
updateScheduler();
}

View file

@ -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 <R> Класс проверяемого объекта
*/
public record DateNotBeforeRule<R>(String fieldName, Function<R, LocalDate> getter, boolean required) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля класса, используется для передачи ошибки
* @param getter Метод получения проверяемой даты
* @param required Флаг обязательности поля
* @param <R> Класс проверяемого объекта
*/
public static <R> DateNotBeforeRule<R> instance(String fieldName, Function<R, LocalDate> getter, boolean required) {
return new DateNotBeforeRule<>(fieldName, getter, required);
}
/**
* @param fieldName Название поля класса, используется для передачи ошибки
* @param getter Метод получения проверяемой даты
* @param <R> Класс проверяемого объекта
*/
public static <R> DateNotBeforeRule<R> instance(String fieldName, Function<R, LocalDate> getter) {
return new DateNotBeforeRule<>(fieldName, getter, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> 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();
}
}

View file

@ -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 <R> Класс проверяемого объекта
* @param <D> Класс словаря
*/
public record DictionaryPresentRule<R, D extends AbstractDictionary>(String fieldName,
Function<R, String> getter,
String dictionaryName,
Class<D> dictionaryClass,
boolean required) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля
* @param getter Метод получения проверяемого значения
* @param dictionaryName Название словаря (см. IMDGDistributedNames)
* @param dictionaryClass Класс словаря (классы *Dictionary.class)
* @param required Флаг обязательности
* @param <R> Класс проверяемого объекта
* @param <D> Класс словаря
*/
public static <R, D extends AbstractDictionary> DictionaryPresentRule<R, D> instance(String fieldName,
Function<R, String> getter,
String dictionaryName,
Class<D> dictionaryClass,
boolean required) {
return new DictionaryPresentRule<>(fieldName, getter, dictionaryName, dictionaryClass, required);
}
/**
* @param fieldName Название поля
* @param getter Метод получения проверяемого значения
* @param dictionaryName Название словаря (см. IMDGDistributedNames)
* @param dictionaryClass Класс словаря (классы *Dictionary.class)
* @param <R> Класс проверяемого объекта
* @param <D> Класс словаря
*/
public static <R, D extends AbstractDictionary> DictionaryPresentRule<R, D> instance(String fieldName,
Function<R, String> getter,
String dictionaryName,
Class<D> dictionaryClass) {
return new DictionaryPresentRule<>(fieldName, getter, dictionaryName, dictionaryClass, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
String enumCode = getter.apply(validatedObject);
if (enumCode == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : empty();
Imdg<D> dictImdg = context.obtainMap(
dictionaryName,
dictionaryClass
);
ImdgPredicateBuilder imdgPredicateBuilder = dictImdg.predicateBuilder();
ImdgPredicate imdgPredicate = imdgPredicateBuilder.equals("code", enumCode);
Collection<D> 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();
}
}

View file

@ -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 <R> Класс проверяемого объекта
* @param <E> Enum
*/
public record EnumPresentRule<R, E extends IEnumKey>(String fieldName,
Function<R, String> getter,
E[] enumValues,
boolean required) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля
* @param getter Метод получения проверяемого значения
* @param enumValues Значения из проверяемого множества (Enum.values())
* @param required Флаг обязательности
* @param <R> Класс проверяемого объекта
* @param <E> Enum
*/
public static <R, E extends IEnumKey> EnumPresentRule<R, E> instance(String fieldName,
Function<R, String> getter,
E[] enumValues,
boolean required) {
return new EnumPresentRule<>(fieldName, getter, enumValues, required);
}
/**
* @param fieldName Название поля
* @param getter Метод получения проверяемого значения
* @param enumValues Значения из проверяемого множества (Enum.values())
* @param <R> Класс проверяемого объекта
* @param <E> Enum
*/
public static <R, E extends IEnumKey> EnumPresentRule<R, E> instance(String fieldName,
Function<R, String> getter,
E[] enumValues) {
return new EnumPresentRule<>(fieldName, getter, enumValues, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> 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);
}
}

View file

@ -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 <R> Класс проверяемого объекта
* @param <V> Класс проверяемого значения
*/
public record FieldRequiredRule<R, V>(String fieldName, Function<R, V> getter) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля
* @param getter Метод получения значения
* @param <R> Класс проверяемого объекта
* @param <V> Класс проверяемого значения
*/
public static <R, V> FieldRequiredRule<R, V> instance(String fieldName, Function<R, V> getter) {
return new FieldRequiredRule<>(fieldName, getter);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
V value = getter.apply(validatedObject);
if (value == null) return of(ValidationError.EmptyRequiredValue, fieldName);
return empty();
}
}

View file

@ -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 <R> Класс проверяемого объекта
* @param <V> Класс связанного объекта
*/
public record IdPresentRule<R, V extends SpcexObjectBase>(
String fieldName,
Function<R, Long> idGetter,
Function<V, ValidationError>[] additionalChecks,
String mapName,
Class<V> mapClass,
ValidationError idNotPresentError,
boolean required
) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля, содержащего Id
* @param idGetter Метод получения Id
* @param mapName Название мапы связанного объекта (см. IMDGDistributedNames)
* @param mapClass Класс связанного объекта
* @param idNotPresentError Ошибка, которая будет возвращена, если Id не найден
* @param required Флаг обязательности
* @param additionalChecks Дополнительные проверки, которые можно провести со связанным объектом
* @param <R> Класс проверяемого объекта
* @param <V> Класс связанного объекта
*/
@SafeVarargs
public static <R, V extends SpcexObjectBase> IdPresentRule<R, V> instance(String fieldName,
Function<R, Long> idGetter,
String mapName,
Class<V> mapClass,
ValidationError idNotPresentError,
boolean required,
Function<V, ValidationError> ... additionalChecks) {
return new IdPresentRule<>(fieldName, idGetter, additionalChecks, mapName, mapClass, idNotPresentError, required);
}
@SafeVarargs
public static <R, V extends SpcexObjectBase> IdPresentRule<R, V> instance(String fieldName,
Function<R, Long> idGetter,
String mapName,
Class<V> mapClass,
ValidationError idNotPresentError,
Function<V, ValidationError> ... additionalChecks) {
return new IdPresentRule<>(fieldName, idGetter, additionalChecks, mapName, mapClass, idNotPresentError, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
Long id = idGetter.apply(validatedObject);
if (id == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : empty();
Imdg<V> imdg = context.obtainMap(mapName, mapClass);
V fromMap = imdg.getSingleObjectByID(id);
if (fromMap == null) {
return of(idNotPresentError, fieldName);
}
for (Function<V, ValidationError> additionalCheck : additionalChecks) {
ValidationError validationError = additionalCheck.apply(fromMap);
if (validationError != null)
return of(validationError, fieldName);
}
return empty();
}
}

View file

@ -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 <R> Класс проверяемого объекта
*/
public record TimeNotBeforeRule<R>(String fieldName, Function<R, LocalTime> getter, boolean required) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля класса, используется для передачи ошибки
* @param getter Метод получения проверяемого времени
* @param required Флаг обязательности поля
* @param <R> Класс проверяемого объекта
*/
public static <R> TimeNotBeforeRule<R> instance(String fieldName, Function<R, LocalTime> getter, boolean required) {
return new TimeNotBeforeRule<>(fieldName, getter, required);
}
/**
* @param fieldName Название поля класса, используется для передачи ошибки
* @param getter Метод получения проверяемого времени
* @param <R> Класс проверяемого объекта
*/
public static <R> TimeNotBeforeRule<R> instance(String fieldName, Function<R, LocalTime> getter) {
return new TimeNotBeforeRule<>(fieldName, getter, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> 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();
}
}

View file

@ -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();
}
}

View file

@ -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<String, Object> mockConsumer;
private MockProducer<String, Object> mockProducer;
@Autowired
private IMessageResolver messageResolver;
@Autowired
private Function<CommonDeleteRequest, IValidator> clearingCalendarDeleteRequestValidation;
@Autowired
private Function<ClearingCalendarNewRequest, IValidator> clearingCalendarNewRequestValidation;
@Autowired
private Function<ClearingCalendarUpdateRequest, IValidator> 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<Company> 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<DayStatusDictionary> 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<ClearingCalendarNewRequest> baseRequest = new BaseRequest<>();
baseRequest.setId(1L);
baseRequest.setActionType(ActionType.NEW);
ClearingCalendarNewRequest newRequest = new ClearingCalendarNewRequest();
baseRequest.setRequestPayload(newRequest);
IMap<Long, ClearingCalendar> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_ClearingCalendar);
//KAFKA
HashMap<TopicPartition, Long> startOffsetsUpdating = new HashMap<>();

View file

@ -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<String, Object> mockConsumer;
private MockProducer<String, Object> mockProducer;
@Autowired
private IMessageResolver messageResolver;
@Autowired
private Function<CommonDeleteRequest, IValidator> plannerTemplateDeleteRequestValidation;
@Autowired
private Function<PlannerTemplateNewRequest, IValidator> plannerTemplateNewRequestValidation;
@Autowired
private Function<PlannerTemplateUpdateRequest, IValidator> 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<TaskDictionary> 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<TaskStatusDictionary> 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<Company> 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<Security> 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());

View file

@ -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<PlannerNewRequest, IValidator> validatorBuilder = plannerNewRequest -> {
ImdgValidationContext<PlannerNewRequest> 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<EnumMessage> 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());
}
}

View file

@ -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 <D extends AbstractDictionary, R, E extends IEnumKey> void testDictionary(String dictionaryKey,
Class<D> dictionaryClass,
Class<R> recordClass,
String fieldName,
E[] enumValues,
Function<R, String> getter,
BiConsumer<R, String> setter) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Imdg<D> 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<R, IValidator> validatorBuilder = request -> {
ImdgValidationContext<R> 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<EnumMessage> 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());
}
}

View file

@ -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 <D extends AbstractDictionary, R, E extends IEnumKey> void testEnum(Class<R> recordClass,
String fieldName,
E[] enumValues,
Function<R, String> getter,
BiConsumer<R, String> setter) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
BiFunction<R, Boolean, IValidator> validatorBuilder = (request, required) -> {
ImdgValidationContext<R> 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<EnumMessage> 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());
}
}

View file

@ -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<PlannerNewRequest, IValidator> validatorBuilder = plannerNewRequest -> {
ImdgValidationContext<PlannerNewRequest> 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<EnumMessage> enumMessages = validator.validateAll();
assertTrue(enumMessages.isEmpty());
plannerNewRequest.setTask(null);
validator = validatorBuilder.apply(plannerNewRequest);
enumMessages = validator.validateAll();
assertEquals(1, enumMessages.size());
}
}

View file

@ -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 <R, D extends SpcexObjectBase> void testIdPresentRule(String fieldName,
Function<R, Long> getter,
BiConsumer<R, Long> setter,
String mapName,
Class<D> mapClass,
Class<R> objClass,
ValidationError notFoundExpectedError,
ValidationError notActiveExpectedError) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Imdg<D> imdg = hazelcastServiceTest.getImdg(mapName, mapClass);
Function<R, IValidator> validatorBuilder = request -> {
ImdgValidationContext<R> 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<EnumMessage> 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());
}
}

View file

@ -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<PlannerNewRequest, IValidator> validatorBuilder = plannerNewRequest -> {
ImdgValidationContext<PlannerNewRequest> 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<EnumMessage> 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());
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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 <R> Класс проверяемого запроса
* @return null если ошибок нет
*/
public <R> RequestInfoUpdate validate(BaseRequest<R> userRequest,
Function<R, IValidator> validatorBuilder,
IMessageResolver messageResolver) {
if (validatorBuilder != null) {
R req = userRequest.getRequestPayload();
IValidator validator = validatorBuilder.apply(req);
Optional<EnumMessage> 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());

View file

@ -39,4 +39,13 @@ public class RequestInfoUpdate {
this.message = message;
return this;
}
@Override
public String toString() {
return "RequestInfoUpdate{" +
"id=" + id +
", status=" + status +
", message='" + message + '\'' +
'}';
}
}