Merge branch 'dev' into cls-265

This commit is contained in:
akulikov 2023-04-27 11:28:02 +03:00
commit 2f369d6ea1
69 changed files with 1978 additions and 914 deletions

View file

@ -11,7 +11,6 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSe
import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer;
import ru.spcex.platform.classes.base.interfaces.WithId;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.text.TextUtil;
import java.math.BigDecimal;
import java.time.LocalDate;

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.spcex.clearing</groupId>
<artifactId>clearing-parent</artifactId>
<version>SPCEX-1.0.0.0</version>
</parent>
<artifactId>cleaning-builders</artifactId>
<name>cleaning-builders</name>
<description>Cleaning builders module</description>
<version>SPCEX-1.0.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>
<version>SPCEX-1.0.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-enum</artifactId>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,66 @@
package ru.spcex.clearing.scheduler;
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.Parent;
import java.time.LocalDate;
import java.time.LocalTime;
public class PlannerAllTodayBuilder {
private Long id;
private String task;
private LocalTime taskTime;
private LocalDate clearingDate;
private String market;
private String taskStatus;
private Long companyId;
private Long securityId;
private String parent;
public static PlannerAllTodayBuilder builder() {
return new PlannerAllTodayBuilder();
}
private PlannerAllTodayBuilder(){}
//пока для clearingCalendar нет сеттера append, если появится нужно поправить ClearingCalendarService.deleteFromPlannerAllTodayMap()
//из-за поля this.parent = Parent.Template.getKey();
public PlannerAllTodayBuilder append(PlannerTemplate plannerTemplate){
this.task = plannerTemplate.getTask();
this.taskTime = plannerTemplate.getTaskTime();
this.taskStatus = plannerTemplate.getTaskStatus();
this.companyId = plannerTemplate.getCompanyId();
this.securityId = plannerTemplate.getSecurityId();
this.parent = Parent.Template.getKey();
this.id = plannerTemplate.getId();
return this;
}
public PlannerAllTodayBuilder append(Planner planner){
this.task = planner.getTask();
this.taskTime = planner.getTaskTime();
this.clearingDate = planner.getClearingDate();
this.market = planner.getMarket();
this.taskStatus = planner.getTaskStatus();
this.companyId = planner.getCompanyId();
this.securityId = planner.getSecurityId();
this.parent = Parent.Planner.getKey();
this.id = planner.getId();
return this;
}
public PlannerAllToday build() {
PlannerAllToday res = new PlannerAllToday();
res.setTask(this.task);
res.setTaskTime(this.taskTime);
res.setClearingDate(this.clearingDate);
res.setMarket(this.market);
res.setTaskStatus(this.taskStatus);
res.setCompanyId(this.companyId);
res.setSecurityId(this.securityId);
res.setParent(this.parent);
res.setParentId(this.id);
return res;
}
}

View file

@ -4,8 +4,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsMoney;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;

View file

@ -1,13 +1,10 @@
package ru.spcex.clearing.service.validation;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.relation.Relation;
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
import ru.spcex.clearing.error.ClearingErrorInternal;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.AccountStatus;
import ru.spcex.platform.enumeration.ClearingCategory;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.WorkflowStatus;

View file

@ -6,10 +6,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.relation.Relation;
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsMoney;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;

View file

@ -0,0 +1,34 @@
package ru.spcex.clearing.scheduler;
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.spcex.platform.enumeration.DayStatus;
import java.time.LocalDate;
public class ISchedulerChecker {
public static boolean isValidPlanner(Planner planner, LocalDate currentDate) {
return planner.getTaskStatus() != null && (planner.getClearingDate() == null || planner.getClearingDate().isEqual(currentDate));
}
public static boolean needRemoveByPlanner(Planner planner, PlannerAllToday plannerAllToday) {
return (planner.getTaskTime() != null && planner.getTaskTime().equals(plannerAllToday.getTaskTime()))
&& (planner.getCompanyId() != null && planner.getCompanyId().equals(plannerAllToday.getCompanyId()))
&& (planner.getSecurityId() != null && planner.getSecurityId().equals(plannerAllToday.getSecurityId()))
&& (planner.getTask() != null && planner.getTask().equalsIgnoreCase(plannerAllToday.getTask()));
}
/**
* @param isWeekend тек.день=СБ-ВС<br>
*/
public static boolean isValidWorkday(ClearingCalendar clearingCalendar, boolean isWeekend) {
if (clearingCalendar.getDayStatus() != null && clearingCalendar.getDayStatus().equalsIgnoreCase(DayStatus.Workday.getKey())) {
if (isWeekend) {
return clearingCalendar.getCompanyId() != null && clearingCalendar.getCompanyId() != 0;
} else return true;
}
return false;
}
}

View file

@ -13,8 +13,8 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.SpyBean;
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.company.ClearingMemberCategory;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.platform.dictionary.ClearingCategoryDictionary;
import ru.spcex.clearing.company.config.BeanConfiguration;
import ru.spcex.clearing.company.config.validation.ClearingMemberCategoryValidationConfig;
@ -41,6 +41,7 @@ import static org.mockito.Mockito.spy;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -78,7 +79,7 @@ class ClearingMemberCategoryServiceTest {
@PostConstruct
private void init() {
hazelcastServiceTest.waitAvailable();
waitAvailableImdgProviderAndAddAdminWithDefaultId();
memberCategoryImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_ClearingMemberCategory,
ClearingMemberCategory.class
@ -151,7 +152,7 @@ class ClearingMemberCategoryServiceTest {
predictableClearingMemberCategory.setClearingMemberCategory(clearingMemberCategory);
//ACT
String jsonString = getJsonStringForUPDATE(memberCategoryUpdateRequest, id);
String jsonString = getJsonStringForUpdate(memberCategoryUpdateRequest, id);
addRecordToKafka((MockConsumer) clearingMemberCategoryService.getConsumer(), TOPIC_MEMBER_CATEGORY_UPDATE, PARTITION, 0, jsonString);
//ASSERT
@ -179,7 +180,7 @@ class ClearingMemberCategoryServiceTest {
memberCategoryDeleteRequest.setId(id);
//ACT
String jsonString = getJsonStringForDELETE(memberCategoryDeleteRequest, id);
String jsonString = getJsonStringForDelete(memberCategoryDeleteRequest, id);
addRecordToKafka((MockConsumer) clearingMemberCategoryService.getConsumer(), TOPIC_MEMBER_CATEGORY_DELETE, PARTITION, 0, jsonString);
//ASSERT

View file

@ -37,6 +37,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -74,7 +75,7 @@ class CompanyInfoServiceTest {
@PostConstruct
private void init() {
hazelcastServiceTest.waitAvailable();
waitAvailableImdgProviderAndAddAdminWithDefaultId();
companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class);
// Словари для теста, применяются в ValidationConfig
@ -164,7 +165,7 @@ class CompanyInfoServiceTest {
predictableCompanyInfo.setFullNameEng("updated fullNameEng");
//ACT
String jsonString = getJsonStringForUPDATE(companyInfoUpdateRequest, ID);
String jsonString = getJsonStringForUpdate(companyInfoUpdateRequest, ID);
addRecordToKafka((MockConsumer) companyInfoService.getConsumer(), TOPIC_COMPANY_INFO_UPDATE, PARTITION, 0, jsonString);

View file

@ -13,9 +13,9 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
import ru.clearing.platform.dictionary.CompanySymbolDictionary;
import ru.clearing.platform.dictionary.WorkflowStatusDictionary;
import ru.spcex.clearing.company.config.BeanConfiguration;
@ -45,6 +45,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -83,7 +84,7 @@ class CompanyServiceTest {
@PostConstruct
private void init() {
hazelcastServiceTest.waitAvailable();
waitAvailableImdgProviderAndAddAdminWithDefaultId();
companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class);
companySymbolsImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
@ -137,7 +138,7 @@ class CompanyServiceTest {
commonDeleteRequest.setId(ID);
//ACT
String jsonString = getJsonStringForDELETE(commonDeleteRequest, ID);
String jsonString = getJsonStringForDelete(commonDeleteRequest, ID);
addRecordToKafka((MockConsumer) companyService.getConsumer(), TOPIC_COMPANY_DELETE, PARTITION, 0, jsonString);
//ASSERT

View file

@ -36,6 +36,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -73,7 +74,7 @@ class CompanySymbolServiceTest {
@PostConstruct
private void init() {
hazelcastServiceTest.waitAvailable();
waitAvailableImdgProviderAndAddAdminWithDefaultId();
companySymbolsImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
@ -130,7 +131,7 @@ class CompanySymbolServiceTest {
predictableCompanySymbols.setCompanySymbolValue(companySymbolValue);
//ACT
String jsonString = getJsonStringForUPDATE(companySymbolUpdateRequest, ID);
String jsonString = getJsonStringForUpdate(companySymbolUpdateRequest, ID);
addRecordToKafka((MockConsumer) companySymbolService.getConsumer(), TOPIC_COMPANY_SYMBOL_UPDATE, PARTITION, 0, jsonString);
//ASSERT

View file

@ -38,6 +38,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -73,7 +74,7 @@ class ContactServiceTest {
@PostConstruct
private void init() {
hazelcastServiceTest.waitAvailable();
waitAvailableImdgProviderAndAddAdminWithDefaultId();
contactImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Contact, Contact.class);
Imdg<Company> companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class);
@ -147,7 +148,7 @@ class ContactServiceTest {
predictableContact.setContactValue("new ContactValue");
//ACT
String jsonString = getJsonStringForUPDATE(contactUpdateRequest, existContactID);
String jsonString = getJsonStringForUpdate(contactUpdateRequest, existContactID);
addRecordToKafka((MockConsumer) contactService.getConsumer(), TOPIC_CONTACT_UPDATE, PARTITION, 0, jsonString);
//ASSERT

View file

@ -43,6 +43,7 @@ import static org.mockito.Mockito.spy;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -88,7 +89,7 @@ class ProfileDocumentServiceTest {
@PostConstruct
private void init() {
hazelcastServiceTest.waitAvailable();
waitAvailableImdgProviderAndAddAdminWithDefaultId();
this.profileDocumentMap = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class);
this.companyMap = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class);
@ -214,7 +215,7 @@ class ProfileDocumentServiceTest {
profileDocumentUpdateRequest.setLink("new_link");
//ACT
String jsonString = getJsonStringForUPDATE(profileDocumentUpdateRequest, ID);
String jsonString = getJsonStringForUpdate(profileDocumentUpdateRequest, ID);
addRecordToKafka((MockConsumer) profileDocumentService.getConsumer(), TOPIC_DESTINATION_PROFILE_DOCUMENT_UPDATE, PARTITION, 0, jsonString);
@ -249,7 +250,7 @@ class ProfileDocumentServiceTest {
profileDocumentDeleteRequest.setId(PROFILE_DOCUMENT_ID);
//ACT
String jsonString = getJsonStringForUPDATE(profileDocumentDeleteRequest, ID);
String jsonString = getJsonStringForUpdate(profileDocumentDeleteRequest, ID);
addRecordToKafka((MockConsumer) profileDocumentService.getConsumer(), TOPIC_DESTINATION_PROFILE_DOCUMENT_DELETE, PARTITION, 0, jsonString);

View file

@ -75,6 +75,16 @@
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-enum</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>cleaning-builders</artifactId>
<version>SPCEX-1.0.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>clearing-validation</artifactId>
</dependency>
<!-- TEST -->
<dependency>

View file

@ -24,7 +24,7 @@ public class HazelcastConfiguration {
this.hzSettings = imdgSettings.getHazelcast();
}
@Bean
@Bean("hazelcastInstanceImdg")
public HazelcastInstance hazelcastServerInstance(Config config) {
return Hazelcast.newHazelcastInstance(config);
}

View file

@ -3,23 +3,21 @@ 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.beans.factory.annotation.Qualifier;
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.clearing.scheduler.PlannerAllTodayBuilder;
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 java.util.*;
import static ru.spcex.clearing.imdg.IMDGDistributedNames.*;
import static ru.spcex.clearing.scheduler.ISchedulerChecker.*;
@Service
public class PlannerAllTodayMaker {
@ -30,14 +28,14 @@ public class PlannerAllTodayMaker {
private final IMap<Long, PlannerAllToday> plannerAllTodayMap;
@Autowired
public PlannerAllTodayMaker(HazelcastInstance hazelcastInstance) {
public PlannerAllTodayMaker(@Qualifier("hazelcastInstanceImdg") 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<>();
@ -45,17 +43,15 @@ public class PlannerAllTodayMaker {
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));
}
.filter(x -> isValidPlanner(x, currentDate)).forEach((planner) -> {
if (planner.getTaskStatus().equalsIgnoreCase(Status.Active.getKey())) {
listOfPlannerAllToday.add(PlannerAllTodayBuilder.builder().append(planner).build());
}
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()));
}
});
if (planner.getTaskStatus().equalsIgnoreCase(Status.Cancel.getKey()) || planner.getTaskStatus().equalsIgnoreCase(Status.Blocked.getKey())) {
listOfPlannerAllToday.removeIf((allToday) -> needRemoveByPlanner(planner, allToday));
}
});
for (PlannerAllToday plannerAllToday : listOfPlannerAllToday) {
plannerAllToday.setId(hazelcastInstance.getIdGenerator(MAP_SEQUENCE_NAME).newId());
plannerAllTodayMap.put(plannerAllToday.getId(), plannerAllToday);
@ -63,55 +59,28 @@ public class PlannerAllTodayMaker {
}
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));
}
}
if (needAddFromPlannerTemplate(currentDate, clearingCalendarMap.values())){
plannerTemplateMap.values().stream().filter(plannerTemplate -> Status.Active.equalsByKey(plannerTemplate.getTaskStatus()))
.forEach(plannerTemplate -> res.add(PlannerAllTodayBuilder.builder().append(plannerTemplate).build()));
}
return res;
}
public boolean needAddFromPlannerTemplate(LocalDate currentDate, Collection<ClearingCalendar> clearingCalendar){
boolean isWeekend = Arrays.asList(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY).contains(currentDate.getDayOfWeek());
if (clearingCalendar == null || clearingCalendar.isEmpty()) {
return !isWeekend;
} else {
Optional<ClearingCalendar> clearingCalendarOptional = clearingCalendarMap.values().stream()
.filter((calendar) -> calendar.getClearingDate().isEqual(currentDate))
Optional<ClearingCalendar> clearingCalendarOptional = clearingCalendar.stream()
.filter((calendar) -> calendar.getClearingDate() != null && 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 isValidWorkday(calendar, isWeekend);
} else return !isWeekend;
}
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,13 +1,11 @@
package ru.spcex.clearing.imdg;
import com.hazelcast.config.MapStoreConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -68,6 +66,12 @@ public class AllMapStoreTest {
Path path = Paths.get("src", "main", "resources");
String currentPath = path.toAbsolutePath().toString();
System.setProperty("spring.config.location", currentPath);
Hazelcast.shutdownAll();
}
@AfterAll
static void shutdownAll() {
Hazelcast.shutdownAll();
}
@PostConstruct

View file

@ -6,6 +6,7 @@ import com.hazelcast.core.HazelcastInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@ -16,6 +17,7 @@ import org.springframework.context.annotation.Import;
public class TestConfiguration {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
@Qualifier("hazelcastInstanceImdg")
private HazelcastInstance hazelcastInstance;
@Autowired

View file

@ -0,0 +1,119 @@
package ru.spcex.clearing.imdg.services;
import com.hazelcast.core.Hazelcast;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
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.spcex.clearing.imdg.config.TestConfiguration;
import ru.spcex.platform.enumeration.DayStatus;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Collections;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static ru.spcex.clearing.scheduler.ISchedulerChecker.*;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
TestConfiguration.class
})
class PlannerAllTodayMakerTest {
@Autowired
TestConfiguration testConfig;
private final LocalDate weekendDate = LocalDate.of(2023, 4, 16);
private final LocalDate workDate = LocalDate.of(2023, 4, 14);
@BeforeAll
static void setProperty() {
Path path = Paths.get("src", "main", "resources");
String currentPath = path.toAbsolutePath().toString();
System.setProperty("spring.config.location", currentPath);
Hazelcast.shutdownAll();
}
@AfterAll
static void shutdownAll() {
Hazelcast.shutdownAll();
}
@Test
void needAddFromPlannerTemplate() {
PlannerAllTodayMaker plannerAllTodayMaker = new PlannerAllTodayMaker(testConfig.getHazelcastInstance());
assertFalse(plannerAllTodayMaker.needAddFromPlannerTemplate(weekendDate, null));
assertTrue(plannerAllTodayMaker.needAddFromPlannerTemplate(workDate, null));
ClearingCalendar clearingCalendar = new ClearingCalendar();
assertTrue(plannerAllTodayMaker.needAddFromPlannerTemplate(workDate, Collections.singleton(clearingCalendar)));
clearingCalendar.setClearingDate(workDate);
clearingCalendar.setDayStatus(DayStatus.Workday.getKey());
assertTrue(plannerAllTodayMaker.needAddFromPlannerTemplate(workDate, Collections.singleton(clearingCalendar)));
clearingCalendar.setClearingDate(weekendDate);
clearingCalendar.setDayStatus(DayStatus.Workday.getKey());
assertFalse(plannerAllTodayMaker.needAddFromPlannerTemplate(weekendDate, Collections.singleton(clearingCalendar)));
clearingCalendar.setCompanyId(11L);
assertTrue(plannerAllTodayMaker.needAddFromPlannerTemplate(weekendDate, Collections.singleton(clearingCalendar)));
}
@Test
void isValidWorkdayTest() {
ClearingCalendar clearingCalendar = new ClearingCalendar();
assertFalse(isValidWorkday(clearingCalendar, true));
clearingCalendar.setDayStatus(DayStatus.Workday.getKey());
assertFalse(isValidWorkday(clearingCalendar, true));
clearingCalendar.setDayStatus(DayStatus.DayOff.getKey());
assertFalse(isValidWorkday(clearingCalendar, true));
assertFalse(isValidWorkday(clearingCalendar, false));
clearingCalendar.setDayStatus(DayStatus.Workday.getKey());
assertTrue(isValidWorkday(clearingCalendar, false));
assertFalse(isValidWorkday(clearingCalendar, true));
clearingCalendar.setCompanyId(1L);
assertTrue(isValidWorkday(clearingCalendar, true));
}
@Test
void needRemoveByPlannerTest() {
PlannerAllToday plannerAllToday = new PlannerAllToday();
Planner planner = new Planner();
LocalTime localTime = LocalTime.now();
assertFalse(needRemoveByPlanner(planner, plannerAllToday));
planner.setTaskTime(localTime);
assertFalse(needRemoveByPlanner(planner, plannerAllToday));
plannerAllToday.setTaskTime(localTime);
assertFalse(needRemoveByPlanner(planner, plannerAllToday));
planner.setCompanyId(1L);
assertFalse(needRemoveByPlanner(planner, plannerAllToday));
plannerAllToday.setCompanyId(1L);
assertFalse(needRemoveByPlanner(planner, plannerAllToday));
planner.setSecurityId(1L);
assertFalse(needRemoveByPlanner(planner, plannerAllToday));
plannerAllToday.setSecurityId(1L);
assertFalse(needRemoveByPlanner(planner, plannerAllToday));
plannerAllToday.setTask("1L");
assertFalse(needRemoveByPlanner(planner, plannerAllToday));
planner.setTask("1L");
assertTrue(needRemoveByPlanner(planner, plannerAllToday));
}
@Test
void isValidPlannerTest() {
Planner planner = new Planner();
assertFalse(isValidPlanner(planner, weekendDate));
planner.setTaskStatus("ACTV");
assertTrue(isValidPlanner(planner, weekendDate));
planner.setClearingDate(workDate);
assertFalse(isValidPlanner(planner, weekendDate));
planner.setClearingDate(weekendDate);
assertTrue(isValidPlanner(planner, weekendDate));
}
}

View file

@ -24,8 +24,6 @@ import ru.clearing.classes.statics.data.profile.ProfileDocumentHistory;
import ru.clearing.classes.statics.data.register.*;
import ru.clearing.classes.statics.data.scheduler.*;
import ru.clearing.classes.statics.data.sdf.*;
import ru.clearing.classes.statics.data.security.Security;
import ru.clearing.classes.statics.data.security.SecurityHistory;
import ru.clearing.classes.statics.data.statement.Statement;
import ru.clearing.classes.statics.data.user.*;
import ru.clearing.platform.dictionary.*;

View file

@ -35,6 +35,7 @@
<module>clearing-service</module>
<module>registry-service</module>
<module>test-clearing</module>
<module>cleaning-builders</module>
</modules>
<properties>

View file

@ -36,6 +36,24 @@
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>clearing-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>security-util</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>cleaning-builders</artifactId>
<version>SPCEX-1.0.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
@ -51,6 +69,11 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>test-clearing</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -78,6 +101,23 @@
<finalName>${project.artifactId}</finalName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.2.0-M1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0-M1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

View file

@ -0,0 +1,38 @@
package ru.spcex.clearing.scheduler.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.scheduler.PlannerAllToday;
import ru.spcex.clearing.scheduler.service.TaskManager;
import ru.spcex.platform.utils.log.ExceptionUtils;
import javax.validation.constraints.NotNull;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@Configuration
public class PlannerQueueConfig {
private static final Logger log = LoggerFactory.getLogger(TaskManager.class);
private final static BlockingQueue<Map.Entry<TaskManager.Process, PlannerAllToday>> plannerQueue = new LinkedBlockingQueue<>();
@Bean(name = "plannerQueue")
public BlockingQueue<Map.Entry<TaskManager.Process, PlannerAllToday>> plannerQueue() {
return plannerQueue;
}
public static void addToPlannerQueue(@NotNull TaskManager.Process process, @NotNull PlannerAllToday plannerAllToday) {
try {
Objects.requireNonNull(process);
Objects.requireNonNull(plannerAllToday);
plannerQueue.put(Map.entry(process, plannerAllToday));
} catch (InterruptedException e) {
log.warn("InterruptedException plannerQueue.put {}", ExceptionUtils.getStackTrace(e));
Thread.currentThread().interrupt();
}
}
}

View file

@ -43,7 +43,7 @@ public class ClearingCalendarValidationConfig {
IMDGDistributedNames.Map_Company,
Company.class,
ValidationError.CompanyNotFound,
company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
DictionaryPresentRule.instance("dayStatus",
ClearingCalendarNewRequest::getDayStatus,
IMDGDistributedNames.Map_DayStatusDictionary,
@ -58,6 +58,7 @@ public class ClearingCalendarValidationConfig {
ImdgValidationContext<ClearingCalendarUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(clearingCalendarUpdateRequest);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_ClearingCalendar);
addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_DayStatusDictionary);
return new ValidatorImpl<>(context,
@ -73,7 +74,7 @@ public class ClearingCalendarValidationConfig {
IMDGDistributedNames.Map_Company,
Company.class,
ValidationError.CompanyNotFound,
company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
DictionaryPresentRule.instance("dayStatus",
ClearingCalendarUpdateRequest::getDayStatus,
IMDGDistributedNames.Map_DayStatusDictionary,
@ -83,10 +84,12 @@ public class ClearingCalendarValidationConfig {
}
@Bean("clearingCalendarDeleteRequestValidator")
public Function<CommonDeleteRequest, IValidator> clearingCalendarDeleteRequestValidator() {
public Function<CommonDeleteRequest, IValidator> clearingCalendarDeleteRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return clearingCalendarDeleteRequest -> {
ImdgValidationContext<CommonDeleteRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(clearingCalendarDeleteRequest);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_ClearingCalendar);
return new ValidatorImpl<>(context,
IdPresentRule.instance("id",
CommonDeleteRequest::getId,

View file

@ -55,13 +55,13 @@ public class PlannerTemplateValidationConfig {
IMDGDistributedNames.Map_Company,
Company.class,
ValidationError.CompanyNotFound,
company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
company -> WorkflowStatus.Active.equalsByKey(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)
security -> WorkflowStatus.Active.equalsByKey(security.getWorkflowStatus()) ? null : ValidationError.SecurityNotActive)
);
};
}
@ -74,6 +74,7 @@ public class PlannerTemplateValidationConfig {
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_TaskDictionary);
addImdg.accept(IMDGDistributedNames.Map_TaskStatusDictionary);
addImdg.accept(IMDGDistributedNames.Map_PlannerTemplate);
addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_Security);
return new ValidatorImpl<>(context,
@ -83,42 +84,44 @@ public class PlannerTemplateValidationConfig {
PlannerTemplate.class,
ValidationError.RecordNotFound),
DictionaryPresentRule.instance("task",
PlannerTemplateNewRequest::getTask,
PlannerTemplateUpdateRequest::getTask,
IMDGDistributedNames.Map_TaskDictionary,
TaskDictionary.class,
false),
TimeNotBeforeRule.instance("taskTime",
PlannerTemplateNewRequest::getTaskTime,
PlannerTemplateUpdateRequest::getTaskTime,
false),
DictionaryPresentRule.instance("taskStatus",
PlannerTemplateNewRequest::getTaskStatus,
PlannerTemplateUpdateRequest::getTaskStatus,
IMDGDistributedNames.Map_TaskStatusDictionary,
TaskStatusDictionary.class,
false),
IdPresentRule.instance("companyId",
PlannerTemplateNewRequest::getCompanyId,
PlannerTemplateUpdateRequest::getCompanyId,
IMDGDistributedNames.Map_Company,
Company.class,
ValidationError.CompanyNotFound,
false,
company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
IdPresentRule.instance("securityId",
PlannerTemplateNewRequest::getSecurityId,
PlannerTemplateUpdateRequest::getSecurityId,
IMDGDistributedNames.Map_Security,
Security.class,
ValidationError.SecurityNotFound,
false,
security -> WorkflowStatus.Active.getKey().equals(security.getWorkflowStatus()) ? null : ValidationError.SecurityNotActive)
security -> WorkflowStatus.Active.equalsByKey(security.getWorkflowStatus()) ? null : ValidationError.SecurityNotActive)
);
};
}
@Bean("plannerTemplateDeleteRequestValidator")
public Function<CommonDeleteRequest, IValidator> plannerTemplateDeleteRequestValidator() {
public Function<CommonDeleteRequest, IValidator> plannerTemplateDeleteRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return plannerTemplateDeleteRequest -> {
ImdgValidationContext<CommonDeleteRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerTemplateDeleteRequest);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_PlannerTemplate);
return new ValidatorImpl<>(context,
IdPresentRule.instance("id",
CommonDeleteRequest::getId,

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(),
@ -60,13 +62,13 @@ public class PlannerValidationConfig {
IMDGDistributedNames.Map_Company,
Company.class,
ValidationError.CompanyNotFound,
company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
company -> WorkflowStatus.Active.equalsByKey(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)
security -> WorkflowStatus.Active.equalsByKey(security.getWorkflowStatus()) ? null : ValidationError.SecurityNotActive)
);
};
}
@ -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),
@ -113,23 +117,25 @@ public class PlannerValidationConfig {
Company.class,
ValidationError.CompanyNotFound,
false,
company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
company -> WorkflowStatus.Active.equalsByKey(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)
security -> WorkflowStatus.Active.equalsByKey(security.getWorkflowStatus()) ? null : ValidationError.SecurityNotActive)
);
};
}
@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

@ -3,8 +3,9 @@ package ru.spcex.clearing.scheduler.error;
import ru.spcex.platform.utils.enumeration.IErrorEnumId;
public enum ValidationError implements IErrorEnumId {
WrongDictionaryValue(10003L),
EmptyRequiredValue(10002L),
UserVerifyDenial(18001L),
EmptyRequiredValue(18002L),
WrongDictionaryValue(18003L),
WrongEnumValue(777L), //todo set code
RecordNotFound(7006L),
TaskForPastDate(7010L),
@ -12,8 +13,7 @@ public enum ValidationError implements IErrorEnumId {
CompanyNotFound(7014L),
SecurityNotFound(7012L),
CompanyNotActive(7015L),
SecurityNotActive(7013L)
;
SecurityNotActive(7013L);
private final Long id;

View file

@ -9,6 +9,8 @@ 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;
import ru.spcex.clearing.platform.messaging.domain.Consts;
@ -17,19 +19,34 @@ import ru.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendar
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.clearing.scheduler.PlannerAllTodayBuilder;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.platform.enumeration.DayStatus;
import ru.spcex.platform.enumeration.Parent;
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;
import static ru.spcex.clearing.scheduler.config.PlannerQueueConfig.addToPlannerQueue;
@Service
public class ClearingCalendarService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg<ClearingCalendar> clearingCalendarMap;
private final Imdg<PlannerTemplate> plannerTemplateMap;
private final Imdg<PlannerAllToday> plannerAllTodayMap;
private final IMessageResolver messageResolver;
private final UserRoleVerification userRoleVerification;
private final Function<CommonDeleteRequest, IValidator> clearingCalendarDeleteRequestValidation;
private final Function<ClearingCalendarNewRequest, IValidator> clearingCalendarNewRequestValidation;
private final Function<ClearingCalendarUpdateRequest, IValidator> clearingCalendarUpdateRequestValidation;
@ -38,11 +55,15 @@ public class ClearingCalendarService extends QueueConsumer implements Initializi
public ClearingCalendarService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
IMessageResolver messageResolver,
@Qualifier("userRoleVerificationBean") UserRoleVerification userRoleVerification,
@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.plannerTemplateMap = imdgProvider.getImdg(IMDGDistributedNames.Map_PlannerTemplate, PlannerTemplate.class);
this.plannerAllTodayMap = imdgProvider.getImdg(IMDGDistributedNames.Map_PlannerAllToday, PlannerAllToday.class);
this.userRoleVerification = userRoleVerification;
this.clearingCalendarDeleteRequestValidation = clearingCalendarDeleteRequestValidator;
this.clearingCalendarNewRequestValidation = clearingCalendarNewRequestValidator;
this.clearingCalendarUpdateRequestValidation = clearingCalendarUpdateRequestValidator;
@ -66,24 +87,35 @@ public class ClearingCalendarService extends QueueConsumer implements Initializi
private RequestInfoUpdate newClearingCalendar(BaseRequest<ClearingCalendarNewRequest> userRequest) {
ClearingCalendarNewRequest req = userRequest.getRequestPayload();
log.debug("ClearingCalendarNewRequest received");
RequestInfoUpdate requestInfoUpdate = validate(userRequest, clearingCalendarNewRequestValidation, messageResolver);
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
requestInfoUpdate = validate(userRequest, clearingCalendarNewRequestValidation, messageResolver);
if (requestInfoUpdate != null) return requestInfoUpdate;
ClearingCalendar clearingCalendar = new ClearingCalendar();
Instant created = Instant.now();
clearingCalendar.setCreated(created);
clearingCalendar.setUpdated(created);
clearingCalendar.setClearingDate(req.getClearingDate());
clearingCalendar.setCompanyId(req.getCompanyId());
clearingCalendar.setDayStatus(req.getDayStatus());
clearingCalendarMap.insert(clearingCalendar);
log.debug("successfully processed, new id {}", clearingCalendar.getId());
//если clearingCalendar.getClearingDate() сегодняшний день необходимо проверить/добавить plannerTemplate
createPlannerAllTodayFromPlannerTemplateIfIsValidWorkday(clearingCalendar);
return null;
}
private RequestInfoUpdate updateClearingCalendar(BaseRequest<ClearingCalendarUpdateRequest> userRequest) {
ClearingCalendarUpdateRequest req = userRequest.getRequestPayload();
log.debug("ClearingCalendarUpdateRequest received");
RequestInfoUpdate requestInfoUpdate = validate(userRequest, clearingCalendarUpdateRequestValidation, messageResolver);
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return 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());
@ -92,16 +124,63 @@ public class ClearingCalendarService extends QueueConsumer implements Initializi
clearingCalendar.setUpdated(updated);
clearingCalendarMap.update(clearingCalendar);
log.debug("successfully processed, new id {}", clearingCalendar.getId());
//если clearingCalendar.getClearingDate() сегодняшний день необходимо проверить/добавить plannerTemplate
createPlannerAllTodayFromPlannerTemplateIfIsValidWorkday(clearingCalendar);
return null;
}
private RequestInfoUpdate deleteClearingCalendar(BaseRequest<CommonDeleteRequest> userRequest) {
CommonDeleteRequest req = userRequest.getRequestPayload();
RequestInfoUpdate requestInfoUpdate = validate(userRequest, clearingCalendarDeleteRequestValidation, messageResolver);
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return 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);
deleteFromPlannerAllTodayMap();
return null;
}
private void createPlannerAllTodayFromPlannerTemplateIfIsValidWorkday(ClearingCalendar clearingCalendar) {
LocalDate currentDate = LocalDate.now();
if (clearingCalendar.getClearingDate() == null || !clearingCalendar.getClearingDate().equals(currentDate))
return;
boolean isWeekend = Arrays.asList(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY).contains(currentDate.getDayOfWeek());
if (isValidWorkday(clearingCalendar, isWeekend)) {
for (PlannerTemplate plannerTemplate : plannerTemplateMap.getAllValues()) {
PlannerAllToday plannerAllToday = plannerAllTodayMap.getSingleObjectBySQL(String.format("parentId = %s", plannerTemplate.getId()));
if (plannerAllToday == null) {
plannerAllToday = PlannerAllTodayBuilder.builder().append(plannerTemplate).build();
plannerAllTodayMap.insert(plannerAllToday);
addToPlannerQueue(TaskManager.Process.add, plannerAllToday);
}
}
}
}
public void deleteFromPlannerAllTodayMap() {
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) {
//если будет хоть один валидные ClearingCalendar на сегодня на основании которого(и plannerTemplate -ов) могли быть созданы PlannerAllToday
//ничего проверять\удалять дальше не будем
if (isValidWorkday(calendar, isWeekend)) return;
}
}
//удалим все PlannerAllToday созданные на основании plannerTemplate кроме созданных на основании planner
Collection<PlannerAllToday> values = plannerAllTodayMap.getCollectionObjectsByFieldValues(Map.of("parent", Parent.Template.getKey()));
values.forEach(plannerAllToday -> {
plannerAllTodayMap.delete(plannerAllToday);
addToPlannerQueue(TaskManager.Process.delete, plannerAllToday);
});
}
}

View file

@ -39,6 +39,7 @@ public class LauncherSender {
BaseRequest<Object> request = new BaseRequest<>();
request.setId(idGenerator.nextId());
request.setActionType(ActionType.NEW);
request.setUserId(userId);
request.setRequestPayload(toRequest);// iAction.toRequest()
return request;
}

View file

@ -7,6 +7,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.Launcher;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
@ -14,6 +15,9 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.platform.enumeration.Task;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
@ -27,12 +31,16 @@ public class LauncherService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg<Launcher> launcherMap;
private final Producer<String, Object> kafkaProducer;
private final UserRoleVerification userRoleVerification;
@Autowired
public LauncherService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
@Qualifier("userRoleVerificationBean") UserRoleVerification userRoleVerification,
ImdgProvider imdgProvider) {
super(kafkaQueue, kafkaProducer);
super(kafkaQueue, null);
this.kafkaProducer = kafkaProducer;
this.userRoleVerification = userRoleVerification;
this.launcherMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Launcher, Launcher.class);
}
@ -47,6 +55,14 @@ public class LauncherService extends QueueConsumer implements InitializingBean {
private void newLauncher(BaseRequest<LauncherCommandRequest> userRequest) {
LauncherCommandRequest req = userRequest.getRequestPayload();
log.debug("LauncherCommandRequest received");
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) throw new IllegalStateException(ValidationError.UserVerifyDenial.name());
if (req.getUserId() == null || !req.getUserId().equals(userRequest.getUserId())) {
throw new IllegalStateException(String.format("User id in request must match: baseRequest.userId = %s, launcherCommandRequest.userId = %s", userRequest.getUserId(), req.getUserId()));
}
Instant created = Instant.now();
Launcher launcher = new Launcher();
if (getEnumByKey(Task.class, req.getTaskName()) == null) {

View file

@ -9,6 +9,7 @@ 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.clearing.classes.statics.data.scheduler.PlannerAllToday;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
@ -17,19 +18,30 @@ import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewReques
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.clearing.scheduler.PlannerAllTodayBuilder;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.platform.enumeration.Status;
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.time.LocalDate;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import static ru.spcex.clearing.scheduler.config.PlannerQueueConfig.addToPlannerQueue;
@Service
public class PlannerService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg<Planner> plannerMap;
private final Imdg<PlannerAllToday> plannerAllTodayMap;
private final IMessageResolver messageResolver;
private final UserRoleVerification userRoleVerification;
private final Function<CommonDeleteRequest, IValidator> plannerDeleteRequestValidation;
private final Function<PlannerNewRequest, IValidator> plannerNewRequestValidation;
private final Function<PlannerUpdateRequest, IValidator> plannerUpdateRequestValidation;
@ -39,12 +51,15 @@ public class PlannerService extends QueueConsumer implements InitializingBean {
Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
IMessageResolver messageResolver,
@Qualifier("userRoleVerificationBean") UserRoleVerification userRoleVerification,
@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.plannerAllTodayMap = imdgProvider.getImdg(IMDGDistributedNames.Map_PlannerAllToday, PlannerAllToday.class);
this.messageResolver = messageResolver;
this.userRoleVerification = userRoleVerification;
this.plannerDeleteRequestValidation = plannerDeleteRequestValidator;
this.plannerNewRequestValidation = plannerNewRequestValidator;
this.plannerUpdateRequestValidation = plannerUpdateRequestValidator;
@ -53,24 +68,30 @@ public class PlannerService extends QueueConsumer implements InitializingBean {
@Override
public void afterPropertiesSet() {
callback(PlannerNewRequest.class)
.setFunction(this::newScheduler)
.setFunction(this::newPlanner)
.forDestination(Consts.DESTINATION_PLANNER_NEW, callbacks::put);
callback(PlannerUpdateRequest.class)
.setFunction(this::updateScheduler)
.setFunction(this::updatePlanner)
.forDestination(Consts.DESTINATION_PLANNER_UPDATE, callbacks::put);
callback(CommonDeleteRequest.class)
.setFunction(this::deleteScheduler)
.setFunction(this::deletePlanner)
.forDestination(Consts.DESTINATION_PLANNER_DELETE, callbacks::put);
init();
}
private RequestInfoUpdate newScheduler(BaseRequest<PlannerNewRequest> userRequest) {
private RequestInfoUpdate newPlanner(BaseRequest<PlannerNewRequest> userRequest) {
PlannerNewRequest req = userRequest.getRequestPayload();
log.debug("PlannerNewRequest received");
RequestInfoUpdate requestInfoUpdate = validate(userRequest, plannerNewRequestValidation, messageResolver);
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
requestInfoUpdate = validate(userRequest, plannerNewRequestValidation, messageResolver);
if (requestInfoUpdate != null) return requestInfoUpdate;
Instant created = Instant.now();
Planner planner = new Planner();
planner.setCreated(Instant.now());
planner.setCreated(created);
planner.setUpdated(created);
planner.setTask(req.getTask());
planner.setTaskTime(req.getTaskTime());
planner.setClearingDate(req.getClearingDate());
@ -79,15 +100,23 @@ public class PlannerService extends QueueConsumer implements InitializingBean {
planner.setCompanyId(req.getCompanyId());
planner.setSecurityId(req.getSecurityId());
plannerMap.insert(planner);
LocalDate currentDate = LocalDate.now();
if (req.getClearingDate() != null && currentDate.equals(req.getClearingDate()) && planner.getTaskStatus() != null) {
cudPlannerAllToday(planner);
}
log.debug("successfully processed, new id {}", planner.getId());
return null;
}
private RequestInfoUpdate updateScheduler(BaseRequest<PlannerUpdateRequest> userRequest) {
private RequestInfoUpdate updatePlanner(BaseRequest<PlannerUpdateRequest> userRequest) {
PlannerUpdateRequest req = userRequest.getRequestPayload();
log.debug("PlannerUpdateRequest received id = {}", req.getId());
RequestInfoUpdate requestInfoUpdate = validate(userRequest, plannerUpdateRequestValidation, messageResolver);
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return 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());
@ -98,17 +127,54 @@ public class PlannerService extends QueueConsumer implements InitializingBean {
planner.setCompanyId(req.getCompanyId());
planner.setSecurityId(req.getSecurityId());
plannerMap.update(planner);
LocalDate currentDate = LocalDate.now();
if (req.getClearingDate() != null && currentDate.equals(req.getClearingDate()) && planner.getTaskStatus() != null) {
cudPlannerAllToday(planner);
}
return null;
}
private RequestInfoUpdate deleteScheduler(BaseRequest<CommonDeleteRequest> userRequest) {
private RequestInfoUpdate deletePlanner(BaseRequest<CommonDeleteRequest> userRequest) {
CommonDeleteRequest req = userRequest.getRequestPayload();
log.debug("CommonDeleteRequest received id = {}", req.getId());
RequestInfoUpdate requestInfoUpdate = validate(userRequest, plannerDeleteRequestValidation, messageResolver);
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
requestInfoUpdate = validate(userRequest, plannerDeleteRequestValidation, messageResolver);
if (requestInfoUpdate != null) return requestInfoUpdate;
Planner planner = plannerMap.getSingleObjectByID(req.getId());
plannerMap.delete(planner);
Collection<PlannerAllToday> values = plannerAllTodayMap.getCollectionObjectsBySQL(String.format("parentId = %s", planner.getId()));
values.forEach(plannerAllTodayMap::delete);
return null;
}
public void cudPlannerAllToday(Planner planner) {
if (planner.getTaskStatus().equalsIgnoreCase(Status.Active.getKey())) {
PlannerAllToday plannerAllToday = PlannerAllTodayBuilder.builder().append(planner).build();
PlannerAllToday oldPlannerAllToday = plannerAllTodayMap.getSingleObjectBySQL(String.format("parentId = %s", planner.getId()));
if (oldPlannerAllToday != null) {
plannerAllToday.setId(oldPlannerAllToday.getId());
plannerAllTodayMap.insert(plannerAllToday);
addToPlannerQueue(TaskManager.Process.update, oldPlannerAllToday);
} else {
plannerAllTodayMap.insert(plannerAllToday);
addToPlannerQueue(TaskManager.Process.add, plannerAllToday);
}
}
if (planner.getTaskStatus().equalsIgnoreCase(Status.Cancel.getKey()) || planner.getTaskStatus().equalsIgnoreCase(Status.Blocked.getKey())) {
Collection<PlannerAllToday> values = plannerAllTodayMap.getCollectionObjectsByFieldValues(Map.of(
"task", planner.getTask(),
"taskTime", planner.getTaskTime(),
"securityId", planner.getSecurityId(),
"companyId", planner.getCompanyId()));
values.forEach(plannerAllToday -> {
plannerAllTodayMap.delete(plannerAllToday);
addToPlannerQueue(TaskManager.Process.delete, plannerAllToday);
});
}
}
}

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,33 @@ 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;
import static ru.spcex.clearing.scheduler.config.PlannerQueueConfig.addToPlannerQueue;
@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 +54,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 +72,55 @@ 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()) {
PlannerAllToday plannerAllToday = PlannerAllTodayBuilder.builder().append(plannerTemplate).build();
plannerAllTodayMap.insert(plannerAllToday);
addToPlannerQueue(TaskManager.Process.add, plannerAllToday);
}
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 +130,56 @@ public class PlannerTemplateService extends QueueConsumer implements Initializin
plannerTemplate.setCompanyId(req.getCompanyId());
plannerTemplate.setSecurityId(req.getSecurityId());
plannerTemplateMap.update(plannerTemplate);
if (todayWorkDay()) {
PlannerAllToday plannerAllToday = PlannerAllTodayBuilder.builder().append(plannerTemplate).build();
PlannerAllToday oldPlannerAllToday = plannerAllTodayMap.getSingleObjectBySQL(String.format("parentId = %s", plannerTemplate.getId()));
if (oldPlannerAllToday != null) {
plannerAllToday.setId(oldPlannerAllToday.getId());
plannerAllTodayMap.insert(plannerAllToday);
addToPlannerQueue(TaskManager.Process.update, oldPlannerAllToday);
}else {
plannerAllTodayMap.insert(plannerAllToday);
addToPlannerQueue(TaskManager.Process.add, plannerAllToday);
}
}
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);
addToPlannerQueue(TaskManager.Process.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

@ -1,15 +1,10 @@
package ru.spcex.clearing.scheduler.service;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.map.listener.EntryAddedListener;
import com.hazelcast.map.listener.EntryRemovedListener;
import com.hazelcast.map.listener.EntryUpdatedListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.lang.NonNull;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.scheduler.Launcher;
@ -18,15 +13,13 @@ 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 ru.spcex.platform.utils.log.ExceptionUtils;
import java.time.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import static ru.spcex.clearing.imdg.IMDGDistributedNames.Map_Launcher;
@ -39,118 +32,127 @@ import static ru.spcex.platform.utils.enumeration.IEnumKey.getEnumByKey;
* <p>
*/
@Service("userReportTask")
@Lazy
public class TaskManager implements EntryAddedListener<Long, PlannerAllToday>,
EntryUpdatedListener<Long, PlannerAllToday>, EntryRemovedListener<Long, PlannerAllToday>,
InitializingBean {
public class TaskManager implements InitializingBean, AutoCloseable {
private static final Logger log = LoggerFactory.getLogger(TaskManager.class);
public static final Long systemId = 0L;//для системных задач по договоренности, должен быть пользователь с правами админа и id=0L
private final TaskScheduler taskScheduler;
private final ImdgProvider imdgProvider;
private Imdg<Launcher> launcherMap;
private Imdg<PlannerAllToday> plannerAllTodayMap;
private ConcurrentHashMap<LocalTime, ScheduledFuture> scheduledJobs;
private ConcurrentHashMap<Long, ScheduledFuture> scheduledJobs;
private LauncherSender launcherSender;
private final BlockingQueue<Map.Entry<Process, PlannerAllToday>> plannerQueue;
private final Map<Process, Consumer<PlannerAllToday>> callbacks = new HashMap<>();
private final AtomicBoolean closed = new AtomicBoolean(false);
private final ExecutorService outputExecutor;
@Autowired
TaskManager(TaskScheduler taskScheduler,
ImdgProvider imdgProvider,
LauncherSender launcherSender) {
LauncherSender launcherSender,
@Qualifier("plannerQueue") BlockingQueue<Map.Entry<Process, PlannerAllToday>> plannerQueue) {
this.taskScheduler = taskScheduler;
this.imdgProvider = imdgProvider;
this.launcherSender = launcherSender;
this.plannerQueue = plannerQueue;
this.outputExecutor = Executors.newSingleThreadExecutor();
}
private static LocalDateTime dateOldTypeConvert(@NonNull Date oldDate) {
return LocalDateTime.ofInstant(oldDate.toInstant(), ZoneId.systemDefault());
}
private static LocalDate dateTypeConvert(@NonNull Date oldDate) {
return dateOldTypeConvert(oldDate).toLocalDate();
}
private static LocalTime timeTypeConvert(@NonNull Date oldDate) {
return dateOldTypeConvert(oldDate).toLocalTime();
public enum Process {
add, update, delete
}
@Override
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);
}
callbacks.put(Process.add, this::entryAdded);
callbacks.put(Process.update, this::entryUpdated);
callbacks.put(Process.delete, this::entryRemoved);
scheduledJobs = new ConcurrentHashMap<>();
//если сервис стартовал раньше imdg, дождемся создания всех PlannerAllToday.
imdgProvider.waitAvailable();
updateScheduler();
process();
}
// --- Слушатели Hazelcast Map ---
@Override
public void entryAdded(EntryEvent<Long, PlannerAllToday> event) {
PlannerAllToday task = event.getValue();
private void process() {
outputExecutor.submit(() -> {
while (!closed.get()) {
try {
//процесс ожидает пока появится новое сообщение в очереди
Map.Entry<Process, PlannerAllToday> entry = plannerQueue.take();
callbacks.get(entry.getKey()).accept(entry.getValue());
} catch (InterruptedException e) {
closed.set(true);
Thread.currentThread().interrupt();
} catch (Throwable t) {
log.error("InterruptedException in process, {}", ExceptionUtils.getStackTrace(t));
}
}
});
}
Task taskType = getEnumByKey(Task.class, task.getTask());
if (taskType == null) {
log.warn("Task skipped, {} task type not recognized", task.getTask());
// --- Обработчики PlannerAllToday ---
public void entryAdded(PlannerAllToday task) {
String taskStatus = task.getTaskStatus();
if (taskStatus == null) {
log.warn("Task skipped, {} task status not recognized", task.getTask());
return;
}
processTask(task);
if (Active.equalsByKey(taskStatus)) { //&& ACTIVE.equalsById(task.getTaskStatusId())
addOrUpdateActiveTask(task);
}
}
@Override
public void entryUpdated(EntryEvent<Long, PlannerAllToday> event) {
PlannerAllToday task = event.getValue();
PlannerAllToday oldTask = event.getOldValue();
LocalTime oldTime = oldTask.getTaskTime();
public void entryUpdated(PlannerAllToday plannerAllToday) {
PlannerAllToday task = plannerAllTodayMap.getSingleObjectByID(plannerAllToday.getId());//event.getValue();
PlannerAllToday oldTask = plannerAllToday;//event.getOldValue();
//если таск относится к другому обработчику, пропускаем
if (!Objects.equals(task.getTask(), oldTask.getTask())) {
throw new IllegalStateException("changed taskId for SchedulerAllToday in core");
throw new IllegalStateException("changed taskId for PlannerAllToday in core");
}
if (Active.equalsByKey(oldTask.getTaskStatus())) { //&& ACTIVE.equalsById(task.getTaskStatusId())
if (!removeTask(task.getTask(), oldTime)) {
log.debug("cannot cancel task with type {}, time {}", task.getTask(), oldTime.toString());
} else {
log.debug("task with type {}, time {} execution cancelled, adding altered task...", task.getTask(), oldTime.toString());
}
processTask(task);
} else if (Cancel.equalsByKey(oldTask.getTaskStatus())) { //&& TaskStatuses.CANCEL.equalsById(task.getTaskStatusId())
restorePreviouslyRemovedTask(oldTime, oldTask);
processTask(task);
} else if (Blocked.equalsByKey(oldTask.getTaskStatus())) {
processTask(task);
String taskStatus = task.getTaskStatus();
if (taskStatus == null) {
log.warn("Task skipped, {} task status not recognized", task.getTask());
return;
}
if (Active.equalsByKey(taskStatus)) { //&& ACTIVE.equalsById(task.getTaskStatusId())
addOrUpdateActiveTask(task);
} else if (Cancel.equalsByKey(taskStatus)) { //&& TaskStatuses.CANCEL.equalsById(task.getTaskStatusId())
if (removeTask(task.getTask(), task.getId()))
log.debug("task was successfully deleted after update to cancel");
else log.debug("no task for deleted after update to cancel");
} else if (Blocked.equalsByKey(taskStatus)) {
if (removeTask(task.getTask(), task.getId()))
log.debug("task was successfully deleted after update to blocked");
else log.debug("no task for deleted after update to blocked");
}
}
@Override
public void entryRemoved(EntryEvent<Long, PlannerAllToday> event) {
PlannerAllToday taskToRemove = event.getOldValue();
public void entryRemoved(PlannerAllToday taskToRemove) {
if (taskToRemove == null) {
log.debug("no task in removed event");
return;
}
LocalTime removedTaskTime = taskToRemove.getTaskTime();
if (Active.equalsByKey(taskToRemove.getTaskStatus())) {
if (removeTask(taskToRemove.getTask(), removedTaskTime))
log.debug("task successfully canceled");
} else if (Cancel.equalsByKey(taskToRemove.getTaskStatus())) {
restorePreviouslyRemovedTask(removedTaskTime, taskToRemove);
} else if (Blocked.equalsByKey(taskToRemove.getTaskStatus())) {
log.debug("BLOCKED task removed; do nothing");
}
if (removeTask(taskToRemove.getTask(), taskToRemove.getId()))
log.debug("task successfully removed");
else log.debug("no task for removing");
}
private void restorePreviouslyRemovedTask(LocalTime oldTime, PlannerAllToday oldTask) {
ScheduledFuture cancelledFuture = scheduledJobs.get(oldTime);
private void restorePreviouslyRemovedTask(Long oldTaskId, PlannerAllToday oldTask) {
ScheduledFuture cancelledFuture = scheduledJobs.get(oldTaskId);
if (cancelledFuture != null && cancelledFuture.isCancelled()) {
PlannerAllToday schedulerAllToday = new PlannerAllToday();
schedulerAllToday.setTask(oldTask.getTask());
schedulerAllToday.setTaskStatus(Active.name());
schedulerAllToday.setTaskTime(oldTask.getTaskTime());
log.debug("CANCEL task updated/removed; restoring previously cancelled task");
processTask(schedulerAllToday);
addOrUpdateActiveTask(schedulerAllToday);
}
}
@ -161,49 +163,40 @@ public class TaskManager implements EntryAddedListener<Long, PlannerAllToday>,
schedulerAllTodays.stream().sorted((o1, o2) -> (Active.equalsByKey(o1.getTaskStatus()) && Cancel.equalsByKey(o2.getTaskStatus())) ? -1 : 0)
.collect(Collectors.toCollection(ArrayList::new));
for (PlannerAllToday schedulerAllToday : sortedSchedulers) {
processTask(schedulerAllToday);
addOrUpdateActiveTask(schedulerAllToday);
}
}
// --- Работа с задачами ---
private void processTask(PlannerAllToday task) {
private void addOrUpdateActiveTask(PlannerAllToday task) {
LocalTime taskTime = task.getTaskTime();
Task taskType = getEnumByKey(Task.class, task.getTask());
if (taskType == null) {
log.warn("Task skipped, {} task type not recognized", task.getTask());
return;
}
Status taskStatus = getEnumByKey(Status.class, task.getTaskStatus());
if (taskStatus == null) throw new IllegalStateException("task status from core can't be null");
if (taskTime.isBefore(LocalTime.now())) {
log.debug("Task skipped - taskTime {} is before now, taskType {} ok", taskTime, task.getTask());
if (taskStatus == null) {
log.warn("Task skipped, {} task status not recognized", task.getTask());
return;
}
if (taskStatus.equals(Blocked)) {
log.debug("Task skipped - timeTime {} with status {}", taskTime, Blocked);
return;
}
{
ScheduledFuture future = scheduledJobs.get(taskTime);
if (future != null) {
if (Cancel.equals(taskStatus)) {
//случай когда пришел cancel, пытаемся отменить зарегистрированный ранее таск
future.cancel(false);
log.debug("cancelling task time {}", taskTime);
return;
} else if (Active.equals(taskStatus)) {
//случай когда пришел активный таск, и уже был на это время неотмененный
if (!future.isCancelled()) {
log.debug("such task time {} has already been registered", taskTime);
return;
}
}
}
}
if (Cancel.equals(taskStatus)) {
log.debug("task type {} time {} with status CANCEL - no tasks to cancel found", Objects.requireNonNull(taskType).name(), taskTime);
return;
}
//чтобы не получилось, что старый таск не успели отменить а новый уже создали.
if (taskTime.isBefore(LocalTime.now().plusSeconds(1))) {
log.debug("Task skipped - taskTime {} is before now, taskType {} ok", taskTime, task.getTask());
return;
}
//пришел активный таск
log.debug("adding task type {}, time {}", Objects.requireNonNull(taskType).name(), taskTime);
ScheduledFuture future = taskScheduler.schedule(() -> doJob(task), LocalDateTime.of(LocalDate.now(), taskTime).atZone(ZoneId.systemDefault()).toInstant());
ScheduledFuture oldFuture = scheduledJobs.put(taskTime, future);
ScheduledFuture oldFuture = scheduledJobs.put(task.getId(), future);
if (oldFuture != null && !oldFuture.isCancelled()) { //for synchronization, never
log.warn("tasks were added simultaneously, cancel former one");
boolean success = oldFuture.cancel(false);
@ -211,10 +204,10 @@ public class TaskManager implements EntryAddedListener<Long, PlannerAllToday>,
}
}
private boolean removeTask(String task, LocalTime taskTime) {
ScheduledFuture future = scheduledJobs.remove(taskTime);
private boolean removeTask(String task, Long taskId) {
ScheduledFuture future = scheduledJobs.remove(taskId);
if (future == null) {
log.debug("can't cancel task type {}, time {}, not found", task, taskTime);
log.debug("can't cancel task type {}, time {}, not found", task, taskId);
return false;
}
return future.cancel(false);
@ -230,13 +223,20 @@ public class TaskManager implements EntryAddedListener<Long, PlannerAllToday>,
Instant created = Instant.now();
Launcher launcher = new Launcher();
launcher.setTask(task.getTask());
launcher.setSenderId(task.getParentId());
launcher.setSenderId(systemId);
launcher.setCreated(created);
launcher.setUpdated(created);
launcherMap.insert(launcher);
// 2. отправить сообщение
launcherSender.sendCommandToQueue(taskE, task.getParentId());
launcherSender.sendCommandToQueue(taskE, systemId);
log.debug("successfully processed, new id {}", launcher.getId());
}
}
@Override
public void close() {
log.debug("Closing task manager {}", getClass().getSimpleName());
closed.set(true);
outputExecutor.shutdown();
}
}

View file

@ -11,27 +11,42 @@ import java.util.function.Function;
/**
* Проверка поля с LocalTime. Условие проверки: проверяемое время >= текущее время
*
* @param <R> Класс проверяемого объекта
*/
public record TimeNotBeforeRule<R>(String fieldName, Function<R, LocalTime> getter, boolean required) implements IValidationRule<ImdgValidationContext<R>> {
public record TimeNotBeforeRule<R>(String fieldName,
Function<R, LocalTime> getter,
boolean required,
boolean isToday) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля класса, используется для передачи ошибки
* @param getter Метод получения проверяемого времени
* @param required Флаг обязательности поля
* @param <R> Класс проверяемого объекта
* @param getter Метод получения проверяемого времени
* @param required Флаг обязательности поля
* @param <R> Класс проверяемого объекта
* @param isToday Флаг что дата сегодняшняя
*/
public static <R> TimeNotBeforeRule<R> instance(String fieldName, Function<R, LocalTime> getter, boolean required) {
return new TimeNotBeforeRule<>(fieldName, getter, required);
public static <R> TimeNotBeforeRule<R> instance(String fieldName, Function<R, LocalTime> getter, boolean required, boolean isToday) {
return new TimeNotBeforeRule<>(fieldName, getter, required, isToday);
}
/**
* @param fieldName Название поля класса, используется для передачи ошибки
* @param getter Метод получения проверяемого времени
* @param <R> Класс проверяемого объекта
* @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, true);
}
/**
* @param fieldName Название поля класса, используется для передачи ошибки
* @param getter Метод получения проверяемого времени
* @param <R> Класс проверяемого объекта
*/
public static <R> TimeNotBeforeRule<R> instance(String fieldName, Function<R, LocalTime> getter) {
return new TimeNotBeforeRule<>(fieldName, getter, true);
return new TimeNotBeforeRule<>(fieldName, getter, true, true);
}
@Override
@ -39,7 +54,8 @@ public record TimeNotBeforeRule<R>(String fieldName, Function<R, LocalTime> gett
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);
if (date.isBefore(LocalTime.now()))
return isToday ? of(ValidationError.TaskForPastTime, fieldName) : Optional.empty();
return Optional.empty();
}
}

View file

@ -0,0 +1,183 @@
package ru.spcex.clearing.scheduler;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.MockBean;
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.scheduler.*;
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.config.ErrorResolverConfig;
import ru.spcex.clearing.scheduler.config.PlannerQueueConfig;
import ru.spcex.clearing.scheduler.config.SchedulerTestConfig;
import ru.spcex.clearing.scheduler.config.validation.ClearingCalendarValidationConfig;
import ru.spcex.clearing.scheduler.config.validation.PlannerTemplateValidationConfig;
import ru.spcex.clearing.scheduler.config.validation.PlannerValidationConfig;
import ru.spcex.clearing.scheduler.config.validation.ValidationConfig;
import ru.spcex.clearing.scheduler.service.*;
import ru.spcex.clearing.test.MatcherFactory;
import ru.spcex.clearing.test.TestUtils;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.enumeration.DayStatus;
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.api.ImdgProvider;
import java.time.LocalDate;
import java.time.LocalTime;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId;
import static ru.spcex.platform.enumeration.Market.mkrs;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
PlannerService.class,
PlannerTemplateValidationConfig.class,
ClearingCalendarService.class,
PlannerTemplateService.class,
TaskManager.class,
LauncherSender.class,
PlannerValidationConfig.class,
ClearingCalendarValidationConfig.class,
ValidationConfig.class,
LauncherService.class,
ErrorResolverConfig.class,
PlannerQueueConfig.class,
SchedulerTestConfig.class,
ImdgTestConfig.class,
KafkaTestConfig.class})
public abstract class AbstractServiceTest {
protected static final MatcherFactory.Matcher<PlannerAllToday> PLANNER_ALL_TODAY_MATCHER = usingIgnoringFieldsComparator("created", "updated");
protected static final long id = currentID.getAndIncrement();
protected Imdg<PlannerAllToday> plannerAllTodayImdg;
protected Imdg<PlannerTemplate> plannerTemplateImdg;
protected Imdg<ClearingCalendar> clearingCalendarImdg;
protected Imdg<Planner> plannerImdg;
protected Imdg<Launcher> launcherMap;
protected long newCompanyId = currentID.getAndIncrement();
protected long updateCompanyId = currentID.getAndIncrement();
protected long deleteCompanyId = currentID.getAndIncrement();
protected long testSecurityId = currentID.getAndIncrement();
@Captor
protected ArgumentCaptor<ProducerRecord> producerRecord;
@MockBean
protected MockProducer<String, Object> mockProducer;
@Autowired
@Qualifier("hazelcastServiceTest")
protected ImdgProvider imdgProvider;
protected void init() {
waitAvailableImdgProviderAndAddAdminWithDefaultId();
this.plannerAllTodayImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PlannerAllToday, PlannerAllToday.class);
this.plannerTemplateImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PlannerTemplate, PlannerTemplate.class);
this.clearingCalendarImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingCalendar, ClearingCalendar.class);
this.plannerImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Planner, Planner.class);
this.launcherMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Launcher, Launcher.class);
TaskDictionary taskDictionary = new TaskDictionary();
Imdg<TaskDictionary> taskDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TaskDictionary, TaskDictionary.class);
taskDictionary.setCode(Task.accountBlock.getKey());
taskDictionary.setId(id);
taskDictionaryImdg.insert(taskDictionary);
DayStatusDictionary dayStatusDictionary = new DayStatusDictionary();
dayStatusDictionary.setId(0L);
dayStatusDictionary.setCode(DayStatus.Workday.getKey());
Imdg<DayStatusDictionary> dayStatusDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DayStatusDictionary, DayStatusDictionary.class);
dayStatusDictionaryImdg.insert(dayStatusDictionary);
TaskStatusDictionary taskStatusDictionary = new TaskStatusDictionary();
taskStatusDictionary.setCode(Status.Active.getKey());
taskStatusDictionary.setId(id);
Imdg<TaskStatusDictionary> taskStatusDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TaskStatusDictionary, TaskStatusDictionary.class);
taskStatusDictionaryImdg.insert(taskStatusDictionary);
Company company = new Company();
company.setId(newCompanyId);
company.setWorkflowStatus(WorkflowStatus.Active.getKey());
Imdg<Company> companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
companyImdg.insert(company);
company.setId(updateCompanyId);
company.setWorkflowStatus(WorkflowStatus.Active.getKey());
companyImdg.insert(company);
company.setId(deleteCompanyId);
company.setWorkflowStatus(WorkflowStatus.Active.getKey());
companyImdg.insert(company);
Security security = new Security();
security.setId(testSecurityId);
security.setWorkflowStatus(WorkflowStatus.Active.getKey());
Imdg<Security> securityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class);
securityImdg.insert(security);
clearingCalendarImdg.insert(getClearingCalendar());
TestUtils.FutureRecordMetadata future = spy(new TestUtils.FutureRecordMetadata());
doReturn(future).when(mockProducer).send(producerRecord.capture());
}
protected PlannerTemplate getPlannerTemplate(long companyId) {
PlannerTemplate plannerTemplate = new PlannerTemplate();
plannerTemplate.setId(currentID.getAndIncrement());
plannerTemplate.setTask(Task.accountBlock.getKey());
plannerTemplate.setTaskTime(LocalTime.now().plusHours(1).withNano(0));
plannerTemplate.setTaskStatus(Status.Active.getKey());
plannerTemplate.setCompanyId(companyId);
plannerTemplate.setSecurityId(testSecurityId);
return plannerTemplate;
}
protected Planner getPlanner(long companyId) {
Planner planner = new Planner();
planner.setId(currentID.getAndIncrement());
planner.setTask(Task.accountBlock.getKey());
planner.setTaskTime(LocalTime.now().plusHours(1).withNano(0));
planner.setClearingDate(LocalDate.now());
planner.setMarket(mkrs.getKey());
planner.setTaskStatus(Status.Active.getKey());
planner.setCompanyId(companyId);
planner.setSecurityId(testSecurityId);
return planner;
}
protected void checkPlannerAllTodayByPlannerTemplate(PlannerTemplate plannerTemplate) {
PlannerAllToday plannerAllToday = PlannerAllTodayBuilder.builder().append(plannerTemplate).build();
PlannerAllToday plannerAllTodayRes = plannerAllTodayImdg.getSingleObjectBySQL(String.format("companyId = %s", plannerTemplate.getCompanyId()));
plannerAllToday.setId(plannerAllTodayRes.getId());
PLANNER_ALL_TODAY_MATCHER.assertMatch(plannerAllTodayRes, plannerAllToday);
}
protected void checkPlannerAllTodayByPlanner(Planner planner) {
PlannerAllToday plannerAllToday = PlannerAllTodayBuilder.builder().append(planner).build();
PlannerAllToday plannerAllTodayRes = plannerAllTodayImdg.getSingleObjectBySQL(String.format("companyId = %s", planner.getCompanyId()));
plannerAllToday.setId(plannerAllTodayRes.getId());
PLANNER_ALL_TODAY_MATCHER.assertMatch(plannerAllTodayRes, plannerAllToday);
}
protected ClearingCalendar getClearingCalendar() {
ClearingCalendar clearingCalendar = new ClearingCalendar();
clearingCalendar.setId(currentID.getAndIncrement());
clearingCalendar.setClearingDate(LocalDate.now());
clearingCalendar.setCompanyId(deleteCompanyId);
clearingCalendar.setDayStatus(DayStatus.Workday.getKey());
return clearingCalendar;
}
}

View file

@ -0,0 +1,19 @@
package ru.spcex.clearing.scheduler.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@Configuration
public class SchedulerTestConfig {
@Bean
public TaskScheduler threadPoolTaskScheduler(){
ThreadPoolTaskScheduler threadPoolTaskScheduler
= new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(5);
threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
return threadPoolTaskScheduler;
}
}

View file

@ -0,0 +1,197 @@
package ru.spcex.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.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.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.AbstractServiceTest;
import ru.spcex.clearing.scheduler.PlannerAllTodayBuilder;
import ru.spcex.clearing.test.MatcherFactory;
import ru.spcex.platform.enumeration.DayStatus;
import ru.spcex.platform.enumeration.Status;
import javax.annotation.PostConstruct;
import java.time.LocalDate;
import static org.junit.jupiter.api.Assertions.assertEquals;
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 ClearingCalendarServiceTest extends AbstractServiceTest {
protected static final MatcherFactory.Matcher<ClearingCalendar> CLEARING_CALENDAR_MATCHER = usingIgnoringFieldsComparator("created", "updated");
private static final int PARTITION = 0;
private static final String TOPIC_CLEARING_CALENDAR_NEW = Consts.DESTINATION_CLEARING_CALENDAR_NEW;
private static final String TOPIC_CLEARING_CALENDAR_UPDATE = Consts.DESTINATION_CLEARING_CALENDAR_UPDATE;
private static final String TOPIC_CLEARING_CALENDAR_DELETE = Consts.DESTINATION_CLEARING_CALENDAR_DELETE;
private static final Long ID = currentID.getAndIncrement();
@Autowired
ClearingCalendarService clearingCalendarService;
@PostConstruct
public void init() {
super.init();
}
@BeforeEach
public void prepare() {
clearAllInImdg(plannerTemplateImdg);
clearAllInImdg(plannerAllTodayImdg);
}
/**
* {@link ClearingCalendarService#newClearingCalendar(BaseRequest)}(BaseRequest)}<br>
* Тест проверяет создание сущности {@link ClearingCalendar} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link ClearingCalendarNewRequest}:<br>
*/
@Test
public void newClearingCalendar() {
//ARRANGE
ClearingCalendar clearingCalendar = new ClearingCalendar();
clearingCalendar.setClearingDate(LocalDate.now());
clearingCalendar.setCompanyId(newCompanyId);
clearingCalendar.setDayStatus(DayStatus.Workday.getKey());
PlannerTemplate plannerTemplate = getPlannerTemplate(newCompanyId);
plannerTemplateImdg.insert(plannerTemplate);
ClearingCalendarNewRequest clearingCalendarNewRequest = new ClearingCalendarNewRequest();
clearingCalendarNewRequest.setClearingDate(clearingCalendar.getClearingDate());
clearingCalendarNewRequest.setCompanyId(clearingCalendar.getCompanyId());
clearingCalendarNewRequest.setDayStatus(clearingCalendar.getDayStatus());
//ACT
String jsonString = getJsonStringForNew(clearingCalendarNewRequest, ID);
addRecordToKafka((MockConsumer) clearingCalendarService.getConsumer(), TOPIC_CLEARING_CALENDAR_NEW, PARTITION, 0, jsonString);
//ASSERT
waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord);
ClearingCalendar clearingCalendarRes = clearingCalendarImdg.getSingleObjectBySQL(String.format("companyId = %s", clearingCalendar.getCompanyId()));
clearingCalendar.setId(clearingCalendarRes.getId());
CLEARING_CALENDAR_MATCHER.assertMatch(clearingCalendarRes, clearingCalendar);
checkPlannerAllTodayByPlannerTemplate(plannerTemplate);
}
/**
* {@link ClearingCalendarService#updateClearingCalendar(BaseRequest)}(BaseRequest)}<br>
* Тест проверяет создание сущности {@link ClearingCalendar} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link ClearingCalendarUpdateRequest}:<br>
*/
@Test
public void updateClearingCalendar() {
//ARRANGE
ClearingCalendar clearingCalendar = new ClearingCalendar();
clearingCalendar.setId(currentID.getAndIncrement());
clearingCalendar.setClearingDate(LocalDate.now());
clearingCalendar.setCompanyId(newCompanyId);
clearingCalendar.setDayStatus(DayStatus.Workday.getKey());
clearingCalendarImdg.insert(clearingCalendar);
clearingCalendar.setCompanyId(updateCompanyId);
PlannerTemplate plannerTemplate = getPlannerTemplate(newCompanyId);
plannerTemplateImdg.insert(plannerTemplate);
ClearingCalendarUpdateRequest clearingCalendarNewRequest = new ClearingCalendarUpdateRequest();
clearingCalendarNewRequest.setId(clearingCalendar.getId());
clearingCalendarNewRequest.setClearingDate(clearingCalendar.getClearingDate());
clearingCalendarNewRequest.setCompanyId(clearingCalendar.getCompanyId());
clearingCalendarNewRequest.setDayStatus(clearingCalendar.getDayStatus());
//ACT
String jsonString = getJsonStringForUpdate(clearingCalendarNewRequest, ID);
addRecordToKafka((MockConsumer) clearingCalendarService.getConsumer(), TOPIC_CLEARING_CALENDAR_UPDATE, PARTITION, 0, jsonString);
//ASSERT
waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord);
ClearingCalendar clearingCalendarRes = clearingCalendarImdg.getSingleObjectBySQL(String.format("companyId = %s", clearingCalendar.getCompanyId()));
clearingCalendar.setId(clearingCalendarRes.getId());
CLEARING_CALENDAR_MATCHER.assertMatch(clearingCalendarRes, clearingCalendar);
checkPlannerAllTodayByPlannerTemplate(plannerTemplate);
}
/**
* {@link ClearingCalendarService#deleteClearingCalendar(BaseRequest)}(BaseRequest)}<br>
* Тест проверяет удаление сущности {@link ru.clearing.classes.statics.data.scheduler.ClearingCalendar} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link CommonDeleteRequest}:<br>
*/
@Test
public void deleteClearingCalendar() {
//ARRANGE
clearAllInImdg(clearingCalendarImdg);
ClearingCalendar clearingCalendar = getClearingCalendar();
clearingCalendarImdg.insert(clearingCalendar);
PlannerTemplate plannerTemplate = getPlannerTemplate(newCompanyId);
long id = clearingCalendar.getId();
plannerTemplate.setCompanyId(deleteCompanyId);
plannerAllTodayImdg.insert(PlannerAllTodayBuilder.builder().append(plannerTemplate).build());
CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest();
commonDeleteRequest.setId(id);
//ACT
String jsonString = getJsonStringForDelete(commonDeleteRequest, id);
addRecordToKafka((MockConsumer) clearingCalendarService.getConsumer(), TOPIC_CLEARING_CALENDAR_DELETE, PARTITION, 0, jsonString);
//ASSERT
waitingWhenAddedRecordAndCheckIt(id, mockProducer, producerRecord);
ClearingCalendar plannerTemplateRes = clearingCalendarImdg.getSingleObjectBySQL(String.format("companyId = %s", clearingCalendar.getCompanyId()));
assertNull(plannerTemplateRes);
PlannerAllToday plannerAllTodayRes = plannerAllTodayImdg.getSingleObjectBySQL(String.format("companyId = %s", plannerTemplate.getCompanyId()));
assertNull(plannerAllTodayRes);
//добавим в clearingCalendarImdg валидный clearingCalendar на случай если тесты plannerTemplate еще не отработали
clearingCalendarImdg.insert(clearingCalendar);
}
/**
* {@link ClearingCalendarService#deleteFromPlannerAllTodayMap()}}<br>
* Тест проверяет удаление сущности {@link ru.clearing.classes.statics.data.scheduler.PlannerAllToday} в Hazelcast.<br>
*/
@Test
public void deleteFromPlannerAllTodayMap() {
//проверка удаления PlannerAllToday
Planner planner = getPlanner(newCompanyId);
planner.setId(12L);
planner.setTaskStatus(Status.Active.getKey());
planner.setCompanyId(newCompanyId);
planner.setClearingDate(LocalDate.now());
plannerImdg.insert(planner);
plannerAllTodayImdg.insert(PlannerAllTodayBuilder.builder().append(planner).build());
PlannerTemplate plannerTemplate = new PlannerTemplate();
plannerTemplate.setId(13L);
plannerTemplate.setCompanyId(updateCompanyId);
plannerAllTodayImdg.insert(PlannerAllTodayBuilder.builder().append(plannerTemplate).build());
//ни чего не должно быть удалено ест валидный clearingCalendar
clearingCalendarService.deleteFromPlannerAllTodayMap();
assertEquals(2, plannerAllTodayImdg.getAllValues().size());
checkPlannerAllTodayByPlanner(planner);
checkPlannerAllTodayByPlannerTemplate(plannerTemplate);
//сейчас удалятся только созданные на основании plannerTemplate
clearAllInImdg(clearingCalendarImdg);
clearingCalendarService.deleteFromPlannerAllTodayMap();
checkPlannerAllTodayByPlanner(planner);
assertEquals(1, plannerAllTodayImdg.getAllValues().size());
//добавим в clearingCalendarImdg валидный clearingCalendar на случай если тесты plannerTemplate еще не отработали
clearingCalendarImdg.insert(getClearingCalendar());
}
}

View file

@ -0,0 +1,91 @@
package ru.spcex.clearing.scheduler.service;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import ru.clearing.classes.statics.data.scheduler.Launcher;
import ru.clearing.classes.statics.data.scheduler.Planner;
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.schedule.LauncherCommandRequest;
import ru.spcex.clearing.scheduler.AbstractServiceTest;
import ru.spcex.clearing.test.MatcherFactory;
import javax.annotation.PostConstruct;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
import static ru.spcex.clearing.test.config.ImdgTestConfig.defaultAdminId;
import static ru.spcex.platform.enumeration.Task.accountBlock;
class LauncherServiceTest extends AbstractServiceTest {
private final Logger log = LoggerFactory.getLogger(getClass());
protected static final MatcherFactory.Matcher<Launcher> LAUNCHER_MATCHER = usingIgnoringFieldsComparator("created", "updated");
private static final int PARTITION = 0;
private static final String TOPIC_LAUNCHER_NEW = Consts.LAUNCHER_NEW;
private static final Long ID = currentID.getAndIncrement();
@Autowired
private LauncherService launcherService;
@PostConstruct
public void init() {
super.init();
}
@BeforeEach
public void prepare() {
clearAllInImdg(plannerAllTodayImdg);
}
/**
* {@link LauncherService#newLauncher(BaseRequest)}(BaseRequest)}<br>
* Тест проверяет создание сущности {@link Planner} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link LauncherCommandRequest}:<br>
*/
@Test
public void newPlanner() {
//ARRANGE
Launcher launcher = new Launcher();
launcher.setSenderId(defaultAdminId);
launcher.setTask(accountBlock.getKey());
LauncherCommandRequest launcherCommandRequest = new LauncherCommandRequest();
launcherCommandRequest.setTaskName(launcher.getTask());
launcherCommandRequest.setUserId(launcher.getSenderId());
launcherCommandRequest.setCompanyId(newCompanyId);
launcherCommandRequest.setSecurityId(testSecurityId);
BaseRequest<Object> predictableBaseRequest = new BaseRequest<>();
predictableBaseRequest.setRequestPayload(launcherCommandRequest);
predictableBaseRequest.setId(ID);
predictableBaseRequest.setUserId(launcher.getSenderId());
predictableBaseRequest.setActionType(ActionType.NEW);
//ACT
String jsonString = getJsonStringForNew(launcherCommandRequest, ID);
addRecordToKafka((MockConsumer) launcherService.getConsumer(), TOPIC_LAUNCHER_NEW, PARTITION, 0, jsonString);
//ASSERT
verify(mockProducer, timeout(30_000L).times(1))
.send(producerRecord.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) producerRecord.getValue().value();
assertEquals("launcher-" + launcher.getTask(), producerRecord.getValue().topic());
BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest);
Launcher launcherReq = launcherMap.getSingleObjectBySQL(String.format("senderId = %s", launcher.getSenderId()));
launcher.setId(launcherReq.getId());
LAUNCHER_MATCHER.assertMatch(launcherReq, launcher);
}
}

View file

@ -0,0 +1,170 @@
package ru.spcex.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.AbstractServiceTest;
import ru.spcex.clearing.scheduler.PlannerAllTodayBuilder;
import ru.spcex.clearing.test.MatcherFactory;
import ru.spcex.platform.enumeration.Status;
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);
}
}

View file

@ -0,0 +1,133 @@
package ru.spcex.clearing.scheduler.service;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import ru.clearing.classes.statics.data.scheduler.PlannerAllToday;
import ru.clearing.classes.statics.data.scheduler.PlannerTemplate;
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.AbstractServiceTest;
import ru.spcex.clearing.scheduler.PlannerAllTodayBuilder;
import ru.spcex.clearing.test.MatcherFactory;
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 PlannerTemplateServiceTest extends AbstractServiceTest {
protected static final MatcherFactory.Matcher<PlannerTemplate> PLANNER_TEMPLATE_MATCHER = usingIgnoringFieldsComparator("created", "updated");
private static final int PARTITION = 0;
private static final String TOPIC_PLANNER_TEMPLATE_NEW = Consts.DESTINATION_PLANNER_TEMPLATE_NEW;
private static final String TOPIC_PLANNER_TEMPLATE_UPDATE = Consts.DESTINATION_PLANNER_TEMPLATE_UPDATE;
private static final String TOPIC_PLANNER_TEMPLATE_DELETE = Consts.DESTINATION_PLANNER_TEMPLATE_DELETE;
private static final Long ID = currentID.getAndIncrement();
@Autowired
private PlannerTemplateService plannerTemplateService;
@PostConstruct
public void init() {
super.init();
}
/**
* {@link PlannerTemplateService#newPlannerTemplate(BaseRequest)}(BaseRequest)}<br>
* Тест проверяет создание сущности {@link ru.clearing.classes.statics.data.scheduler.PlannerTemplate} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link PlannerTemplateNewRequest}:<br>
*/
@Test
public void newPlannerTemplateInQueue() throws InterruptedException {
//ARRANGE
PlannerTemplate plannerTemplate = getPlannerTemplate(newCompanyId);
PlannerTemplateNewRequest templateNewRequest = new PlannerTemplateNewRequest();
templateNewRequest.setTask(plannerTemplate.getTask());
templateNewRequest.setTaskTime(plannerTemplate.getTaskTime());
templateNewRequest.setTaskStatus(plannerTemplate.getTaskStatus());
templateNewRequest.setCompanyId(plannerTemplate.getCompanyId());
templateNewRequest.setSecurityId(plannerTemplate.getSecurityId());
//ACT
String jsonString = getJsonStringForNew(templateNewRequest, ID);
addRecordToKafka((MockConsumer) plannerTemplateService.getConsumer(), TOPIC_PLANNER_TEMPLATE_NEW, PARTITION, 0, jsonString);
//ASSERT
waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord);
PlannerTemplate plannerTemplateRes = plannerTemplateImdg.getSingleObjectBySQL(String.format("companyId = %s", plannerTemplate.getCompanyId()));
plannerTemplate.setId(plannerTemplateRes.getId());
PLANNER_TEMPLATE_MATCHER.assertMatch(plannerTemplateRes, plannerTemplate);
checkPlannerAllTodayByPlannerTemplate(plannerTemplate);
}
/**
* {@link PlannerTemplateService#updatePlannerTemplate(BaseRequest)}(BaseRequest)}<br>
* Тест проверяет обновление сущности {@link ru.clearing.classes.statics.data.scheduler.PlannerTemplate} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link PlannerTemplateUpdateRequest}:<br>
*/
@Test
public void updatePlannerTemplate() throws InterruptedException {
//ARRANGE
PlannerTemplate plannerTemplate = getPlannerTemplate(newCompanyId);
plannerTemplateImdg.insert(plannerTemplate);
plannerTemplate.setCompanyId(updateCompanyId);
PlannerTemplateUpdateRequest plannerTemplateUpdateRequest = new PlannerTemplateUpdateRequest();
plannerTemplateUpdateRequest.setId(plannerTemplate.getId());
plannerTemplateUpdateRequest.setTask(plannerTemplate.getTask());
plannerTemplateUpdateRequest.setTaskTime(plannerTemplate.getTaskTime());
plannerTemplateUpdateRequest.setTaskStatus(plannerTemplate.getTaskStatus());
plannerTemplateUpdateRequest.setCompanyId(plannerTemplate.getCompanyId());
plannerTemplateUpdateRequest.setSecurityId(plannerTemplate.getSecurityId());
//ACT
String jsonString = getJsonStringForUpdate(plannerTemplateUpdateRequest, ID);
addRecordToKafka((MockConsumer) plannerTemplateService.getConsumer(), TOPIC_PLANNER_TEMPLATE_UPDATE, PARTITION, 0, jsonString);
//ASSERT
waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord);
PlannerTemplate plannerTemplateRes = plannerTemplateImdg.getSingleObjectBySQL(String.format("companyId = %s", plannerTemplate.getCompanyId()));
plannerTemplate.setId(plannerTemplateRes.getId());
PLANNER_TEMPLATE_MATCHER.assertMatch(plannerTemplateRes, plannerTemplate);
checkPlannerAllTodayByPlannerTemplate(plannerTemplate);
}
/**
* {@link PlannerTemplateService#deletePlannerTemplate(BaseRequest)}(BaseRequest)}<br>
* Тест проверяет удаление сущности {@link ru.clearing.classes.statics.data.scheduler.PlannerTemplate} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link CommonDeleteRequest}:<br>
*/
@Test
public void deletePlannerTemplate() throws InterruptedException {
//ARRANGE
PlannerTemplate plannerTemplate = getPlannerTemplate(newCompanyId);
long id = plannerTemplate.getId();
plannerTemplate.setCompanyId(deleteCompanyId);
plannerTemplateImdg.insert(plannerTemplate);
plannerAllTodayImdg.insert(PlannerAllTodayBuilder.builder().append(plannerTemplate).build());
CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest();
commonDeleteRequest.setId(id);
//ACT
String jsonString = getJsonStringForDelete(commonDeleteRequest, id);
addRecordToKafka((MockConsumer) plannerTemplateService.getConsumer(), TOPIC_PLANNER_TEMPLATE_DELETE, PARTITION, 0, jsonString);
//ASSERT
waitingWhenAddedRecordAndCheckIt(id, mockProducer, producerRecord);
PlannerTemplate plannerTemplateRes = plannerTemplateImdg.getSingleObjectBySQL(String.format("companyId = %s", plannerTemplate.getCompanyId()));
assertNull(plannerTemplateRes);
PlannerAllToday plannerAllTodayRes = plannerAllTodayImdg.getSingleObjectBySQL(String.format("companyId = %s", plannerTemplate.getCompanyId()));
assertNull(plannerAllTodayRes);
}
}

View file

@ -0,0 +1,107 @@
package ru.spcex.clearing.scheduler.service;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import ru.clearing.classes.statics.data.scheduler.PlannerAllToday;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.scheduler.AbstractServiceTest;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.enumeration.Task;
import javax.annotation.PostConstruct;
import java.time.LocalTime;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.scheduler.config.PlannerQueueConfig.addToPlannerQueue;
import static ru.spcex.clearing.scheduler.service.TaskManager.systemId;
import static ru.spcex.clearing.test.TestUtils.BASE_REQUEST_MATCHER;
import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
import static ru.spcex.platform.utils.enumeration.IEnumKey.getEnumByKey;
class TaskManagerTest extends AbstractServiceTest {
@Autowired
LauncherSender launcherSender;
@PostConstruct
public void init() {
super.init();
}
/**
* {@link TaskManager#entryAdded(PlannerAllToday)}}<br>
* Тест проверяет создание и отправку LauncherCommandRequest в Apache Kafka.<br>
* Входной запрос {@link PlannerAllToday}:<br>
*/
@Test
void entryAdded() {
//ARRANGE
PlannerAllToday plannerAllToday = getPlannerAllToday(Task.createOrder.getKey());
//ACT
addToPlannerQueue(TaskManager.Process.add, plannerAllToday);
//ASSERT
waitingWhenAddedLauncherCommandRequestAndCheckIt(getEnumByKey(Task.class, plannerAllToday.getTask()), systemId);
}
/**
* {@link TaskManager#entryUpdated(PlannerAllToday)}}<br>
* Тест проверяет создание и отправку LauncherCommandRequest в Apache Kafka.<br>
* Входной запрос {@link PlannerAllToday}:<br>
*/
@Test
void entryUpdated() {
//ARRANGE
PlannerAllToday plannerAllToday = getPlannerAllToday(Task.createReport_GREP.getKey());
PlannerAllToday oldPlanner = getPlannerAllToday(Task.createReport_GREP.getKey());
plannerAllToday.setId(oldPlanner.getId());
plannerAllTodayImdg.insert(plannerAllToday);
addToPlannerQueue(TaskManager.Process.add, oldPlanner);
//ACT
addToPlannerQueue(TaskManager.Process.update, oldPlanner);
//ASSERT
waitingWhenAddedLauncherCommandRequestAndCheckIt(getEnumByKey(Task.class, plannerAllToday.getTask()), systemId);
}
/**
* {@link TaskManager#entryRemoved(PlannerAllToday)}}<br>
* Тест проверяет создание и отправку LauncherCommandRequest в Apache Kafka.<br>
* Входной запрос {@link PlannerAllToday}:<br>
*/
@Test
void entryRemoved() {
//ARRANGE
PlannerAllToday plannerAllToday = getPlannerAllToday(Task.createOrder.getKey());
PlannerAllToday oldPlanner = getPlannerAllToday(Task.createReport_GREP.getKey());
addToPlannerQueue(TaskManager.Process.add, oldPlanner);
addToPlannerQueue(TaskManager.Process.delete, oldPlanner);
//ACT
addToPlannerQueue(TaskManager.Process.add, plannerAllToday);
//ASSERT
waitingWhenAddedLauncherCommandRequestAndCheckIt(getEnumByKey(Task.class, plannerAllToday.getTask()), systemId);
}
protected PlannerAllToday getPlannerAllToday(String task) {
PlannerAllToday plannerAllToday = new PlannerAllToday();
plannerAllToday.setId(currentID.getAndIncrement());
plannerAllToday.setTask(task);
plannerAllToday.setTaskTime(LocalTime.now().plusSeconds(18));
plannerAllToday.setTaskStatus(Status.Active.getKey());
return plannerAllToday;
}
public void waitingWhenAddedLauncherCommandRequestAndCheckIt(Task toTaskQueue, Long userId) {
BaseRequest<Object> predictableBaseRequest = launcherSender.makeCmdRequest(toTaskQueue, userId);
//waiting for kafka producer send message (finale event)
verify(mockProducer, timeout(60_000L).times(1))
.send(producerRecord.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) producerRecord.getValue().value();
assertEquals(toTaskQueue.topic(), producerRecord.getValue().topic());
predictableBaseRequest.setId(baseRequestResult.getId());
BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest);
}
}

View file

@ -1,9 +1,8 @@
package ru.specx.clearing.scheduler.validation;
package ru.spcex.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.AbstractServiceTest;
import ru.spcex.clearing.scheduler.validation.rules.common.DateNotBeforeRule;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
@ -17,8 +16,7 @@ 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 {
class DateNotBeforeRuleTest extends AbstractServiceTest {
@Test
public void dateNotBeforeRuleTest() {

View file

@ -1,11 +1,8 @@
package ru.specx.clearing.scheduler.validation;
package ru.spcex.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;
@ -13,6 +10,7 @@ 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.AbstractServiceTest;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.clearing.scheduler.validation.rules.common.DictionaryPresentRule;
import ru.spcex.platform.enumeration.DayStatus;
@ -25,7 +23,6 @@ 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;
@ -35,10 +32,7 @@ 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 {
class DictionaryPresentRuleTest extends AbstractServiceTest {
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
@ -70,12 +64,12 @@ class DictionaryPresentRuleTest {
}
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 {
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) {

View file

@ -1,14 +1,12 @@
package ru.specx.clearing.scheduler.validation;
package ru.spcex.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.AbstractServiceTest;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.clearing.scheduler.validation.rules.common.EnumPresentRule;
import ru.spcex.platform.enumeration.DayStatus;
@ -20,7 +18,6 @@ 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;
@ -31,10 +28,7 @@ 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 {
class EnumPresentRuleTest extends AbstractServiceTest {
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;

View file

@ -1,9 +1,8 @@
package ru.specx.clearing.scheduler.validation;
package ru.spcex.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.AbstractServiceTest;
import ru.spcex.clearing.scheduler.validation.rules.common.FieldRequiredRule;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
@ -16,8 +15,7 @@ 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 {
class FieldRequiredRuleTest extends AbstractServiceTest {
@Test
public void fieldRequiredRuleTest() {

View file

@ -1,15 +1,13 @@
package ru.specx.clearing.scheduler.validation;
package ru.spcex.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.AbstractServiceTest;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.clearing.scheduler.validation.rules.common.IdPresentRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
@ -19,7 +17,6 @@ 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;
@ -29,10 +26,7 @@ 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 {
class IdPresentRuleTest extends AbstractServiceTest {
private final static Long TEST_ID = 777L;
@Autowired

View file

@ -1,9 +1,8 @@
package ru.specx.clearing.scheduler.validation;
package ru.spcex.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.AbstractServiceTest;
import ru.spcex.clearing.scheduler.validation.rules.common.TimeNotBeforeRule;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
@ -17,8 +16,7 @@ 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 {
class TimeNotBeforeRuleTest extends AbstractServiceTest {
@Test
public void timeNotBeforeRuleTest() {

View file

@ -1,75 +0,0 @@
package ru.specx.clearing.scheduler.config;
import com.hazelcast.config.*;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
@Configuration
public class HazelcastServiceTestConfiguration {
private HazelcastInstance hazelcastInstance;
private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
if (maxPoolSz > 2) {
pool.setKeepAliveSeconds(60);
pool.setAllowCoreThreadTimeOut(true);
}
pool.setCorePoolSize(maxPoolSz);
pool.setWaitForTasksToCompleteOnShutdown(waitForCompletion);
return pool;
}
@Bean(name = "hazelcastServiceTest")
public HazelcastService hazelcastService(@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer, @Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter, HazelcastClientParams params) {
Config cfg = new Config();
cfg.setInstanceName("localhost");
NetworkConfig networkConfig = new NetworkConfig();
JoinConfig joinConfig = new JoinConfig();
joinConfig.setMulticastConfig(new MulticastConfig().setEnabled(false));
joinConfig.setTcpIpConfig(new TcpIpConfig().setEnabled(true).setMembers(List.of("127.0.0.1")));
networkConfig.setJoin(joinConfig);
cfg.setNetworkConfig(networkConfig);
hazelcastInstance = Hazelcast.newHazelcastInstance(cfg);
HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance);
return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params);
}
@Bean(name = "taskExecutorHazelcastClientInitializer")
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() {
return createThreadPoolTaskExecutor(1, true);
}
@Bean(name = "taskExecutorIdGeneratorAwaiter")
public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() {
return createThreadPoolTaskExecutor(1, false);
}
@Bean(name = "hazelcastClientParams")
public HazelcastClientParams getHazelcastClientParams() {
HazelcastClientParams params = new HazelcastClientParams();
params.setLogin("dev");
params.setPassword("dev-pass");
params.setClusterMembers("127.0.0.1");
params.setInstanceName("hzTestClient" + new Random().nextInt());
params.setNearCacheConfig(new NearCacheConfig());
return params;
}
@Bean
public IMessageResolver messageResolver() {
return new SimpleMessageResolver();
}
}

View file

@ -1,192 +0,0 @@
package ru.specx.clearing.scheduler.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hazelcast.core.IMap;
import com.hazelcast.map.listener.EntryRemovedListener;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.common.TopicPartition;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
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.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,
ValidationConfig.class,
ClearingCalendarValidationConfig.class
})
class ClearingCalendarServiceTest {
private static final int PARTITION = 0;
private static final String TOPIC_CLEARING_CALENDAR_NEW = Consts.DESTINATION_CLEARING_CALENDAR_NEW;
private static final Long ID = 0L;
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
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);
mockProducer = new MockProducer<>();
}
/**
* {@link ClearingCalendarService#newTradingCalendar(BaseRequest)}(BaseRequest)}<br>
* Тест проверяет создание сущности {@link ClearingCalendar} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link ClearingCalendarNewRequest}:<br>
*/
@Test
public void newClearingCalendarInQueue() throws InterruptedException {
// 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().plusDays(1));
clearingCalendar.setCompanyId(0L);
clearingCalendar.setDayStatus(DayStatus.Workday.getKey());
ClearingCalendarNewRequest clearingCalendarNewRequest = new ClearingCalendarNewRequest();
clearingCalendarNewRequest.setClearingDate(clearingCalendar.getClearingDate());
clearingCalendarNewRequest.setCompanyId(clearingCalendar.getCompanyId());
clearingCalendarNewRequest.setDayStatus(clearingCalendar.getDayStatus());
BaseRequest<ClearingCalendarNewRequest> baseNewRequest = new BaseRequest<>();
baseNewRequest.setRequestPayload(clearingCalendarNewRequest);
baseNewRequest.setId(ID);
baseNewRequest.setActionType(ActionType.NEW);
String jsonBaseForRequest;
ObjectMapper objectMapper = new ObjectMapper();
try {
jsonBaseForRequest = objectMapper.writeValueAsString(baseNewRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
//ACT
//service set up
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<>();
TopicPartition topic = new TopicPartition(TOPIC_CLEARING_CALENDAR_NEW, PARTITION);
startOffsetsUpdating.put(topic, 0L);
mockConsumer.updateBeginningOffsets(startOffsetsUpdating);
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC_CLEARING_CALENDAR_NEW, PARTITION)));
mockConsumer.addRecord(new ConsumerRecord<>(TOPIC_CLEARING_CALENDAR_NEW, PARTITION, 0, "key", jsonBaseForRequest));
});
//waiting for hazelcast map item removes
Object waiter = new Object();
String listenerID = iMap.addEntryListener((EntryRemovedListener<Long, Contact>) entryEvent -> {
System.out.println("Checking If pushed..");
try {
waiter.wait(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (waiter) {
waiter.notify();
}
}, false);
synchronized (waiter) {
waiter.wait(100);
}
ClearingCalendar clearingCalendarRes = iMap.get(iMap.keySet().stream().findFirst().get());
//ASSERT
Assertions.assertEquals(1, iMap.size());
Assertions.assertNotNull(clearingCalendarRes.getCreated());
Assertions.assertEquals(clearingCalendar.getClearingDate(), clearingCalendarRes.getClearingDate());
Assertions.assertEquals(clearingCalendar.getCompanyId(), clearingCalendarRes.getCompanyId());
Assertions.assertEquals(clearingCalendar.getDayStatus(), clearingCalendarRes.getDayStatus());
//preparing hazelcastImdgProvider for next test
iMap.removeEntryListener(listenerID);
}
}

View file

@ -1,206 +0,0 @@
package ru.specx.clearing.scheduler.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hazelcast.core.IMap;
import com.hazelcast.map.listener.EntryRemovedListener;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.common.TopicPartition;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
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.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,
ValidationConfig.class,
PlannerTemplateValidationConfig.class
})
class PlannerTemplateServiceTest {
private static final int PARTITION = 0;
private static final String TOPIC_PLANNER_TEMPLATE_NEW = Consts.DESTINATION_PLANNER_TEMPLATE_NEW;
private static final Long ID = 0L;
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
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);
mockProducer = new MockProducer<>();
}
/**
* {@link PlannerTemplateService#newTimetable(BaseRequest)}(BaseRequest)}<br>
* Тест проверяет создание сущности {@link ru.clearing.classes.statics.data.scheduler.PlannerTemplate} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link PlannerTemplateNewRequest}:<br>
*/
@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(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());
plannerTemplateNewRequest.setTaskTime(plannerTemplate.getTaskTime());
plannerTemplateNewRequest.setTaskStatus(plannerTemplate.getTaskStatus());
plannerTemplateNewRequest.setCompanyId(plannerTemplate.getCompanyId());
plannerTemplateNewRequest.setSecurityId(plannerTemplate.getSecurityId());
BaseRequest<PlannerTemplateNewRequest> plannerTemplateRequest = new BaseRequest<>();
plannerTemplateRequest.setRequestPayload(plannerTemplateNewRequest);
plannerTemplateRequest.setId(ID);
plannerTemplateRequest.setActionType(ActionType.NEW);
String jsonBaseForDeleteRequest;
ObjectMapper objectMapper = new ObjectMapper();
try {
jsonBaseForDeleteRequest = objectMapper.writeValueAsString(plannerTemplateRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
//ACT
//service set up
PlannerTemplateService plannerTemplateService = new PlannerTemplateService(mockConsumer,
mockProducer,
hazelcastServiceTest,
messageResolver,
plannerTemplateDeleteRequestValidation,
plannerTemplateNewRequestValidation,
plannerTemplateUpdateRequestValidation);
//callbacks set up
plannerTemplateService.afterPropertiesSet();
IMap<Long, PlannerTemplate> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_PlannerTemplate);
//KAFKA
HashMap<TopicPartition, Long> startOffsetsUpdating = new HashMap<>();
TopicPartition topic = new TopicPartition(TOPIC_PLANNER_TEMPLATE_NEW, PARTITION);
startOffsetsUpdating.put(topic, 0L);
mockConsumer.updateBeginningOffsets(startOffsetsUpdating);
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC_PLANNER_TEMPLATE_NEW, PARTITION)));
mockConsumer.addRecord(new ConsumerRecord<>(TOPIC_PLANNER_TEMPLATE_NEW, PARTITION, 0, "key", jsonBaseForDeleteRequest));
});
//waiting for hazelcast map item removes
Object waiter = new Object();
String listenerID = iMap.addEntryListener((EntryRemovedListener<Long, Contact>) entryEvent -> {
System.out.println("Checking If pushed..");
try {
waiter.wait(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (waiter) {
waiter.notify();
}
}, false);
synchronized (waiter) {
waiter.wait(100);
}
PlannerTemplate plannerTemplateRes = iMap.get(iMap.keySet().stream().findFirst().get());
//ASSERT
Assertions.assertEquals(1, iMap.size());
Assertions.assertNotNull(plannerTemplateRes.getCreated());
Assertions.assertEquals(plannerTemplate.getTask(), plannerTemplateRes.getTask());
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());
//preparing hazelcastImdgProvider for next test
iMap.removeEntryListener(listenerID);
}
}

View file

@ -1,38 +0,0 @@
package ru.specx.clearing.scheduler.utils;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Factory for creating test matchers.
* <p>
* Comparing actual and expected objects via AssertJ
*/
public class MatcherFactory {
public static <T> Matcher<T> usingIgnoringFieldsComparator(String... fieldsToIgnore) {
return new Matcher<>(fieldsToIgnore);
}
public static class Matcher<T> {
private final String[] fieldsToIgnore;
private Matcher(String... fieldsToIgnore) {
this.fieldsToIgnore = fieldsToIgnore;
}
public void assertMatch(T actual, T expected) {
assertThat(actual).usingRecursiveComparison().ignoringFields(fieldsToIgnore).isEqualTo(expected);
}
@SafeVarargs
public final void assertMatch(Iterable<T> actual, T... expected) {
assertMatch(actual, Arrays.asList(expected));
}
public void assertMatch(Iterable<T> actual, Iterable<T> expected) {
assertThat(actual).usingRecursiveFieldByFieldElementComparatorIgnoringFields(fieldsToIgnore).isEqualTo(expected);
}
}
}

View file

@ -10,78 +10,77 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSe
import ru.spcex.platform.enumeration.Market;
import ru.spcex.platform.enumeration.Status;
import java.math.BigDecimal;
import java.time.Instant;
public class ListingBuilder {
private Instant created;
private Long securityId;
private BigDecimal lotSize;
private final String market = Market.mkrs.getKey();
private String symbolCode;
private String symbolName;
private String tradingCurrency;
private final String workflowStatus = Status.Active.getKey();
public Listing byNewMms(MoneyMarketSecurity mms, MoneyMarketSecurityNewRequest mmsReq) {
public static ListingBuilder builder() {
return new ListingBuilder();
}
private ListingBuilder() {
}
public ListingBuilder append(MoneyMarketSecurity mms) {
this.created = mms.getCreated();
this.securityId = mms.getId();
this.symbolCode = mms.getSecuritySymbol();
this.symbolName = mms.getFullName();
this.tradingCurrency = mms.getNominalCurrency();
return this;
}
public ListingBuilder append(MoneyMarketSecurityNewRequest mmsReq) {
this.lotSize = mmsReq.getLotSize();
return this;
}
public ListingBuilder append(EquitySecurity equitySecurity) {
this.created = equitySecurity.getCreated();
this.securityId = equitySecurity.getId();
this.symbolCode = equitySecurity.getSecuritySymbol();
this.symbolName = equitySecurity.getFullName();
return this;
}
public ListingBuilder append(EquitySecurityNewRequest request) {
this.lotSize = request.getLotSize();
return this;
}
public ListingBuilder append(FixedIncomeSecurity fixedIncomeSecurity) {
this.created = fixedIncomeSecurity.getCreated();
this.securityId = fixedIncomeSecurity.getId();
this.symbolCode = fixedIncomeSecurity.getSecuritySymbol();
this.symbolName = fixedIncomeSecurity.getFullName();
this.tradingCurrency = fixedIncomeSecurity.getNominalCurrency();
return this;
}
public ListingBuilder append(FixedIncomeSecurityNewRequest request) {
this.lotSize = request.getLotSize();
return this;
}
public Listing build() {
Listing listing = new Listing();
listing.setCreated(mms.getCreated());
listing.setSecurityId(mms.getId());
listing.setLotSize(mmsReq.getLotSize());
listing.setMarket(market);
listing.setSymbolCode(mms.getSecuritySymbol());
listing.setSymbolName(mms.getFullName());
listing.setTradingCurrency(mms.getNominalCurrency());
listing.setWorkflowStatus(Status.Active.getKey());
return listing;
}
public Listing byUpdateMms(MoneyMarketSecurity mms, Listing listing) {
listing.setSecurityId(mms.getId());
listing.setSymbolCode(mms.getSecuritySymbol());
listing.setSymbolName(mms.getFullName());
listing.setTradingCurrency(mms.getNominalCurrency());
listing.setWorkflowStatus(mms.getWorkflowStatus());
listing.setLotSize(mms.getLotSize());
listing.setUpdated(mms.getUpdated());
return listing;
}
public Listing byNewEquity(EquitySecurity equitySecurity, EquitySecurityNewRequest request) {
Listing listing = new Listing();
listing.setCreated(equitySecurity.getCreated());
listing.setSecurityId(equitySecurity.getId());
listing.setLotSize(request.getLotSize());
listing.setMarket(market);
listing.setSymbolCode(equitySecurity.getSecuritySymbol());
listing.setSymbolName(equitySecurity.getFullName());
// listing.setTradingCurrency(equitySecurity.getNominalCurrency());
listing.setWorkflowStatus(Status.Active.getKey());
return listing;
}
public Listing byUpdateEquity(EquitySecurity equitySecurity, Listing listing) {
listing.setSecurityId(equitySecurity.getId());
listing.setSymbolCode(equitySecurity.getSecuritySymbol());
listing.setSymbolName(equitySecurity.getFullName());
listing.setWorkflowStatus(equitySecurity.getWorkflowStatus());
listing.setMarket(market);
listing.setLotSize(equitySecurity.getLotSize());
listing.setUpdated(equitySecurity.getUpdated());
return listing;
}
public Listing byNewFixedIncome(FixedIncomeSecurity instant, FixedIncomeSecurityNewRequest request) {
Listing listing = new Listing();
listing.setCreated(instant.getCreated());
listing.setSecurityId(instant.getId());
listing.setLotSize(request.getLotSize());
listing.setMarket(market);
listing.setSymbolCode(instant.getSecuritySymbol());
listing.setSymbolName(instant.getFullName());
listing.setTradingCurrency(instant.getNominalCurrency());
listing.setWorkflowStatus(Status.Active.getKey());
return listing;
}
public Listing byFixedIncomeEquity(FixedIncomeSecurity fixedIncomeSecurity, Listing listing) {
listing.setSecurityId(fixedIncomeSecurity.getId());
listing.setSymbolCode(fixedIncomeSecurity.getSecuritySymbol());
listing.setSymbolName(fixedIncomeSecurity.getFullName());
listing.setTradingCurrency(fixedIncomeSecurity.getNominalCurrency());
listing.setWorkflowStatus(fixedIncomeSecurity.getWorkflowStatus());
listing.setLotSize(fixedIncomeSecurity.getLotSize());
listing.setUpdated(fixedIncomeSecurity.getUpdated());
listing.setCreated(this.created);
listing.setSecurityId(this.securityId);
listing.setLotSize(this.lotSize);
listing.setMarket(this.market);
listing.setSymbolCode(this.symbolCode);
listing.setSymbolName(this.symbolName);
listing.setTradingCurrency(this.tradingCurrency);
listing.setWorkflowStatus(this.workflowStatus);
return listing;
}
}

View file

@ -21,6 +21,7 @@ import ru.spcex.clearing.securities.component.ListingBuilder;
import ru.spcex.clearing.securities.validation.ValidationProvider;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.Market;
import ru.spcex.platform.enumeration.UserRole;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
@ -40,7 +41,6 @@ public class EquitySecurityService extends QueueConsumer implements Initializing
private final ValidationProvider validation;
private final UserRoleVerification userRoleVerification;
private final ValidationHelper validationHelper;
private final ListingBuilder listingBuilder = new ListingBuilder();
@Autowired
public EquitySecurityService(Consumer<String, Object> kafkaQueue,
@ -103,7 +103,8 @@ public class EquitySecurityService extends QueueConsumer implements Initializing
Imdg<Listing> listingMap = transaction.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
//одним скопом выполняем реквест
equityImdg.insert(equity);
Listing listing = listingBuilder.byNewEquity(equity, req);
Listing listing = ListingBuilder.builder()
.append(equity).append(req).build();
listingMap.insert(listing);
//и сохраняем обновленный
// reqInfoMap.insert(reqInfo);
@ -148,7 +149,7 @@ public class EquitySecurityService extends QueueConsumer implements Initializing
log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId());
return null;
}
listing = listingBuilder.byUpdateEquity(equity, listing);
listing = updateListingByEquity(equity, listing);
listingImdg.update(listing);
return null;
}
@ -179,4 +180,15 @@ public class EquitySecurityService extends QueueConsumer implements Initializing
listingImdg.update(listing);
return null;
}
public Listing updateListingByEquity(EquitySecurity equitySecurity, Listing listing) {
listing.setSecurityId(equitySecurity.getId());
listing.setSymbolCode(equitySecurity.getSecuritySymbol());
listing.setSymbolName(equitySecurity.getFullName());
listing.setWorkflowStatus(equitySecurity.getWorkflowStatus());
listing.setMarket(Market.mkrs.getKey());
listing.setLotSize(equitySecurity.getLotSize());
listing.setUpdated(equitySecurity.getUpdated());
return listing;
}
}

View file

@ -40,7 +40,6 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial
private final ValidationProvider validation;
private final UserRoleVerification userRoleVerification;
private final ValidationHelper validationHelper;
private final ListingBuilder listingBuilder = new ListingBuilder();
@Autowired
public FixedIncomeSecurityService(Consumer<String, Object> kafkaQueue,
@ -108,7 +107,8 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial
Imdg<Listing> listingMap = transaction.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
//одним скопом выполняем реквест
fixedIncomeImdg.insert(fixedIncome);
Listing listing = listingBuilder.byNewFixedIncome(fixedIncome, req);
Listing listing = ListingBuilder.builder()
.append(fixedIncome).append(req).build();
listingMap.insert(listing);
//и сохраняем обновленный
// reqInfoMap.insert(reqInfo);
@ -159,7 +159,7 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial
log.error("updateFixedIncome id {} couldn't find listing with securityId {}", req.getId(), fixedIncome.getId());
return null;
}
listing = listingBuilder.byFixedIncomeEquity(fixedIncome, listing);
listing = updateListingByFixedIncome(fixedIncome, listing);
listingImdg.update(listing);
return null;
}
@ -190,4 +190,15 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial
listingImdg.update(listing);
return null;
}
public Listing updateListingByFixedIncome(FixedIncomeSecurity fixedIncomeSecurity, Listing listing) {
listing.setSecurityId(fixedIncomeSecurity.getId());
listing.setSymbolCode(fixedIncomeSecurity.getSecuritySymbol());
listing.setSymbolName(fixedIncomeSecurity.getFullName());
listing.setTradingCurrency(fixedIncomeSecurity.getNominalCurrency());
listing.setWorkflowStatus(fixedIncomeSecurity.getWorkflowStatus());
listing.setLotSize(fixedIncomeSecurity.getLotSize());
listing.setUpdated(fixedIncomeSecurity.getUpdated());
return listing;
}
}

View file

@ -48,7 +48,6 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial
private final UserRoleVerification userRoleVerification;
private final ValidationHelper validationHelper;
private final IMessageResolver messageResolver;
private final ListingBuilder listingBuilder = new ListingBuilder();
@Autowired
public MoneyMarketSecurityService(Consumer<String, Object> kafkaQueue,
@ -133,7 +132,8 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial
Imdg<Listing> listingMap = transaction.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
//одним скопом выполняем реквест
moneyMarketSecurityMap.insert(mms);
Listing listing = listingBuilder.byNewMms(mms, req);
Listing listing = ListingBuilder.builder()
.append(mms).append(req).build();
listingMap.insert(listing);
//и сохраняем обновленный
// reqInfoMap.insert(reqInfo);
@ -191,7 +191,7 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial
log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), mms.getId());
return null;
}
listing = listingBuilder.byUpdateMms(mms, listing);
listing = updateListingByMms(mms, listing);
listingImdg.update(listing);
return null;
}
@ -229,4 +229,15 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial
listingImdg.update(listing);
return null;
}
public Listing updateListingByMms(MoneyMarketSecurity mms, Listing listing) {
listing.setSecurityId(mms.getId());
listing.setSymbolCode(mms.getSecuritySymbol());
listing.setSymbolName(mms.getFullName());
listing.setTradingCurrency(mms.getNominalCurrency());
listing.setWorkflowStatus(mms.getWorkflowStatus());
listing.setLotSize(mms.getLotSize());
listing.setUpdated(mms.getUpdated());
return listing;
}
}

View file

@ -19,7 +19,6 @@ import ru.clearing.classes.statics.data.misc.Listing;
import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity;
import ru.clearing.platform.dictionary.*;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.securities.component.ListingBuilder;
import ru.spcex.clearing.securities.config.ErrorResolverConfig;
import ru.spcex.clearing.securities.config.ValidationConfig;
import ru.spcex.clearing.securities.service.cud.*;
@ -36,6 +35,7 @@ import java.util.concurrent.atomic.AtomicLong;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -74,7 +74,7 @@ public abstract class AbstractServiceTest {
public static Long issuerId = 13243L;
public static String termType = "TermType";
public static String currencyCode = "RUB";
protected final ListingBuilder listingBuilder = new ListingBuilder();
@Captor
protected ArgumentCaptor<ProducerRecord> producerRecord;
@MockBean
@ -84,7 +84,7 @@ public abstract class AbstractServiceTest {
protected ImdgProvider imdgProvider;
protected void init() {
imdgProvider.waitAvailable();
waitAvailableImdgProviderAndAddAdminWithDefaultId();
this.moneyMarketSecurityMap = imdgProvider.getImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, MoneyMarketSecurity.class);
this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
this.equitySecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class);

View file

@ -107,7 +107,7 @@ public class CouponPeriodServiceTest extends AbstractServiceTest {
request.setPeriodStartDate(testEndDate);
//ACT
String jsonString = getJsonStringForUPDATE(request, id);
String jsonString = getJsonStringForUpdate(request, id);
addRecordToKafka((MockConsumer) couponPeriodService.getConsumer(), TOPIC, PARTITION, 0, jsonString);

View file

@ -82,7 +82,7 @@ public class CurrencyServiceTest extends AbstractServiceTest {
request.setCurrencyCode(currencyCode);
//ACT
String jsonString = getJsonStringForUPDATE(request, ID);
String jsonString = getJsonStringForUpdate(request, ID);
addRecordToKafka((MockConsumer) currencyService.getConsumer(), TOPIC, PARTITION, 0, jsonString);

View file

@ -10,6 +10,7 @@ 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.securitites.EquitySecurityNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityUpdateRequest;
import ru.spcex.clearing.securities.component.ListingBuilder;
import ru.spcex.clearing.securities.service.cud.EquitySecurityService;
import ru.spcex.clearing.test.MatcherFactory;
@ -44,7 +45,8 @@ public class EquitySecurityServiceTest extends AbstractServiceTest {
final EquitySecurity equityPrediction = getEquitySecurity();
final EquitySecurityNewRequest request = getEquitySecurityNewRequest(equityPrediction);
Listing listingPrediction = listingBuilder.byNewEquity(equityPrediction, request);
Listing listingPrediction = ListingBuilder.builder()
.append(equityPrediction).append(request).build();
//ACT
String jsonString = getJsonStringForNew(request, ID);
@ -83,11 +85,11 @@ public class EquitySecurityServiceTest extends AbstractServiceTest {
equityPrediction.setLotSize(BigDecimal.valueOf(updateLotSize));
final EquitySecurityUpdateRequest request = getEquitySecurityUpdateRequest(equityPrediction);
Listing listingPrediction = new Listing();
listingPrediction = listingBuilder.byUpdateEquity(equityPrediction, listingPrediction);
listingPrediction = equitySecurityService.updateListingByEquity(equityPrediction, listingPrediction);
listingImdg.insert(listingPrediction);
//ACT
String jsonString = getJsonStringForUPDATE(request, ID);
String jsonString = getJsonStringForUpdate(request, ID);
addRecordToKafka((MockConsumer) equitySecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString);
@ -121,7 +123,7 @@ public class EquitySecurityServiceTest extends AbstractServiceTest {
equityPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey());
Listing listingPrediction = new Listing();
listingPrediction = listingBuilder.byUpdateEquity(equityPrediction, listingPrediction);
listingPrediction = equitySecurityService.updateListingByEquity(equityPrediction, listingPrediction);
listingImdg.insert(listingPrediction);
listingPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey());
@ -129,7 +131,7 @@ public class EquitySecurityServiceTest extends AbstractServiceTest {
commonDeleteRequest.setId(ID);
//ACT
String jsonString = getJsonStringForDELETE(commonDeleteRequest, ID);
String jsonString = getJsonStringForDelete(commonDeleteRequest, ID);
addRecordToKafka((MockConsumer) equitySecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString);

View file

@ -138,7 +138,7 @@ class FixedIncomeCashFlowServiceTest {
predictableFixedIncomeCashFlow.setValueDate(TEST_DATE);
//ACT
String jsonString = getJsonStringForUPDATE(updateRequest, id);
String jsonString = getJsonStringForUpdate(updateRequest, id);
addRecordToKafka((MockConsumer) fixedIncomeCashFlowService.getConsumer(), TOPIC_FIXED_INCOME_CASH_FLOW_UPDATE, PARTITION, 0, jsonString);

View file

@ -10,6 +10,7 @@ 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.securitites.FixedIncomeSecurityNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityUpdateRequest;
import ru.spcex.clearing.securities.component.ListingBuilder;
import ru.spcex.clearing.securities.service.cud.FixedIncomeSecurityService;
import ru.spcex.clearing.test.MatcherFactory;
@ -45,7 +46,8 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest {
final FixedIncomeSecurity fixedIncomePrediction = getFixedIncomeSecurity();
final FixedIncomeSecurityNewRequest request = getFixedIncomeSecurityNewRequest(fixedIncomePrediction);
Listing listingPrediction = listingBuilder.byNewFixedIncome(fixedIncomePrediction, request);
Listing listingPrediction = ListingBuilder.builder()
.append(fixedIncomePrediction).append(request).build();
//ACT
String jsonString = getJsonStringForNew(request, ID);
@ -85,11 +87,11 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest {
fixedIncomePrediction.setLotSize(BigDecimal.valueOf(updateLotSize));
final FixedIncomeSecurityUpdateRequest request = getFixedIncomeSecurityUpdateRequest(fixedIncomePrediction);
Listing listingPrediction = new Listing();
listingPrediction = listingBuilder.byFixedIncomeEquity(fixedIncomePrediction, listingPrediction);
listingPrediction = fixedIncomeSecurityService.updateListingByFixedIncome(fixedIncomePrediction, listingPrediction);
listingImdg.insert(listingPrediction);
//ACT
String jsonString = getJsonStringForUPDATE(request, ID);
String jsonString = getJsonStringForUpdate(request, ID);
addRecordToKafka((MockConsumer) fixedIncomeSecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString);
@ -123,7 +125,7 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest {
fixedIncomePrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey());
Listing listingPrediction = new Listing();
listingPrediction = listingBuilder.byFixedIncomeEquity(fixedIncomePrediction, listingPrediction);
listingPrediction = fixedIncomeSecurityService.updateListingByFixedIncome(fixedIncomePrediction, listingPrediction);
listingImdg.insert(listingPrediction);
listingPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey());
@ -131,7 +133,7 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest {
commonDeleteRequest.setId(ID);
//ACT
String jsonString = getJsonStringForDELETE(commonDeleteRequest, ID);
String jsonString = getJsonStringForDelete(commonDeleteRequest, ID);
addRecordToKafka((MockConsumer) fixedIncomeSecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString);

View file

@ -13,6 +13,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSe
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.clearing.securities.component.ListingBuilder;
import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService;
import ru.spcex.clearing.test.MatcherFactory;
import ru.spcex.platform.imdg.api.Imdg;
@ -24,13 +25,14 @@ import java.util.Map;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{
public class MoneyMarketSecurityServiceTest extends AbstractServiceTest {
private static final MatcherFactory.Matcher<MoneyMarketSecurity> MONEY_MARKET_SECURITY_MATCHER = usingIgnoringFieldsComparator("created", "updated");
private final long ID = currentId.getAndIncrement();
private final int PARTITION = 0;
private MoneyMarketSecurityFactory moneyMarketSecurityFactory;
@Autowired
private MoneyMarketSecurityService moneyMarketSecurityService;
@PostConstruct
protected void init() {
super.init();
@ -56,7 +58,7 @@ public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{
* {@link MoneyMarketSecurityNewRequest#fullName} - "estat"<br>
*/
@Test
public void testNewMoneyMarketSecurity(){
public void testNewMoneyMarketSecurity() {
clearAllInImdg(moneyMarketSecurityMap);
final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_NEW;
@ -64,7 +66,8 @@ public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{
.getMoneyMarketSecurity();
final MoneyMarketSecurityNewRequest keyRequest = moneyMarketSecurityFactory
.getMoneyMarketSecurityNewRequest();
Listing listingPrediction = listingBuilder.byNewMms(moneyMarketSecurityPrediction, keyRequest);
Listing listingPrediction = ListingBuilder.builder()
.append(moneyMarketSecurityPrediction).append(keyRequest).build();
//ACT
String jsonString = getJsonStringForNew(keyRequest, ID);
@ -92,7 +95,7 @@ public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{
* {@link CommonDeleteRequest#id} - Идентификатор записи<br>
*/
@Test
public void testDeleteMoneyMarket(){
public void testDeleteMoneyMarket() {
clearAllInImdg(moneyMarketSecurityMap);
final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_DELETE;
@ -102,7 +105,7 @@ public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{
moneyMarketSecurityPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey());
Listing listingPrediction = new Listing();
listingPrediction = listingBuilder.byUpdateMms(moneyMarketSecurityPrediction, listingPrediction);
listingPrediction = moneyMarketSecurityService.updateListingByMms(moneyMarketSecurityPrediction, listingPrediction);
listingImdg.insert(listingPrediction);
listingPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey());
@ -110,7 +113,7 @@ public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{
commonDeleteRequest.setId(ID);
//ACT
String jsonString = getJsonStringForDELETE(commonDeleteRequest, ID);
String jsonString = getJsonStringForDelete(commonDeleteRequest, ID);
addRecordToKafka((MockConsumer) moneyMarketSecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString);
@ -154,12 +157,12 @@ public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{
keyRequest.setTermType(termType);
keyRequest.setLotSize(updateLotSize);
Listing listingPrediction = new Listing();
listingPrediction = listingBuilder.byUpdateMms(moneyMarketSecurityPrediction, listingPrediction);
listingPrediction = moneyMarketSecurityService.updateListingByMms(moneyMarketSecurityPrediction, listingPrediction);
listingImdg.insert(listingPrediction);
listingPrediction.setLotSize(updateLotSize);
//ACT
String jsonString = getJsonStringForUPDATE(keyRequest, ID);
String jsonString = getJsonStringForUpdate(keyRequest, ID);
addRecordToKafka((MockConsumer) moneyMarketSecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString);

View file

@ -46,6 +46,8 @@ public class UserRoleVerification {
this.roleVerificationError = roleVerificationError;
}
//нужен чтобы спринг мог создать бин
private UserRoleVerification(){}
public UserRoleVerification(ImdgProvider imdg,
IMessageResolver messageResolver,
UserRole roleForVerification,

View file

@ -60,5 +60,13 @@
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-imdg-api-hazelcast-impl</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-enum</artifactId>
</dependency>
</dependencies>
</project>

View file

@ -31,6 +31,7 @@ import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.platform.messaging.service.Status.Success;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.config.ImdgTestConfig.defaultAdminId;
public class TestUtils {
public static final MatcherFactory.Matcher<BaseRequest<Object>> BASE_REQUEST_MATCHER = usingIgnoringFieldsComparator();
@ -93,11 +94,11 @@ public class TestUtils {
return getJsonBaseRequest(accountRequest, id, ActionType.NEW);
}
public static <T> String getJsonStringForUPDATE(T accountRequest, long id) {
public static <T> String getJsonStringForUpdate(T accountRequest, long id) {
return getJsonBaseRequest(accountRequest, id, ActionType.UPDATE);
}
public static <T> String getJsonStringForDELETE(T accountRequest, long id) {
public static <T> String getJsonStringForDelete(T accountRequest, long id) {
return getJsonBaseRequest(accountRequest, id, ActionType.DELETE);
}
@ -105,6 +106,7 @@ public class TestUtils {
BaseRequest<T> baseRequest = new BaseRequest<>();
baseRequest.setRequestPayload(accountRequest);
baseRequest.setId(id);
baseRequest.setUserId(defaultAdminId);
baseRequest.setActionType(actionType);
String jsonBaseRequest;
try {

View file

@ -8,6 +8,11 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import ru.clearing.classes.statics.data.user.UserRoleSession;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.enumeration.UserRole;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@ -21,7 +26,19 @@ import java.util.concurrent.atomic.AtomicLong;
public class ImdgTestConfig {
public static final AtomicLong currentID = new AtomicLong(0L);
public static final Long defaultAdminId = 1000L;
private HazelcastInstance hazelcastInstance;
private static ImdgProvider imdgProvider;
public static void waitAvailableImdgProviderAndAddAdminWithDefaultId(){
imdgProvider.waitAvailable();
Imdg<UserRoleSession> userRoleSessions = imdgProvider.getImdg(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class);
UserRoleSession userRoleSession = new UserRoleSession();
userRoleSession.setUserId(defaultAdminId);
userRoleSession.setUserRole(UserRole.Admin.getKey());
userRoleSession.setStatus(Status.Active.getKey());
userRoleSessions.insert(userRoleSession);
}
private static ThreadPoolTaskExecutor createThreadPoolTestTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
@ -61,7 +78,8 @@ public class ImdgTestConfig {
cfg.setNetworkConfig(networkConfig);
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg);
HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance);
return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params);
imdgProvider = new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params);
return imdgProvider;
}
@Bean(name = "hazelcastClientParams")

View file

@ -16,6 +16,18 @@ public enum Task implements IEnumKey {
createOrderConfirm("CORC"),
getAllBalance("GALB"),
createReport_GREP("GREP"), // Создание отчёта (report-service) RPRT нескольких видов, этот GREP
unloadingSession_LIMM("LIMM"),//Выгрузка в торговую систему остатков секции МКР
unloadingSession_LIMF("LIMF"),//Выгрузка в торговую систему остатков Фондовой секции
liquidationSession_LIQU("LIQU"),//Ликвидационная сессия по обязательтсвам участника
startSession_STRM("STRM"),//Начало торговой сессии секции МКР
terminationSession_ETRM("ETRM"),//Завершение торговой сессии секции МКР
startSession_SIPO("SIPO"),//Начало торговой сессии по первичным торгам
terminationSession_EIPO("EIPO"),//Завершение торговой сессии по первичным торгам
startSession_STRF("STRF"),//Начало торговой сессии по вторичным торгам
terminationSession_ETRF("ETRF"),//Завершение торговой сессии по вторичным торгам
reconciliationRequest_RCHK("RCHK"),//Запрос на сверку активов
createRegistry_GRYT("GRYT"),//Сформировать регистр на текущий день
createRegistry_GRRT("GRRT"),//Сформировать реестр на текущий день
createRegistry_GORD("GORD"), // Формирование реестра распоряжений, направленных расчетному депозитарию
;

View file

@ -149,6 +149,15 @@ public class ImdgHazelcast<T extends SpcexObjectBase> implements Imdg<T> {
return result;
}
@Override
public Collection<Long> getCollectionIdsBySQL(String paramString) {
SqlPredicate sqlPredicate = new SqlPredicate(paramString);
Set<Map.Entry<Long, T>> found = map.entrySet(sqlPredicate);
List<Long> result = new ArrayList<>(found.size());
for (Map.Entry<Long, T> entry : found) result.add(entry.getKey());
return result;
}
@Override
public Long nextIDSequenceFor() {
return idGenerator.newId();