Skip to content

Commit e90d9b0

Browse files
authored
Merge pull request duracloud#206 from mikejritter/dc-1355
DC-1355: Sort timerseries data
2 parents 3ef6b82 + 8d6c948 commit e90d9b0

3 files changed

Lines changed: 97 additions & 16 deletions

File tree

.github/workflows/ci-build.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,18 @@ jobs:
1717

1818
# https://github.com/actions/checkout
1919
- name: Checkout codebase
20-
uses: actions/checkout@v2
20+
uses: actions/checkout@v4
2121

2222
# https://github.com/actions/setup-java
2323
- name: Install JDK 17
24-
uses: actions/setup-java@v2
24+
uses: actions/setup-java@v4
2525
with:
2626
java-version: 17
2727
distribution: adopt
2828

2929
# https://github.com/actions/cache
3030
- name: Cache Maven dependencies
31-
uses: actions/cache@v2
31+
uses: actions/cache@v4
3232
with:
3333
# Cache entire ~/.m2/repository
3434
path: ~/.m2/repository
@@ -44,7 +44,7 @@ jobs:
4444
# Sets up Java again, preparing the settings.xml to deploy to Sonatype (Maven)
4545
# ONLY on push to develop branch (using Sonatype snapshots repo)
4646
- name: Set up for deploy to Sonatype
47-
uses: actions/setup-java@v2
47+
uses: actions/setup-java@v4
4848
if: github.ref == 'refs/heads/develop' && github.event_name == 'push'
4949
with:
5050
java-version: 17
@@ -56,7 +56,7 @@ jobs:
5656
gpg-passphrase: CODESIGN_GPG_PASSPHRASE # env variable for GPG private key passphrase
5757
# ONLY on push to main branch (using Sonatype releases repo)
5858
- name: Set up for deploy to Sonatype
59-
uses: actions/setup-java@v2
59+
uses: actions/setup-java@v4
6060
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
6161
with:
6262
java-version: 17

durastore/src/main/java/org/duracloud/durastore/rest/StorageStatsResource.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import java.math.BigDecimal;
1111
import java.util.ArrayList;
12+
import java.util.Comparator;
1213
import java.util.Date;
1314
import java.util.List;
1415

@@ -33,7 +34,7 @@ public class StorageStatsResource {
3334

3435
final long ONE_DAY_IN_MS = 24 * 60 * 60 * 1000;
3536

36-
public static enum GroupBy {
37+
public enum GroupBy {
3738
day,
3839
week,
3940
month;
@@ -64,6 +65,7 @@ public List<SpaceStatsDTO> getSpaceStats(String accountId,
6465
((BigDecimal) s[5]).longValue()));
6566
}
6667

68+
dtos.sort(Comparator.comparing(SpaceStatsDTO::getTimestamp));
6769
return dtos;
6870
}
6971

@@ -99,6 +101,7 @@ public List<StoreStatsDTO> getStorageProviderStats(String account,
99101
((BigDecimal) s[4]).longValue()));
100102
}
101103

104+
dtos.sort(Comparator.comparing(StoreStatsDTO::getTimestamp));
102105
return dtos;
103106
}
104107

durastore/src/test/java/org/duracloud/durastore/rest/StorageStatsResourceTest.java

Lines changed: 88 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,19 @@
1515
import static org.easymock.EasyMock.verify;
1616
import static org.junit.Assert.assertEquals;
1717

18+
import java.math.BigDecimal;
19+
import java.time.Instant;
20+
import java.time.LocalDate;
21+
import java.time.ZoneOffset;
22+
import java.time.format.DateTimeFormatter;
1823
import java.util.ArrayList;
1924
import java.util.Date;
25+
import java.util.List;
2026

2127
import org.duracloud.mill.db.repo.JpaSpaceStatsRepo;
28+
import org.duracloud.reportdata.storage.StoreStatsDTO;
2229
import org.easymock.Capture;
2330
import org.easymock.Mock;
24-
import org.joda.time.format.DateTimeFormat;
25-
import org.joda.time.format.DateTimeFormatter;
2631
import org.junit.Test;
2732

2833
/**
@@ -33,14 +38,14 @@ public class StorageStatsResourceTest {
3338
@Mock
3439
private JpaSpaceStatsRepo spaceStatsRepo;
3540

36-
@Test
37-
public void testGetStorageStats() throws Exception {
41+
final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_INSTANT;
3842

43+
@Test
44+
public void testGetStorageStats() {
3945
spaceStatsRepo = mock(JpaSpaceStatsRepo.class);
4046
final String accountId = "account-id";
4147
final String storeId = "id";
42-
DateTimeFormatter format = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss z").withZoneUTC();
43-
final Date date = format.parseDateTime("2019-12-31 12:00:00 UTC").toDate();
48+
final Date date = Date.from(Instant.from(dateTimeFormatter.parse(("2019-12-31T12:00:00Z"))));
4449

4550
final Capture<Date> captureStart = Capture.newInstance();
4651
final Capture<Date> captureEnd = Capture.newInstance();
@@ -57,10 +62,83 @@ public void testGetStorageStats() throws Exception {
5762
final Date end = captureEnd.getValue();
5863
//assertEquals("Start date should be 00:00:00 GMT of the same day as input date", "2019-12-31 00:00:00 UTC",
5964
// format.print(start.getTime()));
60-
assertEquals("Start date should be 00:00:00 GMT of the next day as input date", "2019-12-31 00:00:00 UTC",
61-
format.print(start.getTime()));
62-
assertEquals("End date should be 00:00:00 GMT of the next day as input date", "2020-01-01 00:00:00 UTC",
63-
format.print(end.getTime()));
65+
assertEquals("Start date should be 00:00:00 GMT of the next day as input date", "2019-12-31T00:00:00Z",
66+
dateTimeFormatter.format(start.toInstant()));
67+
assertEquals("End date should be 00:00:00 GMT of the next day as input date", "2020-01-01T00:00:00Z",
68+
dateTimeFormatter.format(end.toInstant()));
69+
70+
}
71+
72+
@Test
73+
public void testSortsStorageStats() {
74+
spaceStatsRepo = mock(JpaSpaceStatsRepo.class);
75+
final var accountId = "account-id";
76+
final var storeId = "id";
77+
final var byteCount = new BigDecimal(10000);
78+
final var objectCount = new BigDecimal(100);
79+
80+
final Date firstDate = Date.from(Instant.from(dateTimeFormatter.parse(("2019-12-31T12:00:00Z"))));
81+
final Date lastDate = Date.from(Instant.from(dateTimeFormatter.parse(("2023-12-31T12:00:00Z"))));
82+
final var now = Date.from(Instant.now());
83+
84+
// A few quirks to note from the JpaSpaceStatsRepo:
85+
// - The time returned needs to be divided by 1000. See when creating new StoreStatsDTO/SpaceStatsDTO objects
86+
// - We get back a BigDecimal for the file and byte counts as they use the aggregate function `avg`
87+
final var unsorted = List.of(
88+
List.of(lastDate.getTime() / 1000, accountId, storeId, byteCount, objectCount).toArray(),
89+
List.of(firstDate.getTime() / 1000, accountId, storeId, byteCount, objectCount).toArray());
90+
91+
expect(spaceStatsRepo.getByAccountIdAndStoreId(eq(accountId), eq(storeId), eq(firstDate),
92+
eq(now), eq(JpaSpaceStatsRepo.INTERVAL_DAY)))
93+
.andReturn(unsorted);
94+
95+
replay(spaceStatsRepo);
96+
final var resource = new StorageStatsResource(spaceStatsRepo);
97+
final List<StoreStatsDTO> storageProviderStats =
98+
resource.getStorageProviderStats(accountId, storeId, firstDate, now, StorageStatsResource.GroupBy.day);
99+
verify(spaceStatsRepo);
100+
101+
assertEquals(2, storageProviderStats.size());
102+
assertEquals(firstDate, storageProviderStats.get(0).getTimestamp());
103+
assertEquals(lastDate, storageProviderStats.get(1).getTimestamp());
104+
}
105+
106+
@Test
107+
public void testSortsSpaceStats() {
108+
spaceStatsRepo = mock(JpaSpaceStatsRepo.class);
109+
final var accountId = "account-id";
110+
final var storeId = "id";
111+
final var spaceId = "space-id";
112+
final var byteCount = new BigDecimal(10000);
113+
final var objectCount = new BigDecimal(100);
114+
115+
final var firstDate = Date.from(Instant.from(dateTimeFormatter.parse("2019-12-31T12:00:00Z")));
116+
final var lastDate = Date.from(Instant.from(dateTimeFormatter.parse("2023-12-31T12:00:00Z")));
117+
final var now = Date.from(Instant.now());
118+
119+
// A few quirks to note from the JpaSpaceStatsRepo:
120+
// - The time returned needs to be divided by 1000. See when creating new StoreStatsDTO/SpaceStatsDTO objects
121+
// - We get back a BigDecimal for the file and byte counts as they use the aggregate function `avg`
122+
// - The final column is the timestamp as a local date format (e.g. 2019-12-31)
123+
final List<Object[]> unsorted = List.of(
124+
List.of(lastDate.getTime() / 1000, accountId, storeId, spaceId, byteCount, objectCount,
125+
LocalDate.ofInstant(lastDate.toInstant(), ZoneOffset.UTC).toString()).toArray(),
126+
List.of(firstDate.getTime() / 1000, accountId, storeId, spaceId, byteCount, objectCount,
127+
LocalDate.ofInstant(firstDate.toInstant(), ZoneOffset.UTC).toString()).toArray());
128+
129+
expect(spaceStatsRepo.getByAccountIdAndStoreIdAndSpaceId(eq(accountId), eq(storeId), eq(spaceId),
130+
eq(firstDate), eq(now),
131+
eq(JpaSpaceStatsRepo.INTERVAL_DAY)))
132+
.andReturn(unsorted);
133+
134+
replay(spaceStatsRepo);
135+
final var resource = new StorageStatsResource(spaceStatsRepo);
136+
final var storageProviderStats = resource.getSpaceStats(accountId, storeId, spaceId, firstDate, now,
137+
StorageStatsResource.GroupBy.day);
138+
verify(spaceStatsRepo);
64139

140+
assertEquals(2, storageProviderStats.size());
141+
assertEquals(firstDate, storageProviderStats.get(0).getTimestamp());
142+
assertEquals(lastDate, storageProviderStats.get(1).getTimestamp());
65143
}
66144
}

0 commit comments

Comments
 (0)