Skip to content

Commit

Permalink
Rework to always specify the number of days to fetch from FM4
Browse files Browse the repository at this point in the history
It's a breaking change, but ptherwise the API is confusing
now that FM4 can provide more than 7 days
  • Loading branch information
centic9 committed Feb 23, 2024
1 parent 7d6e387 commit bf75606
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 32 deletions.
21 changes: 18 additions & 3 deletions src/main/java/org/dstadler/audio/fm4/FM4.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.dstadler.commons.http.HttpClientWrapper;
import org.dstadler.commons.logging.jdk.LoggerFactory;

Expand Down Expand Up @@ -37,8 +39,21 @@ public class FM4 {
* @return A list of {@link FM4Stream}
* @throws IOException If fetching data via the FM4 REST API fails
*/
public List<FM4Stream> fetchStreams() throws IOException {
return fetchStreams(FM4_API_URL, FM4_STREAM_URL_BASE);
public List<FM4Stream> fetchStreams(int days) throws IOException {
// 7 days minimum
if (days < 7) {
days = 7;
}

List<FM4Stream> streams = new ArrayList<>();
for (int day = days; day > 7; day--) {
String date = FastDateFormat.getInstance("yyyyMMdd").format(DateUtils.addDays(new Date(), (-1)*day));
streams.addAll(fetchStreams(date));
}

streams.addAll(fetchStreams(FM4_API_URL, FM4_STREAM_URL_BASE));

return streams;
}

/**
Expand Down Expand Up @@ -103,7 +118,7 @@ private static JsonNode parsAPI(String apiUrl) throws IOException {
* @throws IOException If fetching data via the FM4 REST API fails
*/
public List<FM4Stream> filterStreams(String programKey) throws IOException {
List<FM4Stream> streams = fetchStreams();
List<FM4Stream> streams = fetchStreams(14);

return streams.stream().
// filter out future shows
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/org/dstadler/audio/fm4/FM4Cache.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,20 @@ public class FM4Cache implements AutoCloseable {
.build());

private final FM4 fm4;
private final int days;

/**
* Construct up the cache and start periodic background
* refreshes.
*
* @param fm4 An instance of the FM4 access helper.
* This is passed in to facilitate testing.
* @param days The number of days to cache. Should be between
* 7 and 30 for FM4
*/
public FM4Cache(FM4 fm4) {
public FM4Cache(FM4 fm4, int days) {
this.fm4 = fm4;
this.days = days;
executor.scheduleAtFixedRate(this::refresh, 0, 5, TimeUnit.MINUTES);
}

Expand Down Expand Up @@ -242,7 +246,7 @@ public void refresh() {
try {
// first get all streams by programKey
Multimap<String, FM4Stream> streams = ArrayListMultimap.create();
for (FM4Stream stream : fm4.fetchStreams()) {
for (FM4Stream stream : fm4.fetchStreams(days)) {
streams.put(stream.getProgramKey(), stream);
}

Expand Down
46 changes: 23 additions & 23 deletions src/test/java/org/dstadler/audio/fm4/FM4CacheTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void tearDown() throws InterruptedException {

@Test
public void testCache() {
try (FM4Cache cache = new FM4Cache(new FM4())) {
try (FM4Cache cache = new FM4Cache(new FM4(), 7)) {
assertEquals(0, cache.size());

cache.refresh();
Expand All @@ -59,7 +59,7 @@ public void testCache() {
}

// cache itself is not static, so size should be zero again now
try (FM4Cache cache = new FM4Cache(new FM4())) {
try (FM4Cache cache = new FM4Cache(new FM4(), 7)) {
assertEquals(0, cache.size());

verifier.addObject(cache);
Expand All @@ -70,12 +70,12 @@ public void testCache() {
public void testGetNextNotFound() {
try (FM4Cache cache = new FM4Cache(new FM4() {
@Override
public List<FM4Stream> fetchStreams() throws IOException {
public List<FM4Stream> fetchStreams(int days) throws IOException {
// only load two shows to make testing quick
List<FM4Stream> fm4Streams = super.fetchStreams();
List<FM4Stream> fm4Streams = super.fetchStreams(days);
return fm4Streams.subList(0, Math.min(2, fm4Streams.size()));
}
})) {
}, 7)) {
cache.refresh();

assertNull(cache.getNext(null));
Expand All @@ -99,12 +99,12 @@ public List<FM4Stream> fetchStreams() throws IOException {
public void testGetNextFound() {
try (FM4Cache cache = new FM4Cache(new FM4() {
@Override
public List<FM4Stream> fetchStreams() throws IOException {
public List<FM4Stream> fetchStreams(int days) throws IOException {
// only load two shows to make testing quick
List<FM4Stream> fm4Streams = super.fetchStreams();
List<FM4Stream> fm4Streams = super.fetchStreams(days);
return fm4Streams.subList(0, Math.min(2, fm4Streams.size()));
}
})) {
}, 7)) {
cache.refresh();

Collection<FM4Stream> fm4Streams = cache.allStreams();
Expand Down Expand Up @@ -142,12 +142,12 @@ public List<FM4Stream> fetchStreams() throws IOException {
public void testGetPreviousNotFound() {
try (FM4Cache cache = new FM4Cache(new FM4() {
@Override
public List<FM4Stream> fetchStreams() throws IOException {
public List<FM4Stream> fetchStreams(int days) throws IOException {
// only load two shows to make testing quick
List<FM4Stream> fm4Streams = super.fetchStreams();
List<FM4Stream> fm4Streams = super.fetchStreams(days);
return fm4Streams.subList(0, Math.min(2, fm4Streams.size()));
}
})) {
}, 7)) {
cache.refresh();

assertNull(cache.getNext(null));
Expand All @@ -171,12 +171,12 @@ public List<FM4Stream> fetchStreams() throws IOException {
public void testGetPreviousFound() {
try (FM4Cache cache = new FM4Cache(new FM4() {
@Override
public List<FM4Stream> fetchStreams() throws IOException {
public List<FM4Stream> fetchStreams(int days) throws IOException {
// only load two shows to make testing quick
List<FM4Stream> fm4Streams = super.fetchStreams();
List<FM4Stream> fm4Streams = super.fetchStreams(days);
return fm4Streams.subList(0, Math.min(2, fm4Streams.size()));
}
})) {
}, 7)) {
cache.refresh();

Collection<FM4Stream> fm4Streams = cache.allStreams();
Expand Down Expand Up @@ -214,12 +214,12 @@ public List<FM4Stream> fetchStreams() throws IOException {
public void testGetNextByStreamURLNotFound() throws IOException {
try (FM4Cache cache = new FM4Cache(new FM4() {
@Override
public List<FM4Stream> fetchStreams() throws IOException {
public List<FM4Stream> fetchStreams(int days) throws IOException {
// only load two shows to make testing quick
List<FM4Stream> fm4Streams = super.fetchStreams();
List<FM4Stream> fm4Streams = super.fetchStreams(days);
return fm4Streams.subList(0, Math.min(2, fm4Streams.size()));
}
})) {
}, 7)) {
cache.refresh();

assertNull(cache.getNextByStreamURL(null));
Expand All @@ -234,12 +234,12 @@ public List<FM4Stream> fetchStreams() throws IOException {
public void testGetNextByStreamURLFound() throws IOException {
try (FM4Cache cache = new FM4Cache(new FM4() {
@Override
public List<FM4Stream> fetchStreams() throws IOException {
public List<FM4Stream> fetchStreams(int days) throws IOException {
// only load two shows to make testing quick
List<FM4Stream> fm4Streams = super.fetchStreams();
List<FM4Stream> fm4Streams = super.fetchStreams(days);
return fm4Streams.subList(0, Math.min(2, fm4Streams.size()));
}
})) {
}, 7)) {
cache.refresh();

Collection<FM4Stream> fm4Streams = cache.allStreams();
Expand Down Expand Up @@ -279,10 +279,10 @@ public List<FM4Stream> fetchStreams() throws IOException {
public void testIOException() {
try (FM4Cache cache = new FM4Cache(new FM4() {
@Override
public List<FM4Stream> fetchStreams() throws IOException {
public List<FM4Stream> fetchStreams(int days) throws IOException {
throw new IOException("Test-exception");
}
})) {
}, 7)) {
verifier.addObject(cache);

cache.refresh();
Expand All @@ -291,7 +291,7 @@ public List<FM4Stream> fetchStreams() throws IOException {

@Test
public void testThread() throws InterruptedException {
try (FM4Cache cache = new FM4Cache(new FM4())) {
try (FM4Cache cache = new FM4Cache(new FM4(), 7)) {
// wait for the thread be started
for (int i = 0; i < 10; i++) {
if (ExecutorUtil.lookupThread("FM4Cache") != null) {
Expand Down
13 changes: 11 additions & 2 deletions src/test/java/org/dstadler/audio/fm4/FM4StreamTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class FM4StreamTest {

@Test
public void testFM4Stream() throws IOException, ParseException {
List<FM4Stream> fm4Streams = fm4.fetchStreams();
List<FM4Stream> fm4Streams = fm4.fetchStreams(7);

FM4Stream fm4Stream = fm4Streams.get(0);
assertNotNull(fm4Stream.getTitle());
Expand Down Expand Up @@ -83,7 +83,7 @@ public void testFM4Stream() throws IOException, ParseException {
@Test
public void testStreams() throws IOException {
FM4 fm4 = new FM4();
List<FM4Stream> fm4Streams = fm4.fetchStreams();
List<FM4Stream> fm4Streams = fm4.fetchStreams(7);

Assume.assumeFalse("Should get some streams", fm4Streams.isEmpty());

Expand All @@ -94,6 +94,15 @@ public void testStreams() throws IOException {
assertNotNull(streams.get(0));
}

@Test
public void testStreamsMoreDays() throws IOException {
FM4 fm4 = new FM4();
List<FM4Stream> fm4Streams7 = fm4.fetchStreams(7);
List<FM4Stream> fm4Streams14 = fm4.fetchStreams(14);

assertTrue(fm4Streams14.size() > fm4Streams7.size());
}

@Test
public void testEquals() {
ObjectNode node = objectMapper.createObjectNode();
Expand Down
23 changes: 21 additions & 2 deletions src/test/java/org/dstadler/audio/fm4/FM4Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import static org.dstadler.audio.fm4.FM4Stream.FM4_STREAM_URL_BASE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

public class FM4Test {
Expand All @@ -47,7 +50,7 @@ public class FM4Test {

@Test
public void testFetch() throws IOException, ParseException {
List<FM4Stream> fm4Streams = fm4.fetchStreams();
List<FM4Stream> fm4Streams = fm4.fetchStreams(7);

assertNotNull(fm4Streams);
assertFalse(fm4Streams.isEmpty());
Expand All @@ -63,6 +66,22 @@ public void testFetch() throws IOException, ParseException {
}
}

@Test
public void testFetchNoDuplicates() throws IOException {
List<FM4Stream> fm4Streams = fm4.fetchStreams(14);
Set<String> seenStreams = new HashSet<>();
for (FM4Stream stream : fm4Streams) {
assertTrue("Had duplicate for " + stream,
seenStreams.add(stream.getShortTime()));
}
}

@Test
public void testFetchTooManyDays() {
assertThrows(IOException.class,
() -> fm4.fetchStreams(90));
}

@Test
public void testFetchForDate() throws IOException, ParseException {
String date = FastDateFormat.getInstance("yyyyMMdd").format(DateUtils.addDays(new Date(), -3));
Expand All @@ -85,7 +104,7 @@ public void testFetchForDate() throws IOException, ParseException {
@Ignore("Fetches streams for all programs, this runs for some time, so disable for CI")
@Test
public void testFetchAllStreams() throws IOException {
List<FM4Stream> fm4Streams = fm4.fetchStreams();
List<FM4Stream> fm4Streams = fm4.fetchStreams(14);

assertNotNull(fm4Streams);
assertFalse(fm4Streams.isEmpty());
Expand Down

0 comments on commit bf75606

Please sign in to comment.