company-service account-srvice http://jira.mfd.msk:8088/browse/CLS-265 http://jira.mfd.msk:8088/browse/CLS-333 Info-account - доделал правильный инкремент номера счёта

This commit is contained in:
AKurakin 2023-05-27 10:53:12 +03:00
parent 64eb0bf654
commit 1e8ae0a47b
2 changed files with 88 additions and 3 deletions

View file

@ -1,5 +1,6 @@
package ru.spcex.clearing.account.service;
import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
import org.slf4j.Logger;
@ -31,12 +32,16 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.log.ExceptionUtils;
import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Service
public class InformationAccountService extends QueueConsumer implements InitializingBean {
@ -50,6 +55,11 @@ public class InformationAccountService extends QueueConsumer implements Initiali
private final Function<InformationAccountNewRequest, IValidator> infoAccountNewRequestValidator;
private final Imdg<InformationAccount> informationAccountImdg;
private final Imdg<Account> accountImdg;
/**
* Кэш-счётчик сквозных номеров счетов.
* См. accountNextId()
*/
protected AtomicLong infoCounter;
@Autowired
public InformationAccountService(Consumer<String, Object> kafkaQueue,
@ -61,7 +71,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
AccountService accountService,
RequestHelper requestHelper,
@Qualifier("informationAccountNewRequestValidator")
Function<InformationAccountNewRequest, IValidator> infoAccountNewRequestValidator) {
Function<InformationAccountNewRequest, IValidator> infoAccountNewRequestValidator) {
super(kafkaQueue, kafkaResponseQueue);
this.kafkaSender = kafkaSender;
this.messageResolver = messageResolver;
@ -96,7 +106,9 @@ public class InformationAccountService extends QueueConsumer implements Initiali
if (requestInfoUpdate != null) return requestInfoUpdate;
Long newId = informationAccountImdg.nextIDSequenceFor();
String accountValue = generateInfoAccount(newId);
Long infoSequenceId = accountNextId();
String accountValue = generateInfoAccount(infoSequenceId);
log.trace("New info-account id={}, sequenceId={}, account={}", newId, infoSequenceId, accountValue);
ImdgPredicateBuilder accountPredicateBuilder = accountImdg.predicateBuilder();
ImdgPredicate companyIdPredicate = accountPredicateBuilder.equals("companyId", 1L);
@ -184,7 +196,9 @@ public class InformationAccountService extends QueueConsumer implements Initiali
// todo требуется последовательность n+1
Long newId = informationAccountImdg.nextIDSequenceFor();
String accountValue = generateInfoAccount(newId);
Long infoSequenceId = accountNextId();
String accountValue = generateInfoAccount(infoSequenceId);
log.trace("New info-account id={}, sequenceId={}, account={}", newId, infoSequenceId, accountValue);
ImdgPredicate andPredicate = pb.and(
pb.equals("companyId", 1L),
@ -251,4 +265,48 @@ public class InformationAccountService extends QueueConsumer implements Initiali
return "%d%d%08d%d".formatted(39911, 810, id, 7000);
}
/**
* Сквозной номер инфо-счетов
*
* @return infoCounter++
*/
protected Long accountNextId() {
if (infoCounter == null) synchronized (this) {
if (infoCounter == null) {
log.debug("Init account-information counter.");
Collection<Account> allInfoAcc = accountImdg.getCollectionObjectsByFieldValues(Map.of("accountType", AccountType.Info.getKey()));
if (allInfoAcc.isEmpty()) {
infoCounter = new AtomicLong(1);
log.debug("No account information on map. n={}", infoCounter.get());
} else {
Pattern accPattern = Pattern.compile("39911810([0-9]{8})7000");
int maxN = 1;
int parsedCount = 0;
for (Account acc : allInfoAcc) {
try {
String number = acc.getAccount();
if (StringUtils.isEmpty(number)) continue;
Matcher m = accPattern.matcher(number);
if (m.find()) {
String seqNumber = m.group(1);
if (StringUtils.isNotEmpty(seqNumber)) {
int accN = Integer.parseInt(seqNumber);
if (accN > maxN) maxN = accN;
}
parsedCount++;
}
} catch (Exception errParse) {
log.warn("Error parse account {}: {}", acc.getId(), ExceptionUtils.getStackTrace(errParse));
}
}
infoCounter = new AtomicLong(maxN);
log.debug("Parsed {} information accounts ({} pattern match) in map. n={}",
allInfoAcc.size(), parsedCount, infoCounter.get());
}
}
}
return infoCounter.getAndIncrement();
}
}

View file

@ -4,6 +4,7 @@ import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
@ -32,6 +33,7 @@ import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import javax.annotation.PostConstruct;
@ -179,4 +181,29 @@ class InformationAccountServiceTest {
accountImdg.delete(resultAccountNew);
}
@Autowired ImdgProvider imdgProvider;
@Test
void accountIncrementSequence() {
Imdg<InformationAccount> accountInfoImdg = hazelcastServiceTest.getImdg( IMDGDistributedNames.Map_InformationAccount, InformationAccount.class );
{
Account account = new Account();
account.setId(120L);
account.setAccountType(AccountType.Info.getKey());
account.setCompanyId(10L);
account.setAccount("39911810000000127000");
accountImdg.insert(account);
InformationAccount accountInfo = new InformationAccount();
accountInfo.setId(121L);
accountInfo.setAccountId(account.getId());
accountInfo.setCompanyId(account.getCompanyId());
accountInfoImdg.insert(accountInfo);
}
InformationAccountService infoAccSvc=new InformationAccountService(null,null,null,
null, imdgProvider, null, null, null, null);
Long n = infoAccSvc.accountNextId();
Assertions.assertEquals(12L, n);
n = infoAccSvc.accountNextId();
Assertions.assertEquals(13L, n);
}
}