Поправил существующий серис, валидаторы, тесты для plannerTemplate .
This commit is contained in:
psemenkov 2023-04-20 13:53:47 +03:00
parent eae197cef9
commit 6b2acb66e7
4 changed files with 274 additions and 13 deletions

View file

@ -21,6 +21,7 @@ import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
import java.time.LocalDate;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
@ -43,10 +44,11 @@ public class PlannerValidationConfig {
PlannerNewRequest::getTask,
IMDGDistributedNames.Map_TaskDictionary,
TaskDictionary.class),
TimeNotBeforeRule.instance("taskTime",
PlannerNewRequest::getTaskTime),
DateNotBeforeRule.instance("clearingDate",
PlannerNewRequest::getClearingDate),
TimeNotBeforeRule.instance("taskTime",
PlannerNewRequest::getTaskTime,
LocalDate.now().equals(plannerNewRequest.getClearingDate())),
EnumPresentRule.instance("market",
PlannerNewRequest::getMarket,
Market.values(),
@ -78,6 +80,7 @@ public class PlannerValidationConfig {
context.setValidatedObject(plannerUpdateRequest);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_TaskDictionary);
addImdg.accept(IMDGDistributedNames.Map_Planner);
addImdg.accept(IMDGDistributedNames.Map_TaskStatusDictionary);
addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_Security);
@ -94,7 +97,8 @@ public class PlannerValidationConfig {
false),
TimeNotBeforeRule.instance("taskTime",
PlannerUpdateRequest::getTaskTime,
false),
false,
LocalDate.now().equals(plannerUpdateRequest.getClearingDate())),
DateNotBeforeRule.instance("clearingDate",
PlannerUpdateRequest::getClearingDate,
false),
@ -126,10 +130,12 @@ public class PlannerValidationConfig {
}
@Bean("plannerDeleteRequestValidator")
public Function<CommonDeleteRequest, IValidator> plannerDeleteRequestValidator() {
public Function<CommonDeleteRequest, IValidator> plannerDeleteRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return plannerDeleteRequest -> {
ImdgValidationContext<CommonDeleteRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerDeleteRequest);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_Planner);
return new ValidatorImpl<>(context,
IdPresentRule.instance("id",
CommonDeleteRequest::getId,

View file

@ -1,16 +1,26 @@
package ru.spcex.clearing.scheduler.config.validation;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.scheduler.ClearingCalendar;
import ru.clearing.classes.statics.data.scheduler.Planner;
import ru.clearing.classes.statics.data.scheduler.PlannerTemplate;
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.clearing.scheduler.error.ValidationError;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.UserRole;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import java.util.HashMap;
import java.util.Map;
@ -24,6 +34,9 @@ public class ValidationConfig {
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_PlannerTemplate, PlannerTemplate.class);
addImdg.accept(IMDGDistributedNames.Map_Planner, Planner.class);
addImdg.accept(IMDGDistributedNames.Map_ClearingCalendar, ClearingCalendar.class);
addImdg.accept(IMDGDistributedNames.Map_TaskStatusDictionary, TaskStatusDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_Company, Company.class);
addImdg.accept(IMDGDistributedNames.Map_Security, Security.class);
@ -31,4 +44,15 @@ public class ValidationConfig {
return imdg;
}
@Bean("validationHelper")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public ValidationHelper validationHelper(IMessageResolver messageResolver) {
return new ValidationHelper(messageResolver);
}
@Bean("userRoleVerificationBean")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public UserRoleVerification userRoleVerification(ImdgProvider imdgProvider, IMessageResolver messageResolver) {
return new UserRoleVerification(imdgProvider, messageResolver, UserRole.Admin, ValidationError.UserVerifyDenial);
}
}

View file

@ -8,6 +8,8 @@ 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.clearing.classes.statics.data.scheduler.PlannerAllToday;
import ru.clearing.classes.statics.data.scheduler.PlannerTemplate;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
@ -17,19 +19,32 @@ import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerTemplateN
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.clearing.scheduler.PlannerAllTodayBuilder;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.platform.enumeration.DayStatus;
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.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import static ru.spcex.clearing.scheduler.ISchedulerChecker.isValidWorkday;
@Service
public class PlannerTemplateService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg<PlannerTemplate> plannerTemplateMap;
private final Imdg<PlannerAllToday> plannerAllTodayMap;
private final Imdg<ClearingCalendar> clearingCalendarMap;
private final IMessageResolver messageResolver;
private final UserRoleVerification userRoleVerification;
private final Function<CommonDeleteRequest, IValidator> plannerTemplateDeleteRequestValidation;
private final Function<PlannerTemplateNewRequest, IValidator> plannerTemplateNewRequestValidation;
private final Function<PlannerTemplateUpdateRequest, IValidator> plannerTemplateUpdateRequestValidation;
@ -38,11 +53,15 @@ public class PlannerTemplateService extends QueueConsumer implements Initializin
public PlannerTemplateService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
IMessageResolver messageResolver,
@Qualifier("userRoleVerificationBean") UserRoleVerification userRoleVerification,
@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.plannerAllTodayMap = imdgProvider.getImdg(IMDGDistributedNames.Map_PlannerAllToday, PlannerAllToday.class);
this.clearingCalendarMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingCalendar, ClearingCalendar.class);
this.userRoleVerification = userRoleVerification;
this.plannerTemplateDeleteRequestValidation = plannerTemplateDeleteRequestValidator;
this.plannerTemplateNewRequestValidation = plannerTemplateNewRequestValidator;
this.plannerTemplateUpdateRequestValidation = plannerTemplateUpdateRequestValidator;
@ -52,40 +71,51 @@ public class PlannerTemplateService extends QueueConsumer implements Initializin
@Override
public void afterPropertiesSet() {
callback(PlannerTemplateNewRequest.class)
.setFunction(this::newTimetable)
.setFunction(this::newPlannerTemplate)
.forDestination(Consts.DESTINATION_PLANNER_TEMPLATE_NEW, callbacks::put);
callback(PlannerTemplateUpdateRequest.class)
.setFunction(this::updateTimetable)
.setFunction(this::updatePlannerTemplate)
.forDestination(Consts.DESTINATION_PLANNER_TEMPLATE_UPDATE, callbacks::put);
callback(CommonDeleteRequest.class)
.setFunction(this::deleteTimetable)
.setFunction(this::deletePlannerTemplate)
.forDestination(Consts.DESTINATION_PLANNER_TEMPLATE_DELETE, callbacks::put);
init();
}
private RequestInfoUpdate newTimetable(BaseRequest<PlannerTemplateNewRequest> userRequest) {
private RequestInfoUpdate newPlannerTemplate(BaseRequest<PlannerTemplateNewRequest> userRequest) {
PlannerTemplateNewRequest req = userRequest.getRequestPayload();
log.debug("PlannerTemplateNewRequest received");
RequestInfoUpdate requestInfoUpdate = validate(userRequest, plannerTemplateNewRequestValidation, messageResolver);
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
requestInfoUpdate = validate(userRequest, plannerTemplateNewRequestValidation, messageResolver);
if (requestInfoUpdate != null) return requestInfoUpdate;
PlannerTemplate plannerTemplate = new PlannerTemplate();
Instant created = Instant.now();
plannerTemplate.setCreated(created);
plannerTemplate.setUpdated(created);
plannerTemplate.setTask(req.getTask());
plannerTemplate.setTaskTime(req.getTaskTime());
plannerTemplate.setTaskStatus(req.getTaskStatus());
plannerTemplate.setCompanyId(req.getCompanyId());
plannerTemplate.setSecurityId(req.getSecurityId());
plannerTemplateMap.insert(plannerTemplate);
if (todayWorkDay()) plannerAllTodayMap.insert(PlannerAllTodayBuilder.builder().append(plannerTemplate).build());
log.debug("successfully processed, new id {}", plannerTemplate.getId());
return null;
}
private RequestInfoUpdate updateTimetable(BaseRequest<PlannerTemplateUpdateRequest> userRequest) {
private RequestInfoUpdate updatePlannerTemplate(BaseRequest<PlannerTemplateUpdateRequest> userRequest) {
PlannerTemplateUpdateRequest req = userRequest.getRequestPayload();
log.debug("PlannerTemplateUpdateRequest received");
RequestInfoUpdate requestInfoUpdate = validate(userRequest, plannerTemplateUpdateRequestValidation, messageResolver);
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
requestInfoUpdate = validate(userRequest, plannerTemplateUpdateRequestValidation, messageResolver);
if (requestInfoUpdate != null) return requestInfoUpdate;
PlannerTemplate plannerTemplate = plannerTemplateMap.getSingleObjectByID(req.getId());
Instant updated = Instant.now();
plannerTemplate.setUpdated(updated);
@ -95,17 +125,47 @@ public class PlannerTemplateService extends QueueConsumer implements Initializin
plannerTemplate.setCompanyId(req.getCompanyId());
plannerTemplate.setSecurityId(req.getSecurityId());
plannerTemplateMap.update(plannerTemplate);
if (todayWorkDay()) {
PlannerAllToday planner = PlannerAllTodayBuilder.builder().append(plannerTemplate).build();
PlannerAllToday plannerAllToday = plannerAllTodayMap.getSingleObjectBySQL(String.format("parentId = %s", plannerTemplate.getId()));
if (plannerAllToday != null) planner.setId(plannerAllToday.getId());
plannerAllTodayMap.insert(planner);
}
log.debug("successfully processed, new id {}", plannerTemplate.getId());
return null;
}
private RequestInfoUpdate deleteTimetable(BaseRequest<CommonDeleteRequest> userRequest) {
private RequestInfoUpdate deletePlannerTemplate(BaseRequest<CommonDeleteRequest> userRequest) {
CommonDeleteRequest req = userRequest.getRequestPayload();
log.debug("CommonDeleteRequest received id = {}", req.getId());
RequestInfoUpdate requestInfoUpdate = validate(userRequest, plannerTemplateDeleteRequestValidation, messageResolver);
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
requestInfoUpdate = validate(userRequest, plannerTemplateDeleteRequestValidation, messageResolver);
if (requestInfoUpdate != null) return requestInfoUpdate;
PlannerTemplate plannerTemplate = plannerTemplateMap.getSingleObjectByID(req.getId());
if (todayWorkDay()) {
PlannerAllToday plannerAllToday = plannerAllTodayMap.getSingleObjectBySQL(String.format("parentId = %s", plannerTemplate.getId()));
if (plannerAllToday != null) plannerAllTodayMap.delete(plannerAllToday);
}
plannerTemplateMap.delete(plannerTemplate);
return null;
}
private boolean todayWorkDay() {
LocalDate currentDate = LocalDate.now();
boolean isWeekend = Arrays.asList(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY).contains(currentDate.getDayOfWeek());
//проверим есть ли другие записи clearingCalendar с таким же clearingDate, если они актуальные ничего не удаляем
Collection<ClearingCalendar> clearingCalendars = clearingCalendarMap.getCollectionObjectsByFieldValues(Map.of("dayStatus", DayStatus.Workday.getKey(),
"clearingDate", currentDate));
if (clearingCalendars != null && !clearingCalendars.isEmpty()) {
for (ClearingCalendar calendar : clearingCalendars) {
if (isValidWorkday(calendar, isWeekend)) return true;
}
}
return false;
}
}

View file

@ -0,0 +1,171 @@
package ru.specx.clearing.scheduler.service;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import ru.clearing.classes.statics.data.scheduler.Planner;
import ru.clearing.classes.statics.data.scheduler.PlannerAllToday;
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.PlannerNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerUpdateRequest;
import ru.spcex.clearing.scheduler.PlannerAllTodayBuilder;
import ru.spcex.clearing.scheduler.service.PlannerService;
import ru.spcex.clearing.test.MatcherFactory;
import ru.spcex.platform.enumeration.Status;
import ru.specx.clearing.scheduler.AbstractServiceTest;
import javax.annotation.PostConstruct;
import static org.junit.jupiter.api.Assertions.assertNull;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
class PlannerServiceTest extends AbstractServiceTest {
protected static final MatcherFactory.Matcher<Planner> PLANNER_MATCHER = usingIgnoringFieldsComparator("created", "updated");
private static final int PARTITION = 0;
private static final String TOPIC_PLANNER_NEW = Consts.DESTINATION_PLANNER_NEW;
private static final String TOPIC_PLANNER_UPDATE = Consts.DESTINATION_PLANNER_UPDATE;
private static final String TOPIC_PLANNER_DELETE = Consts.DESTINATION_PLANNER_DELETE;
@Autowired
private PlannerService plannerService;
@PostConstruct
public void init() {
super.init();
}
@BeforeEach
public void prepare(){
clearAllInImdg(plannerAllTodayImdg);
}
/**
* {@link PlannerService#newPlanner(BaseRequest)}(BaseRequest)}<br>
* Тест проверяет создание сущности {@link ru.clearing.classes.statics.data.scheduler.Planner} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link PlannerNewRequest}:<br>
*/
@Test
public void newPlanner() {
//ARRANGE
Long ID = currentID.getAndIncrement();
Planner planner = getPlanner(newCompanyId);
PlannerNewRequest plannerNewRequest = new PlannerNewRequest();
plannerNewRequest.setTask(planner.getTask());
plannerNewRequest.setTaskTime(planner.getTaskTime());
plannerNewRequest.setTaskStatus(planner.getTaskStatus());
plannerNewRequest.setClearingDate(planner.getClearingDate());
plannerNewRequest.setMarket(planner.getMarket());
plannerNewRequest.setCompanyId(planner.getCompanyId());
plannerNewRequest.setSecurityId(planner.getSecurityId());
//ACT
String jsonString = getJsonStringForUpdate(plannerNewRequest, ID);
addRecordToKafka((MockConsumer) plannerService.getConsumer(), TOPIC_PLANNER_NEW, PARTITION, 0, jsonString);
//ASSERT
waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord);
Planner plannerReq = plannerImdg.getSingleObjectBySQL(String.format("companyId = %s", planner.getCompanyId()));
planner.setId(plannerReq.getId());
PLANNER_MATCHER.assertMatch(plannerReq, planner);
checkPlannerAllTodayByPlanner(planner);
}
/**
* {@link PlannerService#updatePlanner(BaseRequest)}(BaseRequest)}<br>
* Тест проверяет создание сущности {@link ru.clearing.classes.statics.data.scheduler.Planner} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link PlannerUpdateRequest}:<br>
*/
@Test
public void updateScheduler() {
//ARRANGE
Planner planner = getPlanner(newCompanyId);
plannerImdg.insert(planner);
planner.setCompanyId(updateCompanyId);
PlannerUpdateRequest plannerUpdateRequest = new PlannerUpdateRequest();
plannerUpdateRequest.setId(planner.getId());
plannerUpdateRequest.setTask(planner.getTask());
plannerUpdateRequest.setTaskTime(planner.getTaskTime());
plannerUpdateRequest.setTaskStatus(planner.getTaskStatus());
plannerUpdateRequest.setClearingDate(planner.getClearingDate());
plannerUpdateRequest.setMarket(planner.getMarket());
plannerUpdateRequest.setCompanyId(planner.getCompanyId());
plannerUpdateRequest.setSecurityId(planner.getSecurityId());
//ACT
String jsonString = getJsonStringForUpdate(plannerUpdateRequest, planner.getId());
addRecordToKafka((MockConsumer) plannerService.getConsumer(), TOPIC_PLANNER_UPDATE, PARTITION, 0, jsonString);
//ASSERT
waitingWhenAddedRecordAndCheckIt(planner.getId(), mockProducer, producerRecord);
Planner plannerReq = plannerImdg.getSingleObjectBySQL(String.format("companyId = %s", planner.getCompanyId()));
planner.setId(plannerReq.getId());
PLANNER_MATCHER.assertMatch(plannerReq, planner);
checkPlannerAllTodayByPlanner(planner);
}
/**
* {@link PlannerService#deletePlanner(BaseRequest)}(BaseRequest)}<br>
* Тест проверяет удаление сущности {@link ru.clearing.classes.statics.data.scheduler.Planner} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link CommonDeleteRequest}:<br>
*/
@Test
public void deletePlanner(){
//ARRANGE
clearAllInImdg(plannerImdg);
Planner planner = getPlanner(deleteCompanyId);
plannerImdg.insert(planner);
long plannerId = planner.getId();
plannerAllTodayImdg.insert(PlannerAllTodayBuilder.builder().append(planner).build());
CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest();
commonDeleteRequest.setId(plannerId);
//ACT
String jsonString = getJsonStringForDelete(commonDeleteRequest, plannerId);
addRecordToKafka((MockConsumer) plannerService.getConsumer(), TOPIC_PLANNER_DELETE, PARTITION, 0, jsonString);
//ASSERT
waitingWhenAddedRecordAndCheckIt(plannerId, mockProducer, producerRecord);
Planner plannerReq = plannerImdg.getSingleObjectBySQL(String.format("companyId = %s", planner.getCompanyId()));
assertNull(plannerReq);
PlannerAllToday plannerAllTodayRes = plannerAllTodayImdg.getSingleObjectBySQL(String.format("companyId = %s", planner.getCompanyId()));
assertNull(plannerAllTodayRes);
}
/**
* {@link PlannerService#cudPlannerAllToday(Planner)}(BaseRequest)}<br>
* Тест проверяет добавление, обновление, удаление сущности {@link ru.clearing.classes.statics.data.scheduler.PlannerAllToday} в Hazelcast.<br>
* Входной запрос {@link Planner}:<br>
*/
@Test
public void cudPlannerAllToday(){
//проверка добавления
Planner planner = getPlanner(newCompanyId);
plannerService.cudPlannerAllToday(planner);
checkPlannerAllTodayByPlanner(planner);
//проверка обновления
planner.setCompanyId(updateCompanyId);
plannerService.cudPlannerAllToday(planner);
checkPlannerAllTodayByPlanner(planner);
//проверка удаления всех PlannerAllToday
planner.setTaskStatus(Status.Cancel.getKey());
plannerAllTodayImdg.insert(PlannerAllTodayBuilder.builder().append(planner).build());
plannerService.cudPlannerAllToday(planner);
PlannerAllToday plannerAllTodayRes = plannerAllTodayImdg.getSingleObjectBySQL(String.format("parentId = %s", planner.getId()));
assertNull(plannerAllTodayRes);
}
}