Remove ofy-only functions in TransactionManager (#1826)

Also remove the use of auditedOfy in places other than the
GaeUserIdConverter.
This commit is contained in:
Lai Jiang
2022-10-25 15:52:00 -04:00
committed by GitHub
parent 0746d28e0c
commit 82092b3516
47 changed files with 286 additions and 1091 deletions
@@ -23,7 +23,6 @@ import static google.registry.testing.LogsSubject.assertAboutLogs;
import com.google.common.testing.TestLogHandler;
import google.registry.model.billing.BillingEvent.RenewalPriceBehavior;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.token.AllocationToken;
import google.registry.model.domain.token.AllocationToken.TokenType;
import google.registry.model.domain.token.PackagePromotion;
@@ -96,12 +95,11 @@ public class CheckPackagesComplianceActionTest {
@Test
void testSuccess_noPackageOverCreateLimit() {
Domain domain1 =
persistEppResource(
DatabaseHelper.newDomain("foo.tld", contact)
.asBuilder()
.setCurrentPackageToken(token.createVKey())
.build());
persistEppResource(
DatabaseHelper.newDomain("foo.tld", contact)
.asBuilder()
.setCurrentPackageToken(token.createVKey())
.build());
action.run();
assertAboutLogs()
@@ -74,12 +74,8 @@ public class SyncRegistrarsSheetTest {
void beforeEach() {
createTld("example");
// Remove Registrar entities created by AppEngineExtension (and RegistrarContact's, for jpa).
// We don't do this for ofy because ofy's loadAllOf() can't be called in a transaction but
// _must_ be called in a transaction in JPA.
if (!tm().isOfy()) {
tm().transact(() -> tm().loadAllOf(RegistrarPoc.class))
.forEach(DatabaseHelper::deleteResource);
}
Registrar.loadAll().forEach(DatabaseHelper::deleteResource);
}
@@ -17,7 +17,6 @@ package google.registry.flows;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.EppResourceUtils.loadAtPointInTime;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadAllOf;
import static google.registry.testing.DatabaseHelper.loadByEntity;
@@ -94,7 +93,6 @@ class EppPointInTimeTest {
clock.setTo(timeAtCreate);
eppLoader = new EppLoader(this, "domain_create.xml", ImmutableMap.of("DOMAIN", "example.tld"));
runFlow();
tm().clearSessionCache();
Domain domainAfterCreate = Iterables.getOnlyElement(loadAllOf(Domain.class));
assertThat(domainAfterCreate.getDomainName()).isEqualTo("example.tld");
@@ -102,7 +100,6 @@ class EppPointInTimeTest {
DateTime timeAtFirstUpdate = clock.nowUtc();
eppLoader = new EppLoader(this, "domain_update_dsdata_add.xml");
runFlow();
tm().clearSessionCache();
Domain domainAfterFirstUpdate = loadByEntity(domainAfterCreate);
assertThat(domainAfterCreate).isNotEqualTo(domainAfterFirstUpdate);
@@ -111,14 +108,12 @@ class EppPointInTimeTest {
DateTime timeAtSecondUpdate = clock.nowUtc();
eppLoader = new EppLoader(this, "domain_update_dsdata_rem.xml");
runFlow();
tm().clearSessionCache();
Domain domainAfterSecondUpdate = loadByEntity(domainAfterCreate);
clock.advanceBy(standardDays(2));
DateTime timeAtDelete = clock.nowUtc(); // before 'add' grace period ends
eppLoader = new EppLoader(this, "domain_delete.xml", ImmutableMap.of("DOMAIN", "example.tld"));
runFlow();
tm().clearSessionCache();
assertThat(domainAfterFirstUpdate).isNotEqualTo(domainAfterSecondUpdate);
@@ -126,17 +121,14 @@ class EppPointInTimeTest {
Domain latest = loadByEntity(domainAfterCreate);
// Creation time has millisecond granularity due to isActive() check.
tm().clearSessionCache();
assertThat(loadAtPointInTime(latest, timeAtCreate.minusMillis(1))).isNull();
assertThat(loadAtPointInTime(latest, timeAtCreate)).isNotNull();
assertThat(loadAtPointInTime(latest, timeAtCreate.plusMillis(1))).isNotNull();
tm().clearSessionCache();
assertAboutImmutableObjects()
.that(loadAtPointInTime(latest, timeAtCreate.plusDays(1)))
.isEqualExceptFields(domainAfterCreate, "updateTimestamp");
tm().clearSessionCache();
// In SQL, we are not limited by the day granularity, so when we request the object
// at timeAtFirstUpdate we should receive the object at that first update, even though the
// second update occurred one millisecond later.
@@ -144,18 +136,15 @@ class EppPointInTimeTest {
.that(loadAtPointInTime(latest, timeAtFirstUpdate))
.isEqualExceptFields(domainAfterFirstUpdate, "updateTimestamp");
tm().clearSessionCache();
assertAboutImmutableObjects()
.that(loadAtPointInTime(latest, timeAtSecondUpdate))
.isEqualExceptFields(domainAfterSecondUpdate, "updateTimestamp");
tm().clearSessionCache();
assertAboutImmutableObjects()
.that(loadAtPointInTime(latest, timeAtSecondUpdate.plusDays(1)))
.isEqualExceptFields(domainAfterSecondUpdate, "updateTimestamp");
// Deletion time has millisecond granularity due to isActive() check.
tm().clearSessionCache();
assertThat(loadAtPointInTime(latest, timeAtDelete.minusMillis(1))).isNotNull();
assertThat(loadAtPointInTime(latest, timeAtDelete)).isNull();
assertThat(loadAtPointInTime(latest, timeAtDelete.plusMillis(1))).isNull();
@@ -16,7 +16,6 @@ package google.registry.flows;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType;
import static google.registry.testing.DatabaseHelper.loadAllOf;
import static google.registry.testing.DatabaseHelper.stripBillingEventId;
@@ -226,7 +225,6 @@ public class EppTestCase {
"Running " + inputFilename + " => " + outputFilename,
"epp.response.resData.infData.roid",
"epp.response.trID.svTRID");
tm().clearSessionCache(); // Clear the cache like OfyFilter would.
return actualOutput;
}
@@ -277,8 +277,6 @@ public abstract class FlowTestCase<F extends Flow> {
Arrays.toString(marshal(output, ValidationMode.LENIENT))),
e);
}
// Clear the cache so that we don't see stale results in tests.
tm().clearSessionCache();
return output;
}
@@ -76,9 +76,6 @@ public abstract class ResourceFlowTestCase<F extends Flow, R extends EppResource
@Nullable
protected R reloadResourceByForeignKey(DateTime now) throws Exception {
// 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.
tm().clearSessionCache();
return loadByForeignKey(getResourceClass(), getUniqueIdFromCommand(), now).orElse(null);
}
@@ -88,8 +85,6 @@ public abstract class ResourceFlowTestCase<F extends Flow, R extends EppResource
}
protected <T extends EppResource> T reloadResourceAndCloneAtTime(T resource, DateTime now) {
// Force the session to be cleared.
tm().clearSessionCache();
@SuppressWarnings("unchecked")
T refreshedResource =
(T) tm().transact(() -> tm().loadByEntity(resource)).cloneProjectedAtTime(now);
@@ -58,7 +58,6 @@ public class CreateAutoTimestampTest {
tm().put(object);
return tm().getTransactionTime();
});
tm().clearSessionCache();
assertThat(reload().createTime.getTimestamp()).isEqualTo(transactionTime);
}
@@ -71,7 +70,6 @@ public class CreateAutoTimestampTest {
object.createTime = CreateAutoTimestamp.create(oldCreateTime);
tm().put(object);
});
tm().clearSessionCache();
assertThat(reload().createTime.getTimestamp()).isEqualTo(oldCreateTime);
}
}
@@ -65,7 +65,6 @@ public class UpdateAutoTimestampTest {
tm().insert(object);
return tm().getTransactionTime();
});
tm().clearSessionCache();
assertThat(reload().updateTime.getTimestamp()).isEqualTo(transactionTime);
}
@@ -106,7 +105,6 @@ public class UpdateAutoTimestampTest {
tm().insert(object);
return tm().getTransactionTime();
});
tm().clearSessionCache();
assertThat(reload().updateTime.getTimestamp()).isEqualTo(transactionTime);
}
@@ -38,7 +38,6 @@ import google.registry.testing.DatabaseHelper;
import google.registry.testing.FakeClock;
import java.io.Serializable;
import java.math.BigInteger;
import java.sql.SQLException;
import java.util.NoSuchElementException;
import java.util.function.Supplier;
import javax.persistence.Entity;
@@ -47,7 +46,6 @@ import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.OptimisticLockException;
import javax.persistence.RollbackException;
import org.hibernate.exception.JDBCConnectionException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -205,59 +203,6 @@ class JpaTransactionManagerImplTest {
verify(spyJpaTm, times(6)).delete(theEntityKey);
}
@Test
void transactNewReadOnly_retriesJdbcConnectionExceptions() {
JpaTransactionManager spyJpaTm = spy(jpaTm());
doThrow(JDBCConnectionException.class).when(spyJpaTm).loadByKey(any(VKey.class));
spyJpaTm.transact(() -> spyJpaTm.insert(theEntity));
assertThrows(
JDBCConnectionException.class,
() -> spyJpaTm.transactNewReadOnly(() -> spyJpaTm.loadByKey(theEntityKey)));
verify(spyJpaTm, times(3)).loadByKey(theEntityKey);
Supplier<Runnable> supplier =
() -> {
Runnable work = () -> spyJpaTm.loadByKey(theEntityKey);
work.run();
return null;
};
assertThrows(JDBCConnectionException.class, () -> spyJpaTm.transactNewReadOnly(supplier));
verify(spyJpaTm, times(6)).loadByKey(theEntityKey);
}
@Test
void transactNewReadOnly_retriesNestedJdbcConnectionExceptions() {
JpaTransactionManager spyJpaTm = spy(jpaTm());
doThrow(
new RuntimeException(
new JDBCConnectionException("connection exception", new SQLException())))
.when(spyJpaTm)
.loadByKey(any(VKey.class));
spyJpaTm.transact(() -> spyJpaTm.insert(theEntity));
assertThrows(
RuntimeException.class,
() -> spyJpaTm.transactNewReadOnly(() -> spyJpaTm.loadByKey(theEntityKey)));
verify(spyJpaTm, times(3)).loadByKey(theEntityKey);
Supplier<Runnable> supplier =
() -> {
Runnable work = () -> spyJpaTm.loadByKey(theEntityKey);
work.run();
return null;
};
assertThrows(RuntimeException.class, () -> spyJpaTm.transactNewReadOnly(supplier));
verify(spyJpaTm, times(6)).loadByKey(theEntityKey);
}
@Test
void doTransactionless_retriesJdbcConnectionExceptions() {
JpaTransactionManager spyJpaTm = spy(jpaTm());
doThrow(JDBCConnectionException.class).when(spyJpaTm).loadByKey(any(VKey.class));
spyJpaTm.transact(() -> spyJpaTm.insert(theEntity));
assertThrows(
RuntimeException.class,
() -> spyJpaTm.doTransactionless(() -> spyJpaTm.loadByKey(theEntityKey)));
verify(spyJpaTm, times(3)).loadByKey(theEntityKey);
}
@Test
void insert_throwsExceptionIfEntityExists() {
assertThat(existsInDb(theEntity)).isFalse();
@@ -787,6 +732,7 @@ class JpaTransactionManagerImplTest {
String name;
int age;
@SuppressWarnings("unused")
private CompoundId() {}
private CompoundId(String name, int age) {
@@ -834,6 +780,7 @@ class JpaTransactionManagerImplTest {
String nameField;
int ageField;
@SuppressWarnings("unused")
private NamedCompoundId() {}
private NamedCompoundId(String nameField, int ageField) {
@@ -72,7 +72,7 @@ public class QueryComposerTest {
tm().createQueryComposer(TestEntity.class)
.where("name", Comparator.GT, "bravo")
.first()
.map(QueryComposerTest::assertDetachedIfJpa)
.map(DatabaseHelper::assertDetachedFromEntityManager)
.get()))
.isEqualTo(charlie);
assertThat(
@@ -81,7 +81,7 @@ public class QueryComposerTest {
tm().createQueryComposer(TestEntity.class)
.where("name", Comparator.GTE, "charlie")
.first()
.map(QueryComposerTest::assertDetachedIfJpa)
.map(DatabaseHelper::assertDetachedFromEntityManager)
.get()))
.isEqualTo(charlie);
assertThat(
@@ -90,7 +90,7 @@ public class QueryComposerTest {
tm().createQueryComposer(TestEntity.class)
.where("name", Comparator.LT, "bravo")
.first()
.map(QueryComposerTest::assertDetachedIfJpa)
.map(DatabaseHelper::assertDetachedFromEntityManager)
.get()))
.isEqualTo(alpha);
assertThat(
@@ -99,7 +99,7 @@ public class QueryComposerTest {
tm().createQueryComposer(TestEntity.class)
.where("name", Comparator.LTE, "alpha")
.first()
.map(QueryComposerTest::assertDetachedIfJpa)
.map(DatabaseHelper::assertDetachedFromEntityManager)
.get()))
.isEqualTo(alpha);
}
@@ -120,7 +120,7 @@ public class QueryComposerTest {
assertThat(
tm().transact(
() ->
QueryComposerTest.assertDetachedIfJpa(
DatabaseHelper.assertDetachedFromEntityManager(
tm().createQueryComposer(TestEntity.class)
.where("name", Comparator.EQ, "alpha")
.getSingleResult())))
@@ -169,7 +169,7 @@ public class QueryComposerTest {
.createQueryComposer(TestEntity.class)
.where("name", Comparator.GT, "alpha")
.stream()
.map(QueryComposerTest::assertDetachedIfJpa)
.map(DatabaseHelper::assertDetachedFromEntityManager)
.collect(toImmutableList())))
.containsExactly(bravo, charlie);
assertThat(
@@ -179,7 +179,7 @@ public class QueryComposerTest {
.createQueryComposer(TestEntity.class)
.where("name", Comparator.GTE, "bravo")
.stream()
.map(QueryComposerTest::assertDetachedIfJpa)
.map(DatabaseHelper::assertDetachedFromEntityManager)
.collect(toImmutableList())))
.containsExactly(bravo, charlie);
assertThat(
@@ -189,7 +189,7 @@ public class QueryComposerTest {
.createQueryComposer(TestEntity.class)
.where("name", Comparator.LT, "charlie")
.stream()
.map(QueryComposerTest::assertDetachedIfJpa)
.map(DatabaseHelper::assertDetachedFromEntityManager)
.collect(toImmutableList())))
.containsExactly(alpha, bravo);
assertThat(
@@ -199,7 +199,7 @@ public class QueryComposerTest {
.createQueryComposer(TestEntity.class)
.where("name", Comparator.LTE, "bravo")
.stream()
.map(QueryComposerTest::assertDetachedIfJpa)
.map(DatabaseHelper::assertDetachedFromEntityManager)
.collect(toImmutableList())))
.containsExactly(alpha, bravo);
}
@@ -223,7 +223,7 @@ public class QueryComposerTest {
tm().createQueryComposer(TestEntity.class)
.where("val", Comparator.EQ, 2)
.first()
.map(QueryComposerTest::assertDetachedIfJpa)
.map(DatabaseHelper::assertDetachedFromEntityManager)
.get()))
.isEqualTo(bravo);
}
@@ -238,7 +238,7 @@ public class QueryComposerTest {
.where("val", Comparator.GT, 1)
.orderBy("val")
.stream()
.map(QueryComposerTest::assertDetachedIfJpa)
.map(DatabaseHelper::assertDetachedFromEntityManager)
.collect(toImmutableList())))
.containsExactly(bravo, alpha);
}
@@ -319,13 +319,6 @@ public class QueryComposerTest {
.isEmpty();
}
private static <T> T assertDetachedIfJpa(T entity) {
if (!tm().isOfy()) {
return DatabaseHelper.assertDetachedFromEntityManager(entity);
}
return entity;
}
@javax.persistence.Entity
@Entity(name = "QueryComposerTestEntity")
private static class TestEntity extends ImmutableObject {
@@ -128,31 +128,6 @@ public class ReplicaSimulatingJpaTransactionManager implements JpaTransactionMan
transact(work);
}
@Override
public <T> T transactNew(Supplier<T> work) {
return transact(work);
}
@Override
public void transactNew(Runnable work) {
transact(work);
}
@Override
public <T> T transactNewReadOnly(Supplier<T> work) {
return transact(work);
}
@Override
public void transactNewReadOnly(Runnable work) {
transact(work);
}
@Override
public <T> T doTransactionless(Supplier<T> work) {
return delegate.doTransactionless(work);
}
@Override
public DateTime getTransactionTime() {
return delegate.getTransactionTime();
@@ -285,16 +260,6 @@ public class ReplicaSimulatingJpaTransactionManager implements JpaTransactionMan
return delegate.createQueryComposer(entity);
}
@Override
public void clearSessionCache() {
delegate.clearSessionCache();
}
@Override
public boolean isOfy() {
return delegate.isOfy();
}
@Override
public <T> void assertDelete(VKey<T> key) {
delegate.assertDelete(key);
@@ -111,22 +111,6 @@ public class TransactionManagerTest {
assertEntityExists(theEntity);
}
@Test
void transactNew_succeeds() {
assertEntityNotExist(theEntity);
tm().transactNew(() -> tm().insert(theEntity));
assertEntityExists(theEntity);
}
@Test
void transactNewReadOnly_succeeds() {
assertEntityNotExist(theEntity);
tm().transact(() -> tm().insert(theEntity));
assertEntityExists(theEntity);
TestEntity persisted = tm().transactNewReadOnly(() -> tm().loadByKey(theEntity.key()));
assertThat(persisted).isEqualTo(theEntity);
}
@Test
void saveNew_succeeds() {
assertEntityNotExist(theEntity);
@@ -15,7 +15,6 @@
package google.registry.rde;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadByKey;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -79,7 +78,6 @@ public class EscrowTaskRunnerTest {
runner.lockRunAndRollForward(
task, registry, standardSeconds(30), CursorType.RDE_STAGING, standardDays(1));
verify(task).runWithLock(DateTime.parse("2006-06-06TZ"));
tm().clearSessionCache();
Cursor cursor = loadByKey(Cursor.createScopedVKey(CursorType.RDE_STAGING, registry));
assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-06-07TZ"));
}
@@ -15,7 +15,6 @@
package google.registry.reporting.icann;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTlds;
import static google.registry.testing.DatabaseHelper.loadByKey;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -179,7 +178,6 @@ class IcannReportingUploadActionTest {
when(mockReporter.send(PAYLOAD_SUCCESS, "tld-activity-200606.csv")).thenReturn(true);
IcannReportingUploadAction action = createAction();
action.run();
tm().clearSessionCache();
Cursor cursor =
loadByKey(Cursor.createScopedVKey(CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("tld")));
assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-08-01TZ"));
@@ -190,7 +188,6 @@ class IcannReportingUploadActionTest {
clock.setTo(DateTime.parse("2006-5-01T00:30:00Z"));
IcannReportingUploadAction action = createAction();
action.run();
tm().clearSessionCache();
verifyNoMoreInteractions(mockReporter);
verifyNoMoreInteractions(emailService);
}
@@ -238,7 +235,6 @@ class IcannReportingUploadActionTest {
void testFailure_cursorIsNotAdvancedForward() throws Exception {
runTest_nonRetryableException(
new IOException("Your IP address 25.147.130.158 is not allowed to connect"));
tm().clearSessionCache();
Cursor cursor =
loadByKey(Cursor.createScopedVKey(CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("tld")));
assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-07-01TZ"));
@@ -249,7 +245,6 @@ class IcannReportingUploadActionTest {
clock.setTo(DateTime.parse("2006-05-01T00:30:00Z"));
IcannReportingUploadAction action = createAction();
action.run();
tm().clearSessionCache();
Cursor cursor =
loadByKey(Cursor.createScopedVKey(CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("foo")));
assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-07-01TZ"));
@@ -32,7 +32,6 @@ import static google.registry.model.IdService.allocateId;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.model.ImmutableObjectSubject.immutableObjectCorrespondence;
import static google.registry.model.ResourceTransferUtils.createTransferResponse;
import static google.registry.model.ofy.ObjectifyService.auditedOfy;
import static google.registry.model.tld.Registry.TldState.GENERAL_AVAILABILITY;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
@@ -319,7 +318,7 @@ public final class DatabaseHelper {
final Domain persistedDomain = persistResource(domain);
// Calls {@link LordnTaskUtils#enqueueDomainTask} wrapped in a transaction so that the
// transaction time is set correctly.
tm().transactNew(() -> LordnTaskUtils.enqueueDomainTask(persistedDomain));
tm().transact(() -> LordnTaskUtils.enqueueDomainTask(persistedDomain));
maybeAdvanceClock();
return persistedDomain;
}
@@ -399,7 +398,7 @@ public final class DatabaseHelper {
toImmutableMap(Map.Entry::getKey, entry -> entry.getValue().getValue())))
.build();
// Since we used to persist a PremiumList to Datastore here, it is necessary to allocate an ID
// here to prevent breaking some of the hard-coded flow tests. IDs in tests are allocated in a
// here to prevent breaking some hard-coded flow tests. IDs in tests are allocated in a
// strictly increasing sequence, if we don't pad out the ID here, we would have to renumber
// hundreds of unit tests.
allocateId();
@@ -990,11 +989,6 @@ public final class DatabaseHelper {
.isNotInstanceOf(Buildable.Builder.class);
tm().transact(() -> tm().put(resource));
maybeAdvanceClock();
// 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
// methods, etc.) which is bypassed for entities loaded from the session cache.
tm().clearSessionCache();
return tm().transact(() -> tm().loadByEntity(resource));
}
@@ -1007,9 +1001,6 @@ public final class DatabaseHelper {
}
tm().transact(() -> resources.forEach(e -> tm().put(e)));
maybeAdvanceClock();
// 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.
tm().clearSessionCache();
}
/**
@@ -1017,8 +1008,6 @@ public final class DatabaseHelper {
*
* <p>This was coded for testing RDE since its queries depend on the associated entries.
*
* <p><b>Warning:</b> If you call this multiple times in a single test, you need to inject Ofy's
* clock field and forward it by a millisecond between each subsequent call.
*
* @see #persistResource(ImmutableObject)
*/
@@ -1035,17 +1024,16 @@ public final class DatabaseHelper {
.build());
});
maybeAdvanceClock();
tm().clearSessionCache();
return tm().transact(() -> tm().loadByEntity(resource));
}
/** Returns all of the history entries that are parented off the given EppResource. */
/** Returns all the history entries that are parented off the given EppResource. */
public static List<HistoryEntry> getHistoryEntries(EppResource resource) {
return HistoryEntryDao.loadHistoryObjectsForResource(resource.createVKey());
}
/**
* Returns all of the history entries that are parented off the given EppResource, cast to the
* Returns all the history entries that are parented off the given EppResource, cast to the
* corresponding subclass.
*/
public static <T extends HistoryEntry> List<T> getHistoryEntries(
@@ -1054,7 +1042,7 @@ public final class DatabaseHelper {
}
/**
* Returns all of the history entries that are parented off the given EppResource with the given
* Returns all the history entries that are parented off the given EppResource with the given
* type.
*/
public static ImmutableList<HistoryEntry> getHistoryEntriesOfType(
@@ -1065,8 +1053,8 @@ public final class DatabaseHelper {
}
/**
* Returns all of the history entries that are parented off the given EppResource with the given
* type and cast to the corresponding subclass.
* Returns all the history entries that are parented off the given EppResource with the given type
* and cast to the corresponding subclass.
*/
public static <T extends HistoryEntry> ImmutableList<T> getHistoryEntriesOfType(
EppResource resource, final HistoryEntry.Type type, Class<T> subclazz) {
@@ -1161,16 +1149,10 @@ public final class DatabaseHelper {
public static <R> void insertSimpleResources(final Iterable<R> resources) {
tm().transact(() -> tm().putAll(ImmutableList.copyOf(resources)));
maybeAdvanceClock();
// 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.
tm().clearSessionCache();
}
public static void deleteResource(final Object resource) {
tm().transact(() -> tm().delete(resource));
// 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.
tm().clearSessionCache();
}
/** Force the create and update timestamps to get written into the resource. */
@@ -1201,14 +1183,11 @@ public final class DatabaseHelper {
* Loads all entities from all classes stored in the database.
*
* <p>This is not performant (it requires initializing and detaching all Hibernate entities so
* that they can be used outside of the transaction in which they're loaded) and it should only be
* that they can be used outside the transaction in which they're loaded) and it should only be
* used in situations where we need to verify that, for instance, a dry run flow hasn't affected
* the database at all.
*/
public static List<Object> loadAllEntities() {
if (tm().isOfy()) {
return auditedOfy().load().list();
} else {
return jpaTm()
.transact(
() -> {
@@ -1224,14 +1203,13 @@ public final class DatabaseHelper {
}
return result.build();
});
}
}
/**
* Loads (i.e. reloads) the specified entity from the DB.
*
* <p>If the transaction manager is Cloud SQL, then this creates an inner wrapping transaction for
* convenience, so you don't need to wrap it in a transaction at the callsite.
* convenience, so you don't need to wrap it in a transaction at the call site.
*/
public static <T> T loadByEntity(T entity) {
return tm().transact(() -> tm().loadByEntity(entity));
@@ -1241,7 +1219,7 @@ public final class DatabaseHelper {
* Loads the specified entity by its key from the DB.
*
* <p>If the transaction manager is Cloud SQL, then this creates an inner wrapping transaction for
* convenience, so you don't need to wrap it in a transaction at the callsite.
* convenience, so you don't need to wrap it in a transaction at the call site.
*/
public static <T> T loadByKey(VKey<T> key) {
return tm().transact(() -> tm().loadByKey(key));
@@ -1251,7 +1229,7 @@ public final class DatabaseHelper {
* Loads the specified entity by its key from the DB or empty if it doesn't exist.
*
* <p>If the transaction manager is Cloud SQL, then this creates an inner wrapping transaction for
* convenience, so you don't need to wrap it in a transaction at the callsite.
* convenience, so you don't need to wrap it in a transaction at the call site.
*/
public static <T> Optional<T> loadByKeyIfPresent(VKey<T> key) {
return tm().transact(() -> tm().loadByKeyIfPresent(key));
@@ -1261,17 +1239,17 @@ public final class DatabaseHelper {
* Loads the specified entities by their keys from the DB.
*
* <p>If the transaction manager is Cloud SQL, then this creates an inner wrapping transaction for
* convenience, so you don't need to wrap it in a transaction at the callsite.
* convenience, so you don't need to wrap it in a transaction at the call site.
*/
public static <T> ImmutableCollection<T> loadByKeys(Iterable<? extends VKey<? extends T>> keys) {
return tm().transact(() -> tm().loadByKeys(keys).values());
}
/**
* Loads all of the entities of the specified type from the DB.
* Loads all the entities of the specified type from the DB.
*
* <p>If the transaction manager is Cloud SQL, then this creates an inner wrapping transaction for
* convenience, so you don't need to wrap it in a transaction at the callsite.
* convenience, so you don't need to wrap it in a transaction at the call site.
*/
public static <T> ImmutableList<T> loadAllOf(Class<T> clazz) {
return tm().transact(() -> tm().loadAllOf(clazz));
@@ -1281,7 +1259,7 @@ public final class DatabaseHelper {
* Loads the set of entities by their keys from the DB.
*
* <p>If the transaction manager is Cloud SQL, then this creates an inner wrapping transaction for
* convenience, so you don't need to wrap it in a transaction at the callsite.
* convenience, so you don't need to wrap it in a transaction at the call site.
*
* <p>Nonexistent keys / entities are absent from the resulting map, but no {@link
* NoSuchElementException} will be thrown.
@@ -1295,7 +1273,7 @@ public final class DatabaseHelper {
* Loads all given entities from the database if possible.
*
* <p>If the transaction manager is Cloud SQL, then this creates an inner wrapping transaction for
* convenience, so you don't need to wrap it in a transaction at the callsite.
* convenience, so you don't need to wrap it in a transaction at the call site.
*
* <p>Nonexistent entities are absent from the resulting list, but no {@link
* NoSuchElementException} will be thrown.
@@ -102,6 +102,6 @@ public class LordnTaskUtilsTest {
void test_enqueueDomainTask_throwsNpeOnNullDomain() {
assertThrows(
NullPointerException.class,
() -> tm().transactNew(() -> LordnTaskUtils.enqueueDomainTask(null)));
() -> tm().transact(() -> LordnTaskUtils.enqueueDomainTask(null)));
}
}
@@ -100,9 +100,6 @@ public abstract class CommandTestCase<C extends Command> {
jcommander.parse(args);
command.run();
} finally {
// Clear the session cache so that subsequent reads for verification purposes hit Datastore.
// This primarily matters for AutoTimestamp fields, which otherwise won't have updated values.
tm().clearSessionCache();
// Reset back to UNITTEST environment.
RegistryToolEnvironment.UNITTEST.setup(systemPropertyExtension);
}
@@ -16,7 +16,6 @@ package google.registry.tools;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3_HASH;
@@ -89,9 +88,6 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz");
DateTime after = fakeClock.nowUtc();
// Clear the cache so that the CreateAutoTimestamp field gets reloaded.
tm().clearSessionCache();
Optional<Registrar> registrarOptional = Registrar.loadByRegistrarId("clientz");
assertThat(registrarOptional).isPresent();
Registrar registrar = registrarOptional.get();
@@ -1,27 +0,0 @@
#standardSQL
-- Copyright 2017 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.
-- Query that counts the number of real registrars in system.
SELECT
-- Applies to all TLDs, hence the 'null' magic value.
STRING(NULL) AS tld,
'operational-registrars' AS metricName,
COUNT(registrarName) AS count
FROM
`domain-registry-alpha.latest_datastore_export.Registrar`
WHERE
(type = 'REAL' OR type = 'INTERNAL')
GROUP BY metricName