mirror of
https://github.com/valitydev/liminator.git
synced 2024-11-06 01:15:21 +00:00
modify calculation limit total value (#23)
* modify calculation limit total value * review * review(2) * review (3) * review (4)
This commit is contained in:
parent
db4d2ae383
commit
b201b272a9
@ -1,35 +0,0 @@
|
||||
package com.empayre.liminator.converter;
|
||||
|
||||
import com.empayre.liminator.model.LimitValue;
|
||||
import dev.vality.liminator.LimitResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CurrentLimitValuesToLimitResponseConverter implements Converter<List<LimitValue>, List<LimitResponse>> {
|
||||
|
||||
@Override
|
||||
public List<LimitResponse> convert(List<LimitValue> values) {
|
||||
if (values == null) {
|
||||
log.info("Received LimitValues array is empty");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return values.stream()
|
||||
.map(limitValue -> new LimitResponse(
|
||||
limitValue.getLimitName(),
|
||||
limitValue.getCommitValue(),
|
||||
getTotalValue(limitValue))
|
||||
.setLimitId(limitValue.getLimitId())
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
private static long getTotalValue(LimitValue limitValue) {
|
||||
return limitValue.getHoldValue() + limitValue.getCommitValue() - limitValue.getRollbackValue();
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.empayre.liminator.converter;
|
||||
|
||||
import com.empayre.liminator.model.LimitValue;
|
||||
import dev.vality.liminator.LimitResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class LimitValuesByLimitNameToLimitResponseConverter
|
||||
implements Converter<Map.Entry<String, List<LimitValue>>, LimitResponse> {
|
||||
|
||||
@Override
|
||||
public LimitResponse convert(Map.Entry<String, List<LimitValue>> source) {
|
||||
LimitResponse limitResponse = new LimitResponse();
|
||||
limitResponse.setLimitName(source.getKey());
|
||||
limitResponse.setLimitId(source.getValue().get(0).getLimitId());
|
||||
long commitValue = 0L;
|
||||
long totalValue = 0L;
|
||||
for (LimitValue limitValue : source.getValue()) {
|
||||
switch (limitValue.getState()) {
|
||||
case HOLD -> totalValue = totalValue + limitValue.getOperationValue();
|
||||
case COMMIT -> {
|
||||
commitValue = commitValue + limitValue.getOperationValue();
|
||||
totalValue = totalValue - limitValue.getOperationValue();
|
||||
}
|
||||
case ROLLBACK -> totalValue = totalValue - limitValue.getOperationValue();
|
||||
default -> throw new IllegalStateException("Unexpected value: " + limitValue.getState());
|
||||
}
|
||||
}
|
||||
limitResponse.setCommitValue(commitValue);
|
||||
limitResponse.setTotalValue(totalValue);
|
||||
return limitResponse;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.empayre.liminator.converter;
|
||||
|
||||
import com.empayre.liminator.model.LimitValue;
|
||||
import dev.vality.liminator.LimitResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class LimitValuesToLimitResponsesConverter implements Converter<List<LimitValue>, List<LimitResponse>> {
|
||||
|
||||
private final Converter<Map.Entry<String, List<LimitValue>>, LimitResponse> limitResponseConverter;
|
||||
|
||||
@Override
|
||||
public List<LimitResponse> convert(List<LimitValue> values) {
|
||||
if (CollectionUtils.isEmpty(values)) {
|
||||
log.info("Received LimitValues array is empty");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Map<String, List<LimitValue>> valuesPerLimitName = values.stream()
|
||||
.collect(groupingBy(LimitValue::getLimitName));
|
||||
return valuesPerLimitName.entrySet().stream()
|
||||
.map(limitResponseConverter::convert)
|
||||
.toList();
|
||||
}
|
||||
}
|
@ -11,9 +11,9 @@ public interface OperationStateHistoryDao extends CommonDao<OperationStateHistor
|
||||
|
||||
int[] saveBatch(List<OperationStateHistory> historyList);
|
||||
|
||||
List<LimitValue> getCurrentLimitValue(List<String> limitNames);
|
||||
List<LimitValue> getLimitHistory(List<String> limitNames);
|
||||
|
||||
List<LimitValue> getCurrentLimitValue(List<String> limitNames, String operationId);
|
||||
List<LimitValue> getLimitHistory(List<String> limitNames, String operationId);
|
||||
|
||||
List<OperationStateHistory> get(String operationId, Collection<Long> limitIds, List<OperationState> states);
|
||||
}
|
||||
|
@ -6,23 +6,23 @@ import com.empayre.liminator.domain.tables.pojos.OperationStateHistory;
|
||||
import com.empayre.liminator.model.LimitValue;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RecordMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.empayre.liminator.domain.Tables.LIMIT_DATA;
|
||||
import static com.empayre.liminator.domain.Tables.OPERATION_STATE_HISTORY;
|
||||
import static org.jooq.impl.DSL.raw;
|
||||
import static org.jooq.impl.DSL.val;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class OperationStateHistoryDaoImpl implements OperationStateHistoryDao {
|
||||
|
||||
private static final String DELIMITER = " ,";
|
||||
|
||||
private final DSLContext dslContext;
|
||||
private final RecordMapper<Record, LimitValue> recordMapper;
|
||||
|
||||
@Override
|
||||
public Long save(OperationStateHistory history) {
|
||||
@ -45,88 +45,32 @@ public class OperationStateHistoryDaoImpl implements OperationStateHistoryDao {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LimitValue> getCurrentLimitValue(List<String> limitNames) {
|
||||
String sql = """
|
||||
with hold_data as (
|
||||
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_state_history as ops
|
||||
on ops.limit_name = ld.name
|
||||
and ops.state = 'HOLD'
|
||||
where ld.name in ({0})
|
||||
group by ld.id, ld.name
|
||||
), commit_data as (
|
||||
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_state_history as ops
|
||||
on ops.limit_name = ld.name
|
||||
and ops.state = 'COMMIT'
|
||||
where ld.name in ({0})
|
||||
group by ld.id, ld.name
|
||||
), rollback_data as (
|
||||
select ld.id, ld.name, ld.limit_id, coalesce(sum(ops.operation_value), 0) as rollback_value
|
||||
from lim.limit_data as ld
|
||||
left join lim.operation_state_history as ops
|
||||
on ops.limit_name = ld.name
|
||||
and ops.state = 'ROLLBACK'
|
||||
where ld.name in ({0})
|
||||
group by ld.id, ld.name
|
||||
)
|
||||
|
||||
select cd.limit_id, cd.name as limit_name, cd.commit_value, hd.hold_value, rd.rollback_value
|
||||
from commit_data as cd
|
||||
join hold_data as hd on cd.id = hd.id
|
||||
join rollback_data as rd on cd.id = rd.id;
|
||||
""";
|
||||
public List<LimitValue> getLimitHistory(List<String> limitNames) {
|
||||
return dslContext
|
||||
.resultQuery(sql, raw(arrayToString(limitNames)))
|
||||
.fetchInto(LimitValue.class);
|
||||
.select()
|
||||
.from(OPERATION_STATE_HISTORY.join(LIMIT_DATA)
|
||||
.on(OPERATION_STATE_HISTORY.LIMIT_DATA_ID.eq(LIMIT_DATA.ID))
|
||||
.and(LIMIT_DATA.NAME.in(limitNames)))
|
||||
.fetch()
|
||||
.map(recordMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LimitValue> getCurrentLimitValue(List<String> limitNames, String operationId) {
|
||||
String sql = """
|
||||
with operation_timestamp as (
|
||||
select created_at
|
||||
from lim.operation_state_history
|
||||
where operation_id = {0}
|
||||
), hold_data as (
|
||||
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_state_history as ops
|
||||
on ops.limit_name = ld.name
|
||||
and ops.created_at <= (select created_at from operation_timestamp limit 1)
|
||||
and ops.state = 'HOLD'
|
||||
where ld.name in ({1})
|
||||
group by ld.id, ld.name
|
||||
), commit_data as (
|
||||
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_state_history as ops
|
||||
on ops.limit_name = ld.name
|
||||
and ops.created_at <= (select created_at from operation_timestamp limit 1)
|
||||
and ops.state = 'COMMIT'
|
||||
where ld.name in ({1})
|
||||
group by ld.id, ld.name
|
||||
), rollback_data as (
|
||||
select ld.id, ld.name, ld.limit_id, coalesce(sum(ops.operation_value), 0) as rollback_value
|
||||
from lim.limit_data as ld
|
||||
left join lim.operation_state_history as ops
|
||||
on ops.limit_name = ld.name
|
||||
and ops.created_at <= (select created_at from operation_timestamp limit 1)
|
||||
and ops.state = 'ROLLBACK'
|
||||
where ld.name in ({1})
|
||||
group by ld.id, ld.name
|
||||
)
|
||||
|
||||
select cd.limit_id, cd.name as limit_name, cd.commit_value, hd.hold_value, rd.rollback_value
|
||||
from commit_data as cd
|
||||
join hold_data as hd on cd.id = hd.id
|
||||
join rollback_data as rd on cd.id = rd.id;
|
||||
""";
|
||||
public List<LimitValue> getLimitHistory(List<String> limitNames, String operationId) {
|
||||
return dslContext
|
||||
.resultQuery(sql, val(operationId), raw(arrayToString(limitNames)))
|
||||
.fetchInto(LimitValue.class);
|
||||
.select()
|
||||
.from(OPERATION_STATE_HISTORY.join(LIMIT_DATA)
|
||||
.on(OPERATION_STATE_HISTORY.LIMIT_DATA_ID.eq(LIMIT_DATA.ID))
|
||||
.and(LIMIT_DATA.NAME.in(limitNames)))
|
||||
.where(OPERATION_STATE_HISTORY.CREATED_AT.le(
|
||||
select(OPERATION_STATE_HISTORY.CREATED_AT)
|
||||
.from(OPERATION_STATE_HISTORY)
|
||||
.where(OPERATION_STATE_HISTORY.OPERATION_ID.eq(operationId))
|
||||
.limit(1)
|
||||
)
|
||||
)
|
||||
.fetch()
|
||||
.map(recordMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -134,16 +78,11 @@ public class OperationStateHistoryDaoImpl implements OperationStateHistoryDao {
|
||||
Collection<Long> limitIds,
|
||||
List<OperationState> states) {
|
||||
return dslContext
|
||||
.selectFrom(OPERATION_STATE_HISTORY)
|
||||
.select()
|
||||
.from(OPERATION_STATE_HISTORY)
|
||||
.where(OPERATION_STATE_HISTORY.OPERATION_ID.eq(operationId))
|
||||
.and(OPERATION_STATE_HISTORY.LIMIT_DATA_ID.in(limitIds))
|
||||
.and(OPERATION_STATE_HISTORY.STATE.in(states))
|
||||
.fetchInto(OperationStateHistory.class);
|
||||
}
|
||||
|
||||
private static String arrayToString(List<String> strings) {
|
||||
return strings.stream()
|
||||
.map(limit -> "'%s'".formatted(limit))
|
||||
.collect(Collectors.joining(DELIMITER));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
package com.empayre.liminator.dao.mapper;
|
||||
|
||||
import com.empayre.liminator.domain.enums.OperationState;
|
||||
import com.empayre.liminator.model.LimitValue;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RecordMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static com.empayre.liminator.domain.Tables.OPERATION_STATE_HISTORY;
|
||||
import static com.empayre.liminator.domain.Tables.LIMIT_DATA;
|
||||
|
||||
@Component
|
||||
public class LimitValueMapper implements RecordMapper<Record, LimitValue> {
|
||||
|
||||
@Override
|
||||
public LimitValue map(Record opsDataRecord) {
|
||||
String limitId = opsDataRecord.get(LIMIT_DATA.LIMIT_ID);
|
||||
String limitName = opsDataRecord.get(OPERATION_STATE_HISTORY.LIMIT_NAME);
|
||||
Long operationValue = opsDataRecord.get(OPERATION_STATE_HISTORY.OPERATION_VALUE);
|
||||
OperationState state = OperationState.valueOf(opsDataRecord.get("state", String.class));
|
||||
return new LimitValue(limitId, limitName, state, operationValue);
|
||||
}
|
||||
}
|
@ -5,19 +5,20 @@ import com.empayre.liminator.domain.tables.pojos.LimitData;
|
||||
import com.empayre.liminator.handler.HoldOperationHandler;
|
||||
import com.empayre.liminator.service.LimitDataService;
|
||||
import com.empayre.liminator.service.LimitOperationsHistoryService;
|
||||
import dev.vality.liminator.DuplicateOperation;
|
||||
import dev.vality.liminator.LimitChange;
|
||||
import dev.vality.liminator.LimitRequest;
|
||||
import dev.vality.liminator.OperationAlreadyInFinalState;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.thrift.TException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.empayre.liminator.model;
|
||||
|
||||
import com.empayre.liminator.domain.enums.OperationState;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@ -9,7 +10,6 @@ public class LimitValue {
|
||||
|
||||
private String limitId;
|
||||
private String limitName;
|
||||
private Long commitValue;
|
||||
private Long holdValue;
|
||||
private Long rollbackValue;
|
||||
private OperationState state;
|
||||
private Long operationValue;
|
||||
}
|
||||
|
@ -68,7 +68,9 @@ public class LiminatorService implements LiminatorServiceSrv.Iface {
|
||||
throws LimitNotFound, LimitsValuesReadingException, TException {
|
||||
try {
|
||||
log.info("Get limits with request: {}", request);
|
||||
return getLimitsValuesHandler.handle(request);
|
||||
List<LimitResponse> limitResponses = getLimitsValuesHandler.handle(request);
|
||||
log.info("Success get limit responses: {}", limitResponses);
|
||||
return limitResponses;
|
||||
} catch (DataAccessException ex) {
|
||||
log.error("[GET] Received DaoException for getting limits operation (request: {})", request, ex);
|
||||
throw new LimitsValuesReadingException();
|
||||
@ -80,7 +82,9 @@ public class LiminatorService implements LiminatorServiceSrv.Iface {
|
||||
throws LimitNotFound, LimitsValuesReadingException, TException {
|
||||
try {
|
||||
log.info("Get last limits for limits: {}", Arrays.toString(limitNames.toArray()));
|
||||
return getLastLimitsValuesHandler.handle(limitNames);
|
||||
List<LimitResponse> limitResponses = getLastLimitsValuesHandler.handle(limitNames);
|
||||
log.info("Success get last limits response: {}", limitResponses);
|
||||
return limitResponses;
|
||||
} catch (DataAccessException ex) {
|
||||
log.error("[GET] Received DaoException for getting last limits operation (limitNames: {})", limitNames, ex);
|
||||
throw new LimitsValuesReadingException();
|
||||
|
@ -34,11 +34,11 @@ public class LimitOperationsHistoryService {
|
||||
}
|
||||
|
||||
public List<LimitValue> getCurrentLimitValue(List<String> limitNames) {
|
||||
return operationStateHistoryDao.getCurrentLimitValue(limitNames);
|
||||
return operationStateHistoryDao.getLimitHistory(limitNames);
|
||||
}
|
||||
|
||||
public List<LimitValue> getCurrentLimitValue(List<String> limitNames, String operationId) {
|
||||
return operationStateHistoryDao.getCurrentLimitValue(limitNames, operationId);
|
||||
return operationStateHistoryDao.getLimitHistory(limitNames, operationId);
|
||||
}
|
||||
|
||||
public List<OperationStateHistory> get(String operationId,
|
||||
|
@ -0,0 +1,4 @@
|
||||
DROP INDEX operation_history_idx;
|
||||
|
||||
CREATE INDEX operation_history_idx ON lim.operation_state_history USING btree (limit_data_id, state, created_at, operation_id);
|
||||
|
@ -7,15 +7,18 @@ import com.empayre.liminator.domain.tables.pojos.LimitData;
|
||||
import com.empayre.liminator.domain.tables.pojos.OperationStateHistory;
|
||||
import com.empayre.liminator.model.LimitValue;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
@Slf4j
|
||||
@PostgresqlSpringBootITest
|
||||
@ -57,35 +60,40 @@ class DaoTests {
|
||||
|
||||
@Test
|
||||
void operationDaoHistoryTest() {
|
||||
List<String> limitNamesList = new ArrayList<>();
|
||||
var limitsList = new ArrayList<Pair<String, Long>>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
String limitName = "Limit-odc-1-" + i;
|
||||
String limitId = "Limit-id-odc-1-" + i;
|
||||
limitDataDao.save(new LimitData(null, limitName, LocalDate.now(), LocalDateTime.now(), limitId));
|
||||
limitNamesList.add(limitName);
|
||||
Long id = limitDataDao.save(new LimitData(null, limitName, LocalDate.now(), LocalDateTime.now(), limitId));
|
||||
limitsList.add(Pair.of(limitName, id));
|
||||
}
|
||||
List<OperationStateHistory> operations = new ArrayList<>();
|
||||
String operationNameTemplate = "Operation-odc-1-%s";
|
||||
for (String limitName : limitNamesList) {
|
||||
for (Pair<String, Long> limit : limitsList) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
operations.add(createOperationHistory(limitName, operationNameTemplate.formatted(i)));
|
||||
operations.add(
|
||||
createOperationHistory(
|
||||
limit.getKey(),
|
||||
limit.getValue(),
|
||||
operationNameTemplate.formatted(i))
|
||||
);
|
||||
}
|
||||
}
|
||||
operationStateHistoryDao.saveBatch(operations);
|
||||
|
||||
|
||||
List<String> limitNames = limitsList.stream().map(Pair::getKey).toList();
|
||||
List<LimitValue> currentLimitValue = operationStateHistoryDao.getLimitHistory(limitNames);
|
||||
assertEquals(operations.size(), currentLimitValue.size());
|
||||
currentLimitValue.forEach(value -> assertEquals(100, value.getOperationValue()));
|
||||
|
||||
operations.clear();
|
||||
|
||||
List<LimitValue> currentLimitValue = operationStateHistoryDao.getCurrentLimitValue(limitNamesList);
|
||||
assertEquals(limitNamesList.size(), currentLimitValue.size());
|
||||
currentLimitValue.forEach(value -> assertEquals(0, value.getCommitValue()));
|
||||
currentLimitValue.forEach(value -> assertEquals(0, value.getRollbackValue()));
|
||||
currentLimitValue.forEach(value -> assertNotEquals(0, value.getHoldValue()));
|
||||
currentLimitValue.forEach(value -> assertNotEquals(0, getTotal(value)));
|
||||
|
||||
List<String> commitLimitNames = limitNamesList.subList(0, 3);
|
||||
var commitLimits = limitsList.subList(0, 3);
|
||||
String finalizeOperationName = operationNameTemplate.formatted(1);
|
||||
for (String limitName : commitLimitNames) {
|
||||
for (Pair<String, Long> commitLimit : commitLimits) {
|
||||
var operationHistory = createOperationHistory(
|
||||
limitName,
|
||||
commitLimit.getKey(),
|
||||
commitLimit.getValue(),
|
||||
finalizeOperationName,
|
||||
LocalDateTime.now(),
|
||||
OperationState.COMMIT);
|
||||
@ -94,10 +102,11 @@ class DaoTests {
|
||||
operationStateHistoryDao.saveBatch(operations);
|
||||
operations.clear();
|
||||
|
||||
List<String> rollbackLimitNames = limitNamesList.subList(4, 9);
|
||||
for (String limitName : rollbackLimitNames) {
|
||||
var rollbackLimits = limitsList.subList(4, 9);
|
||||
for (Pair<String, Long> rollbackLimit : rollbackLimits) {
|
||||
var operationHistory = createOperationHistory(
|
||||
limitName,
|
||||
rollbackLimit.getKey(),
|
||||
rollbackLimit.getValue(),
|
||||
finalizeOperationName,
|
||||
LocalDateTime.now(),
|
||||
OperationState.ROLLBACK);
|
||||
@ -106,69 +115,36 @@ class DaoTests {
|
||||
operationStateHistoryDao.saveBatch(operations);
|
||||
operations.clear();
|
||||
|
||||
List<LimitValue> limitValuesAfterChanges = operationStateHistoryDao.getCurrentLimitValue(limitNamesList);
|
||||
List<LimitValue> limitValuesWithCommitData = limitValuesAfterChanges.stream()
|
||||
.filter(value -> value.getCommitValue() == 100
|
||||
&& value.getHoldValue() == 500
|
||||
&& value.getRollbackValue() == 0)
|
||||
.toList();
|
||||
assertEquals(3, limitValuesWithCommitData.size());
|
||||
List<LimitValue> limitValuesAfterChanges = operationStateHistoryDao.getLimitHistory(limitNames);
|
||||
|
||||
List<LimitValue> limitValuesAfterRollback = limitValuesAfterChanges.stream()
|
||||
.filter(value -> value.getHoldValue() == 500
|
||||
&& value.getCommitValue() == 0
|
||||
&& value.getRollbackValue() == 100)
|
||||
List<LimitValue> operationsWithCommitData = limitValuesAfterChanges.stream()
|
||||
.filter(value -> value.getState() == OperationState.COMMIT)
|
||||
.toList();
|
||||
assertEquals(5, limitValuesAfterRollback.size());
|
||||
assertEquals(commitLimits.size(), operationsWithCommitData.size());
|
||||
|
||||
List<LimitValue> limitValuesWithoutChanges = limitValuesAfterChanges.stream()
|
||||
.filter(value -> value.getHoldValue() == 500
|
||||
&& value.getCommitValue() == 0
|
||||
&& value.getRollbackValue() == 0)
|
||||
List<LimitValue> operationsWithRollback = limitValuesAfterChanges.stream()
|
||||
.filter(value -> value.getState() == OperationState.ROLLBACK)
|
||||
.toList();
|
||||
assertEquals(2, limitValuesWithoutChanges.size());
|
||||
assertEquals(rollbackLimits.size(), operationsWithRollback.size());
|
||||
|
||||
List<LimitValue> operationsWithHold = limitValuesAfterChanges.stream()
|
||||
.filter(value -> value.getState() == OperationState.HOLD)
|
||||
.toList();
|
||||
assertEquals(currentLimitValue.size(), operationsWithHold.size());
|
||||
}
|
||||
|
||||
private long getTotal(LimitValue value) {
|
||||
return value.getHoldValue() - value.getCommitValue() - value.getRollbackValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void operationDaoCurrentLimitWithOperationIdTest() {
|
||||
String limitName = "Limit-odc-2";
|
||||
String limitId = "Limit-id-odc-2";
|
||||
Long id = limitDataDao.save(new LimitData(null, limitName, LocalDate.now(), LocalDateTime.now(), limitId));
|
||||
List<OperationStateHistory> operations = new ArrayList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
var operation = createOperationHistory(
|
||||
limitName,
|
||||
"Operation-odc-2-%s-%s".formatted(id, i),
|
||||
LocalDateTime.now().minusMinutes(11L - i),
|
||||
OperationState.HOLD);
|
||||
operationStateHistoryDao.save(operation);
|
||||
operations.add(operation);
|
||||
}
|
||||
|
||||
List<LimitValue> valuesForFifthOperation =
|
||||
operationStateHistoryDao.getCurrentLimitValue(List.of(limitName), operations.get(2).getOperationId());
|
||||
LimitValue limitValue = valuesForFifthOperation.get(0);
|
||||
assertEquals(300, getTotal(limitValue));
|
||||
|
||||
valuesForFifthOperation =
|
||||
operationStateHistoryDao.getCurrentLimitValue(List.of(limitName), operations.get(5).getOperationId());
|
||||
assertEquals(600, getTotal(valuesForFifthOperation.get(0)));
|
||||
}
|
||||
|
||||
private OperationStateHistory createOperationHistory(String limitName, String operationId) {
|
||||
return createOperationHistory(limitName, operationId, LocalDateTime.now(), OperationState.HOLD);
|
||||
private OperationStateHistory createOperationHistory(String limitName, Long id, String operationId) {
|
||||
return createOperationHistory(limitName, id, operationId, LocalDateTime.now(), OperationState.HOLD);
|
||||
}
|
||||
|
||||
private OperationStateHistory createOperationHistory(String limitName,
|
||||
Long id,
|
||||
String operationId,
|
||||
LocalDateTime createdAt,
|
||||
OperationState state) {
|
||||
OperationStateHistory operation = new OperationStateHistory();
|
||||
operation.setLimitName(limitName);
|
||||
operation.setLimitDataId(id);
|
||||
operation.setOperationId(operationId);
|
||||
operation.setState(state);
|
||||
operation.setOperationValue(100L);
|
||||
|
@ -35,6 +35,7 @@ class LiminatorServiceTest {
|
||||
);
|
||||
|
||||
List<LimitResponse> response = liminatorService.hold(request);
|
||||
|
||||
assertEquals(limitName, response.get(0).getLimitName());
|
||||
assertEquals(limitId, response.get(0).getLimitId());
|
||||
assertEquals(holdValue, response.get(0).getTotalValue());
|
||||
@ -59,7 +60,7 @@ class LiminatorServiceTest {
|
||||
@Test
|
||||
void limitNotFoundTest() {
|
||||
String limitName = "TestLimitCommit";
|
||||
String operationId = "OpComit";
|
||||
String operationId = "Op-123";
|
||||
LimitRequest holdRequest = new LimitRequest()
|
||||
.setOperationId(operationId)
|
||||
.setLimitChanges(List.of(new LimitChange(limitName, 500L)));
|
||||
@ -70,7 +71,7 @@ class LiminatorServiceTest {
|
||||
@Test
|
||||
void operationNotFoundWithNotExistHoldTest() throws TException {
|
||||
String limitName = "TestLimitCommit";
|
||||
String operationId = "OpComit";
|
||||
String operationId = "Op-123";
|
||||
LimitRequest holdRequest = new LimitRequest()
|
||||
.setOperationId(operationId)
|
||||
.setLimitChanges(List.of(new LimitChange(limitName, 500L)));
|
||||
@ -86,7 +87,7 @@ class LiminatorServiceTest {
|
||||
void operationNotFoundWithNotExpectedHoldCountTest() throws TException {
|
||||
String firstLimitName = "TestLimit1";
|
||||
String secondLimitName = "TestLimit2";
|
||||
String operationId = "OpComit";
|
||||
String operationId = "Op-123";
|
||||
LimitRequest holdRequest = new LimitRequest()
|
||||
.setOperationId(operationId)
|
||||
.setLimitChanges(List.of(
|
||||
@ -165,21 +166,28 @@ class LiminatorServiceTest {
|
||||
@Test
|
||||
void commitValueTest() throws TException {
|
||||
String limitName = "TestLimitCommit";
|
||||
String operationId = "OpComit";
|
||||
String operationId = "Op-123";
|
||||
String limitId = "limit_day_id";
|
||||
LimitRequest holdRequest = new LimitRequest()
|
||||
.setOperationId(operationId)
|
||||
.setLimitChanges(List.of(new LimitChange(limitName, 500L).setLimitId(limitId)));
|
||||
liminatorService.hold(holdRequest);
|
||||
|
||||
List<LimitResponse> holdResponses = liminatorService.hold(holdRequest);
|
||||
|
||||
assertEquals(1, holdResponses.size());
|
||||
assertEquals(500, holdResponses.get(0).getTotalValue());
|
||||
assertEquals(0, holdResponses.get(0).getCommitValue());
|
||||
assertEquals(limitName, holdResponses.get(0).getLimitName());
|
||||
|
||||
liminatorService.commit(holdRequest);
|
||||
|
||||
List<LimitResponse> limitResponses = liminatorService.getLastLimitsValues(List.of(limitName));
|
||||
List<LimitResponse> commitResponses = liminatorService.getLastLimitsValues(List.of(limitName));
|
||||
|
||||
assertEquals(1, limitResponses.size());
|
||||
assertEquals(1000, limitResponses.get(0).getTotalValue());
|
||||
assertEquals(500, limitResponses.get(0).getCommitValue());
|
||||
assertEquals(limitName, limitResponses.get(0).getLimitName());
|
||||
assertEquals(limitId, limitResponses.get(0).getLimitId());
|
||||
assertEquals(1, commitResponses.size());
|
||||
assertEquals(0, commitResponses.get(0).getTotalValue());
|
||||
assertEquals(500, commitResponses.get(0).getCommitValue());
|
||||
assertEquals(limitName, commitResponses.get(0).getLimitName());
|
||||
assertEquals(limitId, commitResponses.get(0).getLimitId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -189,20 +197,26 @@ class LiminatorServiceTest {
|
||||
LimitRequest holdRequest = new LimitRequest()
|
||||
.setOperationId(operationId)
|
||||
.setLimitChanges(List.of(new LimitChange(limitName, 500L)));
|
||||
liminatorService.hold(holdRequest);
|
||||
List<LimitResponse> holdResponses = liminatorService.hold(holdRequest);
|
||||
|
||||
assertEquals(1, holdResponses.size());
|
||||
assertEquals(500, holdResponses.get(0).getTotalValue());
|
||||
assertEquals(0, holdResponses.get(0).getCommitValue());
|
||||
assertEquals(limitName, holdResponses.get(0).getLimitName());
|
||||
|
||||
liminatorService.rollback(holdRequest);
|
||||
|
||||
List<LimitResponse> limitResponses = liminatorService.getLastLimitsValues(List.of(limitName));
|
||||
List<LimitResponse> rollbackResponses = liminatorService.getLastLimitsValues(List.of(limitName));
|
||||
|
||||
assertEquals(1, limitResponses.size());
|
||||
assertEquals(0, limitResponses.get(0).getTotalValue());
|
||||
assertEquals(0, limitResponses.get(0).getCommitValue());
|
||||
assertEquals(limitName, limitResponses.get(0).getLimitName());
|
||||
assertEquals(1, rollbackResponses.size());
|
||||
assertEquals(0, rollbackResponses.get(0).getTotalValue());
|
||||
assertEquals(0, rollbackResponses.get(0).getCommitValue());
|
||||
assertEquals(limitName, rollbackResponses.get(0).getLimitName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void complexOperationsTest() throws TException {
|
||||
String limitName = "TestLimitRollback";
|
||||
String limitName = "TestLimitComplex";
|
||||
String operationId = "Op-112-%s";
|
||||
LimitRequest firstHoldRequest = new LimitRequest()
|
||||
.setOperationId(operationId.formatted(1))
|
||||
@ -227,28 +241,28 @@ class LiminatorServiceTest {
|
||||
List<LimitResponse> limitResponseAfterFourthHold = liminatorService.hold(fourthHoldRequest);
|
||||
|
||||
assertEquals(1, limitResponseAfterFourthHold.size());
|
||||
assertEquals(500, limitResponseAfterFourthHold.get(0).getTotalValue());
|
||||
assertEquals(300, limitResponseAfterFourthHold.get(0).getTotalValue());
|
||||
assertEquals(100, limitResponseAfterFourthHold.get(0).getCommitValue());
|
||||
assertEquals(limitName, limitResponseAfterFourthHold.get(0).getLimitName());
|
||||
|
||||
liminatorService.rollback(firstHoldRequest);
|
||||
|
||||
LimitRequest fifthHoldRequest = new LimitRequest()
|
||||
.setOperationId(operationId.formatted(4))
|
||||
.setOperationId(operationId.formatted(5))
|
||||
.setLimitChanges(List.of(new LimitChange(limitName, 100L)));
|
||||
liminatorService.hold(fifthHoldRequest);
|
||||
|
||||
List<LimitResponse> limitResponses = liminatorService.hold(fifthHoldRequest);
|
||||
|
||||
assertEquals(1, limitResponses.size());
|
||||
assertEquals(500, limitResponses.get(0).getTotalValue());
|
||||
assertEquals(300, limitResponses.get(0).getTotalValue());
|
||||
assertEquals(100, limitResponses.get(0).getCommitValue());
|
||||
assertEquals(limitName, limitResponses.get(0).getLimitName());
|
||||
|
||||
List<LimitResponse> limitResponseAfterAllForFourthHold = liminatorService.hold(fourthHoldRequest);
|
||||
|
||||
assertEquals(1, limitResponseAfterAllForFourthHold.size());
|
||||
assertEquals(500, limitResponseAfterAllForFourthHold.get(0).getTotalValue());
|
||||
assertEquals(300, limitResponseAfterAllForFourthHold.get(0).getTotalValue());
|
||||
assertEquals(100, limitResponseAfterAllForFourthHold.get(0).getCommitValue());
|
||||
assertEquals(limitName, limitResponseAfterAllForFourthHold.get(0).getLimitName());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user