Implement TransactionManager for datastore (#207)

This PR created the new interface named TransactionManager which defines
methods to manage transaction. Also, the access to all transaction related
methods of Ofy.java are restricted to package private, and they will be exposed
by DatastoreTransactionManager which is the datastore implementation of
TransactionManager.
This commit is contained in:
Shicong Huang 2019-08-07 12:59:08 -04:00 committed by GitHub
parent ce791e8b97
commit a68b1a12fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
98 changed files with 544 additions and 247 deletions

View file

@ -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();

View file

@ -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.

View file

@ -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.

View file

@ -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<? extends ForeignKeyIndex<?>> fki = ForeignKeyIndex.createKey(resource);
int numEntitiesDeleted =
ofy()
tm()
.transact(
() -> {
// This ancestor query selects all descendant entities.

View file

@ -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<? extends ForeignKeyIndex<?>> 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)

View file

@ -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<OneTime> 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();

View file

@ -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<EppResource> 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()));

View file

@ -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);

View file

@ -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;
}

View file

@ -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)));
}

View file

@ -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 {

View file

@ -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<DomainBase, ImmutableSet<?>> getPotentialReferences) throws EppException {
// Enter a transactionless context briefly.
EppException failfastException =
ofy()
tm()
.doTransactionless(
() -> {
final ForeignKeyIndex<R> fki =

View file

@ -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()

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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<StatusValue> statusToRemove = command.getInnerRemove().getStatusValues();

View file

@ -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);

View file

@ -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());

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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<DomainTransferRequestSuperuserExtension> superuserExtension =
eppInput.getSingleExtension(DomainTransferRequestSuperuserExtension.class);

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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());
}
}

View file

@ -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--;
}

View file

@ -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<String, EncryptResponse> encryptedValues) {
ofy()
tm()
.transact(
() -> {
for (Map.Entry<String, EncryptResponse> entry : encryptedValues.entrySet()) {

View file

@ -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<? extends EppResource> key) {
return ofy().doTransactionless(() -> ofy().load().key(key).now());
return tm().doTransactionless(() -> ofy().load().key(key).now());
}
@Override
public Map<Key<? extends EppResource>, EppResource> loadAll(
Iterable<? extends Key<? extends EppResource>> keys) {
return ofy().doTransactionless(() -> loadMultiple(keys));
return tm().doTransactionless(() -> loadMultiple(keys));
}
};

View file

@ -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<String, String> 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&amp;E entities we created. */
private void saveAllEntities() {
ofy().assertInTransaction();
tm().assertInTransaction();
ImmutableList<Registry> registries = ImmutableList.of(sunriseTld, gaTld, eapTld);
ImmutableList<RegistrarContact> contacts = contactsBuilder.build();

View file

@ -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());
}
}
}

View file

@ -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<E extends EppResource> extends BackupGroup
@Override
public Optional<ForeignKeyIndex<?>> load(Key<ForeignKeyIndex<?>> 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<E extends EppResource> extends BackupGroup
Iterable<? extends Key<ForeignKeyIndex<?>>> keys) {
ImmutableSet<Key<ForeignKeyIndex<?>>> typedKeys = ImmutableSet.copyOf(keys);
Map<Key<ForeignKeyIndex<?>>, 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<E extends EppResource> extends BackupGroup
public static <E extends EppResource> Map<String, ForeignKeyIndex<E>> loadCached(
Class<E> clazz, Iterable<String> foreignKeys, final DateTime now) {
if (!RegistryConfig.isEppResourceCachingEnabled()) {
return ofy().doTransactionless(() -> load(clazz, foreignKeys, now));
return tm().doTransactionless(() -> load(clazz, foreignKeys, now));
}
ImmutableList<Key<ForeignKeyIndex<?>>> fkiKeys =
Streams.stream(foreignKeys)

View file

@ -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<R> extends VoidWork {
class CommitLoggedWork<R> implements Runnable {
private final Work<R> work;
private final Clock clock;
@ -74,8 +73,8 @@ class CommitLoggedWork<R> extends VoidWork {
*/
protected ImmutableSet<ImmutableObject> 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<R> work, Clock clock) {
this.work = work;
@ -87,26 +86,26 @@ class CommitLoggedWork<R> 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<ImmutableObject> 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<R> extends VoidWork {
} finally {
Ofy.TRANSACTION_INFO.set(previous);
}
vrunCalled = true;
runCalled = true;
}
/** Records all mutations enrolled by this transaction to a {@link CommitLogManifest} entry. */

View file

@ -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> T transact(Work<T> work) {
return getOfy().transact(work);
}
@Override
public void transact(Runnable work) {
getOfy().transact(work);
}
@Override
public <T> T transactNew(Work<T> work) {
return getOfy().transactNew(work);
}
@Override
public void transactNew(Runnable work) {
getOfy().transactNew(work);
}
@Override
public <R> R transactNewReadOnly(Work<R> work) {
return getOfy().transactNewReadOnly(work);
}
@Override
public void transactNewReadOnly(Runnable work) {
getOfy().transactNewReadOnly(work);
}
@Override
public <R> R doTransactionless(Work<R> work) {
return getOfy().doTransactionless(work);
}
@Override
public DateTime getTransactionTime() {
return getOfy().getTransactionTime();
}
}

View file

@ -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> R transact(Work<R> work) {
<R> R transact(Work<R> 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 {
* <p>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> R transactNew(Work<R> work) {
<R> R transactNew(Work<R> 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 {
* <p>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> R transactNewReadOnly(Work<R> work) {
<R> R transactNewReadOnly(Work<R> work) {
ReadOnlyWork<R> 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> R doTransactionless(Work<R> work) {
<R> R doTransactionless(Work<R> 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;
}

View file

@ -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<R> extends CommitLoggedWork<R> {
}
@Override
public void vrun() {
super.vrun();
public void run() {
super.run();
throw new KillTransactionException();
}

View file

@ -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);

View file

@ -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<ImmutableMap<String, Registrar>> CACHE_BY_CLIENT_ID =
memoizeWithShortExpiration(
() ->
ofy()
tm()
.doTransactionless(
() -> Maps.uniqueIndex(loadAll(), Registrar::getClientId)));

View file

@ -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<RegistrarContact> contacts) {
ofy()
tm()
.transact(
() -> {
ofy()

View file

@ -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<ImmutableMap<String, TldType>> createFreshCache() {
return memoizeWithShortExpiration(
() ->
ofy()
tm()
.doTransactionless(
() -> {
ImmutableMap.Builder<String, TldType> builder =

View file

@ -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()

View file

@ -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<Money, PremiumList.Pr
new CacheLoader<String, PremiumList>() {
@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<Money, PremiumList.Pr
new CacheLoader<Key<PremiumListRevision>, PremiumListRevision>() {
@Override
public PremiumListRevision load(final Key<PremiumListRevision> 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<Money, PremiumList.Pr
new CacheLoader<Key<PremiumListEntry>, Optional<PremiumListEntry>>() {
@Override
public Optional<PremiumListEntry> load(final Key<PremiumListEntry> entryKey) {
return ofy()
return tm()
.doTransactionless(() -> Optional.ofNullable(ofy().load().key(entryKey).now()));
}
});

View file

@ -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<PremiumListEntry> 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()));
}
/**

View file

@ -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"

View file

@ -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) {

View file

@ -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<SignedMarkRevocationList> CACHE =
memoizeWithShortExpiration(
() ->
ofy()
tm()
.transactNewReadOnly(
() -> {
Iterable<SignedMarkRevocationList> 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()

View file

@ -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<String, String> 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(

View file

@ -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);

View file

@ -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> {
R run();
}
/** Returns {@code true} if the caller is in a transaction.
*
* <p>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.
*
* <p>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> T transact(Work<T> 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.
*
* <p>Note that this function is kept for backward compatibility. We will review the use case
* later when adding the cloud sql implementation.
*/
<T> T transactNew(Work<T> work);
/** Pauses the current transaction (if any) and executes the work in a new transaction.
*
* <p>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.
*
* <p>Note that this function is kept for backward compatibility. We will review the use case
* later when adding the cloud sql implementation.
*/
<R> R transactNewReadOnly(Work<R> work);
/** Executes the work in a read-only transaction.
*
* <p>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> R doTransactionless(Work<R> work);
/** Returns the time associated with the start of this particular transaction attempt. */
DateTime getTransactionTime();
}

View file

@ -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;
}
}

View file

@ -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<DateTime, Key<CommitLogManifest>> transformBeforeSave(
ImmutableSortedMap<DateTime, Key<CommitLogManifest>> 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<DateTime, Key<CommitLogManifest>>(Ordering.natural())

View file

@ -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();
}};
}
}

View file

@ -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();
}};
}
}

View file

@ -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<String, String> ianaToBaseUrls = getRdapBaseUrlsPerIanaId();
for (Key<Registrar> registrarKey : ofy().load().type(Registrar.class).keys()) {
ofy()
tm()
.transact(
() -> {
Registrar registrar = ofy().load().key(registrarKey).now();

View file

@ -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());

View file

@ -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();

View file

@ -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<PendingDeposit, DepositFrag
logger.atInfo().log("Manual operation; not advancing cursor or enqueuing upload task");
return;
}
ofy()
tm()
.transact(
() -> {
Registry registry = Registry.get(tld);

View file

@ -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);

View file

@ -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())));
}
}

View file

@ -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<PollMessage> query = getPollMessagesQuery(clientId, clock.nowUtc()).keys();
for (List<Key<PollMessage>> keys : Iterables.partition(query, BATCH_SIZE)) {
ofy()
tm()
.transact(
() -> {
// Load poll messages and filter to just those of interest.

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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<AllocationToken> tokens) {
Collection<AllocationToken> 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();

View file

@ -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<EntityChange> batch : getCollatedEntityChangeBatches()) {
ofy().transact(() -> batch.forEach(this::executeChange));
tm().transact(() -> batch.forEach(this::executeChange));
}
return String.format("Updated %d entities.\n", changedEntitiesMap.size());
}

View file

@ -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<Key<T>> 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);
}
}

View file

@ -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<DomainBase> domainOptional =
loadByForeignKey(DomainBase.class, domainName, now);
// Transactional sanity checks on the off chance that something changed between init() running

View file

@ -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);
}

View file

@ -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<Object> 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(),

View file

@ -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<?>, Key<?>, Void> {
while (batches.hasNext()) {
final List<Key<?>> 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()));

View file

@ -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()));

View file

@ -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(

View file

@ -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<String, ?> 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);
}

View file

@ -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(

View file

@ -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 {

View file

@ -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();

View file

@ -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();

View file

@ -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);

View file

@ -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");

View file

@ -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"))

View file

@ -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));
}
}

View file

@ -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<Root> 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).

View file

@ -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<Integer>() {
assertThat(tm().transact(new Work<Integer>() {
int count = 0;
@ -255,7 +255,7 @@ public class OfyTest {
@Test
public void testTransact_datastoreTimeoutException_noManifest_retries() {
assertThat(ofy().transact(new Work<Integer>() {
assertThat(tm().transact(new Work<Integer>() {
int count = 0;
@ -273,7 +273,7 @@ public class OfyTest {
@Test
public void testTransact_datastoreTimeoutException_manifestNotWrittenToDatastore_retries() {
assertThat(ofy().transact(new Work<Integer>() {
assertThat(tm().transact(new Work<Integer>() {
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<Void>() {
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<Void> commitLoggedWork = new CommitLoggedWork<Void>(work, new SystemClock()) {
@ -322,7 +323,7 @@ public class OfyTest {
}
void doReadOnlyRetryTest(final RuntimeException e) {
assertThat(ofy().transactNewReadOnly(new Work<Integer>() {
assertThat(tm().transactNewReadOnly(new Work<Integer>() {
int count = 0;

View file

@ -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)));

View file

@ -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();

View file

@ -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()

View file

@ -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();
}));

View file

@ -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();

View file

@ -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);

View file

@ -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) {

View file

@ -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<RdeStagingAction> {
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> T unmarshal(Class<T> clazz, byte[] xml) throws XmlException {

View file

@ -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");

View file

@ -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 extends EppResource> 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<R> 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 extends EppResource> 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 <R> ImmutableList<R> persistSimpleResources(final Iterable<R> 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> 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}. */

View file

@ -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)));
}
}