add limitId and lazy create limit while hold (#20)

* add limitId and lazy create limit while hold

* fix review
This commit is contained in:
Gregory 2024-09-30 10:35:31 +03:00 committed by GitHub
parent 20314fd894
commit a0e3197515
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 176 additions and 187 deletions

View File

@ -173,7 +173,7 @@
<dependency>
<groupId>dev.vality</groupId>
<artifactId>liminator-proto</artifactId>
<version>1.5-fe957d8</version>
<version>1.6-5ee237c</version>
</dependency>
<dependency>
<groupId>dev.vality.woody</groupId>

View File

@ -24,6 +24,7 @@ public class CurrentLimitValuesToLimitResponseConverter implements Converter<Lis
limitValue.getLimitName(),
limitValue.getCommitValue(),
limitValue.getHoldValue())
.setLimitId(limitValue.getLimitId())
)
.toList();
}

View File

@ -1,7 +1,7 @@
package com.empayre.liminator.converter;
import com.empayre.liminator.domain.tables.pojos.LimitData;
import dev.vality.liminator.CreateLimitRequest;
import dev.vality.liminator.LimitChange;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
@ -9,12 +9,13 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
@Component
public class CreateLimitRequestToLimitDataConverter implements Converter<CreateLimitRequest, LimitData> {
public class LimitChangeToLimitDataConverter implements Converter<LimitChange, LimitData> {
@Override
public LimitData convert(CreateLimitRequest request) {
public LimitData convert(LimitChange change) {
LimitData data = new LimitData();
data.setName(request.getLimitName());
data.setName(change.getLimitName());
data.setLimitId(change.getLimitId());
data.setCreatedAt(LocalDate.now());
data.setWtime(LocalDateTime.now());
return data;

View File

@ -28,7 +28,7 @@ public class LimitContextDaoImpl implements LimitContextDao {
public LimitContext getLimitContext(Long limitId) {
return dslContext
.selectFrom(LIMIT_CONTEXT)
.where(LIMIT_CONTEXT.LIMIT_ID.eq(limitId))
.where(LIMIT_CONTEXT.LIMIT_DATA_ID.eq(limitId))
.fetchOneInto(LimitContext.class);
}
}

View File

@ -102,14 +102,14 @@ public class OperationDaoImpl implements OperationDao {
public List<LimitValue> getCurrentLimitValue(List<String> limitNames) {
String sql = """
with hold_data as (
select ld.id, ld.name, coalesce(sum(ops.operation_value), 0) as hold_value
select ld.id, ld.name, ld.limit_id, coalesce(sum(ops.operation_value), 0) as hold_value
from lim.limit_data as ld
left join lim.operation as ops
on ops.limit_id = ld.id and ops.state = 'HOLD'
where ld.name in ({0})
group by ld.id, ld.name
), commit_data as (
select ld.id, ld.name, coalesce(sum(ops.operation_value), 0) as commit_value
select ld.id, ld.name, ld.limit_id, coalesce(sum(ops.operation_value), 0) as commit_value
from lim.limit_data as ld
left join lim.operation as ops
on ops.limit_id = ld.id and ops.state = 'COMMIT'
@ -117,7 +117,7 @@ public class OperationDaoImpl implements OperationDao {
group by ld.id, ld.name
)
select cd.name as limit_name, cd.commit_value, hd.hold_value
select cd.limit_id, cd.name as limit_name, cd.commit_value, hd.hold_value
from commit_data as cd
join hold_data as hd on cd.id = hd.id;
""";
@ -134,7 +134,7 @@ public class OperationDaoImpl implements OperationDao {
from lim.operation
where operation_id = {0}
), hold_data as (
select ld.id, ld.name, coalesce(sum(ops.operation_value), 0) as hold_value
select ld.id, ld.name, ld.limit_id, coalesce(sum(ops.operation_value), 0) as hold_value
from lim.limit_data as ld
left join lim.operation as ops
on ops.limit_id = ld.id
@ -143,7 +143,7 @@ public class OperationDaoImpl implements OperationDao {
where ld.name in ({1})
group by ld.id, ld.name
), commit_data as (
select ld.id, ld.name, coalesce(sum(ops.operation_value), 0) as commit_value
select ld.id, ld.name, ld.limit_id, coalesce(sum(ops.operation_value), 0) as commit_value
from lim.limit_data as ld
left join lim.operation as ops
on ops.limit_id = ld.id
@ -153,7 +153,7 @@ public class OperationDaoImpl implements OperationDao {
group by ld.id, ld.name
)
select cd.name as limit_name, cd.commit_value, hd.hold_value
select cd.limit_id, cd.name as limit_name, cd.commit_value, hd.hold_value
from commit_data as cd
join hold_data as hd on cd.id = hd.id;
""";

View File

@ -1,69 +0,0 @@
package com.empayre.liminator.handler.impl;
import com.empayre.liminator.dao.LimitContextDao;
import com.empayre.liminator.dao.LimitDataDao;
import com.empayre.liminator.domain.tables.pojos.LimitContext;
import com.empayre.liminator.domain.tables.pojos.LimitData;
import com.empayre.liminator.handler.Handler;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.vality.liminator.CreateLimitRequest;
import dev.vality.liminator.LimitResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.TException;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Map;
@Slf4j
@Component
@RequiredArgsConstructor
public class CreateLimitHandler implements Handler<CreateLimitRequest, LimitResponse> {
private final ObjectMapper mapper;
private final Converter<CreateLimitRequest, LimitData> createLimitRequestToLimitDataConverter;
private final LimitDataDao limitDataDao;
private final LimitContextDao limitContextDao;
private static final String LOG_PREFIX = "CREATE";
private static final String EMPTY_JSON = "{}";
@Transactional
@Override
public LimitResponse handle(CreateLimitRequest request) throws TException {
String limitName = request.getLimitName();
LimitData existedLimitData = limitDataDao.get(limitName);
if (existedLimitData != null) {
log.info("[{}] Limit {} already exists", LOG_PREFIX, limitName);
return new LimitResponse(limitName, 0, 0);
}
LimitData limitData = createLimitRequestToLimitDataConverter.convert(request);
Long limitId = limitDataDao.save(limitData);
if (request.context != null) {
limitContextDao.save(convertToLimitContext(limitId, request.context));
}
return new LimitResponse(limitName, 0, 0);
}
private LimitContext convertToLimitContext(Long limitId, Map<String, String> contextMap) {
LimitContext context = new LimitContext();
context.setLimitId(limitId);
context.setContext(getContextString(contextMap));
context.setWtime(LocalDateTime.now());
return context;
}
private String getContextString(Map<String, String> contextMap) {
try {
return mapper.writeValueAsString(contextMap);
} catch (JsonProcessingException e) {
log.error("[{}] ContextJSON processing exception", LOG_PREFIX, e);
return EMPTY_JSON;
}
}
}

View File

@ -5,7 +5,7 @@ import com.empayre.liminator.domain.enums.OperationState;
import com.empayre.liminator.domain.tables.pojos.LimitData;
import com.empayre.liminator.domain.tables.pojos.Operation;
import com.empayre.liminator.handler.FinalizeOperationHandler;
import com.empayre.liminator.service.LimitDataGettingService;
import com.empayre.liminator.service.LimitDataService;
import com.empayre.liminator.service.LimitOperationsLoggingService;
import dev.vality.liminator.LimitRequest;
import dev.vality.liminator.OperationNotFound;
@ -24,13 +24,13 @@ import java.util.List;
public class FinalizeOperationHandlerImpl implements FinalizeOperationHandler {
private final OperationDao operationDao;
private final LimitDataGettingService limitDataGettingService;
private final LimitDataService limitDataService;
private final LimitOperationsLoggingService limitOperationsLoggingService;
@Transactional
@Override
public void handle(LimitRequest request, OperationState state) throws TException {
List<LimitData> limitData = limitDataGettingService.get(request, state.getLiteral());
List<LimitData> limitData = limitDataService.get(request, state.getLiteral());
checkExistedHoldOperations(request, limitData, state);
List<Long> limitIds = limitData.stream()
.map(LimitData::getId)

View File

@ -6,10 +6,10 @@ import com.empayre.liminator.domain.enums.OperationState;
import com.empayre.liminator.domain.tables.pojos.LimitData;
import com.empayre.liminator.domain.tables.pojos.Operation;
import com.empayre.liminator.handler.HoldOperationHandler;
import com.empayre.liminator.service.LimitDataGettingService;
import com.empayre.liminator.service.LimitDataService;
import com.empayre.liminator.service.LimitOperationsLoggingService;
import com.empayre.liminator.util.LimitDataUtils;
import dev.vality.liminator.DuplicateOperation;
import dev.vality.liminator.LimitChange;
import dev.vality.liminator.LimitRequest;
import dev.vality.liminator.OperationAlreadyInFinalState;
import lombok.RequiredArgsConstructor;
@ -20,6 +20,7 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -30,9 +31,9 @@ import java.util.Map;
public class HoldOperationHandlerImpl implements HoldOperationHandler {
private final OperationDao operationDao;
private final LimitDataGettingService limitDataGettingService;
private final OperationConverter operationConverter;
private final LimitOperationsLoggingService limitOperationsLoggingService;
private final LimitDataService limitDataService;
@Value("${service.skipExistedHoldOps}")
private boolean skipExistedHoldOps;
@ -42,8 +43,17 @@ public class HoldOperationHandlerImpl implements HoldOperationHandler {
@Transactional
@Override
public void handle(LimitRequest request) throws TException {
List<LimitData> limitData = limitDataGettingService.get(request, LOG_PREFIX);
Map<String, Long> limitNamesMap = LimitDataUtils.createLimitNamesMap(limitData);
var limitNamesMap = new HashMap<String, Long>();
List<LimitChange> limitChanges = request.getLimitChanges();
for (LimitChange change : limitChanges) {
LimitData limitData = limitDataService.get(change.getLimitName());
if (limitData != null) {
limitNamesMap.put(limitData.getName(), limitData.getId());
} else {
var limitId = limitDataService.save(change);
limitNamesMap.put(change.getLimitName(), limitId);
}
}
checkExistedFinalizeOperations(limitNamesMap, request.getOperationId());
if (!skipExistedHoldOps) {

View File

@ -7,6 +7,7 @@ import lombok.Data;
@AllArgsConstructor
public class LimitValue {
private String limitId;
private String limitName;
private Long commitValue;
private Long holdValue;

View File

@ -20,16 +20,11 @@ import java.util.List;
@RequiredArgsConstructor
public class LiminatorService implements LiminatorServiceSrv.Iface {
private final Handler<CreateLimitRequest, LimitResponse> createLimitHandler;
private final HoldOperationHandler holdOperationHandler;
private final FinalizeOperationHandler finalizeOperationHandler;
private final Handler<LimitRequest, List<LimitResponse>> getLimitsValuesHandler;
private final Handler<List<String>, List<LimitResponse>> getLastLimitsValuesHandler;
@Override
public LimitResponse create(CreateLimitRequest createLimitRequest) throws DuplicateLimitName, TException {
return createLimitHandler.handle(createLimitRequest);
}
@Override
public List<LimitResponse> hold(LimitRequest request)

View File

@ -1,39 +0,0 @@
package com.empayre.liminator.service;
import com.empayre.liminator.dao.LimitDataDao;
import com.empayre.liminator.domain.tables.pojos.LimitData;
import dev.vality.liminator.LimitChange;
import dev.vality.liminator.LimitNotFound;
import dev.vality.liminator.LimitRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.TException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
public class LimitDataGettingService {
private final LimitDataDao limitDataDao;
public List<LimitData> get(LimitRequest request, String source) throws TException {
List<String> limitNames = request.getLimitChanges().stream()
.map(LimitChange::getLimitName)
.toList();
List<LimitData> limitData = limitDataDao.get(limitNames);
if (CollectionUtils.isEmpty(limitData)) {
log.error("[{}] Limits not found: {}", source, limitNames);
throw new LimitNotFound();
}
if (limitData.size() != limitNames.size()) {
log.error("[{}] Received limit ({}) size is not equal to expected ({}). " +
"Probably one of limits doesn't exist", source, limitData.size(), limitNames.size());
throw new LimitNotFound();
}
return limitData;
}
}

View File

@ -0,0 +1,86 @@
package com.empayre.liminator.service;
import com.empayre.liminator.dao.LimitContextDao;
import com.empayre.liminator.dao.LimitDataDao;
import com.empayre.liminator.domain.tables.pojos.LimitContext;
import com.empayre.liminator.domain.tables.pojos.LimitData;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.vality.liminator.LimitChange;
import dev.vality.liminator.LimitNotFound;
import dev.vality.liminator.LimitRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.TException;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
@RequiredArgsConstructor
public class LimitDataService {
private static final String EMPTY_JSON = "{}";
private final ObjectMapper mapper;
private final Converter<LimitChange, LimitData> limitChangeToLimitDataConverter;
private final LimitDataDao limitDataDao;
private final LimitContextDao limitContextDao;
public List<LimitData> get(LimitRequest request, String source) throws TException {
List<String> limitNames = request.getLimitChanges().stream()
.map(LimitChange::getLimitName)
.toList();
List<LimitData> limitData = limitDataDao.get(limitNames);
if (CollectionUtils.isEmpty(limitData)) {
log.error("[{}] Limits not found: {}", source, limitNames);
throw new LimitNotFound();
}
if (limitData.size() != limitNames.size()) {
log.error("[{}] Received limit ({}) size is not equal to expected ({}). " +
"Probably one of limits doesn't exist", source, limitData.size(), limitNames.size());
throw new LimitNotFound();
}
return limitData;
}
public LimitData get(String limitName) throws TException {
log.debug("Try to get limit for limitName: {}", limitName);
return limitDataDao.get(limitName);
}
@Transactional
public Long save(LimitChange change) {
log.info("Save limit: {}", change.getLimitName());
LimitData limitData = limitChangeToLimitDataConverter.convert(change);
Long limitId = limitDataDao.save(limitData);
if (change.context != null) {
limitContextDao.save(convertToLimitContext(limitId, change));
}
return limitId;
}
private LimitContext convertToLimitContext(Long limitId, LimitChange change) {
LimitContext context = new LimitContext();
context.setLimitDataId(limitId);
context.setContext(getContextString(change.getContext()));
context.setWtime(LocalDateTime.now());
return context;
}
private String getContextString(Map<String, String> contextMap) {
try {
return mapper.writeValueAsString(contextMap);
} catch (JsonProcessingException e) {
log.error("ContextJSON processing exception", e);
return EMPTY_JSON;
}
}
}

View File

@ -0,0 +1,2 @@
ALTER TABLE lim.limit_context RENAME COLUMN limit_id TO limit_data_id;
ALTER TABLE lim.limit_data ADD COLUMN limit_id character varying;

View File

@ -19,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.*;
@Slf4j
@PostgresqlSpringBootITest
public class DaoTests {
class DaoTests {
@Autowired
private LimitDataDao limitDataDao;
@ -31,11 +31,12 @@ public class DaoTests {
private OperationDao operationDao;
@Test
public void limitDataDaoTest() {
void limitDataDaoTest() {
List<String> limitNames = new ArrayList<>();
for (int i = 0; i < 10; i++) {
String limitName = "Limit-" + i;
limitDataDao.save(new LimitData(null, limitName, LocalDate.now(), LocalDateTime.now()));
String limitId = "limit-id-" + i;
limitDataDao.save(new LimitData(null, limitName, LocalDate.now(), LocalDateTime.now(), limitId));
limitNames.add(limitName);
}
@ -44,10 +45,10 @@ public class DaoTests {
}
@Test
public void limitContextDaoTest() {
void limitContextDaoTest() {
LimitContext limitContext = new LimitContext();
long limitId = 123L;
limitContext.setLimitId(limitId);
limitContext.setLimitDataId(limitId);
limitContext.setContext("{\"provider\":\"test\"}");
limitContextDao.save(limitContext);
LimitContext result = limitContextDao.getLimitContext(limitId);
@ -55,13 +56,14 @@ public class DaoTests {
}
@Test
public void operationDaoTest() {
void operationDaoTest() {
List<Long> limitIdsList = new ArrayList<>();
List<String> limitNamesList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
String limitName = "Limit-odc-1-" + i;
Long limitId = limitDataDao.save(new LimitData(null, limitName, LocalDate.now(), LocalDateTime.now()));
limitIdsList.add(limitId);
String limitId = "Limit-id-odc-1-" + i;
Long id = limitDataDao.save(new LimitData(null, limitName, LocalDate.now(), LocalDateTime.now(), limitId));
limitIdsList.add(id);
limitNamesList.add(limitName);
}
List<Operation> operations = new ArrayList<>();
@ -103,14 +105,15 @@ public class DaoTests {
}
@Test
public void operationDaoCurrentLimitWithOperationIdTest() {
void operationDaoCurrentLimitWithOperationIdTest() {
String limitName = "Limit-odc-2";
Long limitId = limitDataDao.save(new LimitData(null, limitName, LocalDate.now(), LocalDateTime.now()));
String limitId = "Limit-id-odc-2";
Long id = limitDataDao.save(new LimitData(null, limitName, LocalDate.now(), LocalDateTime.now(), limitId));
List<Operation> operations = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Operation operation = createOperation(
limitId,
"Operation-odc-2-%s-%s".formatted(limitId, i),
id,
"Operation-odc-2-%s-%s".formatted(id, i),
LocalDateTime.now().minusMinutes(11L - i));
operationDao.save(operation);
operations.add(operation);

View File

@ -1,7 +1,6 @@
package com.empayre.liminator.service;
import com.empayre.liminator.config.PostgresqlSpringBootITest;
import dev.vality.liminator.CreateLimitRequest;
import dev.vality.liminator.LimitChange;
import dev.vality.liminator.LimitRequest;
import dev.vality.liminator.LimitResponse;
@ -10,11 +9,12 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
@PostgresqlSpringBootITest
public class LiminatorServiceTest {
class LiminatorServiceTest {
@Autowired
private LiminatorService liminatorService;
@ -22,27 +22,36 @@ public class LiminatorServiceTest {
@Test
void createLimitTest() throws TException {
String limitName = "TestLimitCreate";
CreateLimitRequest request = new CreateLimitRequest()
.setLimitName(limitName);
long holdValue = 123L;
String limitId = "limitId";
LimitRequest request = new LimitRequest()
.setOperationId("operationId")
.setLimitChanges(List.of(
new LimitChange()
.setLimitName(limitName)
.setLimitId(limitId)
.setValue(holdValue)
.setContext(Map.of("test", "test"))
)
);
LimitResponse response = liminatorService.create(request);
assertEquals(limitName, response.getLimitName());
assertEquals(0, response.getHoldValue());
assertEquals(0, response.getCommitValue());
List<LimitResponse> response = liminatorService.hold(request);
assertEquals(limitName, response.get(0).getLimitName());
assertEquals(limitId, response.get(0).getLimitId());
assertEquals(holdValue, response.get(0).getHoldValue());
assertEquals(0, response.get(0).getCommitValue());
}
@Test
void holdValueTest() throws TException {
String limitName = "TestLimitHold";
CreateLimitRequest createRequest = new CreateLimitRequest()
.setLimitName(limitName);
liminatorService.create(createRequest);
String operationId = "OpHold";
LimitRequest holdRequest = new LimitRequest()
.setOperationId(operationId)
.setLimitChanges(List.of(new LimitChange(limitName, 500L)));
List<LimitResponse> holdResponse = liminatorService.hold(holdRequest);
assertEquals(1, holdResponse.size());
LimitResponse response = holdResponse.get(0);
assertEquals(500, response.getHoldValue());
@ -53,10 +62,6 @@ public class LiminatorServiceTest {
@Test
void commitValueTest() throws TException {
String limitName = "TestLimitCommit";
CreateLimitRequest createRequest = new CreateLimitRequest()
.setLimitName(limitName);
liminatorService.create(createRequest);
String operationId = "OpComit";
LimitRequest holdRequest = new LimitRequest()
.setOperationId(operationId)
@ -65,6 +70,7 @@ public class LiminatorServiceTest {
liminatorService.commit(holdRequest);
List<LimitResponse> limitResponses = liminatorService.getLastLimitsValues(List.of(limitName));
assertEquals(1, limitResponses.size());
assertEquals(0, limitResponses.get(0).getHoldValue());
assertEquals(500, limitResponses.get(0).getCommitValue());
@ -74,10 +80,6 @@ public class LiminatorServiceTest {
@Test
void rollbackValueTest() throws TException {
String limitName = "TestLimitRollback";
CreateLimitRequest createRequest = new CreateLimitRequest()
.setLimitName(limitName);
liminatorService.create(createRequest);
String operationId = "Op-112";
LimitRequest holdRequest = new LimitRequest()
.setOperationId(operationId)
@ -86,6 +88,7 @@ public class LiminatorServiceTest {
liminatorService.rollback(holdRequest);
List<LimitResponse> limitResponses = liminatorService.getLastLimitsValues(List.of(limitName));
assertEquals(1, limitResponses.size());
assertEquals(0, limitResponses.get(0).getHoldValue());
assertEquals(0, limitResponses.get(0).getCommitValue());

View File

@ -2,7 +2,6 @@ package com.empayre.liminator.transaction;
import com.empayre.liminator.dao.OperationStateHistoryDao;
import com.empayre.liminator.service.LiminatorService;
import dev.vality.liminator.CreateLimitRequest;
import dev.vality.liminator.LimitChange;
import dev.vality.liminator.LimitRequest;
import dev.vality.liminator.LimitResponse;
@ -14,11 +13,10 @@ import org.springframework.boot.test.mock.mockito.SpyBean;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
public class TransactionVisibilityTest extends AbstractIntegrationTestWithEmbeddedPostgres {
class TransactionVisibilityTest extends AbstractIntegrationTestWithEmbeddedPostgres {
@Autowired
private LiminatorService liminatorService;
@ -27,32 +25,29 @@ public class TransactionVisibilityTest extends AbstractIntegrationTestWithEmbedd
private OperationStateHistoryDao operationStateHistoryDao;
@Test
public void rollbackTransactionTest() throws TException, InterruptedException {
void rollbackTransactionTest() throws TException, InterruptedException {
Mockito.doThrow(new RuntimeException()).when(operationStateHistoryDao).saveBatch(any());
String limitName = "TestLimitCommit123";
CreateLimitRequest createRequest = new CreateLimitRequest()
.setLimitName(limitName);
liminatorService.create(createRequest);
List<LimitResponse> limitResponsesBefore = liminatorService.getLastLimitsValues(List.of(limitName));
assertEquals(1, limitResponsesBefore.size());
assertEquals(0, limitResponsesBefore.get(0).getHoldValue());
assertEquals(0, limitResponsesBefore.get(0).getCommitValue());
String operationId = "OpComit123";
LimitRequest holdRequest = new LimitRequest()
String operationId = "operationId";
long value = 123L;
String limitId = "limitId";
LimitRequest request = new LimitRequest()
.setOperationId(operationId)
.setLimitChanges(List.of(new LimitChange(limitName, 500L)));
.setLimitChanges(List.of(
new LimitChange()
.setLimitName(limitName)
.setLimitId(limitId)
.setValue(value)
)
);
assertThrows(RuntimeException.class, () -> liminatorService.hold(holdRequest));
assertThrows(RuntimeException.class, () -> liminatorService.hold(request));
Thread.sleep(1000L);
List<LimitResponse> limitResponses = liminatorService.getLastLimitsValues(List.of(limitName));
assertEquals(1, limitResponses.size());
assertEquals(0, limitResponses.get(0).getHoldValue());
assertEquals(0, limitResponses.get(0).getCommitValue());
assertEquals(limitName, limitResponses.get(0).getLimitName());
assertEquals(0, limitResponses.size());
}
}