Skip to content

Commit

Permalink
Added test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
w3stling committed Dec 22, 2022
1 parent 36d2353 commit ce4cd0f
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 1 deletion.
91 changes: 90 additions & 1 deletion src/main/java/com/apptasticsoftware/lei/IsinLookup.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.*;
import java.util.function.BiFunction;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
Expand All @@ -30,6 +30,7 @@ public class IsinLookup {
private final int cacheSize;
private final ConcurrentSkipListMap<String, String> cache;
private final List<BiFunction<String, String, String>> sendRequestFunctions;
private final ConcurrentHashMap<String, PendingRequest> pendingRequests = new ConcurrentHashMap<>();


/**
Expand Down Expand Up @@ -64,6 +65,13 @@ public Optional<String> getIsinByCusip(String cusip) {
return Optional.of(isin);
}

var pendingRequest = getPendingRequest(cusip);
if (pendingRequest != null) {
return Optional.ofNullable(getPendingResult(cusip));
}

pendingRequest = pendingRequests.get(cusip);

isin = sendRequestFunctions.stream()
.map(f -> {
var isinNumber = f.apply(CUSIP_URL, "cusip=US" + cusip);
Expand All @@ -83,6 +91,8 @@ public Optional<String> getIsinByCusip(String cusip) {
.orElse(null);

putCacheResult(cusip, isin);
pendingRequest.done();
pendingRequests.remove(cusip);
if (isin != null && isin.isEmpty()) {
isin = null;
}
Expand All @@ -104,6 +114,13 @@ public Optional<String> getIsinBySedol(String sedol) {
return Optional.of(isin);
}

var pendingRequest = getPendingRequest(sedol);
if (pendingRequest != null) {
return Optional.ofNullable(getPendingResult(sedol));
}

pendingRequest = pendingRequests.get(sedol);

isin = sendRequestFunctions.stream()
.map(f -> {
var isinNumber = f.apply(SEDOL_URL, "sedol=GB" + sedol);
Expand All @@ -118,6 +135,8 @@ public Optional<String> getIsinBySedol(String sedol) {
.orElse(null);

putCacheResult(sedol, isin);
pendingRequest.done();
pendingRequests.remove(sedol);
if (isin != null && isin.isEmpty()) {
isin = null;
}
Expand Down Expand Up @@ -263,4 +282,74 @@ private void putCacheResult(String key, String value) {
cache.pollLastEntry();
}
}

private PendingRequest getPendingRequest(String request) {
PendingRequest newPendingRequest = new PendingRequest(request);
PendingRequest pendingRequest = pendingRequests.computeIfAbsent(request, k -> newPendingRequest);

if (newPendingRequest != pendingRequest) {
return newPendingRequest;
}

return null;
}

private String getPendingResult(String request) {
var pendingRequest = pendingRequests.get(request);
if (pendingRequest != null) {
try {
return pendingRequest.get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
} catch (ExecutionException e) {
return null;
}
}

return null;
}

private class PendingRequest implements Future<String> {
private final CountDownLatch latch = new CountDownLatch(1);
private final String request;

public PendingRequest(String request) {
this.request = request;
}

@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}

@Override
public boolean isCancelled() {
return false;
}

@Override
public boolean isDone() {
return latch.getCount() == 0;
}

@Override
public String get() throws InterruptedException, ExecutionException {
latch.await();
return cache.get(request);
}

@Override
public String get(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException {
if (latch.await(timeout, unit)) {
return cache.get(request);
} else {
throw new TimeoutException();
}
}

void done() {
latch.countDown();
}
}
}
20 changes: 20 additions & 0 deletions src/test/java/com/apptasticsoftware/lei/IsinLookupTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

Expand Down Expand Up @@ -84,6 +86,15 @@ void lookupByCusip() {
assertFalse(lookup.getIsinByCusip("0@7833105").isPresent());
}

@Test
void pendingRequestLookupByCusip() {
var cusipList = List.of("931142103", "931142103", "931142103", "931142103", "931142103", "931142103");

IsinLookup lookup = new IsinLookup(35);

cusipList.stream().parallel().forEach(cusip -> assertTrue(lookup.getIsinByCusip(cusip).isPresent()));
}

@Test
void lookupByCusipMethod1() {
assertTrue(lookup1.getIsinByCusip("931142103").isPresent());
Expand Down Expand Up @@ -133,6 +144,15 @@ void lookupBySedol() {
assertFalse(lookup.getIsinBySedol("").isPresent());
}

@Test
void pendingRequestLookupBySedol() {
var sedolList = List.of("0884709", "0884709", "0884709", "0884709", "0884709", "0884709");

IsinLookup lookup = new IsinLookup(36);

sedolList.stream().parallel().forEach(sedol -> assertTrue(lookup.getIsinBySedol(sedol).isPresent()));
}

@Test
void lookupBySedolMethod1() {
assertTrue(lookup1.getIsinBySedol("0884709").isPresent());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,18 @@ void testLookupFailed() {
lei = leiLookup.getLeiByLeiCode("ABC123");
assertFalse(lei.isPresent());
}

@Test
void testPendingRequest() {
var leiList = List.of("7LTWFZYICNSX8D621K86", "7LTWFZYICNSX8D621K86", "7LTWFZYICNSX8D621K86",
"7LTWFZYICNSX8D621K86", "7LTWFZYICNSX8D621K86", "7LTWFZYICNSX8D621K86", "7LTWFZYICNSX8D621K86");

LeiLookup leiLookup = LeiLookup.getInstance(48, 48);

leiList.stream().parallel().forEach(lieCode -> {
Optional<Lei> lei = leiLookup.getLeiByLeiCode(lieCode);
assertTrue(lei.isPresent());
}
);
}
}

0 comments on commit ce4cd0f

Please sign in to comment.