RpkiObjectCleanupService { public long cleanupRpkiObjects() throws Exception { final InstantWithoutNanos unreachableSince = InstantWithoutNanos.now().minus(cleanupGraceDuration); final Pair<Long, Long> deleted = Time.timed(() -> rpkiObjects.deleteUnreachableObjects(unreachableSince)); log.info("Removed {} RPKI objects that have not been marked reachable since {}, took {}ms", deleted.getLeft(), unreachableSince, deleted.getRight()); storage.gc(); return deleted.getLeft(); } RpkiObjectCleanupService(@Value("${rpki.validator.rpki.object.cleanup.grace.duration}") String cleanupGraceDuration,
                                    Storage storage); long cleanupRpkiObjects();  }
@Test public void should_delete_objects_not_reachable_from_manifest() throws Exception { BigInteger serial = TrustAnchorsFactory.nextSerial(); TrustAnchor trustAnchor = wtx(tx -> factory.createTrustAnchor(tx, ta -> ta.roaPrefixes(Collections.singletonList(RoaPrefix.of(IpRange.parse("127.0.0.0/8"), null, Asn.parse( "123"), DateTime.now().toInstant().getMillis(), DateTime.now().plusYears(1).toInstant().getMillis(), serial))))); assertThat(subject.cleanupRpkiObjects()).isEqualTo(0); RpkiObject orphan = new RpkiObject( new X509ResourceCertificateBuilder() .withResources(IpResourceSet.parse("10.0.0.0/8")) .withIssuerDN(trustAnchor.getCertificate().getSubject()) .withSubjectDN(new X500Principal("CN=orphan")) .withSerial(serial) .withPublicKey(KEY_PAIR_FACTORY.generate().getPublic()) .withSigningKeyPair(KEY_PAIR_FACTORY.generate()) .withValidityPeriod(new ValidityPeriod(DateTime.now(), DateTime.now().plusYears(1))) .build() ); wtx0(tx -> rpkiObjects.put(tx, orphan)); assertThat(subject.cleanupRpkiObjects()).isEqualTo(0); wtx0(tx -> rpkiObjects.markReachable(tx, orphan.key(), InstantWithoutNanos.now().minus(Duration.ofDays(10)))); assertThat(subject.cleanupRpkiObjects()).isEqualTo(1); }