|
|
@@ -101,15 +101,13 @@ public class BusinessCockpitMapSnapshotAdapter implements CockpitMapSnapshotAdap
|
|
|
String resolvedSnapshotAt = snapshotAt == null ? businessTime() : snapshotAt;
|
|
|
OffsetDateTime requestedAt = OffsetDateTime.parse(resolvedSnapshotAt);
|
|
|
OffsetDateTime now = OffsetDateTime.now(clock);
|
|
|
- if (!requestedAt.isAfter(now.minus(SNAPSHOT_RETENTION))
|
|
|
- || !requestedAt.isBefore(now.plus(SNAPSHOT_RETENTION))) {
|
|
|
- throw new CockpitSnapshotExpiredException("snapshot timestamp outside retention window");
|
|
|
- }
|
|
|
+ validateSnapshotWindow(requestedAt, now, "snapshot timestamp outside retention window");
|
|
|
|
|
|
snapshots.keySet().removeIf(cachedAt ->
|
|
|
!OffsetDateTime.parse(cachedAt).isAfter(now.minus(SNAPSHOT_RETENTION)));
|
|
|
CockpitMapSnapshot cached = snapshots.get(resolvedSnapshotAt);
|
|
|
if (cached != null) {
|
|
|
+ validateSnapshotWindow(requestedAt, OffsetDateTime.now(clock), "snapshot timestamp expired during load");
|
|
|
return cached;
|
|
|
}
|
|
|
|
|
|
@@ -120,6 +118,8 @@ public class BusinessCockpitMapSnapshotAdapter implements CockpitMapSnapshotAdap
|
|
|
if (snapshots.size() < MAX_CACHED_SNAPSHOTS) {
|
|
|
snapshots.putIfAbsent(resolvedSnapshotAt, shared);
|
|
|
}
|
|
|
+ validateSnapshotWindow(requestedAt, OffsetDateTime.now(clock),
|
|
|
+ "snapshot timestamp expired during load");
|
|
|
return shared;
|
|
|
}
|
|
|
}
|
|
|
@@ -129,10 +129,7 @@ public class BusinessCockpitMapSnapshotAdapter implements CockpitMapSnapshotAdap
|
|
|
|
|
|
CockpitMapSnapshot built = buildSnapshot(resolvedSnapshotAt);
|
|
|
OffsetDateTime writeTime = OffsetDateTime.now(clock);
|
|
|
- if (!requestedAt.isAfter(writeTime.minus(SNAPSHOT_RETENTION))
|
|
|
- || !requestedAt.isBefore(writeTime.plus(SNAPSHOT_RETENTION))) {
|
|
|
- throw new CockpitSnapshotExpiredException("snapshot timestamp expired during load");
|
|
|
- }
|
|
|
+ validateSnapshotWindow(requestedAt, writeTime, "snapshot timestamp expired during load");
|
|
|
if (redisTemplate != null) {
|
|
|
Duration remaining = Duration.between(writeTime, requestedAt.plus(SNAPSHOT_RETENTION));
|
|
|
long ttlSeconds = Math.max(1,
|
|
|
@@ -153,6 +150,14 @@ public class BusinessCockpitMapSnapshotAdapter implements CockpitMapSnapshotAdap
|
|
|
return snapshots.getOrDefault(resolvedSnapshotAt, built);
|
|
|
}
|
|
|
|
|
|
+ private static void validateSnapshotWindow(
|
|
|
+ OffsetDateTime requestedAt, OffsetDateTime now, String message) {
|
|
|
+ if (!requestedAt.isAfter(now.minus(SNAPSHOT_RETENTION))
|
|
|
+ || !requestedAt.isBefore(now.plus(SNAPSHOT_RETENTION))) {
|
|
|
+ throw new CockpitSnapshotExpiredException(message);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private CockpitMapSnapshot buildSnapshot(String resolvedSnapshotAt) {
|
|
|
|
|
|
Map<Integer, EquipmentType> types = equipmentTypes();
|