ialbert 2023-07-20 19:26:10 +03:00
parent e1d565522b
commit 62b847fcef
4 changed files with 144 additions and 0 deletions

View file

@ -0,0 +1,57 @@
package ru.spcex.clearing.gatewayapi.service;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import java.util.Comparator;
import java.util.Objects;
import java.util.function.Function;
public class CodeStatusComparator<T> implements Comparator<T> {
private final Function<T, String> codeExtractor;
private final Function<T, String> workflowStatusExtractor;
public CodeStatusComparator(Function<T, String> codeExtractor, Function<T, String> workflowStatusExtractor) {
this.codeExtractor = codeExtractor;
this.workflowStatusExtractor = workflowStatusExtractor;
}
public static <T> CodeStatusComparator<T> create(Function<T, String> codeExtractor, Function<T, String> workflowStatusExtractor) {
return new CodeStatusComparator<T>(codeExtractor, workflowStatusExtractor);
}
@Override
public int compare(T o1, T o2) {
if (codeExtractor == null || workflowStatusExtractor == null) throw new IllegalStateException("codeExtractor and workflowStatusExtractor must be set");
String securitySymbol1 = codeExtractor.apply(o1);
String securitySymbol2 = codeExtractor.apply(o2);
String workflowStatus1 = workflowStatusExtractor.apply(o1);
String workflowStatus2 = workflowStatusExtractor.apply(o2);
//Если приходят несколько объектов с одним security.security_symbol и разными security.workflow_status,
// просьба сначала обрабатывать записи workflow_status="BLKD", а потом с workflow_status="ACTV".
if (!Objects.equals(securitySymbol1, securitySymbol2)) {
return Objects.compare(securitySymbol1, securitySymbol2, Comparator.naturalOrder());
}
if (Objects.equals(workflowStatus1, workflowStatus2)) {
return 0;
}
//сначала достаем workflowStatus из объекта
Function<String, WorkflowStatus> statusObtainer = ws -> {
WorkflowStatus workflowStatus = IEnumKey.getEnumByKey(WorkflowStatus.class, ws);
return Objects.requireNonNullElse(workflowStatus, WorkflowStatus.Active);
};
//потом устанавливаем очередносьб: сначала Blocked
Function<WorkflowStatus, Integer> statusMapper = ws -> {
if (WorkflowStatus.Blocked.equals(ws)) {
return -1;
} else {
return 1;
}
};
Integer o1Ws = statusObtainer.andThen(statusMapper).apply(workflowStatus1);
Integer o2Ws = statusObtainer.andThen(statusMapper).apply(workflowStatus2);
return o1Ws.compareTo(o2Ws);
}
}

View file

@ -34,6 +34,10 @@ public class SecurityService {
public void sendRequest(FondListingsRequest request) {
List<FondSecurity> securityList = request.getSecurities();
CodeStatusComparator<FondSecurity> comparatorBySecSymbolAndWorkflowStatus = CodeStatusComparator.create(
FondSecurity::getSecuritySymbol,
FondSecurity::getWorkflowStatus);
securityList.sort(comparatorBySecSymbolAndWorkflowStatus);
for (FondSecurity security : securityList) {
try {
log.debug("process security uuid: {}", security.getId());

View file

@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ru.spcex.clearing.gatewayapi.controller.inbound.request.listing.mkr.ExchangeInstrument;
import ru.spcex.clearing.gatewayapi.controller.inbound.request.listing.mkr.MMListingsRequest;
import ru.spcex.clearing.gatewayapi.service.CodeStatusComparator;
import ru.spcex.clearing.gatewayapi.service.adapter.MoneyMarketSecurityRequestAdapter;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewGatewayRequest;
@ -30,6 +31,10 @@ public class ListingMMProcessor {
public void process(MMListingsRequest request) {
List<ExchangeInstrument> exchangeInstrumentList = request.getExchangeInstrumentList();
CodeStatusComparator<ExchangeInstrument> comparatorByCodeAndWorkflowStatus = CodeStatusComparator.create(
ExchangeInstrument::getCode,
ExchangeInstrument::getWorkflowStatus);
exchangeInstrumentList.sort(comparatorByCodeAndWorkflowStatus);
for (ExchangeInstrument exchangeInstrument : exchangeInstrumentList) {
try {
UUID exchangeInstrumentId = exchangeInstrument.getId();

View file

@ -0,0 +1,78 @@
package ru.spcex.clearing.gatewayapi.service;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import ru.spcex.clearing.gatewayapi.controller.inbound.request.listing.fond.FondSecurity;
import ru.spcex.platform.enumeration.WorkflowStatus;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
class CodeStatusComparatorTest {
private final static FondSecurity secActive = security("a", WorkflowStatus.Active.getKey());
private final static FondSecurity secBlocked = security("a", WorkflowStatus.Blocked.getKey());
private final static FondSecurity secNull = security("a", null);
private final static FondSecurity secEmpty = security("a", "");
private final static FondSecurity secUnparsable = security("a", "ulala");
private final static FondSecurity secOtherCode = security("b", WorkflowStatus.Blocked.getKey());
private final static CodeStatusComparator<FondSecurity> comp = CodeStatusComparator.create(
FondSecurity::getSecuritySymbol,
FondSecurity::getWorkflowStatus);
@Test
void compare() {
List<FondSecurity> fondSecurities = Arrays.asList(
security("2", "a", WorkflowStatus.Active.getKey()),
security("1", "a", WorkflowStatus.Blocked.getKey()),
security("3", "b", WorkflowStatus.Blocked.getKey()),
security("4", "b", WorkflowStatus.Active.getKey()),
security("6", "c", WorkflowStatus.Active.getKey()),
security("7", "d", WorkflowStatus.Blocked.getKey()),
security("8", "d", WorkflowStatus.Blocked.getKey()),
security("5", "c", WorkflowStatus.Blocked.getKey())
);
//signum(compare(x, y)) == -signum(compare(y, x)) for all x and y
//((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.
//Finally, the implementor must ensure that compare(x, y)==0 implies that signum(compare(x, z))==signum(compare(y, z)) for all z
fondSecurities.sort(comp);
for (int i = 0; i < fondSecurities.size(); i++) {
assertEquals(Integer.parseInt(fondSecurities.get(i).getShortName()), i + 1);
}
}
@Test
public void compare2() {
Assertions.assertTrue(comp.compare(secActive, secBlocked) > 0);
Assertions.assertTrue(comp.compare(secBlocked, secActive) < 0);
Assertions.assertTrue(comp.compare(secActive, secOtherCode) < 0);
Assertions.assertTrue(comp.compare(secOtherCode, secActive) > 0);
Assertions.assertTrue(comp.compare(secBlocked, secNull) < 0);
Assertions.assertTrue(comp.compare(secNull, secBlocked) > 0);
Assertions.assertEquals(0, comp.compare(secEmpty, secNull));
Assertions.assertEquals(0, comp.compare(secNull, secEmpty));
Assertions.assertEquals(0, comp.compare(secEmpty, secUnparsable));
Assertions.assertTrue(comp.compare(secBlocked, secUnparsable) < 0);
}
private static FondSecurity security(String shortName, String securitySymbol, String workflowStatus) {
FondSecurity sec = new FondSecurity();
sec.setShortName(shortName);
sec.setSecuritySymbol(securitySymbol);
sec.setWorkflowStatus(workflowStatus);
return sec;
}
private static FondSecurity security(String securitySymbol, String workflowStatus) {
FondSecurity sec = new FondSecurity();
sec.setSecuritySymbol(securitySymbol);
sec.setWorkflowStatus(workflowStatus);
return sec;
}
}