diff --git a/core/src/main/java/google/registry/backup/CommitLogCheckpointAction.java b/core/src/main/java/google/registry/backup/CommitLogCheckpointAction.java index 7617e0343..dc9e6485f 100644 --- a/core/src/main/java/google/registry/backup/CommitLogCheckpointAction.java +++ b/core/src/main/java/google/registry/backup/CommitLogCheckpointAction.java @@ -19,6 +19,7 @@ import static com.google.appengine.api.taskqueue.TaskOptions.Builder.withUrl; import static google.registry.backup.ExportCommitLogDiffAction.LOWER_CHECKPOINT_TIME_PARAM; import static google.registry.backup.ExportCommitLogDiffAction.UPPER_CHECKPOINT_TIME_PARAM; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.isBeforeOrAt; import com.google.common.flogger.FluentLogger; @@ -63,7 +64,7 @@ public final class CommitLogCheckpointAction implements Runnable { final CommitLogCheckpoint checkpoint = strategy.computeCheckpoint(); logger.atInfo().log( "Generated candidate checkpoint for time: %s", checkpoint.getCheckpointTime()); - ofy() + tm() .transact( () -> { DateTime lastWrittenTime = CommitLogCheckpointRoot.loadRoot().getLastWrittenTime(); diff --git a/core/src/main/java/google/registry/backup/DeleteOldCommitLogsAction.java b/core/src/main/java/google/registry/backup/DeleteOldCommitLogsAction.java index 90a551e8b..a64af7357 100644 --- a/core/src/main/java/google/registry/backup/DeleteOldCommitLogsAction.java +++ b/core/src/main/java/google/registry/backup/DeleteOldCommitLogsAction.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static google.registry.mapreduce.MapreduceRunner.PARAM_DRY_RUN; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; @@ -276,7 +277,7 @@ public final class DeleteOldCommitLogsAction implements Runnable { return; } - DeletionResult deletionResult = ofy().transactNew(() -> { + DeletionResult deletionResult = tm().transactNew(() -> { CommitLogManifest manifest = ofy().load().key(manifestKey).now(); // It is possible that the same manifestKey was run twice, if a shard had to be restarted // or some weird failure. If this happens, we want to exit immediately. diff --git a/core/src/main/java/google/registry/batch/DeleteContactsAndHostsAction.java b/core/src/main/java/google/registry/batch/DeleteContactsAndHostsAction.java index bf32e8f70..579a3e0a7 100644 --- a/core/src/main/java/google/registry/batch/DeleteContactsAndHostsAction.java +++ b/core/src/main/java/google/registry/batch/DeleteContactsAndHostsAction.java @@ -39,6 +39,7 @@ import static google.registry.model.reporting.HistoryEntry.Type.CONTACT_DELETE; import static google.registry.model.reporting.HistoryEntry.Type.CONTACT_DELETE_FAILURE; import static google.registry.model.reporting.HistoryEntry.Type.HOST_DELETE; import static google.registry.model.reporting.HistoryEntry.Type.HOST_DELETE_FAILURE; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.model.transfer.TransferStatus.SERVER_CANCELLED; import static java.math.RoundingMode.CEILING; import static java.util.concurrent.TimeUnit.DAYS; @@ -308,7 +309,7 @@ public class DeleteContactsAndHostsAction implements Runnable { final boolean hasNoActiveReferences = !Iterators.contains(values, true); logger.atInfo().log("Processing async deletion request for %s", deletionRequest.key()); DeletionResult result = - ofy() + tm() .transactNew( () -> { DeletionResult deletionResult = @@ -329,7 +330,7 @@ public class DeleteContactsAndHostsAction implements Runnable { private DeletionResult attemptToDeleteResource( DeletionRequest deletionRequest, boolean hasNoActiveReferences) { - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); EppResource resource = ofy().load().key(deletionRequest.key()).now().cloneProjectedAtTime(now); // Double-check transactionally that the resource is still active and in PENDING_DELETE. diff --git a/core/src/main/java/google/registry/batch/DeleteLoadTestDataAction.java b/core/src/main/java/google/registry/batch/DeleteLoadTestDataAction.java index 4a80ee551..b31d61966 100644 --- a/core/src/main/java/google/registry/batch/DeleteLoadTestDataAction.java +++ b/core/src/main/java/google/registry/batch/DeleteLoadTestDataAction.java @@ -19,6 +19,7 @@ import static google.registry.config.RegistryEnvironment.PRODUCTION; import static google.registry.mapreduce.MapreduceRunner.PARAM_DRY_RUN; import static google.registry.mapreduce.inputs.EppResourceInputs.createEntityInput; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.request.Action.Method.POST; import com.google.appengine.tools.mapreduce.Mapper; @@ -124,7 +125,7 @@ public class DeleteLoadTestDataAction implements Runnable { Key.create(EppResourceIndex.create(Key.create(resource))); final Key> fki = ForeignKeyIndex.createKey(resource); int numEntitiesDeleted = - ofy() + tm() .transact( () -> { // This ancestor query selects all descendant entities. diff --git a/core/src/main/java/google/registry/batch/DeleteProberDataAction.java b/core/src/main/java/google/registry/batch/DeleteProberDataAction.java index a0ae9cf45..c03534c00 100644 --- a/core/src/main/java/google/registry/batch/DeleteProberDataAction.java +++ b/core/src/main/java/google/registry/batch/DeleteProberDataAction.java @@ -23,6 +23,7 @@ import static google.registry.model.ResourceTransferUtils.updateForeignKeyIndexD import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.registry.Registries.getTldsOfType; import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_DELETE; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.request.Action.Method.POST; import static google.registry.request.RequestParameters.PARAM_TLDS; import static org.joda.time.DateTimeZone.UTC; @@ -219,7 +220,7 @@ public class DeleteProberDataAction implements Runnable { final Key> fki = ForeignKeyIndex.createKey(domain); int entitiesDeleted = - ofy() + tm() .transact( () -> { // This ancestor query selects all descendant HistoryEntries, BillingEvents, @@ -245,16 +246,16 @@ public class DeleteProberDataAction implements Runnable { } private void softDeleteDomain(final DomainBase domain) { - ofy().transactNew(() -> { + tm().transactNew(() -> { DomainBase deletedDomain = domain .asBuilder() - .setDeletionTime(ofy().getTransactionTime()) + .setDeletionTime(tm().getTransactionTime()) .setStatusValues(null) .build(); HistoryEntry historyEntry = new HistoryEntry.Builder() .setParent(domain) .setType(DOMAIN_DELETE) - .setModificationTime(ofy().getTransactionTime()) + .setModificationTime(tm().getTransactionTime()) .setBySuperuser(true) .setReason("Deletion of prober data") .setClientId(registryAdminClientId) diff --git a/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java b/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java index 9eee1f9f5..b18ebdcb8 100644 --- a/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java +++ b/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java @@ -23,6 +23,7 @@ import static google.registry.model.common.Cursor.CursorType.RECURRING_BILLING; import static google.registry.model.domain.Period.Unit.YEARS; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_AUTORENEW; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost; import static google.registry.util.CollectionUtils.union; import static google.registry.util.DateTimeUtils.START_OF_TIME; @@ -150,7 +151,7 @@ public class ExpandRecurringBillingEventsAction implements Runnable { } int numBillingEventsSaved = 0; try { - numBillingEventsSaved = ofy().transactNew(() -> { + numBillingEventsSaved = tm().transactNew(() -> { ImmutableSet.Builder syntheticOneTimesBuilder = new ImmutableSet.Builder<>(); final Registry tld = Registry.get(getTldFromDomainName(recurring.getTargetId())); @@ -183,7 +184,7 @@ public class ExpandRecurringBillingEventsAction implements Runnable { HistoryEntry historyEntry = new HistoryEntry.Builder() .setBySuperuser(false) .setClientId(recurring.getClientId()) - .setModificationTime(ofy().getTransactionTime()) + .setModificationTime(tm().getTransactionTime()) .setParent(domainKey) .setPeriod(Period.create(1, YEARS)) .setReason("Domain autorenewal by ExpandRecurringBillingEventsAction") @@ -308,7 +309,7 @@ public class ExpandRecurringBillingEventsAction implements Runnable { logger.atInfo().log( "Recurring event expansion %s complete for billing event range [%s, %s).", isDryRun ? "(dry run) " : "", cursorTime, executionTime); - ofy() + tm() .transact( () -> { Cursor cursor = ofy().load().key(Cursor.createGlobalKey(RECURRING_BILLING)).now(); diff --git a/core/src/main/java/google/registry/batch/ResaveAllEppResourcesAction.java b/core/src/main/java/google/registry/batch/ResaveAllEppResourcesAction.java index efa3f3d3f..3b8689817 100644 --- a/core/src/main/java/google/registry/batch/ResaveAllEppResourcesAction.java +++ b/core/src/main/java/google/registry/batch/ResaveAllEppResourcesAction.java @@ -15,6 +15,7 @@ package google.registry.batch; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.appengine.tools.mapreduce.Mapper; import com.google.common.collect.ImmutableList; @@ -69,7 +70,7 @@ public class ResaveAllEppResourcesAction implements Runnable { @Override public final void map(final Key resourceKey) { - ofy() + tm() .transact( () -> { EppResource projectedResource = @@ -77,7 +78,7 @@ public class ResaveAllEppResourcesAction implements Runnable { .load() .key(resourceKey) .now() - .cloneProjectedAtTime(ofy().getTransactionTime()); + .cloneProjectedAtTime(tm().getTransactionTime()); ofy().save().entity(projectedResource).now(); }); getContext().incrementCounter(String.format("%s entities re-saved", resourceKey.getKind())); diff --git a/core/src/main/java/google/registry/batch/ResaveEntityAction.java b/core/src/main/java/google/registry/batch/ResaveEntityAction.java index 799ef5b25..e31a91f45 100644 --- a/core/src/main/java/google/registry/batch/ResaveEntityAction.java +++ b/core/src/main/java/google/registry/batch/ResaveEntityAction.java @@ -18,6 +18,7 @@ import static google.registry.batch.AsyncTaskEnqueuer.PARAM_REQUESTED_TIME; import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESAVE_TIMES; import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; @@ -73,11 +74,11 @@ public class ResaveEntityAction implements Runnable { public void run() { logger.atInfo().log( "Re-saving entity %s which was enqueued at %s.", resourceKey, requestedTime); - ofy().transact(() -> { + tm().transact(() -> { ImmutableObject entity = ofy().load().key(resourceKey).now(); ofy().save().entity( (entity instanceof EppResource) - ? ((EppResource) entity).cloneProjectedAtTime(ofy().getTransactionTime()) : entity + ? ((EppResource) entity).cloneProjectedAtTime(tm().getTransactionTime()) : entity ); if (!resaveTimes.isEmpty()) { asyncTaskEnqueuer.enqueueAsyncResave(entity, requestedTime, resaveTimes); diff --git a/core/src/main/java/google/registry/export/SyncGroupMembersAction.java b/core/src/main/java/google/registry/export/SyncGroupMembersAction.java index ffa1a064c..5c81470e5 100644 --- a/core/src/main/java/google/registry/export/SyncGroupMembersAction.java +++ b/core/src/main/java/google/registry/export/SyncGroupMembersAction.java @@ -17,6 +17,7 @@ package google.registry.export; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableSet.toImmutableSet; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.request.Action.Method.POST; import static google.registry.util.CollectionUtils.nullToEmpty; import static google.registry.util.RegistrarUtils.normalizeClientId; @@ -163,7 +164,7 @@ public final class SyncGroupMembersAction implements Runnable { registrarsToSave.add(result.getKey().asBuilder().setContactsRequireSyncing(false).build()); } } - ofy().transactNew(() -> ofy().save().entities(registrarsToSave.build())); + tm().transactNew(() -> ofy().save().entities(registrarsToSave.build())); return errors; } diff --git a/core/src/main/java/google/registry/export/sheet/SyncRegistrarsSheet.java b/core/src/main/java/google/registry/export/sheet/SyncRegistrarsSheet.java index 92d1ae1fd..f81fa37a0 100644 --- a/core/src/main/java/google/registry/export/sheet/SyncRegistrarsSheet.java +++ b/core/src/main/java/google/registry/export/sheet/SyncRegistrarsSheet.java @@ -25,6 +25,7 @@ import static google.registry.model.registrar.RegistrarContact.Type.LEGAL; import static google.registry.model.registrar.RegistrarContact.Type.MARKETING; import static google.registry.model.registrar.RegistrarContact.Type.TECH; import static google.registry.model.registrar.RegistrarContact.Type.WHOIS; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.START_OF_TIME; import com.google.common.base.Joiner; @@ -152,7 +153,7 @@ class SyncRegistrarsSheet { return builder.build(); }) .collect(toImmutableList())); - ofy() + tm() .transact( () -> ofy().save().entity(Cursor.createGlobal(SYNC_REGISTRAR_SHEET, executionTime))); } diff --git a/core/src/main/java/google/registry/flows/FlowRunner.java b/core/src/main/java/google/registry/flows/FlowRunner.java index 8df7f0083..4e130e387 100644 --- a/core/src/main/java/google/registry/flows/FlowRunner.java +++ b/core/src/main/java/google/registry/flows/FlowRunner.java @@ -14,7 +14,7 @@ package google.registry.flows; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.xml.XmlTransformer.prettyPrint; import com.google.common.base.Strings; @@ -80,7 +80,7 @@ public class FlowRunner { return eppOutput; } try { - return ofy() + return tm() .transact( () -> { try { diff --git a/core/src/main/java/google/registry/flows/ResourceFlowUtils.java b/core/src/main/java/google/registry/flows/ResourceFlowUtils.java index 9118f41da..d9549ddb2 100644 --- a/core/src/main/java/google/registry/flows/ResourceFlowUtils.java +++ b/core/src/main/java/google/registry/flows/ResourceFlowUtils.java @@ -19,6 +19,7 @@ import static google.registry.model.EppResourceUtils.loadByForeignKey; import static google.registry.model.EppResourceUtils.queryForLinkedDomains; import static google.registry.model.index.ForeignKeyIndex.loadAndGetKey; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; @@ -77,7 +78,7 @@ public final class ResourceFlowUtils { final Function> getPotentialReferences) throws EppException { // Enter a transactionless context briefly. EppException failfastException = - ofy() + tm() .doTransactionless( () -> { final ForeignKeyIndex fki = diff --git a/core/src/main/java/google/registry/flows/contact/ContactCreateFlow.java b/core/src/main/java/google/registry/flows/contact/ContactCreateFlow.java index 08b4754de..be4471b7d 100644 --- a/core/src/main/java/google/registry/flows/contact/ContactCreateFlow.java +++ b/core/src/main/java/google/registry/flows/contact/ContactCreateFlow.java @@ -20,6 +20,7 @@ import static google.registry.flows.contact.ContactFlowUtils.validateAsciiPostal import static google.registry.flows.contact.ContactFlowUtils.validateContactAgainstPolicy; import static google.registry.model.EppResourceUtils.createRepoId; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.googlecode.objectify.Key; import google.registry.config.RegistryConfig.Config; @@ -71,7 +72,7 @@ public final class ContactCreateFlow implements TransactionalFlow { extensionManager.validate(); validateClientIsLoggedIn(clientId); Create command = (Create) resourceCommand; - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); verifyResourceDoesNotExist(ContactResource.class, targetId, now, clientId); ContactResource newContact = new ContactResource.Builder() diff --git a/core/src/main/java/google/registry/flows/contact/ContactDeleteFlow.java b/core/src/main/java/google/registry/flows/contact/ContactDeleteFlow.java index 10fb6897a..41742d205 100644 --- a/core/src/main/java/google/registry/flows/contact/ContactDeleteFlow.java +++ b/core/src/main/java/google/registry/flows/contact/ContactDeleteFlow.java @@ -22,6 +22,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo; import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership; import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; @@ -84,7 +85,7 @@ public final class ContactDeleteFlow implements TransactionalFlow { extensionManager.register(MetadataExtension.class); extensionManager.validate(); validateClientIsLoggedIn(clientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); failfastForAsyncDelete(targetId, now, ContactResource.class, DomainBase::getReferencedContacts); ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now); verifyNoDisallowedStatuses(existingContact, DISALLOWED_STATUSES); @@ -93,7 +94,7 @@ public final class ContactDeleteFlow implements TransactionalFlow { verifyResourceOwnership(clientId, existingContact); } asyncTaskEnqueuer.enqueueAsyncDelete( - existingContact, ofy().getTransactionTime(), clientId, trid, isSuperuser); + existingContact, tm().getTransactionTime(), clientId, trid, isSuperuser); ContactResource newContact = existingContact.asBuilder().addStatusValue(StatusValue.PENDING_DELETE).build(); historyBuilder diff --git a/core/src/main/java/google/registry/flows/contact/ContactTransferApproveFlow.java b/core/src/main/java/google/registry/flows/contact/ContactTransferApproveFlow.java index 4c0f8136c..87b9b4880 100644 --- a/core/src/main/java/google/registry/flows/contact/ContactTransferApproveFlow.java +++ b/core/src/main/java/google/registry/flows/contact/ContactTransferApproveFlow.java @@ -23,6 +23,7 @@ import static google.registry.flows.contact.ContactFlowUtils.createGainingTransf import static google.registry.flows.contact.ContactFlowUtils.createTransferResponse; import static google.registry.model.ResourceTransferUtils.approvePendingTransfer; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.googlecode.objectify.Key; import google.registry.flows.EppException; @@ -78,7 +79,7 @@ public final class ContactTransferApproveFlow implements TransactionalFlow { extensionManager.register(MetadataExtension.class); extensionManager.validate(); validateClientIsLoggedIn(clientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now); verifyOptionalAuthInfo(authInfo, existingContact); verifyHasPendingTransfer(existingContact); diff --git a/core/src/main/java/google/registry/flows/contact/ContactTransferCancelFlow.java b/core/src/main/java/google/registry/flows/contact/ContactTransferCancelFlow.java index ceb3c4a17..aae58f227 100644 --- a/core/src/main/java/google/registry/flows/contact/ContactTransferCancelFlow.java +++ b/core/src/main/java/google/registry/flows/contact/ContactTransferCancelFlow.java @@ -23,6 +23,7 @@ import static google.registry.flows.contact.ContactFlowUtils.createLosingTransfe import static google.registry.flows.contact.ContactFlowUtils.createTransferResponse; import static google.registry.model.ResourceTransferUtils.denyPendingTransfer; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.googlecode.objectify.Key; import google.registry.flows.EppException; @@ -74,7 +75,7 @@ public final class ContactTransferCancelFlow implements TransactionalFlow { extensionManager.register(MetadataExtension.class); extensionManager.validate(); validateClientIsLoggedIn(clientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now); verifyOptionalAuthInfo(authInfo, existingContact); verifyHasPendingTransfer(existingContact); diff --git a/core/src/main/java/google/registry/flows/contact/ContactTransferRejectFlow.java b/core/src/main/java/google/registry/flows/contact/ContactTransferRejectFlow.java index a0e503dda..e744d3fd3 100644 --- a/core/src/main/java/google/registry/flows/contact/ContactTransferRejectFlow.java +++ b/core/src/main/java/google/registry/flows/contact/ContactTransferRejectFlow.java @@ -23,6 +23,7 @@ import static google.registry.flows.contact.ContactFlowUtils.createGainingTransf import static google.registry.flows.contact.ContactFlowUtils.createTransferResponse; import static google.registry.model.ResourceTransferUtils.denyPendingTransfer; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.googlecode.objectify.Key; import google.registry.flows.EppException; @@ -72,7 +73,7 @@ public final class ContactTransferRejectFlow implements TransactionalFlow { extensionManager.register(MetadataExtension.class); extensionManager.validate(); validateClientIsLoggedIn(clientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now); verifyOptionalAuthInfo(authInfo, existingContact); verifyHasPendingTransfer(existingContact); diff --git a/core/src/main/java/google/registry/flows/contact/ContactTransferRequestFlow.java b/core/src/main/java/google/registry/flows/contact/ContactTransferRequestFlow.java index 2adadcb93..12d911fd7 100644 --- a/core/src/main/java/google/registry/flows/contact/ContactTransferRequestFlow.java +++ b/core/src/main/java/google/registry/flows/contact/ContactTransferRequestFlow.java @@ -24,6 +24,7 @@ import static google.registry.flows.contact.ContactFlowUtils.createLosingTransfe import static google.registry.flows.contact.ContactFlowUtils.createTransferResponse; import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; @@ -91,7 +92,7 @@ public final class ContactTransferRequestFlow implements TransactionalFlow { extensionManager.register(MetadataExtension.class); extensionManager.validate(); validateClientIsLoggedIn(gainingClientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now); verifyAuthInfoPresentForResourceTransfer(authInfo); verifyAuthInfo(authInfo.get(), existingContact); diff --git a/core/src/main/java/google/registry/flows/contact/ContactUpdateFlow.java b/core/src/main/java/google/registry/flows/contact/ContactUpdateFlow.java index 34cb11733..e53c63fd7 100644 --- a/core/src/main/java/google/registry/flows/contact/ContactUpdateFlow.java +++ b/core/src/main/java/google/registry/flows/contact/ContactUpdateFlow.java @@ -25,6 +25,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership; import static google.registry.flows.contact.ContactFlowUtils.validateAsciiPostalInfo; import static google.registry.flows.contact.ContactFlowUtils.validateContactAgainstPolicy; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; @@ -92,7 +93,7 @@ public final class ContactUpdateFlow implements TransactionalFlow { extensionManager.validate(); validateClientIsLoggedIn(clientId); Update command = (Update) resourceCommand; - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now); verifyOptionalAuthInfo(authInfo, existingContact); ImmutableSet statusToRemove = command.getInnerRemove().getStatusValues(); diff --git a/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java b/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java index f415a27a9..680480660 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java @@ -42,11 +42,11 @@ import static google.registry.flows.domain.DomainFlowUtils.verifyRegistrarIsActi import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears; import static google.registry.model.EppResourceUtils.createDomainRepoId; import static google.registry.model.eppcommon.StatusValue.SERVER_HOLD; -import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.registry.Registry.TldState.GENERAL_AVAILABILITY; import static google.registry.model.registry.Registry.TldState.QUIET_PERIOD; import static google.registry.model.registry.Registry.TldState.START_DATE_SUNRISE; import static google.registry.model.registry.label.ReservationType.NAME_COLLISION; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.END_OF_TIME; import static google.registry.util.DateTimeUtils.leapSafeAddYears; @@ -221,7 +221,7 @@ public class DomainCreateFlow implements TransactionalFlow { extensionManager.validate(); validateClientIsLoggedIn(clientId); verifyRegistrarIsActive(clientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); DomainCommand.Create command = cloneAndLinkReferences((Create) resourceCommand, now); Period period = command.getPeriod(); verifyUnitIsYears(period); diff --git a/core/src/main/java/google/registry/flows/domain/DomainDeleteFlow.java b/core/src/main/java/google/registry/flows/domain/DomainDeleteFlow.java index ee0989e8d..4ab308588 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainDeleteFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainDeleteFlow.java @@ -34,6 +34,7 @@ import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PE import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.ADD_FIELDS; import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.RENEW_FIELDS; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost; import static google.registry.util.CollectionUtils.nullToEmpty; import static google.registry.util.CollectionUtils.union; @@ -140,7 +141,7 @@ public final class DomainDeleteFlow implements TransactionalFlow { flowCustomLogic.beforeValidation(); extensionManager.validate(); validateClientIsLoggedIn(clientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); // Loads the target resource if it exists DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now); Registry registry = Registry.get(existingDomain.getTld()); diff --git a/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java b/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java index ffb580d93..b755c51c4 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java @@ -28,7 +28,7 @@ import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge; import static google.registry.flows.domain.DomainFlowUtils.validateRegistrationPeriod; import static google.registry.flows.domain.DomainFlowUtils.verifyRegistrarIsActive; import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.leapSafeAddYears; import com.google.common.collect.ImmutableList; @@ -137,7 +137,7 @@ public final class DomainRenewFlow implements TransactionalFlow { extensionManager.validate(); validateClientIsLoggedIn(clientId); verifyRegistrarIsActive(clientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); Renew command = (Renew) resourceCommand; // Loads the target resource if it exists DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now); diff --git a/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java b/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java index d2e4e951d..32577ebd6 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java @@ -27,6 +27,7 @@ import static google.registry.flows.domain.DomainFlowUtils.verifyPremiumNameIsNo import static google.registry.flows.domain.DomainFlowUtils.verifyRegistrarIsActive; import static google.registry.model.ResourceTransferUtils.updateForeignKeyIndexDeletionTime; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.END_OF_TIME; import com.google.common.collect.ImmutableList; @@ -133,7 +134,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow { validateClientIsLoggedIn(clientId); verifyRegistrarIsActive(clientId); Update command = (Update) resourceCommand; - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now); FeesAndCredits feesAndCredits = pricingLogic.getRestorePrice(Registry.get(existingDomain.getTld()), targetId, now); diff --git a/core/src/main/java/google/registry/flows/domain/DomainTransferApproveFlow.java b/core/src/main/java/google/registry/flows/domain/DomainTransferApproveFlow.java index d8881ae52..ae14b7f61 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainTransferApproveFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainTransferApproveFlow.java @@ -29,6 +29,7 @@ import static google.registry.model.ResourceTransferUtils.approvePendingTransfer import static google.registry.model.domain.DomainBase.extendRegistrationWithCap; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_SUCCESSFUL; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost; import static google.registry.util.CollectionUtils.union; import static google.registry.util.DateTimeUtils.END_OF_TIME; @@ -102,7 +103,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow { extensionManager.register(MetadataExtension.class); extensionManager.validate(); validateClientIsLoggedIn(clientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now); verifyOptionalAuthInfo(authInfo, existingDomain); verifyHasPendingTransfer(existingDomain); diff --git a/core/src/main/java/google/registry/flows/domain/DomainTransferCancelFlow.java b/core/src/main/java/google/registry/flows/domain/DomainTransferCancelFlow.java index 7251180cb..57ddc1f87 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainTransferCancelFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainTransferCancelFlow.java @@ -27,6 +27,7 @@ import static google.registry.flows.domain.DomainTransferUtils.createTransferRes import static google.registry.model.ResourceTransferUtils.denyPendingTransfer; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_SUCCESSFUL; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.END_OF_TIME; import com.google.common.collect.ImmutableSet; @@ -87,7 +88,7 @@ public final class DomainTransferCancelFlow implements TransactionalFlow { extensionManager.register(MetadataExtension.class); extensionManager.validate(); validateClientIsLoggedIn(clientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now); verifyOptionalAuthInfo(authInfo, existingDomain); verifyHasPendingTransfer(existingDomain); diff --git a/core/src/main/java/google/registry/flows/domain/DomainTransferRejectFlow.java b/core/src/main/java/google/registry/flows/domain/DomainTransferRejectFlow.java index 4b01ab1b9..5a47ae27d 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainTransferRejectFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainTransferRejectFlow.java @@ -28,6 +28,7 @@ import static google.registry.model.ResourceTransferUtils.denyPendingTransfer; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_NACKED; import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_SUCCESSFUL; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.CollectionUtils.union; import static google.registry.util.DateTimeUtils.END_OF_TIME; @@ -89,7 +90,7 @@ public final class DomainTransferRejectFlow implements TransactionalFlow { extensionManager.register(MetadataExtension.class); extensionManager.validate(); validateClientIsLoggedIn(clientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now); Registry registry = Registry.get(existingDomain.getTld()); HistoryEntry historyEntry = buildHistoryEntry(existingDomain, registry, now); diff --git a/core/src/main/java/google/registry/flows/domain/DomainTransferRequestFlow.java b/core/src/main/java/google/registry/flows/domain/DomainTransferRequestFlow.java index 3c728bd2e..83613dc35 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainTransferRequestFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainTransferRequestFlow.java @@ -32,6 +32,7 @@ import static google.registry.flows.domain.DomainTransferUtils.createTransferSer import static google.registry.model.domain.DomainBase.extendRegistrationWithCap; import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -143,7 +144,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow { extensionManager.validate(); validateClientIsLoggedIn(gainingClientId); verifyRegistrarIsActive(gainingClientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now); Optional superuserExtension = eppInput.getSingleExtension(DomainTransferRequestSuperuserExtension.class); diff --git a/core/src/main/java/google/registry/flows/domain/DomainUpdateFlow.java b/core/src/main/java/google/registry/flows/domain/DomainUpdateFlow.java index d969e11e2..0e877e314 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainUpdateFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainUpdateFlow.java @@ -38,7 +38,7 @@ import static google.registry.flows.domain.DomainFlowUtils.validateRegistrantAll import static google.registry.flows.domain.DomainFlowUtils.validateRequiredContactsPresent; import static google.registry.flows.domain.DomainFlowUtils.verifyClientUpdateNotProhibited; import static google.registry.flows.domain.DomainFlowUtils.verifyNotInPendingDelete; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.common.collect.ImmutableSet; import com.google.common.net.InternetDomainName; @@ -154,7 +154,7 @@ public final class DomainUpdateFlow implements TransactionalFlow { flowCustomLogic.beforeValidation(); extensionManager.validate(); validateClientIsLoggedIn(clientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); Update command = cloneAndLinkReferences((Update) resourceCommand, now); DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now); verifyUpdateAllowed(command, existingDomain, now); diff --git a/core/src/main/java/google/registry/flows/host/HostCreateFlow.java b/core/src/main/java/google/registry/flows/host/HostCreateFlow.java index ec6078c09..4ef0306e3 100644 --- a/core/src/main/java/google/registry/flows/host/HostCreateFlow.java +++ b/core/src/main/java/google/registry/flows/host/HostCreateFlow.java @@ -22,6 +22,7 @@ import static google.registry.flows.host.HostFlowUtils.verifySuperordinateDomain import static google.registry.flows.host.HostFlowUtils.verifySuperordinateDomainOwnership; import static google.registry.model.EppResourceUtils.createRepoId; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.CollectionUtils.isNullOrEmpty; import static google.registry.util.CollectionUtils.union; @@ -103,7 +104,7 @@ public final class HostCreateFlow implements TransactionalFlow { extensionManager.validate(); validateClientIsLoggedIn(clientId); Create command = (Create) resourceCommand; - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); verifyResourceDoesNotExist(HostResource.class, targetId, now, clientId); // The superordinate domain of the host object if creating an in-bailiwick host, or null if // creating an external host. This is looked up before we actually create the Host object so diff --git a/core/src/main/java/google/registry/flows/host/HostDeleteFlow.java b/core/src/main/java/google/registry/flows/host/HostDeleteFlow.java index fc395d734..2b6c0bf2e 100644 --- a/core/src/main/java/google/registry/flows/host/HostDeleteFlow.java +++ b/core/src/main/java/google/registry/flows/host/HostDeleteFlow.java @@ -22,6 +22,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership; import static google.registry.flows.host.HostFlowUtils.validateHostName; import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; @@ -85,7 +86,7 @@ public final class HostDeleteFlow implements TransactionalFlow { extensionManager.register(MetadataExtension.class); extensionManager.validate(); validateClientIsLoggedIn(clientId); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); validateHostName(targetId); failfastForAsyncDelete(targetId, now, HostResource.class, DomainBase::getNameservers); HostResource existingHost = loadAndVerifyExistence(HostResource.class, targetId, now); @@ -101,7 +102,7 @@ public final class HostDeleteFlow implements TransactionalFlow { verifyResourceOwnership(clientId, owningResource); } asyncTaskEnqueuer.enqueueAsyncDelete( - existingHost, ofy().getTransactionTime(), clientId, trid, isSuperuser); + existingHost, tm().getTransactionTime(), clientId, trid, isSuperuser); HostResource newHost = existingHost.asBuilder().addStatusValue(StatusValue.PENDING_DELETE).build(); historyBuilder diff --git a/core/src/main/java/google/registry/flows/host/HostUpdateFlow.java b/core/src/main/java/google/registry/flows/host/HostUpdateFlow.java index 72a4493ec..fdbb96cf8 100644 --- a/core/src/main/java/google/registry/flows/host/HostUpdateFlow.java +++ b/core/src/main/java/google/registry/flows/host/HostUpdateFlow.java @@ -28,6 +28,7 @@ import static google.registry.flows.host.HostFlowUtils.verifySuperordinateDomain import static google.registry.flows.host.HostFlowUtils.verifySuperordinateDomainOwnership; import static google.registry.model.index.ForeignKeyIndex.loadAndGetKey; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.CollectionUtils.isNullOrEmpty; import com.google.common.collect.ImmutableSet; @@ -129,7 +130,7 @@ public final class HostUpdateFlow implements TransactionalFlow { Update command = (Update) resourceCommand; Change change = command.getInnerChange(); String suppliedNewHostName = change.getFullyQualifiedHostName(); - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); validateHostName(targetId); HostResource existingHost = loadAndVerifyExistence(HostResource.class, targetId, now); boolean isHostRename = suppliedNewHostName != null; @@ -271,7 +272,7 @@ public final class HostUpdateFlow implements TransactionalFlow { } // We must also enqueue updates for all domains that use this host as their nameserver so // that their NS records can be updated to point at the new name. - asyncTaskEnqueuer.enqueueAsyncDnsRefresh(existingHost, ofy().getTransactionTime()); + asyncTaskEnqueuer.enqueueAsyncDnsRefresh(existingHost, tm().getTransactionTime()); } } diff --git a/core/src/main/java/google/registry/flows/poll/PollAckFlow.java b/core/src/main/java/google/registry/flows/poll/PollAckFlow.java index 008629bd8..b98bdf77d 100644 --- a/core/src/main/java/google/registry/flows/poll/PollAckFlow.java +++ b/core/src/main/java/google/registry/flows/poll/PollAckFlow.java @@ -21,6 +21,7 @@ import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_NO_MESSAG import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.poll.PollMessageExternalKeyConverter.makePollMessageExternalId; import static google.registry.model.poll.PollMessageExternalKeyConverter.parsePollMessageExternalId; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.isBeforeOrAt; import com.googlecode.objectify.Key; @@ -78,7 +79,7 @@ public class PollAckFlow implements TransactionalFlow { throw new InvalidMessageIdException(messageId); } - final DateTime now = ofy().getTransactionTime(); + final DateTime now = tm().getTransactionTime(); // Load the message to be acked. If a message is queued to be delivered in the future, we treat // it as if it doesn't exist yet. Same for if the message ID year isn't the same as the actual @@ -124,7 +125,7 @@ public class PollAckFlow implements TransactionalFlow { // acked, then we return a special status code indicating that. Note that the query will // include the message being acked. - int messageCount = ofy().doTransactionless(() -> getPollMessagesQuery(clientId, now).count()); + int messageCount = tm().doTransactionless(() -> getPollMessagesQuery(clientId, now).count()); if (!includeAckedMessageInCount) { messageCount--; } diff --git a/core/src/main/java/google/registry/keyring/kms/KmsUpdater.java b/core/src/main/java/google/registry/keyring/kms/KmsUpdater.java index 970a4eab5..2b522b2e7 100644 --- a/core/src/main/java/google/registry/keyring/kms/KmsUpdater.java +++ b/core/src/main/java/google/registry/keyring/kms/KmsUpdater.java @@ -33,6 +33,7 @@ import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.RDE_SSH_CLIE import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.RDE_SSH_CLIENT_PUBLIC_STRING; import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.SAFE_BROWSING_API_KEY; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; import com.google.common.collect.ImmutableMap; @@ -182,7 +183,7 @@ public final class KmsUpdater { */ private static void persistEncryptedValues( final ImmutableMap encryptedValues) { - ofy() + tm() .transact( () -> { for (Map.Entry entry : encryptedValues.entrySet()) { diff --git a/core/src/main/java/google/registry/model/EppResource.java b/core/src/main/java/google/registry/model/EppResource.java index b14d08806..22dbca018 100644 --- a/core/src/main/java/google/registry/model/EppResource.java +++ b/core/src/main/java/google/registry/model/EppResource.java @@ -22,6 +22,7 @@ import static com.google.common.collect.Sets.union; import static google.registry.config.RegistryConfig.getEppResourceCachingDuration; import static google.registry.config.RegistryConfig.getEppResourceMaxCachedEntries; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.CollectionUtils.nullToEmpty; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.DateTimeUtils.END_OF_TIME; @@ -325,13 +326,13 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable { @Override public EppResource load(Key key) { - return ofy().doTransactionless(() -> ofy().load().key(key).now()); + return tm().doTransactionless(() -> ofy().load().key(key).now()); } @Override public Map, EppResource> loadAll( Iterable> keys) { - return ofy().doTransactionless(() -> loadMultiple(keys)); + return tm().doTransactionless(() -> loadMultiple(keys)); } }; diff --git a/core/src/main/java/google/registry/model/OteAccountBuilder.java b/core/src/main/java/google/registry/model/OteAccountBuilder.java index 5c10742df..f40c3d822 100644 --- a/core/src/main/java/google/registry/model/OteAccountBuilder.java +++ b/core/src/main/java/google/registry/model/OteAccountBuilder.java @@ -21,6 +21,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.registry.Registry.TldState.GENERAL_AVAILABILITY; import static google.registry.model.registry.Registry.TldState.START_DATE_SUNRISE; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.START_OF_TIME; import com.google.common.collect.ImmutableList; @@ -236,7 +237,7 @@ public final class OteAccountBuilder { */ public ImmutableMap buildAndPersist() { // save all the entitiesl in a single transaction - ofy().transact(this::saveAllEntities); + tm().transact(this::saveAllEntities); return clientIdToTld; } @@ -249,7 +250,7 @@ public final class OteAccountBuilder { /** Saves all the OT&E entities we created. */ private void saveAllEntities() { - ofy().assertInTransaction(); + tm().assertInTransaction(); ImmutableList registries = ImmutableList.of(sunriseTld, gaTld, eapTld); ImmutableList contacts = contactsBuilder.build(); diff --git a/core/src/main/java/google/registry/model/common/GaeUserIdConverter.java b/core/src/main/java/google/registry/model/common/GaeUserIdConverter.java index 57d08e156..02fd44556 100644 --- a/core/src/main/java/google/registry/model/common/GaeUserIdConverter.java +++ b/core/src/main/java/google/registry/model/common/GaeUserIdConverter.java @@ -17,6 +17,7 @@ package google.registry.model.common; import static com.google.common.base.Preconditions.checkState; import static google.registry.model.ofy.ObjectifyService.allocateId; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.appengine.api.users.User; import com.google.common.base.Splitter; @@ -55,13 +56,13 @@ public class GaeUserIdConverter extends ImmutableObject { try { // Perform these operations in a transactionless context to avoid enlisting in some outer // transaction (if any). - ofy().doTransactionless(() -> ofy().saveWithoutBackup().entity(gaeUserIdConverter).now()); + tm().doTransactionless(() -> ofy().saveWithoutBackup().entity(gaeUserIdConverter).now()); // The read must be done in its own transaction to avoid reading from the session cache. - return ofy() + return tm() .transactNew(() -> ofy().load().entity(gaeUserIdConverter).safe().user.getUserId()); } finally { - ofy().doTransactionless(() -> ofy().deleteWithoutBackup().entity(gaeUserIdConverter).now()); + tm().doTransactionless(() -> ofy().deleteWithoutBackup().entity(gaeUserIdConverter).now()); } } } diff --git a/core/src/main/java/google/registry/model/index/ForeignKeyIndex.java b/core/src/main/java/google/registry/model/index/ForeignKeyIndex.java index b98bc77c9..d0a6dc6fc 100644 --- a/core/src/main/java/google/registry/model/index/ForeignKeyIndex.java +++ b/core/src/main/java/google/registry/model/index/ForeignKeyIndex.java @@ -19,6 +19,7 @@ import static com.google.common.collect.Maps.filterValues; import static google.registry.config.RegistryConfig.getEppResourceCachingDuration; import static google.registry.config.RegistryConfig.getEppResourceMaxCachedEntries; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.TypeUtils.instantiate; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -188,7 +189,7 @@ public abstract class ForeignKeyIndex extends BackupGroup @Override public Optional> load(Key> key) { - return Optional.ofNullable(ofy().doTransactionless(() -> ofy().load().key(key).now())); + return Optional.ofNullable(tm().doTransactionless(() -> ofy().load().key(key).now())); } @Override @@ -196,7 +197,7 @@ public abstract class ForeignKeyIndex extends BackupGroup Iterable>> keys) { ImmutableSet>> typedKeys = ImmutableSet.copyOf(keys); Map>, ForeignKeyIndex> existingFkis = - ofy().doTransactionless(() -> ofy().load().keys(typedKeys)); + tm().doTransactionless(() -> ofy().load().keys(typedKeys)); // ofy() omits keys that don't have values in Datastore, so re-add them in // here with Optional.empty() values. return Maps.asMap( @@ -250,7 +251,7 @@ public abstract class ForeignKeyIndex extends BackupGroup public static Map> loadCached( Class clazz, Iterable foreignKeys, final DateTime now) { if (!RegistryConfig.isEppResourceCachingEnabled()) { - return ofy().doTransactionless(() -> load(clazz, foreignKeys, now)); + return tm().doTransactionless(() -> load(clazz, foreignKeys, now)); } ImmutableList>> fkiKeys = Streams.stream(foreignKeys) diff --git a/core/src/main/java/google/registry/model/ofy/CommitLoggedWork.java b/core/src/main/java/google/registry/model/ofy/CommitLoggedWork.java index 8da543c85..f3e76e6a6 100644 --- a/core/src/main/java/google/registry/model/ofy/CommitLoggedWork.java +++ b/core/src/main/java/google/registry/model/ofy/CommitLoggedWork.java @@ -28,10 +28,9 @@ import static google.registry.util.DateTimeUtils.isBeforeOrAt; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; -import com.googlecode.objectify.VoidWork; -import com.googlecode.objectify.Work; import google.registry.model.BackupGroupRoot; import google.registry.model.ImmutableObject; +import google.registry.model.transaction.TransactionManager.Work; import google.registry.util.Clock; import java.util.HashSet; import java.util.Map; @@ -40,7 +39,7 @@ import java.util.Set; import org.joda.time.DateTime; /** Wrapper for {@link Work} that associates a time with each attempt. */ -class CommitLoggedWork extends VoidWork { +class CommitLoggedWork implements Runnable { private final Work work; private final Clock clock; @@ -74,8 +73,8 @@ class CommitLoggedWork extends VoidWork { */ protected ImmutableSet mutations = ImmutableSet.of(); - /** Lifecycle marker to track whether {@link #vrun} has been called. */ - private boolean vrunCalled; + /** Lifecycle marker to track whether {@link #run} has been called. */ + private boolean runCalled; CommitLoggedWork(Work work, Clock clock) { this.work = work; @@ -87,26 +86,26 @@ class CommitLoggedWork extends VoidWork { } boolean hasRun() { - return vrunCalled; + return runCalled; } R getResult() { - checkState(vrunCalled, "Cannot call getResult() before vrun()"); + checkState(runCalled, "Cannot call getResult() before run()"); return result; } CommitLogManifest getManifest() { - checkState(vrunCalled, "Cannot call getManifest() before vrun()"); + checkState(runCalled, "Cannot call getManifest() before run()"); return manifest; } ImmutableSet getMutations() { - checkState(vrunCalled, "Cannot call getMutations() before vrun()"); + checkState(runCalled, "Cannot call getMutations() before run()"); return mutations; } @Override - public void vrun() { + public void run() { // The previous time will generally be null, except when using transactNew. TransactionInfo previous = Ofy.TRANSACTION_INFO.get(); // Set the time to be used for "now" within the transaction. @@ -117,7 +116,7 @@ class CommitLoggedWork extends VoidWork { } finally { Ofy.TRANSACTION_INFO.set(previous); } - vrunCalled = true; + runCalled = true; } /** Records all mutations enrolled by this transaction to a {@link CommitLogManifest} entry. */ diff --git a/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java b/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java new file mode 100644 index 000000000..ded206aa1 --- /dev/null +++ b/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java @@ -0,0 +1,86 @@ +// Copyright 2019 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package google.registry.model.ofy; + + +import static google.registry.model.ofy.ObjectifyService.ofy; + +import google.registry.model.transaction.TransactionManager; +import org.joda.time.DateTime; + +/** Datastore implementation of {@link TransactionManager}. */ +public class DatastoreTransactionManager implements TransactionManager { + + private Ofy injectedOfy; + + /** Constructs an instance. */ + public DatastoreTransactionManager(Ofy injectedOfy) { + this.injectedOfy = injectedOfy; + } + + private Ofy getOfy() { + return injectedOfy == null ? ofy() : injectedOfy; + } + + @Override + public boolean inTransaction() { + return getOfy().inTransaction(); + } + + @Override + public void assertInTransaction() { + getOfy().assertInTransaction(); + } + + @Override + public T transact(Work work) { + return getOfy().transact(work); + } + + @Override + public void transact(Runnable work) { + getOfy().transact(work); + } + + @Override + public T transactNew(Work work) { + return getOfy().transactNew(work); + } + + @Override + public void transactNew(Runnable work) { + getOfy().transactNew(work); + } + + @Override + public R transactNewReadOnly(Work work) { + return getOfy().transactNewReadOnly(work); + } + + @Override + public void transactNewReadOnly(Runnable work) { + getOfy().transactNewReadOnly(work); + } + + @Override + public R doTransactionless(Work work) { + return getOfy().doTransactionless(work); + } + + @Override + public DateTime getTransactionTime() { + return getOfy().getTransactionTime(); + } +} diff --git a/core/src/main/java/google/registry/model/ofy/Ofy.java b/core/src/main/java/google/registry/model/ofy/Ofy.java index e94024d24..fbf834d8d 100644 --- a/core/src/main/java/google/registry/model/ofy/Ofy.java +++ b/core/src/main/java/google/registry/model/ofy/Ofy.java @@ -32,13 +32,13 @@ import com.google.common.flogger.FluentLogger; import com.googlecode.objectify.Key; import com.googlecode.objectify.Objectify; import com.googlecode.objectify.ObjectifyFactory; -import com.googlecode.objectify.Work; import com.googlecode.objectify.cmd.Deleter; import com.googlecode.objectify.cmd.Loader; import com.googlecode.objectify.cmd.Saver; import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.VirtualEntity; import google.registry.model.ofy.ReadOnlyWork.KillTransactionException; +import google.registry.model.transaction.TransactionManager.Work; import google.registry.util.Clock; import google.registry.util.NonFinalForTesting; import google.registry.util.Sleeper; @@ -111,11 +111,11 @@ public class Ofy { ofy().clear(); } - public boolean inTransaction() { + boolean inTransaction() { return ofy().getTransaction() != null; } - public void assertInTransaction() { + void assertInTransaction() { checkState(inTransaction(), "Must be called in a transaction"); } @@ -194,7 +194,7 @@ public class Ofy { } /** Execute a transaction. */ - public R transact(Work work) { + R transact(Work work) { // If we are already in a transaction, don't wrap in a CommitLoggedWork. return inTransaction() ? work.run() : transactNew(work); } @@ -205,7 +205,7 @@ public class Ofy { *

This overload is used for transactions that don't return a value, formerly implemented using * VoidWork. */ - public void transact(Runnable work) { + void transact(Runnable work) { transact( () -> { work.run(); @@ -214,7 +214,7 @@ public class Ofy { } /** Pause the current transaction (if any) and complete this one before returning to it. */ - public R transactNew(Work work) { + R transactNew(Work work) { // Wrap the Work in a CommitLoggedWork so that we can give transactions a frozen view of time // and maintain commit logs for them. return transactCommitLoggedWork(new CommitLoggedWork<>(work, getClock())); @@ -226,7 +226,7 @@ public class Ofy { *

This overload is used for transactions that don't return a value, formerly implemented using * VoidWork. */ - public void transactNew(Runnable work) { + void transactNew(Runnable work) { transactNew( () -> { work.run(); @@ -246,7 +246,10 @@ public class Ofy { true; attempt++, sleepMillis *= 2) { try { - ofy().transactNew(work); + ofy().transactNew(() -> { + work.run(); + return null; + }); return work.getResult(); } catch (TransientFailureException | TimestampInversionException @@ -295,10 +298,13 @@ public class Ofy { } /** A read-only transaction is useful to get strongly consistent reads at a shared timestamp. */ - public R transactNewReadOnly(Work work) { + R transactNewReadOnly(Work work) { ReadOnlyWork readOnlyWork = new ReadOnlyWork<>(work, getClock()); try { - ofy().transactNew(readOnlyWork); + ofy().transactNew(() -> { + readOnlyWork.run(); + return null; + }); } catch (TransientFailureException | DatastoreTimeoutException | DatastoreFailureException e) { // These are always retryable for a read-only operation. return transactNewReadOnly(work); @@ -309,7 +315,7 @@ public class Ofy { throw new AssertionError(); // How on earth did we get here? } - public void transactNewReadOnly(Runnable work) { + void transactNewReadOnly(Runnable work) { transactNewReadOnly( () -> { work.run(); @@ -318,7 +324,7 @@ public class Ofy { } /** Execute some work in a transactionless context. */ - public R doTransactionless(Work work) { + R doTransactionless(Work work) { try { com.googlecode.objectify.ObjectifyService.push( com.googlecode.objectify.ObjectifyService.ofy().transactionless()); @@ -347,7 +353,7 @@ public class Ofy { } /** Get the time associated with the start of this particular transaction attempt. */ - public DateTime getTransactionTime() { + DateTime getTransactionTime() { assertInTransaction(); return TRANSACTION_INFO.get().transactionTime; } diff --git a/core/src/main/java/google/registry/model/ofy/ReadOnlyWork.java b/core/src/main/java/google/registry/model/ofy/ReadOnlyWork.java index 70a7b419e..c93873ddf 100644 --- a/core/src/main/java/google/registry/model/ofy/ReadOnlyWork.java +++ b/core/src/main/java/google/registry/model/ofy/ReadOnlyWork.java @@ -14,7 +14,7 @@ package google.registry.model.ofy; -import com.googlecode.objectify.Work; +import google.registry.model.transaction.TransactionManager.Work; import google.registry.util.Clock; /** Wrapper for {@link Work} that disallows mutations and fails the transaction at the end. */ @@ -30,8 +30,8 @@ class ReadOnlyWork extends CommitLoggedWork { } @Override - public void vrun() { - super.vrun(); + public void run() { + super.run(); throw new KillTransactionException(); } diff --git a/core/src/main/java/google/registry/model/rde/RdeRevision.java b/core/src/main/java/google/registry/model/rde/RdeRevision.java index 3ae7bf494..4fc8dfa16 100644 --- a/core/src/main/java/google/registry/model/rde/RdeRevision.java +++ b/core/src/main/java/google/registry/model/rde/RdeRevision.java @@ -19,6 +19,7 @@ import static com.google.common.base.Verify.verify; import static com.google.common.base.Verify.verifyNotNull; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.rde.RdeNamingUtils.makePartialName; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.common.base.VerifyException; import com.googlecode.objectify.annotation.Entity; @@ -70,7 +71,7 @@ public final class RdeRevision extends ImmutableObject { public static void saveRevision(String tld, DateTime date, RdeMode mode, int revision) { checkArgument(revision >= 0, "Negative revision: %s", revision); String triplet = makePartialName(tld, date, mode); - ofy().assertInTransaction(); + tm().assertInTransaction(); RdeRevision object = ofy().load().type(RdeRevision.class).id(triplet).now(); if (revision == 0) { verify(object == null, "RdeRevision object already created: %s", object); diff --git a/core/src/main/java/google/registry/model/registrar/Registrar.java b/core/src/main/java/google/registry/model/registrar/Registrar.java index 16e450050..fa15c3101 100644 --- a/core/src/main/java/google/registry/model/registrar/Registrar.java +++ b/core/src/main/java/google/registry/model/registrar/Registrar.java @@ -31,6 +31,7 @@ import static google.registry.model.CacheUtils.memoizeWithShortExpiration; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.registry.Registries.assertTldsExist; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy; import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; @@ -206,7 +207,7 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable private static final Supplier> CACHE_BY_CLIENT_ID = memoizeWithShortExpiration( () -> - ofy() + tm() .doTransactionless( () -> Maps.uniqueIndex(loadAll(), Registrar::getClientId))); diff --git a/core/src/main/java/google/registry/model/registrar/RegistrarContact.java b/core/src/main/java/google/registry/model/registrar/RegistrarContact.java index b7ff0d85f..c660b724d 100644 --- a/core/src/main/java/google/registry/model/registrar/RegistrarContact.java +++ b/core/src/main/java/google/registry/model/registrar/RegistrarContact.java @@ -19,6 +19,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.common.collect.Sets.difference; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.registrar.Registrar.checkValidEmail; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy; import static java.util.stream.Collectors.joining; @@ -154,7 +155,7 @@ public class RegistrarContact extends ImmutableObject implements Jsonifiable { */ public static void updateContacts( final Registrar registrar, final Set contacts) { - ofy() + tm() .transact( () -> { ofy() diff --git a/core/src/main/java/google/registry/model/registry/Registries.java b/core/src/main/java/google/registry/model/registry/Registries.java index f1c3f8e4c..3805f4c77 100644 --- a/core/src/main/java/google/registry/model/registry/Registries.java +++ b/core/src/main/java/google/registry/model/registry/Registries.java @@ -24,6 +24,7 @@ import static com.google.common.collect.Maps.filterValues; import static google.registry.model.CacheUtils.memoizeWithShortExpiration; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; import com.google.common.base.Joiner; @@ -52,7 +53,7 @@ public final class Registries { private static Supplier> createFreshCache() { return memoizeWithShortExpiration( () -> - ofy() + tm() .doTransactionless( () -> { ImmutableMap.Builder builder = diff --git a/core/src/main/java/google/registry/model/registry/Registry.java b/core/src/main/java/google/registry/model/registry/Registry.java index 5fb481f86..e4501ac2f 100644 --- a/core/src/main/java/google/registry/model/registry/Registry.java +++ b/core/src/main/java/google/registry/model/registry/Registry.java @@ -21,6 +21,7 @@ import static com.google.common.base.Predicates.not; import static google.registry.config.RegistryConfig.getSingletonCacheRefreshDuration; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.DateTimeUtils.END_OF_TIME; import static google.registry.util.DateTimeUtils.START_OF_TIME; @@ -222,7 +223,7 @@ public class Registry extends ImmutableObject implements Buildable { // Enter a transactionless context briefly; we don't want to enroll every TLD in a // transaction that might be wrapping this call. return Optional.ofNullable( - ofy() + tm() .doTransactionless( () -> ofy() .load() diff --git a/core/src/main/java/google/registry/model/registry/label/PremiumList.java b/core/src/main/java/google/registry/model/registry/label/PremiumList.java index 2158db1d8..6e5ccb014 100644 --- a/core/src/main/java/google/registry/model/registry/label/PremiumList.java +++ b/core/src/main/java/google/registry/model/registry/label/PremiumList.java @@ -22,6 +22,7 @@ import static google.registry.config.RegistryConfig.getStaticPremiumListMaxCache import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.allocateId; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static java.util.concurrent.TimeUnit.MILLISECONDS; import com.google.common.annotations.VisibleForTesting; @@ -150,7 +151,7 @@ public final class PremiumList extends BaseDomainLabelList() { @Override public PremiumList load(final String name) { - return ofy().doTransactionless(() -> loadPremiumList(name)); + return tm().doTransactionless(() -> loadPremiumList(name)); } }); } @@ -174,7 +175,7 @@ public final class PremiumList extends BaseDomainLabelList, PremiumListRevision>() { @Override public PremiumListRevision load(final Key revisionKey) { - return ofy().doTransactionless(() -> ofy().load().key(revisionKey).now()); + return tm().doTransactionless(() -> ofy().load().key(revisionKey).now()); } }); @@ -214,7 +215,7 @@ public final class PremiumList extends BaseDomainLabelList, Optional>() { @Override public Optional load(final Key entryKey) { - return ofy() + return tm() .doTransactionless(() -> Optional.ofNullable(ofy().load().key(entryKey).now())); } }); diff --git a/core/src/main/java/google/registry/model/registry/label/PremiumListUtils.java b/core/src/main/java/google/registry/model/registry/label/PremiumListUtils.java index d8df27851..3faeda30e 100644 --- a/core/src/main/java/google/registry/model/registry/label/PremiumListUtils.java +++ b/core/src/main/java/google/registry/model/registry/label/PremiumListUtils.java @@ -27,6 +27,7 @@ import static google.registry.model.registry.label.DomainLabelMetrics.PremiumLis import static google.registry.model.registry.label.PremiumList.cachePremiumListEntries; import static google.registry.model.registry.label.PremiumList.cachePremiumListRevisions; import static google.registry.model.registry.label.PremiumList.cachePremiumLists; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static org.joda.time.DateTimeZone.UTC; import com.google.auto.value.AutoValue; @@ -151,12 +152,12 @@ public final class PremiumListUtils { // Save the new child entities in a series of transactions. for (final List batch : partition(parentedEntries, TRANSACTION_BATCH_SIZE)) { - ofy().transactNew(() -> ofy().save().entities(batch)); + tm().transactNew(() -> ofy().save().entities(batch)); } // Save the new PremiumList and revision itself. - PremiumList updated = ofy().transactNew(() -> { - DateTime now = ofy().getTransactionTime(); + PremiumList updated = tm().transactNew(() -> { + DateTime now = tm().getTransactionTime(); // Assert that the premium list hasn't been changed since we started this process. PremiumList existing = ofy().load() .type(PremiumList.class) @@ -201,7 +202,7 @@ public final class PremiumListUtils { /** Deletes the PremiumList and all of its child entities. */ public static void deletePremiumList(final PremiumList premiumList) { - ofy().transactNew(() -> ofy().delete().entity(premiumList)); + tm().transactNew(() -> ofy().delete().entity(premiumList)); deleteRevisionAndEntriesOfPremiumList(premiumList); cachePremiumLists.invalidate(premiumList.getName()); } @@ -214,9 +215,9 @@ public final class PremiumListUtils { partition( ofy().load().type(PremiumListEntry.class).ancestor(premiumList.revisionKey).keys(), TRANSACTION_BATCH_SIZE)) { - ofy().transactNew(() -> ofy().delete().keys(batch)); + tm().transactNew(() -> ofy().delete().keys(batch)); } - ofy().transactNew(() -> ofy().delete().key(premiumList.getRevisionKey())); + tm().transactNew(() -> ofy().delete().key(premiumList.getRevisionKey())); } /** diff --git a/core/src/main/java/google/registry/model/server/Lock.java b/core/src/main/java/google/registry/model/server/Lock.java index b897c76e0..bd008a905 100644 --- a/core/src/main/java/google/registry/model/server/Lock.java +++ b/core/src/main/java/google/registry/model/server/Lock.java @@ -16,6 +16,7 @@ package google.registry.model.server; import static com.google.common.base.Preconditions.checkArgument; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.isAtOrAfter; import com.google.auto.value.AutoValue; @@ -176,10 +177,10 @@ public class Lock extends ImmutableObject implements Serializable { // access to resources like GCS that can't be transactionally rolled back. Therefore, the lock // must be definitively acquired before it is used, even when called inside another transaction. AcquireResult acquireResult = - ofy() + tm() .transactNew( () -> { - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); // Checking if an unexpired lock still exists - if so, the lock can't be acquired. Lock lock = ofy().load().type(Lock.class).id(lockId).now(); @@ -217,7 +218,7 @@ public class Lock extends ImmutableObject implements Serializable { /** Release the lock. */ public void release() { // Just use the default clock because we aren't actually doing anything that will use the clock. - ofy() + tm() .transact( () -> { // To release a lock, check that no one else has already obtained it and if not @@ -231,7 +232,7 @@ public class Lock extends ImmutableObject implements Serializable { logger.atInfo().log("Deleting lock: %s", lockId); ofy().deleteWithoutBackup().entity(Lock.this); lockMetrics.recordRelease( - resourceName, tld, new Duration(acquiredTime, ofy().getTransactionTime())); + resourceName, tld, new Duration(acquiredTime, tm().getTransactionTime())); } else { logger.atSevere().log( "The lock we acquired was transferred to someone else before we" diff --git a/core/src/main/java/google/registry/model/server/ServerSecret.java b/core/src/main/java/google/registry/model/server/ServerSecret.java index b36fd5d0c..107d6cd34 100644 --- a/core/src/main/java/google/registry/model/server/ServerSecret.java +++ b/core/src/main/java/google/registry/model/server/ServerSecret.java @@ -15,6 +15,7 @@ package google.registry.model.server; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.common.annotations.VisibleForTesting; import com.google.common.cache.CacheBuilder; @@ -54,7 +55,7 @@ public class ServerSecret extends CrossTldSingleton { return secret; } // Slow path - transactionally create a new ServerSecret (once per app setup). - return ofy().transact(() -> { + return tm().transact(() -> { // Check again for an existing secret within the transaction to avoid races. ServerSecret secret1 = ofy().load().entity(new ServerSecret()).now(); if (secret1 == null) { diff --git a/core/src/main/java/google/registry/model/smd/SignedMarkRevocationList.java b/core/src/main/java/google/registry/model/smd/SignedMarkRevocationList.java index e5222d229..73d5a2f82 100644 --- a/core/src/main/java/google/registry/model/smd/SignedMarkRevocationList.java +++ b/core/src/main/java/google/registry/model/smd/SignedMarkRevocationList.java @@ -22,6 +22,7 @@ import static google.registry.model.CacheUtils.memoizeWithShortExpiration; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.allocateId; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.START_OF_TIME; import static google.registry.util.DateTimeUtils.isBeforeOrAt; @@ -92,7 +93,7 @@ public class SignedMarkRevocationList extends ImmutableObject { private static final Supplier CACHE = memoizeWithShortExpiration( () -> - ofy() + tm() .transactNewReadOnly( () -> { Iterable shards = @@ -150,7 +151,7 @@ public class SignedMarkRevocationList extends ImmutableObject { /** Save this list to Datastore in sharded form. Returns {@code this}. */ public SignedMarkRevocationList save() { - ofy() + tm() .transact( () -> { ofy() diff --git a/core/src/main/java/google/registry/model/tmch/ClaimsListShard.java b/core/src/main/java/google/registry/model/tmch/ClaimsListShard.java index 7527296b5..b3dd8cbd0 100644 --- a/core/src/main/java/google/registry/model/tmch/ClaimsListShard.java +++ b/core/src/main/java/google/registry/model/tmch/ClaimsListShard.java @@ -21,6 +21,7 @@ import static com.google.common.base.Verify.verify; import static google.registry.model.CacheUtils.memoizeWithShortExpiration; import static google.registry.model.ofy.ObjectifyService.allocateId; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.START_OF_TIME; import com.google.common.annotations.VisibleForTesting; @@ -111,7 +112,7 @@ public class ClaimsListShard extends ImmutableObject { Concurrent.transform( shardKeys, key -> - ofy() + tm() .transactNewReadOnly( () -> { ClaimsListShard claimsListShard = ofy().load().key(key).now(); @@ -188,7 +189,7 @@ public class ClaimsListShard extends ImmutableObject { Concurrent.transform( CollectionUtils.partitionMap(labelsToKeys, shardSize), (final ImmutableMap labelsToKeysShard) -> - ofy() + tm() .transactNew( () -> { ClaimsListShard shard = create(creationTime, labelsToKeysShard); @@ -199,7 +200,7 @@ public class ClaimsListShard extends ImmutableObject { })); // Persist the new revision, thus causing the newly created shards to go live. - ofy() + tm() .transactNew( () -> { verify( diff --git a/core/src/main/java/google/registry/model/tmch/TmchCrl.java b/core/src/main/java/google/registry/model/tmch/TmchCrl.java index 939474750..2a61c915b 100644 --- a/core/src/main/java/google/registry/model/tmch/TmchCrl.java +++ b/core/src/main/java/google/registry/model/tmch/TmchCrl.java @@ -16,6 +16,7 @@ package google.registry.model.tmch; import static com.google.common.base.Preconditions.checkNotNull; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.googlecode.objectify.annotation.Entity; import google.registry.model.annotations.NotBackedUp; @@ -48,11 +49,11 @@ public final class TmchCrl extends CrossTldSingleton { * and actually newer than the one currently in Datastore. */ public static void set(final String crl, final String url) { - ofy() + tm() .transactNew( () -> { TmchCrl tmchCrl = new TmchCrl(); - tmchCrl.updated = ofy().getTransactionTime(); + tmchCrl.updated = tm().getTransactionTime(); tmchCrl.crl = checkNotNull(crl, "crl"); tmchCrl.url = checkNotNull(url, "url"); ofy().saveWithoutBackup().entity(tmchCrl); diff --git a/core/src/main/java/google/registry/model/transaction/TransactionManager.java b/core/src/main/java/google/registry/model/transaction/TransactionManager.java new file mode 100644 index 000000000..ba1ec7e6a --- /dev/null +++ b/core/src/main/java/google/registry/model/transaction/TransactionManager.java @@ -0,0 +1,84 @@ +// Copyright 2019 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package google.registry.model.transaction; + +import org.joda.time.DateTime; + +/** + * This interface defines the methods to execute database operations with or without a transaction. + */ +public interface TransactionManager { + + /** This functional interface defines a method to execute a work and return the result. */ + @FunctionalInterface + interface Work { + R run(); + } + + /** Returns {@code true} if the caller is in a transaction. + * + *

Note that this function is kept for backward compatibility. We will review the use case + * later when adding the cloud sql implementation. + */ + boolean inTransaction(); + + /** Throws {@link IllegalStateException} if the caller is not in a transaction. + * + *

Note that this function is kept for backward compatibility. We will review the use case + * later when adding the cloud sql implementation. + */ + void assertInTransaction(); + + /** Executes the work in a transaction and returns the result. */ + T transact(Work work); + + /** Executes the work in a transaction. */ + void transact(Runnable work); + + /** Pauses the current transaction (if any), executes the work in a new transaction + * and returns the result. + * + *

Note that this function is kept for backward compatibility. We will review the use case + * later when adding the cloud sql implementation. + */ + T transactNew(Work work); + + /** Pauses the current transaction (if any) and executes the work in a new transaction. + * + *

Note that this function is kept for backward compatibility. We will review the use case + * later when adding the cloud sql implementation. + */ + void transactNew(Runnable work); + + /** Executes the work in a read-only transaction and returns the result. + * + *

Note that this function is kept for backward compatibility. We will review the use case + * later when adding the cloud sql implementation. + */ + R transactNewReadOnly(Work work); + + /** Executes the work in a read-only transaction. + * + *

Note that this function is kept for backward compatibility. We will review the use case + * later when adding the cloud sql implementation. + */ + void transactNewReadOnly(Runnable work); + + /** Executes the work in a transactionless context. */ + R doTransactionless(Work work); + + /** Returns the time associated with the start of this particular transaction attempt. */ + DateTime getTransactionTime(); +} diff --git a/core/src/main/java/google/registry/model/transaction/TransactionManagerFactory.java b/core/src/main/java/google/registry/model/transaction/TransactionManagerFactory.java new file mode 100644 index 000000000..1dc0231f9 --- /dev/null +++ b/core/src/main/java/google/registry/model/transaction/TransactionManagerFactory.java @@ -0,0 +1,37 @@ +// Copyright 2019 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package google.registry.model.transaction; + +import google.registry.model.ofy.DatastoreTransactionManager; + +/** Factory class to create {@link TransactionManager} instance. */ +public class TransactionManagerFactory { + + private static final TransactionManager TM = createTransactionManager(); + + private TransactionManagerFactory() {} + + private static TransactionManager createTransactionManager() { + // TODO: Conditionally returns the corresponding implementation once we have + // CloudSqlTransactionManager + return new DatastoreTransactionManager(null); + } + + /** Returns {@link TransactionManager} instance. */ + public static TransactionManager tm() { + + return TM; + } +} diff --git a/core/src/main/java/google/registry/model/translators/CommitLogRevisionsTranslatorFactory.java b/core/src/main/java/google/registry/model/translators/CommitLogRevisionsTranslatorFactory.java index 45f9a65f0..e3601e9af 100644 --- a/core/src/main/java/google/registry/model/translators/CommitLogRevisionsTranslatorFactory.java +++ b/core/src/main/java/google/registry/model/translators/CommitLogRevisionsTranslatorFactory.java @@ -17,6 +17,7 @@ package google.registry.model.translators; import static com.google.common.base.MoreObjects.firstNonNull; import static google.registry.config.RegistryConfig.getCommitLogDatastoreRetention; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.START_OF_TIME; import com.google.common.collect.ImmutableSortedMap; @@ -62,7 +63,7 @@ public final class CommitLogRevisionsTranslatorFactory @Override ImmutableSortedMap> transformBeforeSave( ImmutableSortedMap> revisions) { - DateTime now = ofy().getTransactionTime(); + DateTime now = tm().getTransactionTime(); DateTime threshold = now.minus(getCommitLogDatastoreRetention()); DateTime preThresholdTime = firstNonNull(revisions.floorKey(threshold), START_OF_TIME); return new ImmutableSortedMap.Builder>(Ordering.natural()) diff --git a/core/src/main/java/google/registry/model/translators/CreateAutoTimestampTranslatorFactory.java b/core/src/main/java/google/registry/model/translators/CreateAutoTimestampTranslatorFactory.java index e8b9825c2..61f69017b 100644 --- a/core/src/main/java/google/registry/model/translators/CreateAutoTimestampTranslatorFactory.java +++ b/core/src/main/java/google/registry/model/translators/CreateAutoTimestampTranslatorFactory.java @@ -15,7 +15,7 @@ package google.registry.model.translators; import static com.google.common.base.MoreObjects.firstNonNull; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static org.joda.time.DateTimeZone.UTC; import google.registry.model.CreateAutoTimestamp; @@ -46,7 +46,7 @@ public class CreateAutoTimestampTranslatorFactory /** Save a timestamp, setting it to the current time if it did not have a previous value. */ @Override public Date saveValue(CreateAutoTimestamp pojoValue) { - return firstNonNull(pojoValue.getTimestamp(), ofy().getTransactionTime()).toDate(); + return firstNonNull(pojoValue.getTimestamp(), tm().getTransactionTime()).toDate(); }}; } } diff --git a/core/src/main/java/google/registry/model/translators/UpdateAutoTimestampTranslatorFactory.java b/core/src/main/java/google/registry/model/translators/UpdateAutoTimestampTranslatorFactory.java index d70329a17..ea73848ea 100644 --- a/core/src/main/java/google/registry/model/translators/UpdateAutoTimestampTranslatorFactory.java +++ b/core/src/main/java/google/registry/model/translators/UpdateAutoTimestampTranslatorFactory.java @@ -14,7 +14,7 @@ package google.registry.model.translators; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static org.joda.time.DateTimeZone.UTC; import google.registry.model.UpdateAutoTimestamp; @@ -46,7 +46,7 @@ public class UpdateAutoTimestampTranslatorFactory /** Save a timestamp, setting it to the current time. */ @Override public Date saveValue(UpdateAutoTimestamp pojoValue) { - return ofy().getTransactionTime().toDate(); + return tm().getTransactionTime().toDate(); }}; } } diff --git a/core/src/main/java/google/registry/rdap/UpdateRegistrarRdapBaseUrlsAction.java b/core/src/main/java/google/registry/rdap/UpdateRegistrarRdapBaseUrlsAction.java index b62e25569..7f1290f8c 100644 --- a/core/src/main/java/google/registry/rdap/UpdateRegistrarRdapBaseUrlsAction.java +++ b/core/src/main/java/google/registry/rdap/UpdateRegistrarRdapBaseUrlsAction.java @@ -17,6 +17,7 @@ package google.registry.rdap; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.api.client.http.GenericUrl; @@ -197,7 +198,7 @@ public final class UpdateRegistrarRdapBaseUrlsAction implements Runnable { ImmutableSetMultimap ianaToBaseUrls = getRdapBaseUrlsPerIanaId(); for (Key registrarKey : ofy().load().type(Registrar.class).keys()) { - ofy() + tm() .transact( () -> { Registrar registrar = ofy().load().key(registrarKey).now(); diff --git a/core/src/main/java/google/registry/rde/EscrowTaskRunner.java b/core/src/main/java/google/registry/rde/EscrowTaskRunner.java index e68a404f9..3052894f6 100644 --- a/core/src/main/java/google/registry/rde/EscrowTaskRunner.java +++ b/core/src/main/java/google/registry/rde/EscrowTaskRunner.java @@ -15,6 +15,7 @@ package google.registry.rde; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.common.flogger.FluentLogger; import google.registry.model.common.Cursor; @@ -98,7 +99,7 @@ class EscrowTaskRunner { task.runWithLock(nextRequiredRun); DateTime nextRun = nextRequiredRun.plus(interval); logger.atInfo().log("Rolling cursor forward to %s.", nextRun); - ofy().transact(() -> ofy().save().entity(Cursor.create(cursorType, nextRun, registry))); + tm().transact(() -> ofy().save().entity(Cursor.create(cursorType, nextRun, registry))); return null; }; String lockName = String.format("EscrowTaskRunner %s", task.getClass().getSimpleName()); diff --git a/core/src/main/java/google/registry/rde/PendingDepositChecker.java b/core/src/main/java/google/registry/rde/PendingDepositChecker.java index 64c91a1e5..89b1415c1 100644 --- a/core/src/main/java/google/registry/rde/PendingDepositChecker.java +++ b/core/src/main/java/google/registry/rde/PendingDepositChecker.java @@ -16,6 +16,7 @@ package google.registry.rde; import static com.google.common.base.Preconditions.checkArgument; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.isBeforeOrAt; import com.google.common.collect.ImmutableSetMultimap; @@ -106,7 +107,7 @@ public final class PendingDepositChecker { final Registry registry, final CursorType cursorType, final DateTime initialValue) { - return ofy() + return tm() .transact( () -> { Cursor cursor = ofy().load().key(Cursor.createKey(cursorType, registry)).now(); diff --git a/core/src/main/java/google/registry/rde/RdeStagingReducer.java b/core/src/main/java/google/registry/rde/RdeStagingReducer.java index 0b51d9e3b..170903cb3 100644 --- a/core/src/main/java/google/registry/rde/RdeStagingReducer.java +++ b/core/src/main/java/google/registry/rde/RdeStagingReducer.java @@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Verify.verify; import static google.registry.model.common.Cursor.getCursorTimeOrStartOfTime; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.appengine.tools.cloudstorage.GcsFilename; @@ -202,7 +203,7 @@ public final class RdeStagingReducer extends Reducer { Registry registry = Registry.get(tld); diff --git a/core/src/main/java/google/registry/rde/RdeUploadAction.java b/core/src/main/java/google/registry/rde/RdeUploadAction.java index b2d446d5e..c1f5991a1 100644 --- a/core/src/main/java/google/registry/rde/RdeUploadAction.java +++ b/core/src/main/java/google/registry/rde/RdeUploadAction.java @@ -22,6 +22,7 @@ import static google.registry.model.common.Cursor.CursorType.RDE_UPLOAD_SFTP; import static google.registry.model.common.Cursor.getCursorTimeOrStartOfTime; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.rde.RdeMode.FULL; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.request.Action.Method.POST; import static google.registry.util.DateTimeUtils.isBeforeOrAt; import static java.util.Arrays.asList; @@ -169,11 +170,11 @@ public final class RdeUploadAction implements Runnable, EscrowTask { () -> upload(xmlFilename, xmlLength, watermark, name), JSchException.class); logger.atInfo().log( "Updating RDE cursor '%s' for TLD '%s' following successful upload.", RDE_UPLOAD_SFTP, tld); - ofy() + tm() .transact( () -> { Cursor updatedSftpCursor = - Cursor.create(RDE_UPLOAD_SFTP, ofy().getTransactionTime(), Registry.get(tld)); + Cursor.create(RDE_UPLOAD_SFTP, tm().getTransactionTime(), Registry.get(tld)); ofy().save().entity(updatedSftpCursor); }); response.setContentType(PLAIN_TEXT_UTF_8); diff --git a/core/src/main/java/google/registry/tmch/LordnTaskUtils.java b/core/src/main/java/google/registry/tmch/LordnTaskUtils.java index 855a73b3e..ab8fe8218 100644 --- a/core/src/main/java/google/registry/tmch/LordnTaskUtils.java +++ b/core/src/main/java/google/registry/tmch/LordnTaskUtils.java @@ -16,7 +16,7 @@ package google.registry.tmch; import static com.google.appengine.api.taskqueue.QueueFactory.getQueue; import static com.google.common.base.Preconditions.checkState; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.appengine.api.taskqueue.TaskOptions; import com.google.appengine.api.taskqueue.TaskOptions.Method; @@ -47,7 +47,7 @@ public final class LordnTaskUtils { * Enqueues a task in the LORDN queue representing a line of CSV for LORDN export. */ public static void enqueueDomainBaseTask(DomainBase domain) { - ofy().assertInTransaction(); + tm().assertInTransaction(); // This method needs to use ofy transactionTime as the DomainBase's creationTime because // CreationTime isn't yet populated when this method is called during the resource flow. String tld = domain.getTld(); @@ -55,12 +55,12 @@ public final class LordnTaskUtils { getQueue(QUEUE_SUNRISE).add(TaskOptions.Builder .withTag(tld) .method(Method.PULL) - .payload(getCsvLineForSunriseDomain(domain, ofy().getTransactionTime()))); + .payload(getCsvLineForSunriseDomain(domain, tm().getTransactionTime()))); } else { getQueue(QUEUE_CLAIMS).add(TaskOptions.Builder .withTag(tld) .method(Method.PULL) - .payload(getCsvLineForClaimsDomain(domain, ofy().getTransactionTime()))); + .payload(getCsvLineForClaimsDomain(domain, tm().getTransactionTime()))); } } diff --git a/core/src/main/java/google/registry/tools/AckPollMessagesCommand.java b/core/src/main/java/google/registry/tools/AckPollMessagesCommand.java index 1169f0263..b73a190b1 100644 --- a/core/src/main/java/google/registry/tools/AckPollMessagesCommand.java +++ b/core/src/main/java/google/registry/tools/AckPollMessagesCommand.java @@ -19,6 +19,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static google.registry.flows.poll.PollFlowUtils.getPollMessagesQuery; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.poll.PollMessageExternalKeyConverter.makePollMessageExternalId; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -85,7 +86,7 @@ final class AckPollMessagesCommand implements CommandWithRemoteApi { public void run() { QueryKeys query = getPollMessagesQuery(clientId, clock.nowUtc()).keys(); for (List> keys : Iterables.partition(query, BATCH_SIZE)) { - ofy() + tm() .transact( () -> { // Load poll messages and filter to just those of interest. diff --git a/core/src/main/java/google/registry/tools/DeleteAllocationTokensCommand.java b/core/src/main/java/google/registry/tools/DeleteAllocationTokensCommand.java index 6ee184d12..9a5d66ab5 100644 --- a/core/src/main/java/google/registry/tools/DeleteAllocationTokensCommand.java +++ b/core/src/main/java/google/registry/tools/DeleteAllocationTokensCommand.java @@ -19,6 +19,7 @@ import static com.google.common.collect.Iterables.partition; import static com.google.common.collect.Streams.stream; import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -64,7 +65,7 @@ final class DeleteAllocationTokensCommand extends UpdateOrDeleteAllocationTokens protected String execute() { long numDeleted = stream(partition(tokensToDelete, BATCH_SIZE)) - .mapToLong(batch -> ofy().transact(() -> deleteBatch(batch))) + .mapToLong(batch -> tm().transact(() -> deleteBatch(batch))) .sum(); return String.format("Deleted %d tokens in total.", numDeleted); } diff --git a/core/src/main/java/google/registry/tools/DeleteTldCommand.java b/core/src/main/java/google/registry/tools/DeleteTldCommand.java index 4859f2e4d..cbe246a11 100644 --- a/core/src/main/java/google/registry/tools/DeleteTldCommand.java +++ b/core/src/main/java/google/registry/tools/DeleteTldCommand.java @@ -16,6 +16,7 @@ package google.registry.tools; import static com.google.common.base.Preconditions.checkState; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -76,7 +77,7 @@ final class DeleteTldCommand extends ConfirmingCommand implements CommandWithRem @Override protected String execute() { - ofy().transactNew(() -> ofy().delete().entity(registry).now()); + tm().transactNew(() -> ofy().delete().entity(registry).now()); registry.invalidateInCache(); return String.format("Deleted TLD '%s'.\n", tld); } diff --git a/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java b/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java index eadaf99a9..08a869f25 100644 --- a/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java +++ b/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java @@ -21,6 +21,7 @@ import static com.google.common.collect.Sets.difference; import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE; import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.CollectionUtils.nullToEmpty; import static google.registry.util.StringGenerator.DEFAULT_PASSWORD_LENGTH; import static java.nio.charset.StandardCharsets.UTF_8; @@ -191,7 +192,7 @@ class GenerateAllocationTokensCommand implements CommandWithRemoteApi { @VisibleForTesting int saveTokens(final ImmutableSet tokens) { Collection savedTokens = - dryRun ? tokens : ofy().transact(() -> ofy().save().entities(tokens).now().values()); + dryRun ? tokens : tm().transact(() -> ofy().save().entities(tokens).now().values()); savedTokens.forEach( t -> System.out.println(SKIP_NULLS.join(t.getDomainName().orElse(null), t.getToken()))); return savedTokens.size(); diff --git a/core/src/main/java/google/registry/tools/MutatingCommand.java b/core/src/main/java/google/registry/tools/MutatingCommand.java index c0ac3d525..a7f88898e 100644 --- a/core/src/main/java/google/registry/tools/MutatingCommand.java +++ b/core/src/main/java/google/registry/tools/MutatingCommand.java @@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Strings.emptyToNull; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DatastoreServiceUtils.getNameOrId; import static google.registry.util.DiffUtils.prettyPrintEntityDeepDiff; import static java.util.stream.Collectors.joining; @@ -140,7 +141,7 @@ public abstract class MutatingCommand extends ConfirmingCommand implements Comma @Override protected String execute() throws Exception { for (final List batch : getCollatedEntityChangeBatches()) { - ofy().transact(() -> batch.forEach(this::executeChange)); + tm().transact(() -> batch.forEach(this::executeChange)); } return String.format("Updated %d entities.\n", changedEntitiesMap.size()); } diff --git a/core/src/main/java/google/registry/tools/ResaveEnvironmentEntitiesCommand.java b/core/src/main/java/google/registry/tools/ResaveEnvironmentEntitiesCommand.java index 790bf47c1..dd693c5b9 100644 --- a/core/src/main/java/google/registry/tools/ResaveEnvironmentEntitiesCommand.java +++ b/core/src/main/java/google/registry/tools/ResaveEnvironmentEntitiesCommand.java @@ -17,6 +17,7 @@ package google.registry.tools; import static com.google.common.collect.Lists.partition; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.beust.jcommander.Parameters; import com.googlecode.objectify.Key; @@ -46,7 +47,7 @@ final class ResaveEnvironmentEntitiesCommand implements CommandWithRemoteApi { System.out.printf("Re-saving %s entities.\n", clazz.getSimpleName()); for (final Iterable> batch : partition(ofy().load().type(clazz).ancestor(getCrossTldKey()).keys().list(), BATCH_SIZE)) { - ofy().transact(() -> ofy().save().entities(ofy().load().keys(batch).values())); + tm().transact(() -> ofy().save().entities(ofy().load().keys(batch).values())); System.out.printf("Re-saved entities batch: %s.\n", batch); } } diff --git a/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java b/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java index 385eee325..f49c267e6 100644 --- a/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java +++ b/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java @@ -21,6 +21,7 @@ import static google.registry.flows.domain.DomainFlowUtils.newAutorenewPollMessa import static google.registry.flows.domain.DomainFlowUtils.updateAutorenewRecurrenceEndTime; import static google.registry.model.EppResourceUtils.loadByForeignKey; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.util.DateTimeUtils.isBeforeOrAt; import static google.registry.util.DateTimeUtils.leapSafeSubtractYears; @@ -153,15 +154,15 @@ class UnrenewDomainCommand extends ConfirmingCommand implements CommandWithRemot @Override protected String execute() { for (String domainName : mainParameters) { - ofy().transact(() -> unrenewDomain(domainName)); + tm().transact(() -> unrenewDomain(domainName)); System.out.printf("Unrenewed %s\n", domainName); } return "Successfully unrenewed all domains."; } private void unrenewDomain(String domainName) { - ofy().assertInTransaction(); - DateTime now = ofy().getTransactionTime(); + tm().assertInTransaction(); + DateTime now = tm().getTransactionTime(); Optional domainOptional = loadByForeignKey(DomainBase.class, domainName, now); // Transactional sanity checks on the off chance that something changed between init() running diff --git a/core/src/main/java/google/registry/tools/UpdateAllocationTokensCommand.java b/core/src/main/java/google/registry/tools/UpdateAllocationTokensCommand.java index 171b9e760..b31fad518 100644 --- a/core/src/main/java/google/registry/tools/UpdateAllocationTokensCommand.java +++ b/core/src/main/java/google/registry/tools/UpdateAllocationTokensCommand.java @@ -19,6 +19,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.common.collect.Iterables.partition; import static com.google.common.collect.Streams.stream; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -109,7 +110,7 @@ final class UpdateAllocationTokensCommand extends UpdateOrDeleteAllocationTokens protected String execute() { long numUpdated = stream(partition(tokensToSave, BATCH_SIZE)) - .mapToLong(batch -> ofy().transact(() -> saveBatch(batch))) + .mapToLong(batch -> tm().transact(() -> saveBatch(batch))) .sum(); return String.format("Updated %d tokens in total.", numUpdated); } diff --git a/core/src/main/java/google/registry/tools/server/DeleteEntityAction.java b/core/src/main/java/google/registry/tools/server/DeleteEntityAction.java index 157d0282f..cf96d81b0 100644 --- a/core/src/main/java/google/registry/tools/server/DeleteEntityAction.java +++ b/core/src/main/java/google/registry/tools/server/DeleteEntityAction.java @@ -17,6 +17,7 @@ package google.registry.tools.server; import static com.google.appengine.api.datastore.DatastoreServiceFactory.getDatastoreService; import static com.googlecode.objectify.Key.create; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.datastore.EntityNotFoundException; @@ -94,7 +95,7 @@ public class DeleteEntityAction implements Runnable { getDatastoreService().delete(rawDeletions); // Delete ofy entities. final ImmutableList ofyDeletions = ofyDeletionsBuilder.build(); - ofy().transactNew(() -> ofy().delete().entities(ofyDeletions).now()); + tm().transactNew(() -> ofy().delete().entities(ofyDeletions).now()); String message = String.format( "Deleted %d raw entities and %d registered entities", rawDeletions.size(), diff --git a/core/src/main/java/google/registry/tools/server/KillAllEntitiesReducer.java b/core/src/main/java/google/registry/tools/server/KillAllEntitiesReducer.java index eb6a6ac9c..a99662b1a 100644 --- a/core/src/main/java/google/registry/tools/server/KillAllEntitiesReducer.java +++ b/core/src/main/java/google/registry/tools/server/KillAllEntitiesReducer.java @@ -16,6 +16,7 @@ package google.registry.tools.server; import static com.google.common.collect.Iterators.partition; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.appengine.tools.mapreduce.Reducer; import com.google.appengine.tools.mapreduce.ReducerInput; @@ -36,7 +37,7 @@ public class KillAllEntitiesReducer extends Reducer, Key, Void> { while (batches.hasNext()) { final List> batch = batches.next(); // Use a transaction to get retrying for free. - ofy().transact(() -> ofy().deleteWithoutBackup().keys(batch)); + tm().transact(() -> ofy().deleteWithoutBackup().keys(batch)); getContext().incrementCounter("entities deleted", batch.size()); for (Key key : batch) { getContext().incrementCounter(String.format("%s deleted", key.getKind())); diff --git a/core/src/main/java/google/registry/tools/server/ResaveAllHistoryEntriesAction.java b/core/src/main/java/google/registry/tools/server/ResaveAllHistoryEntriesAction.java index 6f48430f9..24cb7529d 100644 --- a/core/src/main/java/google/registry/tools/server/ResaveAllHistoryEntriesAction.java +++ b/core/src/main/java/google/registry/tools/server/ResaveAllHistoryEntriesAction.java @@ -15,6 +15,7 @@ package google.registry.tools.server; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import com.google.appengine.tools.mapreduce.Mapper; import com.google.common.collect.ImmutableList; @@ -68,7 +69,7 @@ public class ResaveAllHistoryEntriesAction implements Runnable { @Override public final void map(final HistoryEntry historyEntry) { - ofy().transact(() -> ofy().save().entity(ofy().load().entity(historyEntry).now()).now()); + tm().transact(() -> ofy().save().entity(ofy().load().entity(historyEntry).now()).now()); getContext().incrementCounter( String.format( "HistoryEntries parented under %s re-saved", historyEntry.getParent().getKind())); diff --git a/core/src/main/java/google/registry/ui/server/registrar/ConsoleRegistrarCreatorAction.java b/core/src/main/java/google/registry/ui/server/registrar/ConsoleRegistrarCreatorAction.java index c3071e7ae..83098c812 100644 --- a/core/src/main/java/google/registry/ui/server/registrar/ConsoleRegistrarCreatorAction.java +++ b/core/src/main/java/google/registry/ui/server/registrar/ConsoleRegistrarCreatorAction.java @@ -22,6 +22,7 @@ import static com.google.common.net.HttpHeaders.LOCATION; import static com.google.common.net.HttpHeaders.X_FRAME_OPTIONS; import static google.registry.model.common.GaeUserIdConverter.convertEmailAddressToGaeUserId; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; import static javax.servlet.http.HttpServletResponse.SC_MOVED_TEMPORARILY; @@ -294,7 +295,7 @@ public final class ConsoleRegistrarCreatorAction implements Runnable { .setEmailAddress(consoleUserEmail.get()) .setGaeUserId(gaeUserId) .build(); - ofy() + tm() .transact( () -> { checkState( diff --git a/core/src/main/java/google/registry/ui/server/registrar/RegistrarSettingsAction.java b/core/src/main/java/google/registry/ui/server/registrar/RegistrarSettingsAction.java index f63d0891d..4a4e68c6c 100644 --- a/core/src/main/java/google/registry/ui/server/registrar/RegistrarSettingsAction.java +++ b/core/src/main/java/google/registry/ui/server/registrar/RegistrarSettingsAction.java @@ -21,6 +21,7 @@ import static com.google.common.collect.Sets.difference; import static google.registry.config.RegistryEnvironment.PRODUCTION; import static google.registry.export.sheet.SyncRegistrarsSheetAction.enqueueRegistrarSheetSync; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.security.JsonResponseHelper.Status.ERROR; import static google.registry.security.JsonResponseHelper.Status.SUCCESS; import static google.registry.util.PreconditionsUtils.checkArgumentPresent; @@ -174,7 +175,7 @@ public class RegistrarSettingsAction implements Runnable, JsonActionRunner.JsonA } private RegistrarResult update(final Map args, String clientId) { - return ofy() + return tm() .transact( () -> { // We load the registrar here rather than outside of the transaction - to make @@ -302,12 +303,12 @@ public class RegistrarSettingsAction implements Runnable, JsonActionRunner.JsonA RegistrarFormFields.CLIENT_CERTIFICATE_FIELD .extractUntyped(args) .ifPresent( - certificate -> builder.setClientCertificate(certificate, ofy().getTransactionTime())); + certificate -> builder.setClientCertificate(certificate, tm().getTransactionTime())); RegistrarFormFields.FAILOVER_CLIENT_CERTIFICATE_FIELD .extractUntyped(args) .ifPresent( certificate -> - builder.setFailoverClientCertificate(certificate, ofy().getTransactionTime())); + builder.setFailoverClientCertificate(certificate, tm().getTransactionTime())); return checkNotChangedUnlessAllowed(builder, initialRegistrar, Role.OWNER); } diff --git a/core/src/test/java/google/registry/backup/CommitLogCheckpointStrategyTest.java b/core/src/test/java/google/registry/backup/CommitLogCheckpointStrategyTest.java index ce91a46a9..a31d31849 100644 --- a/core/src/test/java/google/registry/backup/CommitLogCheckpointStrategyTest.java +++ b/core/src/test/java/google/registry/backup/CommitLogCheckpointStrategyTest.java @@ -27,8 +27,10 @@ import com.google.common.collect.ImmutableMap; import google.registry.model.common.Cursor; import google.registry.model.ofy.CommitLogBucket; import google.registry.model.ofy.CommitLogCheckpoint; +import google.registry.model.ofy.DatastoreTransactionManager; import google.registry.model.ofy.Ofy; import google.registry.model.registry.Registry; +import google.registry.model.transaction.TransactionManager; import google.registry.testing.AppEngineRule; import google.registry.testing.FakeClock; import google.registry.testing.InjectRule; @@ -54,6 +56,7 @@ public class CommitLogCheckpointStrategyTest { final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01TZ")); final Ofy ofy = new Ofy(clock); + final TransactionManager tm = new DatastoreTransactionManager(ofy); final CommitLogCheckpointStrategy strategy = new CommitLogCheckpointStrategy(); /** @@ -289,17 +292,17 @@ public class CommitLogCheckpointStrategyTest { private void writeCommitLogToBucket(final int bucketId) { fakeBucketIdSupplier.value = bucketId; - ofy.transact( + tm.transact( () -> { Cursor cursor = - Cursor.create(RDE_REPORT, ofy.getTransactionTime(), Registry.get("tld" + bucketId)); + Cursor.create(RDE_REPORT, tm.getTransactionTime(), Registry.get("tld" + bucketId)); ofy().save().entity(cursor); }); fakeBucketIdSupplier.value = null; } private void saveBucketWithLastWrittenTime(final int bucketId, final DateTime lastWrittenTime) { - ofy.transact( + tm.transact( () -> ofy.saveWithoutBackup() .entity( diff --git a/core/src/test/java/google/registry/batch/ExpandRecurringBillingEventsActionTest.java b/core/src/test/java/google/registry/batch/ExpandRecurringBillingEventsActionTest.java index 7362fb5b9..ce77a7fa1 100644 --- a/core/src/test/java/google/registry/batch/ExpandRecurringBillingEventsActionTest.java +++ b/core/src/test/java/google/registry/batch/ExpandRecurringBillingEventsActionTest.java @@ -19,6 +19,7 @@ import static google.registry.model.common.Cursor.CursorType.RECURRING_BILLING; import static google.registry.model.domain.Period.Unit.YEARS; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_AUTORENEW; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatastoreHelper.assertBillingEvents; import static google.registry.testing.DatastoreHelper.assertBillingEventsForResource; import static google.registry.testing.DatastoreHelper.createTld; @@ -101,7 +102,7 @@ public class ExpandRecurringBillingEventsActionTest } void saveCursor(final DateTime cursorTime) { - ofy().transact(() -> ofy().save().entity(Cursor.createGlobal(RECURRING_BILLING, cursorTime))); + tm().transact(() -> ofy().save().entity(Cursor.createGlobal(RECURRING_BILLING, cursorTime))); } void runMapreduce() throws Exception { diff --git a/core/src/test/java/google/registry/flows/custom/TestDomainCreateFlowCustomLogic.java b/core/src/test/java/google/registry/flows/custom/TestDomainCreateFlowCustomLogic.java index ac00748c1..fb2451386 100644 --- a/core/src/test/java/google/registry/flows/custom/TestDomainCreateFlowCustomLogic.java +++ b/core/src/test/java/google/registry/flows/custom/TestDomainCreateFlowCustomLogic.java @@ -14,7 +14,7 @@ package google.registry.flows.custom; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import google.registry.flows.FlowMetadata; import google.registry.flows.SessionMetadata; @@ -35,7 +35,7 @@ public class TestDomainCreateFlowCustomLogic extends DomainCreateFlowCustomLogic PollMessage extraPollMessage = new PollMessage.OneTime.Builder() .setParent(parameters.historyEntry()) - .setEventTime(ofy().getTransactionTime()) + .setEventTime(tm().getTransactionTime()) .setClientId(getSessionMetadata().getClientId()) .setMsg("Custom logic was triggered") .build(); diff --git a/core/src/test/java/google/registry/model/CreateAutoTimestampTest.java b/core/src/test/java/google/registry/model/CreateAutoTimestampTest.java index 59e198dbd..b361c7185 100644 --- a/core/src/test/java/google/registry/model/CreateAutoTimestampTest.java +++ b/core/src/test/java/google/registry/model/CreateAutoTimestampTest.java @@ -16,6 +16,7 @@ package google.registry.model; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static org.joda.time.DateTimeZone.UTC; import com.googlecode.objectify.ObjectifyService; @@ -56,13 +57,13 @@ public class CreateAutoTimestampTest { @Test public void testSaveSetsTime() { DateTime transactionTime = - ofy() + tm() .transact( () -> { TestObject object = new TestObject(); assertThat(object.createTime.getTimestamp()).isNull(); ofy().save().entity(object); - return ofy().getTransactionTime(); + return tm().getTransactionTime(); }); ofy().clearSessionCache(); assertThat(reload().createTime.timestamp).isEqualTo(transactionTime); @@ -71,7 +72,7 @@ public class CreateAutoTimestampTest { @Test public void testResavingRespectsOriginalTime() { final DateTime oldCreateTime = DateTime.now(UTC).minusDays(1); - ofy() + tm() .transact( () -> { TestObject object = new TestObject(); diff --git a/core/src/test/java/google/registry/model/UpdateAutoTimestampTest.java b/core/src/test/java/google/registry/model/UpdateAutoTimestampTest.java index 00be0f9c2..3236d2039 100644 --- a/core/src/test/java/google/registry/model/UpdateAutoTimestampTest.java +++ b/core/src/test/java/google/registry/model/UpdateAutoTimestampTest.java @@ -16,6 +16,7 @@ package google.registry.model; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static org.joda.time.DateTimeZone.UTC; import com.googlecode.objectify.ObjectifyService; @@ -56,13 +57,13 @@ public class UpdateAutoTimestampTest { @Test public void testSaveSetsTime() { DateTime transactionTime = - ofy() + tm() .transact( () -> { TestObject object = new TestObject(); assertThat(object.updateTime.timestamp).isNull(); ofy().save().entity(object); - return ofy().getTransactionTime(); + return tm().getTransactionTime(); }); ofy().clearSessionCache(); assertThat(reload().updateTime.timestamp).isEqualTo(transactionTime); @@ -71,13 +72,13 @@ public class UpdateAutoTimestampTest { @Test public void testResavingOverwritesOriginalTime() { DateTime transactionTime = - ofy() + tm() .transact( () -> { TestObject object = new TestObject(); object.updateTime = UpdateAutoTimestamp.create(DateTime.now(UTC).minusDays(1)); ofy().save().entity(object); - return ofy().getTransactionTime(); + return tm().getTransactionTime(); }); ofy().clearSessionCache(); assertThat(reload().updateTime.timestamp).isEqualTo(transactionTime); diff --git a/core/src/test/java/google/registry/model/common/CursorTest.java b/core/src/test/java/google/registry/model/common/CursorTest.java index 2a87f8c7d..c20dcfc15 100644 --- a/core/src/test/java/google/registry/model/common/CursorTest.java +++ b/core/src/test/java/google/registry/model/common/CursorTest.java @@ -19,6 +19,7 @@ import static google.registry.model.common.Cursor.CursorType.BRDA; import static google.registry.model.common.Cursor.CursorType.RDE_UPLOAD; import static google.registry.model.common.Cursor.CursorType.RECURRING_BILLING; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatastoreHelper.createTld; import static google.registry.testing.DatastoreHelper.persistActiveDomain; import static google.registry.testing.JUnitBackports.assertThrows; @@ -38,7 +39,7 @@ public class CursorTest extends EntityTestCase { createTld("tld"); clock.advanceOneMilli(); final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z"); - ofy().transact(() -> ofy().save().entity(Cursor.create(RDE_UPLOAD, time, Registry.get("tld")))); + tm().transact(() -> ofy().save().entity(Cursor.create(RDE_UPLOAD, time, Registry.get("tld")))); assertThat(ofy().load().key(Cursor.createKey(BRDA, Registry.get("tld"))).now()).isNull(); assertThat( ofy() @@ -52,7 +53,7 @@ public class CursorTest extends EntityTestCase { @Test public void testSuccess_persistGlobalCursor() { final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z"); - ofy().transact(() -> ofy().save().entity(Cursor.createGlobal(RECURRING_BILLING, time))); + tm().transact(() -> ofy().save().entity(Cursor.createGlobal(RECURRING_BILLING, time))); assertThat(ofy().load().key(Cursor.createGlobalKey(RECURRING_BILLING)).now().getCursorTime()) .isEqualTo(time); } @@ -60,7 +61,7 @@ public class CursorTest extends EntityTestCase { @Test public void testIndexing() throws Exception { final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z"); - ofy().transact(() -> ofy().save().entity(Cursor.createGlobal(RECURRING_BILLING, time))); + tm().transact(() -> ofy().save().entity(Cursor.createGlobal(RECURRING_BILLING, time))); Cursor cursor = ofy().load().key(Cursor.createGlobalKey(RECURRING_BILLING)).now(); verifyIndexing(cursor); } @@ -75,7 +76,7 @@ public class CursorTest extends EntityTestCase { assertThrows( IllegalArgumentException.class, () -> - ofy().transact(() -> ofy().save().entity(Cursor.create(RDE_UPLOAD, time, domain)))); + tm().transact(() -> ofy().save().entity(Cursor.create(RDE_UPLOAD, time, domain)))); assertThat(thrown) .hasMessageThat() .contains("Class required for cursor does not match scope class"); diff --git a/core/src/test/java/google/registry/model/common/GaeUserIdConverterTest.java b/core/src/test/java/google/registry/model/common/GaeUserIdConverterTest.java index 8d5094702..802b9094a 100644 --- a/core/src/test/java/google/registry/model/common/GaeUserIdConverterTest.java +++ b/core/src/test/java/google/registry/model/common/GaeUserIdConverterTest.java @@ -16,6 +16,7 @@ package google.registry.model.common; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import google.registry.testing.AppEngineRule; import org.junit.After; @@ -46,7 +47,7 @@ public class GaeUserIdConverterTest { @Test public void testSuccess_inTransaction() { - ofy() + tm() .transactNew( () -> assertThat(GaeUserIdConverter.convertEmailAddressToGaeUserId("example@example.com")) diff --git a/core/src/test/java/google/registry/model/ofy/CommitLogMutationTest.java b/core/src/test/java/google/registry/model/ofy/CommitLogMutationTest.java index 1bf68f403..45ae24a8f 100644 --- a/core/src/test/java/google/registry/model/ofy/CommitLogMutationTest.java +++ b/core/src/test/java/google/registry/model/ofy/CommitLogMutationTest.java @@ -16,6 +16,7 @@ package google.registry.model.ofy; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatastoreHelper.createTld; import com.google.appengine.api.datastore.Entity; @@ -69,7 +70,7 @@ public class CommitLogMutationTest { Entity rawEntity = convertToEntityInTxn(someObject); // Needs to be in a transaction so that registry-saving-to-entity will work. CommitLogMutation mutation = - ofy().transact(() -> CommitLogMutation.create(manifestKey, someObject)); + tm().transact(() -> CommitLogMutation.create(manifestKey, someObject)); assertThat(Key.create(mutation)) .isEqualTo(CommitLogMutation.createKey(manifestKey, Key.create(someObject))); assertThat(mutation.getEntity()).isEqualTo(rawEntity); @@ -89,6 +90,6 @@ public class CommitLogMutationTest { } private static Entity convertToEntityInTxn(final ImmutableObject object) { - return ofy().transact(() -> ofy().save().toEntity(object)); + return tm().transact(() -> ofy().save().toEntity(object)); } } diff --git a/core/src/test/java/google/registry/model/ofy/OfyCommitLogTest.java b/core/src/test/java/google/registry/model/ofy/OfyCommitLogTest.java index b92653f2b..5d4792972 100644 --- a/core/src/test/java/google/registry/model/ofy/OfyCommitLogTest.java +++ b/core/src/test/java/google/registry/model/ofy/OfyCommitLogTest.java @@ -20,6 +20,7 @@ import static com.googlecode.objectify.ObjectifyService.register; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.CommitLogBucket.getBucketKey; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.JUnitBackports.assertThrows; import com.google.common.collect.ImmutableSet; @@ -64,13 +65,13 @@ public class OfyCommitLogTest { @Test public void testTransact_doesNothing_noCommitLogIsSaved() { - ofy().transact(() -> {}); + tm().transact(() -> {}); assertThat(ofy().load().type(CommitLogManifest.class)).isEmpty(); } @Test public void testTransact_savesDataAndCommitLog() { - ofy().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey())).now()); + tm().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey())).now()); assertThat(ofy().load().key(Key.create(getCrossTldKey(), Root.class, 1)).now().value) .isEqualTo("value"); assertThat(ofy().load().type(CommitLogManifest.class)).hasSize(1); @@ -79,7 +80,7 @@ public class OfyCommitLogTest { @Test public void testTransact_saveWithoutBackup_noCommitLogIsSaved() { - ofy().transact(() -> ofy().saveWithoutBackup().entity(Root.create(1, getCrossTldKey())).now()); + tm().transact(() -> ofy().saveWithoutBackup().entity(Root.create(1, getCrossTldKey())).now()); assertThat(ofy().load().key(Key.create(getCrossTldKey(), Root.class, 1)).now().value) .isEqualTo("value"); assertThat(ofy().load().type(CommitLogManifest.class)).isEmpty(); @@ -88,8 +89,8 @@ public class OfyCommitLogTest { @Test public void testTransact_deleteWithoutBackup_noCommitLogIsSaved() { - ofy().transact(() -> ofy().saveWithoutBackup().entity(Root.create(1, getCrossTldKey())).now()); - ofy().transact(() -> ofy().deleteWithoutBackup().key(Key.create(Root.class, 1))); + tm().transact(() -> ofy().saveWithoutBackup().entity(Root.create(1, getCrossTldKey())).now()); + tm().transact(() -> ofy().deleteWithoutBackup().key(Key.create(Root.class, 1))); assertThat(ofy().load().key(Key.create(Root.class, 1)).now()).isNull(); assertThat(ofy().load().type(CommitLogManifest.class)).isEmpty(); assertThat(ofy().load().type(CommitLogMutation.class)).isEmpty(); @@ -97,12 +98,12 @@ public class OfyCommitLogTest { @Test public void testTransact_savesEntity_itsProtobufFormIsStoredInCommitLog() { - ofy().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey())).now()); + tm().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey())).now()); final byte[] entityProtoBytes = ofy().load().type(CommitLogMutation.class).first().now().entityProtoBytes; // This transaction is needed so that save().toEntity() can access ofy().getTransactionTime() // when it attempts to set the update timestamp. - ofy() + tm() .transact( () -> assertThat(entityProtoBytes) @@ -113,7 +114,7 @@ public class OfyCommitLogTest { @Test public void testTransact_savesEntity_mutationIsChildOfManifest() { - ofy().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey())).now()); + tm().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey())).now()); assertThat( ofy() .load() @@ -124,7 +125,7 @@ public class OfyCommitLogTest { @Test public void testTransactNew_savesDataAndCommitLog() { - ofy().transactNew(() -> ofy().save().entity(Root.create(1, getCrossTldKey())).now()); + tm().transactNew(() -> ofy().save().entity(Root.create(1, getCrossTldKey())).now()); assertThat(ofy().load().key(Key.create(getCrossTldKey(), Root.class, 1)).now().value) .isEqualTo("value"); assertThat(ofy().load().type(CommitLogManifest.class)).hasSize(1); @@ -133,7 +134,7 @@ public class OfyCommitLogTest { @Test public void testTransact_multipleSaves_logsMultipleMutations() { - ofy() + tm() .transact( () -> { ofy().save().entity(Root.create(1, getCrossTldKey())).now(); @@ -145,10 +146,10 @@ public class OfyCommitLogTest { @Test public void testTransact_deletion_deletesAndLogsWithoutMutation() { - ofy().transact(() -> ofy().saveWithoutBackup().entity(Root.create(1, getCrossTldKey())).now()); + tm().transact(() -> ofy().saveWithoutBackup().entity(Root.create(1, getCrossTldKey())).now()); clock.advanceOneMilli(); final Key otherTldKey = Key.create(getCrossTldKey(), Root.class, 1); - ofy().transact(() -> ofy().delete().key(otherTldKey)); + tm().transact(() -> ofy().delete().key(otherTldKey)); assertThat(ofy().load().key(otherTldKey).now()).isNull(); assertThat(ofy().load().type(CommitLogManifest.class)).hasSize(1); assertThat(ofy().load().type(CommitLogMutation.class)).isEmpty(); @@ -163,7 +164,7 @@ public class OfyCommitLogTest { IllegalArgumentException thrown = assertThrows( IllegalArgumentException.class, - () -> ofy().transactNew(() -> ofy().delete().entity(backupsArentAllowedOnMe))); + () -> tm().transactNew(() -> ofy().delete().entity(backupsArentAllowedOnMe))); assertThat(thrown).hasMessageThat().contains("Can't save/delete a @NotBackedUp"); } @@ -174,7 +175,7 @@ public class OfyCommitLogTest { IllegalArgumentException thrown = assertThrows( IllegalArgumentException.class, - () -> ofy().transactNew(() -> ofy().save().entity(backupsArentAllowedOnMe))); + () -> tm().transactNew(() -> ofy().save().entity(backupsArentAllowedOnMe))); assertThat(thrown).hasMessageThat().contains("Can't save/delete a @NotBackedUp"); } @@ -184,7 +185,7 @@ public class OfyCommitLogTest { IllegalArgumentException thrown = assertThrows( IllegalArgumentException.class, - () -> ofy().transactNew(() -> ofy().delete().key(virtualEntityKey))); + () -> tm().transactNew(() -> ofy().delete().key(virtualEntityKey))); assertThat(thrown).hasMessageThat().contains("Can't save/delete a @VirtualEntity"); } @@ -194,7 +195,7 @@ public class OfyCommitLogTest { IllegalArgumentException thrown = assertThrows( IllegalArgumentException.class, - () -> ofy().transactNew(() -> ofy().save().entity(virtualEntity))); + () -> tm().transactNew(() -> ofy().save().entity(virtualEntity))); assertThat(thrown).hasMessageThat().contains("Can't save/delete a @VirtualEntity"); } @@ -223,7 +224,7 @@ public class OfyCommitLogTest { assertThrows( IllegalArgumentException.class, () -> - ofy() + tm() .transact( () -> { ofy().save().entity(Root.create(1, getCrossTldKey())); @@ -238,7 +239,7 @@ public class OfyCommitLogTest { assertThrows( IllegalArgumentException.class, () -> - ofy() + tm() .transact( () -> { ofy().save().entity(Root.create(1, getCrossTldKey())); @@ -249,12 +250,12 @@ public class OfyCommitLogTest { @Test public void testSavingRootAndChild_updatesTimestampOnBackupGroupRoot() { - ofy().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey()))); + tm().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey()))); ofy().clearSessionCache(); assertThat(ofy().load().key(Key.create(getCrossTldKey(), Root.class, 1)).now() .getUpdateAutoTimestamp().getTimestamp()).isEqualTo(clock.nowUtc()); clock.advanceOneMilli(); - ofy() + tm() .transact( () -> { ofy().save().entity(Root.create(1, getCrossTldKey())); @@ -267,12 +268,12 @@ public class OfyCommitLogTest { @Test public void testSavingOnlyChild_updatesTimestampOnBackupGroupRoot() { - ofy().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey()))); + tm().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey()))); ofy().clearSessionCache(); assertThat(ofy().load().key(Key.create(getCrossTldKey(), Root.class, 1)).now() .getUpdateAutoTimestamp().getTimestamp()).isEqualTo(clock.nowUtc()); clock.advanceOneMilli(); - ofy().transact(() -> ofy().save().entity(new Child())); + tm().transact(() -> ofy().save().entity(new Child())); ofy().clearSessionCache(); assertThat(ofy().load().key(Key.create(getCrossTldKey(), Root.class, 1)).now() .getUpdateAutoTimestamp().getTimestamp()).isEqualTo(clock.nowUtc()); @@ -280,13 +281,13 @@ public class OfyCommitLogTest { @Test public void testDeletingChild_updatesTimestampOnBackupGroupRoot() { - ofy().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey()))); + tm().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey()))); ofy().clearSessionCache(); assertThat(ofy().load().key(Key.create(getCrossTldKey(), Root.class, 1)).now() .getUpdateAutoTimestamp().getTimestamp()).isEqualTo(clock.nowUtc()); clock.advanceOneMilli(); // The fact that the child was never persisted is irrelevant. - ofy().transact(() -> ofy().delete().entity(new Child())); + tm().transact(() -> ofy().delete().entity(new Child())); ofy().clearSessionCache(); assertThat(ofy().load().key(Key.create(getCrossTldKey(), Root.class, 1)).now() .getUpdateAutoTimestamp().getTimestamp()).isEqualTo(clock.nowUtc()); @@ -294,12 +295,12 @@ public class OfyCommitLogTest { @Test public void testReadingRoot_doesntUpdateTimestamp() { - ofy().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey()))); + tm().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey()))); ofy().clearSessionCache(); assertThat(ofy().load().key(Key.create(getCrossTldKey(), Root.class, 1)).now() .getUpdateAutoTimestamp().getTimestamp()).isEqualTo(clock.nowUtc()); clock.advanceOneMilli(); - ofy() + tm() .transact( () -> { // Don't remove this line, as without saving *something* the commit log code will @@ -314,12 +315,12 @@ public class OfyCommitLogTest { @Test public void testReadingChild_doesntUpdateTimestampOnBackupGroupRoot() { - ofy().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey()))); + tm().transact(() -> ofy().save().entity(Root.create(1, getCrossTldKey()))); ofy().clearSessionCache(); assertThat(ofy().load().key(Key.create(getCrossTldKey(), Root.class, 1)).now() .getUpdateAutoTimestamp().getTimestamp()).isEqualTo(clock.nowUtc()); clock.advanceOneMilli(); - ofy() + tm() .transact( () -> { // Don't remove this line, as without saving *something* the commit log code will @@ -335,7 +336,7 @@ public class OfyCommitLogTest { @Test public void testSavingAcrossBackupGroupRoots_updatesCorrectTimestamps() { // Create three roots. - ofy() + tm() .transact( () -> { ofy().save().entity(Root.create(1, getCrossTldKey())); @@ -349,7 +350,7 @@ public class OfyCommitLogTest { } clock.advanceOneMilli(); // Mutate one root, and a child of a second, ignoring the third. - ofy() + tm() .transact( () -> { ofy().save().entity(new Child()); // All Child objects are under Root(1). diff --git a/core/src/test/java/google/registry/model/ofy/OfyTest.java b/core/src/test/java/google/registry/model/ofy/OfyTest.java index 7cb2d4b97..f84224ca5 100644 --- a/core/src/test/java/google/registry/model/ofy/OfyTest.java +++ b/core/src/test/java/google/registry/model/ofy/OfyTest.java @@ -20,6 +20,7 @@ import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterrup import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.ofy.Ofy.getBaseEntityClassFromEntityOrKey; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatastoreHelper.createTld; import static google.registry.testing.DatastoreHelper.newContactResource; import static google.registry.testing.DatastoreHelper.persistActiveContact; @@ -35,8 +36,6 @@ import com.google.appengine.api.datastore.DatastoreTimeoutException; import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.taskqueue.TransientFailureException; import com.googlecode.objectify.Key; -import com.googlecode.objectify.VoidWork; -import com.googlecode.objectify.Work; import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.OnLoad; import com.googlecode.objectify.annotation.OnSave; @@ -46,6 +45,7 @@ import google.registry.model.contact.ContactResource; import google.registry.model.domain.DomainBase; import google.registry.model.eppcommon.Trid; import google.registry.model.reporting.HistoryEntry; +import google.registry.model.transaction.TransactionManager.Work; import google.registry.testing.AppEngineRule; import google.registry.testing.DatastoreHelper; import google.registry.testing.FakeClock; @@ -114,7 +114,7 @@ public class OfyTest { assertThrows( IllegalArgumentException.class, () -> - ofy() + tm() .transact( () -> { ofy().save().entity(someObject); @@ -129,7 +129,7 @@ public class OfyTest { assertThrows( IllegalArgumentException.class, () -> - ofy() + tm() .transact( () -> { ofy().delete().entity(someObject); @@ -144,7 +144,7 @@ public class OfyTest { assertThrows( IllegalArgumentException.class, () -> - ofy() + tm() .transact( () -> { ofy().save().entity(someObject); @@ -159,7 +159,7 @@ public class OfyTest { assertThrows( IllegalArgumentException.class, () -> - ofy() + tm() .transact( () -> { ofy().delete().entity(someObject); @@ -172,7 +172,7 @@ public class OfyTest { public void testSavingKeyTwiceInOneCall() { assertThrows( IllegalArgumentException.class, - () -> ofy().transact(() -> ofy().save().entities(someObject, someObject))); + () -> tm().transact(() -> ofy().save().entities(someObject, someObject))); } /** Simple entity class with lifecycle callbacks. */ @@ -212,7 +212,7 @@ public class OfyTest { public void testLifecycleCallbacks_loadFromDatastore() { ofy().factory().register(LifecycleObject.class); final LifecycleObject object = new LifecycleObject(); - ofy().transact(() -> ofy().save().entity(object).now()); + tm().transact(() -> ofy().save().entity(object).now()); assertThat(object.onSaveCalled).isTrue(); ofy().clearSessionCache(); assertThat(ofy().load().entity(object).now().onLoadCalled).isTrue(); @@ -221,25 +221,25 @@ public class OfyTest { /** Avoid regressions of b/21309102 where transaction time did not change on each retry. */ @Test public void testTransact_getsNewTimestampOnEachTry() { - ofy().transact(new VoidWork() { + tm().transact(new Runnable() { DateTime firstAttemptTime; @Override - public void vrun() { + public void run() { if (firstAttemptTime == null) { // Sleep a bit to ensure that the next attempt is at a new millisecond. - firstAttemptTime = ofy().getTransactionTime(); + firstAttemptTime = tm().getTransactionTime(); sleepUninterruptibly(10, MILLISECONDS); throw new ConcurrentModificationException(); } - assertThat(ofy().getTransactionTime()).isGreaterThan(firstAttemptTime); + assertThat(tm().getTransactionTime()).isGreaterThan(firstAttemptTime); }}); } @Test public void testTransact_transientFailureException_retries() { - assertThat(ofy().transact(new Work() { + assertThat(tm().transact(new Work() { int count = 0; @@ -255,7 +255,7 @@ public class OfyTest { @Test public void testTransact_datastoreTimeoutException_noManifest_retries() { - assertThat(ofy().transact(new Work() { + assertThat(tm().transact(new Work() { int count = 0; @@ -273,7 +273,7 @@ public class OfyTest { @Test public void testTransact_datastoreTimeoutException_manifestNotWrittenToDatastore_retries() { - assertThat(ofy().transact(new Work() { + assertThat(tm().transact(new Work() { int count = 0; @@ -292,17 +292,18 @@ public class OfyTest { @Test public void testTransact_datastoreTimeoutException_manifestWrittenToDatastore_returnsSuccess() { // A work unit that throws if it is ever retried. - VoidWork work = new VoidWork() { + Work work = new Work() { boolean firstCallToVrun = true; @Override - public void vrun() { + public Void run() { if (firstCallToVrun) { firstCallToVrun = false; ofy().save().entity(someObject); - return; + return null; } fail("Shouldn't have retried."); + return null; }}; // A commit logged work that throws on the first attempt to get its result. CommitLoggedWork commitLoggedWork = new CommitLoggedWork(work, new SystemClock()) { @@ -322,7 +323,7 @@ public class OfyTest { } void doReadOnlyRetryTest(final RuntimeException e) { - assertThat(ofy().transactNewReadOnly(new Work() { + assertThat(tm().transactNewReadOnly(new Work() { int count = 0; diff --git a/core/src/test/java/google/registry/model/rde/RdeRevisionTest.java b/core/src/test/java/google/registry/model/rde/RdeRevisionTest.java index 924f02576..d0352aeab 100644 --- a/core/src/test/java/google/registry/model/rde/RdeRevisionTest.java +++ b/core/src/test/java/google/registry/model/rde/RdeRevisionTest.java @@ -19,6 +19,7 @@ import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.rde.RdeMode.FULL; import static google.registry.model.rde.RdeRevision.getNextRevision; import static google.registry.model.rde.RdeRevision.saveRevision; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.JUnitBackports.assertThrows; import com.google.common.base.VerifyException; @@ -50,8 +51,8 @@ public class RdeRevisionTest { @Test public void testSaveRevision_objectDoesntExist_newRevisionIsZero_nextRevIsOne() { - ofy().transact(() -> saveRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL, 0)); - ofy() + tm().transact(() -> saveRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL, 0)); + tm() .transact( () -> assertThat(getNextRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL)) @@ -64,7 +65,7 @@ public class RdeRevisionTest { assertThrows( VerifyException.class, () -> - ofy() + tm() .transact( () -> saveRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL, 1))); @@ -78,7 +79,7 @@ public class RdeRevisionTest { assertThrows( VerifyException.class, () -> - ofy() + tm() .transact( () -> saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 0))); assertThat(thrown).hasMessageThat().contains("object already created"); @@ -87,8 +88,8 @@ public class RdeRevisionTest { @Test public void testSaveRevision_objectExistsAtZero_newRevisionIsOne_nextRevIsTwo() { save("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 0); - ofy().transact(() -> saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 1)); - ofy() + tm().transact(() -> saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 1)); + tm() .transact( () -> assertThat(getNextRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL)) @@ -102,7 +103,7 @@ public class RdeRevisionTest { assertThrows( VerifyException.class, () -> - ofy() + tm() .transact( () -> saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 2))); assertThat(thrown).hasMessageThat().contains("should be at 1 "); @@ -114,7 +115,7 @@ public class RdeRevisionTest { assertThrows( IllegalArgumentException.class, () -> - ofy() + tm() .transact( () -> saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, -1))); diff --git a/core/src/test/java/google/registry/model/registrar/RegistrarTest.java b/core/src/test/java/google/registry/model/registrar/RegistrarTest.java index b44a1285c..bc21dcc6c 100644 --- a/core/src/test/java/google/registry/model/registrar/RegistrarTest.java +++ b/core/src/test/java/google/registry/model/registrar/RegistrarTest.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkState; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth8.assertThat; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.CertificateSamples.SAMPLE_CERT; import static google.registry.testing.CertificateSamples.SAMPLE_CERT2; import static google.registry.testing.CertificateSamples.SAMPLE_CERT2_HASH; @@ -567,7 +568,7 @@ public class RegistrarTest extends EntityTestCase { @Test public void testLoadByClientIdCached_isTransactionless() { - ofy() + tm() .transact( () -> { assertThat(Registrar.loadByClientIdCached("registrar")).isPresent(); diff --git a/core/src/test/java/google/registry/model/registry/label/PremiumListUtilsTest.java b/core/src/test/java/google/registry/model/registry/label/PremiumListUtilsTest.java index cc37d6a63..1505b7399 100644 --- a/core/src/test/java/google/registry/model/registry/label/PremiumListUtilsTest.java +++ b/core/src/test/java/google/registry/model/registry/label/PremiumListUtilsTest.java @@ -30,6 +30,7 @@ import static google.registry.model.registry.label.PremiumListUtils.deletePremiu import static google.registry.model.registry.label.PremiumListUtils.doesPremiumListExist; import static google.registry.model.registry.label.PremiumListUtils.getPremiumPrice; import static google.registry.model.registry.label.PremiumListUtils.savePremiumListAndEntries; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatastoreHelper.createTld; import static google.registry.testing.DatastoreHelper.loadPremiumListEntries; import static google.registry.testing.DatastoreHelper.persistPremiumList; @@ -197,7 +198,7 @@ public class PremiumListUtilsTest { @Test public void testGetPremiumPrice_bloomFilterFalsePositive() { // Remove one of the premium list entries from behind the Bloom filter's back. - ofy() + tm() .transactNew( () -> ofy() diff --git a/core/src/test/java/google/registry/model/smd/SignedMarkRevocationListTest.java b/core/src/test/java/google/registry/model/smd/SignedMarkRevocationListTest.java index 565221aca..17b01503e 100644 --- a/core/src/test/java/google/registry/model/smd/SignedMarkRevocationListTest.java +++ b/core/src/test/java/google/registry/model/smd/SignedMarkRevocationListTest.java @@ -17,6 +17,7 @@ package google.registry.model.smd; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.smd.SignedMarkRevocationList.SHARD_SIZE; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.JUnitBackports.assertThrows; import static google.registry.util.DateTimeUtils.START_OF_TIME; import static org.joda.time.Duration.standardDays; @@ -46,13 +47,13 @@ public class SignedMarkRevocationListTest { assertThrows( SignedMarkRevocationList.UnshardedSaveException.class, () -> - ofy() + tm() .transact( () -> { SignedMarkRevocationList smdrl = SignedMarkRevocationList.create( - ofy().getTransactionTime(), - ImmutableMap.of("a", ofy().getTransactionTime())); + tm().getTransactionTime(), + ImmutableMap.of("a", tm().getTransactionTime())); smdrl.id = 1; // Without an id this won't save anyways. ofy().saveWithoutBackup().entity(smdrl).now(); })); diff --git a/core/src/test/java/google/registry/model/tmch/ClaimsListShardTest.java b/core/src/test/java/google/registry/model/tmch/ClaimsListShardTest.java index 8ea80936b..4858db0f1 100644 --- a/core/src/test/java/google/registry/model/tmch/ClaimsListShardTest.java +++ b/core/src/test/java/google/registry/model/tmch/ClaimsListShardTest.java @@ -17,6 +17,7 @@ package google.registry.model.tmch; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth8.assertThat; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.JUnitBackports.assertThrows; import static google.registry.util.DateTimeUtils.START_OF_TIME; import static org.joda.time.DateTimeZone.UTC; @@ -51,12 +52,12 @@ public class ClaimsListShardTest { assertThrows( UnshardedSaveException.class, () -> - ofy() + tm() .transact( () -> { ClaimsListShard claimsList = ClaimsListShard.create( - ofy().getTransactionTime(), ImmutableMap.of("a", "b")); + tm().getTransactionTime(), ImmutableMap.of("a", "b")); claimsList.id = 1; // Without an id this won't save anyways. claimsList.parent = ClaimsListRevision.createKey(); ofy().saveWithoutBackup().entity(claimsList).now(); diff --git a/core/src/test/java/google/registry/model/translators/CommitLogRevisionsTranslatorFactoryTest.java b/core/src/test/java/google/registry/model/translators/CommitLogRevisionsTranslatorFactoryTest.java index b7e8bf120..7ff8b1ba2 100644 --- a/core/src/test/java/google/registry/model/translators/CommitLogRevisionsTranslatorFactoryTest.java +++ b/core/src/test/java/google/registry/model/translators/CommitLogRevisionsTranslatorFactoryTest.java @@ -16,6 +16,7 @@ package google.registry.model.translators; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static org.joda.time.Duration.standardDays; import static org.joda.time.Duration.standardHours; @@ -66,7 +67,7 @@ public class CommitLogRevisionsTranslatorFactoryTest { } private void save(final TestObject object) { - ofy().transact(() -> ofy().save().entity(object)); + tm().transact(() -> ofy().save().entity(object)); } private TestObject reload() { @@ -150,7 +151,7 @@ public class CommitLogRevisionsTranslatorFactoryTest { save(new TestObject()); clock.advanceBy(standardDays(1)); com.google.appengine.api.datastore.Entity entity = - ofy().transactNewReadOnly(() -> ofy().save().toEntity(reload())); + tm().transactNewReadOnly(() -> ofy().save().toEntity(reload())); assertThat(entity.getProperties().keySet()).containsExactly("revisions.key", "revisions.value"); assertThat(entity.getProperties()).containsEntry( "revisions.key", ImmutableList.of(START_TIME.toDate(), START_TIME.plusDays(1).toDate())); @@ -167,7 +168,7 @@ public class CommitLogRevisionsTranslatorFactoryTest { @Test public void testLoad_missingRevisionRawProperties_createsEmptyObject() { com.google.appengine.api.datastore.Entity entity = - ofy().transactNewReadOnly(() -> ofy().save().toEntity(new TestObject())); + tm().transactNewReadOnly(() -> ofy().save().toEntity(new TestObject())); entity.removeProperty("revisions.key"); entity.removeProperty("revisions.value"); TestObject object = ofy().load().fromEntity(entity); diff --git a/core/src/test/java/google/registry/rde/PendingDepositCheckerTest.java b/core/src/test/java/google/registry/rde/PendingDepositCheckerTest.java index 174fc40a3..4c3729281 100644 --- a/core/src/test/java/google/registry/rde/PendingDepositCheckerTest.java +++ b/core/src/test/java/google/registry/rde/PendingDepositCheckerTest.java @@ -20,6 +20,7 @@ import static google.registry.model.common.Cursor.CursorType.RDE_STAGING; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.rde.RdeMode.FULL; import static google.registry.model.rde.RdeMode.THIN; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatastoreHelper.createTld; import static google.registry.testing.DatastoreHelper.persistResource; import static org.joda.time.DateTimeConstants.TUESDAY; @@ -163,7 +164,7 @@ public class PendingDepositCheckerTest { private static void setCursor( final Registry registry, final CursorType cursorType, final DateTime value) { - ofy().transact(() -> ofy().save().entity(Cursor.create(cursorType, value, registry))); + tm().transact(() -> ofy().save().entity(Cursor.create(cursorType, value, registry))); } private static void createTldWithEscrowEnabled(final String tld) { diff --git a/core/src/test/java/google/registry/rde/RdeStagingActionTest.java b/core/src/test/java/google/registry/rde/RdeStagingActionTest.java index 6f84e7465..33c02b4c6 100644 --- a/core/src/test/java/google/registry/rde/RdeStagingActionTest.java +++ b/core/src/test/java/google/registry/rde/RdeStagingActionTest.java @@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat; import static google.registry.model.common.Cursor.CursorType.BRDA; import static google.registry.model.common.Cursor.CursorType.RDE_STAGING; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.rde.RdeFixtures.makeContactResource; import static google.registry.rde.RdeFixtures.makeDomainBase; import static google.registry.rde.RdeFixtures.makeHostResource; @@ -847,7 +848,7 @@ public class RdeStagingActionTest extends MapreduceTestCase { private void setCursor( final Registry registry, final CursorType cursorType, final DateTime value) { clock.advanceOneMilli(); - ofy().transact(() -> ofy().save().entity(Cursor.create(cursorType, value, registry)).now()); + tm().transact(() -> ofy().save().entity(Cursor.create(cursorType, value, registry)).now()); } public static T unmarshal(Class clazz, byte[] xml) throws XmlException { diff --git a/core/src/test/java/google/registry/rde/RdeUploadActionTest.java b/core/src/test/java/google/registry/rde/RdeUploadActionTest.java index 6b0cdd577..b5320bc7c 100644 --- a/core/src/test/java/google/registry/rde/RdeUploadActionTest.java +++ b/core/src/test/java/google/registry/rde/RdeUploadActionTest.java @@ -19,8 +19,8 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static google.registry.model.common.Cursor.CursorType.RDE_STAGING; import static google.registry.model.common.Cursor.CursorType.RDE_UPLOAD_SFTP; -import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.rde.RdeMode.FULL; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatastoreHelper.createTld; import static google.registry.testing.DatastoreHelper.persistResource; import static google.registry.testing.DatastoreHelper.persistSimpleResource; @@ -194,7 +194,7 @@ public class RdeUploadActionTest { writeGcsFile(gcsService, LENGTH_R1_FILE, Long.toString(DEPOSIT_XML.size()).getBytes(UTF_8)); writeGcsFile(gcsService, REPORT_FILE, Ghostryde.encode(REPORT_XML.read(), encryptKey)); writeGcsFile(gcsService, REPORT_R1_FILE, Ghostryde.encode(REPORT_XML.read(), encryptKey)); - ofy() + tm() .transact( () -> { RdeRevision.saveRevision("lol", DateTime.parse("2010-10-17TZ"), FULL, 0); @@ -282,7 +282,7 @@ public class RdeUploadActionTest { @Test public void testRunWithLock_resend() throws Exception { - ofy().transact(() -> RdeRevision.saveRevision("tld", DateTime.parse("2010-10-17TZ"), FULL, 1)); + tm().transact(() -> RdeRevision.saveRevision("tld", DateTime.parse("2010-10-17TZ"), FULL, 1)); int port = sftpd.serve("user", "password", folder.getRoot()); URI uploadUrl = URI.create(String.format("sftp://user:password@localhost:%d/", port)); DateTime stagingCursor = DateTime.parse("2010-10-18TZ"); diff --git a/core/src/test/java/google/registry/testing/DatastoreHelper.java b/core/src/test/java/google/registry/testing/DatastoreHelper.java index 945656431..eb390807b 100644 --- a/core/src/test/java/google/registry/testing/DatastoreHelper.java +++ b/core/src/test/java/google/registry/testing/DatastoreHelper.java @@ -30,6 +30,7 @@ import static google.registry.model.ResourceTransferUtils.createTransferResponse import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.registry.Registry.TldState.GENERAL_AVAILABILITY; import static google.registry.model.registry.label.PremiumListUtils.parentPremiumListEntriesOnRevision; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost; import static google.registry.util.CollectionUtils.difference; import static google.registry.util.CollectionUtils.union; @@ -288,7 +289,7 @@ public class DatastoreHelper { // Calls {@link LordnTaskUtils#enqueueDomainBaseTask} wrapped in an ofy transaction so that // the // transaction time is set correctly. - ofy().transactNew(() -> LordnTaskUtils.enqueueDomainBaseTask(persistedDomain)); + tm().transactNew(() -> LordnTaskUtils.enqueueDomainBaseTask(persistedDomain)); return persistedDomain; } @@ -864,7 +865,7 @@ public class DatastoreHelper { assertWithMessage("Attempting to persist a Builder is almost certainly an error in test code") .that(resource) .isNotInstanceOf(Buildable.Builder.class); - ofy().transact(() -> saveResource(resource, wantBackup)); + tm().transact(() -> saveResource(resource, wantBackup)); // Force the session cache to be cleared so that when we read the resource back, we read from // Datastore and not from the session cache. This is needed to trigger Objectify's load process // (unmarshalling entity protos to POJOs, nulling out empty collections, calling @OnLoad @@ -877,7 +878,7 @@ public class DatastoreHelper { public static R persistEppResourceInFirstBucket(final R resource) { final EppResourceIndex eppResourceIndex = EppResourceIndex.create(Key.create(EppResourceIndexBucket.class, 1), Key.create(resource)); - ofy() + tm() .transact( () -> { Saver saver = ofy().save(); @@ -900,7 +901,7 @@ public class DatastoreHelper { } // Persist domains ten at a time, to avoid exceeding the entity group limit. for (final List chunk : Iterables.partition(resources, 10)) { - ofy().transact(() -> chunk.forEach(resource -> saveResource(resource, wantBackup))); + tm().transact(() -> chunk.forEach(resource -> saveResource(resource, wantBackup))); } // Force the session to be cleared so that when we read it back, we read from Datastore // and not from the transaction's session cache. @@ -921,8 +922,8 @@ public class DatastoreHelper { * @see #persistResource(Object) */ public static R persistEppResource(final R resource) { - checkState(!ofy().inTransaction()); - ofy() + checkState(!tm().inTransaction()); + tm() .transact( () -> { ofy() @@ -932,7 +933,7 @@ public class DatastoreHelper { new HistoryEntry.Builder() .setParent(resource) .setType(getHistoryEntryType(resource)) - .setModificationTime(ofy().getTransactionTime()) + .setModificationTime(tm().getTransactionTime()) .build()); ofy().save().entity(ForeignKeyIndex.create(resource, resource.getDeletionTime())); }); @@ -1008,7 +1009,7 @@ public class DatastoreHelper { * ForeignKeyedEppResources. */ public static ImmutableList persistSimpleResources(final Iterable resources) { - ofy().transact(() -> ofy().saveWithoutBackup().entities(resources)); + tm().transact(() -> ofy().saveWithoutBackup().entities(resources)); // Force the session to be cleared so that when we read it back, we read from Datastore // and not from the transaction's session cache. ofy().clearSessionCache(); @@ -1024,7 +1025,7 @@ public class DatastoreHelper { /** Force the create and update timestamps to get written into the resource. **/ public static R cloneAndSetAutoTimestamps(final R resource) { - return ofy().transact(() -> ofy().load().fromEntity(ofy().save().toEntity(resource))); + return tm().transact(() -> ofy().load().fromEntity(ofy().save().toEntity(resource))); } /** Returns the entire map of {@link PremiumListEntry}s for the given {@link PremiumList}. */ diff --git a/core/src/test/java/google/registry/tmch/LordnTaskUtilsTest.java b/core/src/test/java/google/registry/tmch/LordnTaskUtilsTest.java index 167c6e7bf..4beb02615 100644 --- a/core/src/test/java/google/registry/tmch/LordnTaskUtilsTest.java +++ b/core/src/test/java/google/registry/tmch/LordnTaskUtilsTest.java @@ -16,6 +16,7 @@ package google.registry.tmch; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatastoreHelper.createTld; import static google.registry.testing.DatastoreHelper.loadRegistrar; import static google.registry.testing.DatastoreHelper.persistActiveContact; @@ -95,7 +96,7 @@ public class LordnTaskUtilsTest { @Test public void test_oteRegistrarWithNullIanaId() { - ofy() + tm() .transact( () -> ofy() @@ -130,6 +131,6 @@ public class LordnTaskUtilsTest { public void test_enqueueDomainBaseTask_throwsNpeOnNullDomain() { assertThrows( NullPointerException.class, - () -> ofy().transactNew(() -> LordnTaskUtils.enqueueDomainBaseTask(null))); + () -> tm().transactNew(() -> LordnTaskUtils.enqueueDomainBaseTask(null))); } }