diff --git a/java/google/registry/tools/server/KillAllDomainApplicationsAction.java b/java/google/registry/tools/server/KillAllDomainApplicationsAction.java index 8b639ba09..0c9673b20 100644 --- a/java/google/registry/tools/server/KillAllDomainApplicationsAction.java +++ b/java/google/registry/tools/server/KillAllDomainApplicationsAction.java @@ -75,20 +75,34 @@ public class KillAllDomainApplicationsAction implements Runnable { getContext().incrementCounter("applications already deleted"); return; } + Key applicationKey = Key.create(application); DomainApplicationIndex dai = ofy().load().key(DomainApplicationIndex.createKey(application)).now(); EppResourceIndex eri = ofy().load().entity(EppResourceIndex.create(applicationKey)).now(); - if (dai == null || eri == null) { + + if (dai == null) { logger.atSevere().log( - "Missing index(es) for application %s; skipping.", applicationKey); - getContext().incrementCounter("missing indexes"); - return; + "Missing domain application index for application %s.", applicationKey); + getContext().incrementCounter("missing domain application indexes"); + } else { + ofy().delete().entity(dai); } + + // This case shouldn't be possible except in extremely rare circumstances, as this + // mapreduce itself is relying on EPP resource indexes to load the domain + // applications to delete. + if (eri == null) { + logger.atSevere().log( + "Missing EPP resource index for application %s.", applicationKey); + getContext().incrementCounter("missing EPP resource indexes"); + } else { + ofy().delete().entity(eri); + } + // Delete the application, its descendents, and the indexes. ofy().delete().keys(ofy().load().ancestor(application).keys()); - ofy().delete().entities(dai, eri); logger.atInfo().log("Deleted domain application %s.", applicationKey); getContext().incrementCounter("applications deleted"); }); diff --git a/javatests/google/registry/tools/server/KillAllDomainApplicationsActionTest.java b/javatests/google/registry/tools/server/KillAllDomainApplicationsActionTest.java index 102df8adf..544457a0f 100644 --- a/javatests/google/registry/tools/server/KillAllDomainApplicationsActionTest.java +++ b/javatests/google/registry/tools/server/KillAllDomainApplicationsActionTest.java @@ -16,6 +16,7 @@ package google.registry.tools.server; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.testing.DatastoreHelper.createTld; import static google.registry.testing.DatastoreHelper.createTlds; import static google.registry.testing.DatastoreHelper.persistActiveContact; import static google.registry.testing.DatastoreHelper.persistActiveDomain; @@ -91,4 +92,26 @@ public class KillAllDomainApplicationsActionTest .entities(application, applicationEri, applicationDai, applicationHistoryEntry)) .isEmpty(); } + + @Test + public void test_deletesApplication_evenWhenIndexIsMissing() throws Exception { + createTld("tld1"); + DomainApplication application = persistActiveDomainApplication("applied.tld1"); + EppResourceIndex applicationEri = + ofy().load().entity(EppResourceIndex.create(Key.create(application))).now(); + HistoryEntry applicationHistoryEntry = + persistResource(new HistoryEntry.Builder().setParent(application).build()); + + // Delete the domain application index. + ofy().transact(() -> ofy().delete().key(DomainApplicationIndex.createKey(application)).now()); + ofy().clearSessionCache(); + + runMapreduce(); + ofy().clearSessionCache(); + + // Check that the domain application and history entry were deleted even though the indexes + // couldn't be found. + assertThat(ofy().load().entities(application, applicationEri, applicationHistoryEntry)) + .isEmpty(); + } }