|
1 | | -package com.uid2.admin.secret; |
| 1 | +package com.uid2.admin.salt; |
2 | 2 |
|
3 | 3 | import com.uid2.admin.AdminConst; |
4 | 4 | import com.uid2.shared.model.SaltEntry; |
|
10 | 10 | import org.slf4j.Logger; |
11 | 11 | import org.slf4j.LoggerFactory; |
12 | 12 |
|
13 | | -import java.time.Duration; |
14 | | -import java.time.Instant; |
15 | | -import java.time.LocalDate; |
16 | | -import java.time.ZoneOffset; |
17 | | -import java.time.format.DateTimeFormatter; |
| 13 | +import java.time.*; |
18 | 14 | import java.time.temporal.ChronoUnit; |
19 | 15 | import java.util.*; |
20 | 16 | import java.util.stream.Collectors; |
@@ -60,9 +56,9 @@ public Result rotateSalts( |
60 | 56 |
|
61 | 57 | var postRotationSalts = rotateSalts(preRotationSalts, saltsToRotate, targetDate); |
62 | 58 |
|
63 | | - logSaltAgeCounts("rotatable-salts", targetDate, rotatableSalts); |
64 | | - logSaltAgeCounts("rotated-salts", targetDate, saltsToRotate); |
65 | | - logSaltAgeCounts("total-salts", targetDate, Arrays.asList(postRotationSalts)); |
| 59 | + logSaltAges("rotatable-salts", targetDate, rotatableSalts); |
| 60 | + logSaltAges("rotated-salts", targetDate, saltsToRotate); |
| 61 | + logSaltAges("total-salts", targetDate, Arrays.asList(postRotationSalts)); |
66 | 62 |
|
67 | 63 | var nextSnapshot = new SaltSnapshot( |
68 | 64 | nextEffective, |
@@ -118,15 +114,15 @@ private SaltEntry updateSalt(SaltEntry oldSalt, TargetDate targetDate, boolean s |
118 | 114 | } |
119 | 115 |
|
120 | 116 | private long calculateRefreshFrom(SaltEntry salt, TargetDate targetDate) { |
121 | | - long multiplier = targetDate.ageOfSaltInMs(salt) / THIRTY_DAYS_IN_MS + 1; |
| 117 | + long multiplier = targetDate.saltAgeInDays(salt) / 30 + 1; |
122 | 118 | return salt.lastUpdated() + (multiplier * THIRTY_DAYS_IN_MS); |
123 | 119 | } |
124 | 120 |
|
125 | 121 | private String calculatePreviousSalt(SaltEntry salt, boolean shouldRotate, TargetDate targetDate) { |
126 | 122 | if (shouldRotate) { |
127 | 123 | return salt.currentSalt(); |
128 | 124 | } |
129 | | - if (targetDate.ageOfSaltInDays(salt) < 90) { |
| 125 | + if (targetDate.saltAgeInDays(salt) < 90) { |
130 | 126 | return salt.previousSalt(); |
131 | 127 | } |
132 | 128 | return null; |
@@ -167,88 +163,38 @@ private List<SaltEntry> pickSaltsToRotateInTimeWindow( |
167 | 163 | long minLastUpdated, |
168 | 164 | long maxLastUpdated |
169 | 165 | ) { |
170 | | - var candidateSalts = new ArrayList<SaltEntry>(); |
171 | | - for (SaltEntry salt : rotatableSalts) { |
172 | | - var lastUpdated = salt.lastUpdated(); |
173 | | - var isInTimeWindow = minLastUpdated <= lastUpdated && lastUpdated < maxLastUpdated; |
174 | | - |
175 | | - if (isInTimeWindow) { |
176 | | - candidateSalts.add(salt); |
177 | | - } |
178 | | - } |
| 166 | + ArrayList<SaltEntry> candidateSalts = rotatableSalts.stream() |
| 167 | + .filter(salt -> minLastUpdated <= salt.lastUpdated() && salt.lastUpdated() < maxLastUpdated) |
| 168 | + .collect(Collectors.toCollection(ArrayList::new)); |
179 | 169 |
|
180 | 170 | if (candidateSalts.size() <= maxIndexes) { |
181 | 171 | return candidateSalts; |
182 | 172 | } |
183 | 173 |
|
184 | 174 | Collections.shuffle(candidateSalts); |
185 | | - return candidateSalts.subList(0, Math.min(maxIndexes, candidateSalts.size())); |
| 175 | + |
| 176 | + return candidateSalts.stream().limit(maxIndexes).collect(Collectors.toList()); |
186 | 177 | } |
187 | 178 |
|
188 | | - private void logSaltAgeCounts(String saltCountType, TargetDate targetDate, Collection<SaltEntry> salts) { |
| 179 | + private void logSaltAges(String saltCountType, TargetDate targetDate, Collection<SaltEntry> salts) { |
189 | 180 | var ages = new HashMap<Long, Long>(); // salt age to count |
190 | 181 | for (var salt : salts) { |
191 | | - long ageInDays = targetDate.ageOfSaltInDays(salt); |
| 182 | + long ageInDays = targetDate.saltAgeInDays(salt); |
192 | 183 | ages.put(ageInDays, ages.getOrDefault(ageInDays, 0L) + 1); |
193 | 184 | } |
194 | 185 |
|
195 | 186 | for (var entry : ages.entrySet()) { |
196 | | - LOGGER.info("salt-count-type={} target-date={} age={} salt-count={}", saltCountType, targetDate, entry.getKey(), entry.getValue()); |
197 | | - } |
198 | | - } |
199 | | - |
200 | | - public static class TargetDate { |
201 | | - private final static long DAY_IN_MS = Duration.ofDays(1).toMillis(); |
202 | | - |
203 | | - private final LocalDate date; |
204 | | - private final long epochMs; |
205 | | - private final Instant instant; |
206 | | - private final String formatted; |
207 | | - |
208 | | - public TargetDate(LocalDate date) { |
209 | | - this.instant = date.atStartOfDay().toInstant(ZoneOffset.UTC); |
210 | | - this.date = date; |
211 | | - this.epochMs = instant.toEpochMilli(); |
212 | | - this.formatted = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); |
213 | | - } |
214 | | - |
215 | | - public static TargetDate of(int year, int month, int day) { |
216 | | - return new TargetDate(LocalDate.of(year, month, day)); |
217 | | - } |
218 | | - |
219 | | - public long asEpochMs() { |
220 | | - return epochMs; |
221 | | - } |
222 | | - |
223 | | - public Instant asInstant() { |
224 | | - return instant; |
225 | | - } |
226 | | - |
227 | | - public long ageOfSaltInMs(SaltEntry salt) { |
228 | | - return this.asEpochMs() - salt.lastUpdated(); |
229 | | - } |
230 | | - |
231 | | - public long ageOfSaltInDays(SaltEntry salt) { |
232 | | - return ageOfSaltInMs(salt) / DAY_IN_MS; |
233 | | - } |
234 | | - |
235 | | - public TargetDate plusDays(int days) { |
236 | | - return new TargetDate(date.plusDays(days)); |
237 | | - } |
238 | | - |
239 | | - public TargetDate minusDays(int days) { |
240 | | - return new TargetDate(date.minusDays(days)); |
241 | | - } |
242 | | - |
243 | | - @Override |
244 | | - public String toString() { |
245 | | - return formatted; |
| 187 | + LOGGER.info("salt-count-type={} target-date={} age={} salt-count={}", |
| 188 | + saltCountType, |
| 189 | + targetDate, |
| 190 | + entry.getKey(), |
| 191 | + entry.getValue() |
| 192 | + ); |
246 | 193 | } |
247 | 194 | } |
248 | 195 |
|
249 | 196 | @Getter |
250 | 197 | public static class Result { |
251 | | - |
252 | 198 | private final SaltSnapshot snapshot; // can be null if new snapshot is not needed |
253 | 199 | private final String reason; // why you are not getting a new snapshot |
254 | 200 |
|
|
0 commit comments