This commit is contained in:
parent
e1d565522b
commit
62b847fcef
4 changed files with 144 additions and 0 deletions
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -34,6 +34,10 @@ public class SecurityService {
|
||||||
|
|
||||||
public void sendRequest(FondListingsRequest request) {
|
public void sendRequest(FondListingsRequest request) {
|
||||||
List<FondSecurity> securityList = request.getSecurities();
|
List<FondSecurity> securityList = request.getSecurities();
|
||||||
|
CodeStatusComparator<FondSecurity> comparatorBySecSymbolAndWorkflowStatus = CodeStatusComparator.create(
|
||||||
|
FondSecurity::getSecuritySymbol,
|
||||||
|
FondSecurity::getWorkflowStatus);
|
||||||
|
securityList.sort(comparatorBySecSymbolAndWorkflowStatus);
|
||||||
for (FondSecurity security : securityList) {
|
for (FondSecurity security : securityList) {
|
||||||
try {
|
try {
|
||||||
log.debug("process security uuid: {}", security.getId());
|
log.debug("process security uuid: {}", security.getId());
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Service;
|
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.ExchangeInstrument;
|
||||||
import ru.spcex.clearing.gatewayapi.controller.inbound.request.listing.mkr.MMListingsRequest;
|
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.gatewayapi.service.adapter.MoneyMarketSecurityRequestAdapter;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewGatewayRequest;
|
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewGatewayRequest;
|
||||||
|
|
@ -30,6 +31,10 @@ public class ListingMMProcessor {
|
||||||
|
|
||||||
public void process(MMListingsRequest request) {
|
public void process(MMListingsRequest request) {
|
||||||
List<ExchangeInstrument> exchangeInstrumentList = request.getExchangeInstrumentList();
|
List<ExchangeInstrument> exchangeInstrumentList = request.getExchangeInstrumentList();
|
||||||
|
CodeStatusComparator<ExchangeInstrument> comparatorByCodeAndWorkflowStatus = CodeStatusComparator.create(
|
||||||
|
ExchangeInstrument::getCode,
|
||||||
|
ExchangeInstrument::getWorkflowStatus);
|
||||||
|
exchangeInstrumentList.sort(comparatorByCodeAndWorkflowStatus);
|
||||||
for (ExchangeInstrument exchangeInstrument : exchangeInstrumentList) {
|
for (ExchangeInstrument exchangeInstrument : exchangeInstrumentList) {
|
||||||
try {
|
try {
|
||||||
UUID exchangeInstrumentId = exchangeInstrument.getId();
|
UUID exchangeInstrumentId = exchangeInstrument.getId();
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue