Skip to content

Commit dd0e5fd

Browse files
authored
Merge pull request #491 from IABTechLab/gdm-UID2-5557-refreshfrom-hotfix
Added day truncation for refresh from
2 parents d708de3 + 90b173d commit dd0e5fd

File tree

5 files changed

+34
-20
lines changed

5 files changed

+34
-20
lines changed

src/main/java/com/uid2/admin/salt/SaltRotation.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import java.util.stream.Collectors;
1717

1818
public class SaltRotation {
19-
private final static long THIRTY_DAYS_IN_MS = Duration.ofDays(30).toMillis();
19+
private static final long THIRTY_DAYS_IN_MS = Duration.ofDays(30).toMillis();
2020

2121
private final IKeyGenerator keyGenerator;
2222
private final boolean isRefreshFromEnabled;
@@ -31,8 +31,7 @@ public Result rotateSalts(
3131
SaltSnapshot lastSnapshot,
3232
Duration[] minAges,
3333
double fraction,
34-
TargetDate targetDate
35-
) throws Exception {
34+
TargetDate targetDate) throws Exception {
3635
var preRotationSalts = lastSnapshot.getAllRotatingSalts();
3736
var nextEffective = targetDate.asInstant();
3837
var nextExpires = nextEffective.plus(7, ChronoUnit.DAYS);
@@ -79,7 +78,7 @@ private Set<SaltEntry> findRefreshableSalts(SaltEntry[] preRotationSalts, Target
7978

8079
private boolean isRefreshable(TargetDate targetDate, SaltEntry salt) {
8180
if (this.isRefreshFromEnabled) {
82-
return salt.refreshFrom().equals(targetDate.asEpochMs());
81+
return Instant.ofEpochMilli(salt.refreshFrom()).truncatedTo(ChronoUnit.DAYS).equals(targetDate.asInstant());
8382
}
8483

8584
return true;
@@ -116,7 +115,7 @@ private SaltEntry updateSalt(SaltEntry oldSalt, TargetDate targetDate, boolean s
116115

117116
private long calculateRefreshFrom(SaltEntry salt, TargetDate targetDate) {
118117
long multiplier = targetDate.saltAgeInDays(salt) / 30 + 1;
119-
return salt.lastUpdated() + (multiplier * THIRTY_DAYS_IN_MS);
118+
return Instant.ofEpochMilli(salt.lastUpdated()).truncatedTo(ChronoUnit.DAYS).toEpochMilli() + (multiplier * THIRTY_DAYS_IN_MS);
120119
}
121120

122121
private String calculatePreviousSalt(SaltEntry salt, boolean shouldRotate, TargetDate targetDate) {
@@ -133,8 +132,7 @@ private List<SaltEntry> pickSaltsToRotate(
133132
Set<SaltEntry> refreshableSalts,
134133
TargetDate targetDate,
135134
Duration[] minAges,
136-
int numSaltsToRotate
137-
) {
135+
int numSaltsToRotate) {
138136
var thresholds = Arrays.stream(minAges)
139137
.map(minAge -> targetDate.asInstant().minusSeconds(minAge.getSeconds()))
140138
.sorted()
@@ -162,8 +160,7 @@ private List<SaltEntry> pickSaltsToRotateInTimeWindow(
162160
Set<SaltEntry> refreshableSalts,
163161
int maxIndexes,
164162
long minLastUpdated,
165-
long maxLastUpdated
166-
) {
163+
long maxLastUpdated) {
167164
ArrayList<SaltEntry> candidateSalts = refreshableSalts.stream()
168165
.filter(salt -> minLastUpdated <= salt.lastUpdated() && salt.lastUpdated() < maxLastUpdated)
169166
.collect(Collectors.toCollection(ArrayList::new));
@@ -195,7 +192,7 @@ private void logSaltAges(String saltCountType, TargetDate targetDate, Collection
195192
}
196193

197194
@Getter
198-
public static class Result {
195+
public static final class Result {
199196
private final SaltSnapshot snapshot; // can be null if new snapshot is not needed
200197
private final String reason; // why you are not getting a new snapshot
201198

src/main/java/com/uid2/admin/salt/TargetDate.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44

55
import java.time.*;
66
import java.time.format.DateTimeFormatter;
7+
import java.time.temporal.ChronoUnit;
78
import java.util.Objects;
89

910
public class TargetDate {
10-
private final static long DAY_IN_MS = Duration.ofDays(1).toMillis();
11+
private static final long DAY_IN_MS = Duration.ofDays(1).toMillis();
1112

1213
private final LocalDate date;
1314
private final long epochMs;
@@ -39,7 +40,7 @@ public Instant asInstant() {
3940

4041
// relative to this date
4142
public long saltAgeInDays(SaltEntry salt) {
42-
return (this.asEpochMs() - salt.lastUpdated()) / DAY_IN_MS;
43+
return (this.asEpochMs() - Instant.ofEpochMilli(salt.lastUpdated()).truncatedTo(ChronoUnit.DAYS).toEpochMilli()) / DAY_IN_MS;
4344
}
4445

4546
public TargetDate plusDays(int days) {

src/test/java/com/uid2/admin/salt/SaltRotationTest.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import ch.qos.logback.classic.Logger;
3030
import org.slf4j.LoggerFactory;
3131

32-
public class SaltRotationTest {
32+
class SaltRotationTest {
3333
@Mock
3434
private IKeyGenerator keyGenerator;
3535
private SaltRotation saltRotation;
@@ -50,7 +50,7 @@ void setup() {
5050
}
5151

5252
@AfterEach
53-
void tearDown() throws Exception {
53+
void teardown() throws Exception {
5454
appender.stop();
5555
mocks.close();
5656
}
@@ -209,13 +209,16 @@ void rotateSaltsRotateSaltsInsufficientOutdatedSalts() throws Exception {
209209

210210
@ParameterizedTest
211211
@CsvSource({
212-
"5, 30", // Soon after rotation, use 30 days post rotation
213-
"40, 60", // >30 days after rotation use the next increment of 30 days
214-
"60, 90", // Exactly at multiple of 30 days post rotation, use next increment of 30 days
212+
"5, 0, 30", // Soon after rotation, use 30 days post rotation
213+
"5, 100, 30", // Soon after rotation, use 30 days post rotation with some offset
214+
"40, 0, 60", // >30 days after rotation use the next increment of 30 days
215+
"40, 100, 60", // >30 days after rotation use the next increment of 30 days with some offset
216+
"60, 0, 90", // Exactly at multiple of 30 days post rotation, use next increment of 30 days
217+
"60, 100, 90" // Exactly at multiple of 30 days post rotation, use next increment of 30 days with some offset
215218
})
216-
void testRefreshFromCalculation(int lastRotationDaysAgo, int refreshFromDaysFromRotation) throws Exception {
219+
void testRefreshFromCalculation(int lastRotationDaysAgo, int lastRotationMsOffset, int refreshFromDaysFromRotation) throws Exception {
217220
var lastRotation = daysEarlier(lastRotationDaysAgo);
218-
SaltBuilder saltBuilder = SaltBuilder.start().lastUpdated(lastRotation);
221+
SaltBuilder saltBuilder = SaltBuilder.start().lastUpdated(lastRotation.asInstant().plusMillis(lastRotationMsOffset));
219222
var lastSnapshot = SaltSnapshotBuilder.start()
220223
.entries(saltBuilder)
221224
.build();

src/test/java/com/uid2/admin/salt/helper/SaltBuilder.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,21 @@ public SaltBuilder lastUpdated(TargetDate lastUpdated) {
3232
return this;
3333
}
3434

35+
public SaltBuilder lastUpdated(Instant lastUpdated) {
36+
this.lastUpdated = lastUpdated;
37+
return this;
38+
}
39+
3540
public SaltBuilder refreshFrom(TargetDate refreshFrom) {
3641
this.refreshFrom = refreshFrom.asInstant();
3742
return this;
3843
}
3944

45+
public SaltBuilder refreshFrom(Instant refreshFrom) {
46+
this.refreshFrom = refreshFrom;
47+
return this;
48+
}
49+
4050
public SaltBuilder currentSalt(String currentSalt) {
4151
this.currentSalt = currentSalt;
4252
return this;

src/test/java/com/uid2/admin/salt/helper/TargetDateUtil.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
import com.uid2.admin.salt.TargetDate;
44

5-
public class TargetDateUtil {
5+
public final class TargetDateUtil {
66
private static final TargetDate TARGET_DATE = TargetDate.of(2025, 1, 1);
77

8+
private TargetDateUtil() {
9+
}
10+
811
public static TargetDate daysEarlier(int days) {
912
return TARGET_DATE.minusDays(days);
1013
}

0 commit comments

Comments
 (0)