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

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