diff --git a/core/src/main/java/google/registry/model/EntityClasses.java b/core/src/main/java/google/registry/model/EntityClasses.java index 782241db9..fa8e3f184 100644 --- a/core/src/main/java/google/registry/model/EntityClasses.java +++ b/core/src/main/java/google/registry/model/EntityClasses.java @@ -16,7 +16,6 @@ package google.registry.model; import com.google.common.collect.ImmutableSet; import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.model.common.EntityGroupRoot; import google.registry.model.common.GaeUserIdConverter; import google.registry.model.contact.Contact; import google.registry.model.contact.ContactHistory; @@ -41,7 +40,6 @@ public final class EntityClasses { ContactHistory.class, Domain.class, DomainHistory.class, - EntityGroupRoot.class, EppResourceIndex.class, EppResourceIndexBucket.class, ForeignKeyIndex.ForeignKeyContactIndex.class, diff --git a/core/src/main/java/google/registry/model/annotations/InCrossTld.java b/core/src/main/java/google/registry/model/annotations/InCrossTld.java deleted file mode 100644 index 0c267fbd7..000000000 --- a/core/src/main/java/google/registry/model/annotations/InCrossTld.java +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2021 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.annotations; - -import com.googlecode.objectify.annotation.Entity; -import google.registry.model.common.EntityGroupRoot; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation for an Objectify {@link Entity} to indicate that it is in the cross-TLD entity group. - * - *

This means that the entity's @Parent field has to have the value of {@link - * EntityGroupRoot#getCrossTldKey}. - */ -@DeleteAfterMigration -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) -@Inherited -public @interface InCrossTld {} diff --git a/core/src/main/java/google/registry/model/common/CrossTldSingleton.java b/core/src/main/java/google/registry/model/common/CrossTldSingleton.java index d57db4afe..f8ef86288 100644 --- a/core/src/main/java/google/registry/model/common/CrossTldSingleton.java +++ b/core/src/main/java/google/registry/model/common/CrossTldSingleton.java @@ -14,26 +14,17 @@ package google.registry.model.common; -import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; - -import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Id; -import com.googlecode.objectify.annotation.Parent; import google.registry.model.ImmutableObject; import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.model.annotations.InCrossTld; import javax.persistence.MappedSuperclass; -import javax.persistence.Transient; -/** A singleton entity in Datastore. */ +/** A singleton entity in the database. */ @DeleteAfterMigration @MappedSuperclass -@InCrossTld public abstract class CrossTldSingleton extends ImmutableObject { public static final long SINGLETON_ID = 1; // There is always exactly one of these. @Id @javax.persistence.Id long id = SINGLETON_ID; - - @Transient @Parent Key parent = getCrossTldKey(); } diff --git a/core/src/main/java/google/registry/model/common/EntityGroupRoot.java b/core/src/main/java/google/registry/model/common/EntityGroupRoot.java deleted file mode 100644 index bbd4f273c..000000000 --- a/core/src/main/java/google/registry/model/common/EntityGroupRoot.java +++ /dev/null @@ -1,57 +0,0 @@ -// 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. - -package google.registry.model.common; - -import com.google.apphosting.api.ApiProxy; -import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Entity; -import com.googlecode.objectify.annotation.Id; -import google.registry.model.BackupGroupRoot; -import google.registry.model.annotations.DeleteAfterMigration; -import javax.annotation.Nullable; - -/** - * The root key for the entity group which is known as the cross-tld entity group for historical - * reasons. - * - *

This exists as a storage place for common configuration options and global settings that - * aren't updated too frequently. Entities in this entity group are usually cached upon load. The - * reason this common entity group exists is because it enables strongly consistent queries and - * updates across this seldomly updated data. This shared entity group also helps cut down on a - * potential ballooning in the number of entity groups enlisted in transactions. - * - *

Historically, each TLD used to have a separate namespace, and all entities for a TLD were in a - * single EntityGroupRoot for that TLD. Hence why there was a "cross-tld" entity group -- it was the - * entity group for the single namespace where global data applicable for all TLDs lived. - */ -@Entity -@DeleteAfterMigration -public class EntityGroupRoot extends BackupGroupRoot { - - @SuppressWarnings("unused") - @Id - private String id; - - /** The root key for cross-tld resources such as registrars. */ - public static @Nullable Key getCrossTldKey() { - // If we cannot get a current environment, calling Key.create() will fail. Instead we return a - // null in cases where this key is not actually needed (for example when loading an entity from - // SQL) to initialize an object, to avoid having to register a DatastoreEntityExtension in - // tests. - return ApiProxy.getCurrentEnvironment() == null - ? null - : Key.create(EntityGroupRoot.class, "cross-tld"); - } -} diff --git a/core/src/main/java/google/registry/model/domain/DomainBase.java b/core/src/main/java/google/registry/model/domain/DomainBase.java index 488191ffc..027263623 100644 --- a/core/src/main/java/google/registry/model/domain/DomainBase.java +++ b/core/src/main/java/google/registry/model/domain/DomainBase.java @@ -41,7 +41,6 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Ordering; import com.google.common.collect.Sets; -import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Ignore; import com.googlecode.objectify.annotation.IgnoreSave; import com.googlecode.objectify.annotation.Index; @@ -51,7 +50,6 @@ import google.registry.flows.ResourceFlowUtils; import google.registry.model.EppResource; import google.registry.model.EppResource.ResourceWithTransferData; import google.registry.model.billing.BillingEvent; -import google.registry.model.common.EntityGroupRoot; import google.registry.model.contact.Contact; import google.registry.model.domain.launch.LaunchNotice; import google.registry.model.domain.rgp.GracePeriodStatus; @@ -60,7 +58,6 @@ import google.registry.model.domain.token.AllocationToken; import google.registry.model.eppcommon.StatusValue; import google.registry.model.host.Host; import google.registry.model.poll.PollMessage; -import google.registry.model.reporting.HistoryEntry; import google.registry.model.tld.Registry; import google.registry.model.transfer.DomainTransferData; import google.registry.model.transfer.TransferStatus; @@ -286,15 +283,6 @@ public class DomainBase extends EppResource return Optional.ofNullable(dnsRefreshRequestTime); } - public static VKey restoreOfyFrom(Key domainKey, VKey key, Long historyId) { - if (historyId == null) { - // This is a legacy key (or a null key, in which case this works too) - return VKey.restoreOfyFrom(key, EntityGroupRoot.class, "per-tld"); - } else { - return VKey.restoreOfyFrom(key, domainKey, HistoryEntry.class, historyId); - } - } - public ImmutableSet getSubordinateHosts() { return nullToEmptyImmutableCopy(subordinateHosts); } diff --git a/core/src/main/java/google/registry/model/server/Lock.java b/core/src/main/java/google/registry/model/server/Lock.java index 072b62c80..22a3c859a 100644 --- a/core/src/main/java/google/registry/model/server/Lock.java +++ b/core/src/main/java/google/registry/model/server/Lock.java @@ -240,8 +240,6 @@ public class Lock extends ImmutableObject implements Serializable { Lock newLock = create(resourceName, scope, requestStatusChecker.getLogId(), now, leaseLength); - // Locks are not parented under an EntityGroupRoot (so as to avoid write - // contention) and don't need to be backed up. jpaTm().put(newLock); return AcquireResult.create(now, lock, newLock, lockState); diff --git a/core/src/main/java/google/registry/model/tld/Registries.java b/core/src/main/java/google/registry/model/tld/Registries.java index edf7ac1ee..34bd1b9b2 100644 --- a/core/src/main/java/google/registry/model/tld/Registries.java +++ b/core/src/main/java/google/registry/model/tld/Registries.java @@ -22,7 +22,6 @@ import static com.google.common.base.Strings.emptyToNull; import static com.google.common.collect.ImmutableSet.toImmutableSet; 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.auditedOfy; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; @@ -66,7 +65,6 @@ public final class Registries { auditedOfy() .load() .type(Registry.class) - .ancestor(getCrossTldKey()) .keys() .list() .stream() diff --git a/core/src/main/java/google/registry/persistence/transaction/TransactionManager.java b/core/src/main/java/google/registry/persistence/transaction/TransactionManager.java index 698218de9..2b5778887 100644 --- a/core/src/main/java/google/registry/persistence/transaction/TransactionManager.java +++ b/core/src/main/java/google/registry/persistence/transaction/TransactionManager.java @@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import google.registry.model.ImmutableObject; -import google.registry.model.annotations.InCrossTld; import google.registry.persistence.VKey; import java.util.NoSuchElementException; import java.util.Optional; @@ -176,18 +175,14 @@ public interface TransactionManager { /** * Returns a list of all entities of the given type that exist in the database. * - *

The resulting list is empty if there are no entities of this type. In Datastore mode, if the - * class is a member of the cross-TLD entity group (i.e. if it has the {@link InCrossTld} - * annotation, then the correct ancestor query will automatically be applied. + *

The resulting list is empty if there are no entities of this type. */ ImmutableList loadAllOf(Class clazz); /** * Returns a stream of all entities of the given type that exist in the database. * - *

The resulting stream is empty if there are no entities of this type. In Datastore mode, if - * the class is a member of the cross-TLD entity group (i.e. if it has the {@link InCrossTld} - * annotation, then the correct ancestor query will automatically be applied. + *

The resulting stream is empty if there are no entities of this type. */ Stream loadAllOfStream(Class clazz); diff --git a/core/src/main/java/google/registry/tools/RegistryTool.java b/core/src/main/java/google/registry/tools/RegistryTool.java index 40b00ad53..b8160c10c 100644 --- a/core/src/main/java/google/registry/tools/RegistryTool.java +++ b/core/src/main/java/google/registry/tools/RegistryTool.java @@ -92,7 +92,6 @@ public final class RegistryTool { .put("pending_escrow", PendingEscrowCommand.class) .put("registrar_poc", RegistrarPocCommand.class) .put("renew_domain", RenewDomainCommand.class) - .put("resave_environment_entities", ResaveEnvironmentEntitiesCommand.class) .put("save_sql_credential", SaveSqlCredentialCommand.class) .put("send_escrow_report_to_icann", SendEscrowReportToIcannCommand.class) .put("set_database_migration_state", SetDatabaseMigrationStateCommand.class) diff --git a/core/src/main/java/google/registry/tools/ResaveEnvironmentEntitiesCommand.java b/core/src/main/java/google/registry/tools/ResaveEnvironmentEntitiesCommand.java deleted file mode 100644 index 0d5a08f0c..000000000 --- a/core/src/main/java/google/registry/tools/ResaveEnvironmentEntitiesCommand.java +++ /dev/null @@ -1,57 +0,0 @@ -// 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. - -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.auditedOfy; -import static google.registry.persistence.transaction.TransactionManagerFactory.tm; - -import com.beust.jcommander.Parameters; -import com.googlecode.objectify.Key; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.model.registrar.Registrar; -import google.registry.model.registrar.RegistrarPoc; -import google.registry.model.tld.Registry; - -/** - * Command to re-save all environment entities to ensure that they have valid commit logs. - * - *

The entities that are re-saved are those of type {@link Registry}, {@link Registrar}, and - * {@link RegistrarPoc}. - */ -@Parameters(commandDescription = "Re-save all environment entities.") -@DeleteAfterMigration -final class ResaveEnvironmentEntitiesCommand implements CommandWithRemoteApi { - - private static final int BATCH_SIZE = 10; - - @Override - public void run() { - batchSave(Registry.class); - batchSave(Registrar.class); - batchSave(RegistrarPoc.class); - } - - private static void batchSave(Class clazz) { - System.out.printf("Re-saving %s entities.\n", clazz.getSimpleName()); - for (final Iterable> batch : - partition( - auditedOfy().load().type(clazz).ancestor(getCrossTldKey()).keys().list(), BATCH_SIZE)) { - tm().transact(() -> auditedOfy().save().entities(auditedOfy().load().keys(batch).values())); - System.out.printf("Re-saved entities batch: %s.\n", batch); - } - } -} diff --git a/core/src/test/java/google/registry/model/common/ClassPathManagerTest.java b/core/src/test/java/google/registry/model/common/ClassPathManagerTest.java index 373f9e615..9381fd72d 100644 --- a/core/src/test/java/google/registry/model/common/ClassPathManagerTest.java +++ b/core/src/test/java/google/registry/model/common/ClassPathManagerTest.java @@ -51,7 +51,6 @@ public class ClassPathManagerTest { assertThat(ClassPathManager.getClass("GaeUserIdConverter")).isEqualTo(GaeUserIdConverter.class); assertThat(ClassPathManager.getClass("EppResourceIndexBucket")) .isEqualTo(EppResourceIndexBucket.class); - assertThat(ClassPathManager.getClass("EntityGroupRoot")).isEqualTo(EntityGroupRoot.class); assertThat(ClassPathManager.getClass("Domain")).isEqualTo(Domain.class); assertThat(ClassPathManager.getClass("HistoryEntry")).isEqualTo(HistoryEntry.class); assertThat(ClassPathManager.getClass("ForeignKeyHostIndex")) @@ -100,7 +99,6 @@ public class ClassPathManagerTest { .isEqualTo("GaeUserIdConverter"); assertThat(ClassPathManager.getClassName(EppResourceIndexBucket.class)) .isEqualTo("EppResourceIndexBucket"); - assertThat(ClassPathManager.getClassName(EntityGroupRoot.class)).isEqualTo("EntityGroupRoot"); assertThat(ClassPathManager.getClassName(Domain.class)).isEqualTo("Domain"); assertThat(ClassPathManager.getClassName(HistoryEntry.class)).isEqualTo("HistoryEntry"); assertThat(ClassPathManager.getClassName(ForeignKeyHostIndex.class)) diff --git a/core/src/test/java/google/registry/model/ofy/OfyTest.java b/core/src/test/java/google/registry/model/ofy/OfyTest.java deleted file mode 100644 index 2d576c3c3..000000000 --- a/core/src/test/java/google/registry/model/ofy/OfyTest.java +++ /dev/null @@ -1,348 +0,0 @@ -// 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. - -package google.registry.model.ofy; - -import static com.google.appengine.api.datastore.DatastoreServiceFactory.getDatastoreService; -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterruptibly; -import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects; -import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; -import static google.registry.model.ofy.ObjectifyService.auditedOfy; -import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.model.ofy.Ofy.getBaseEntityClassFromEntityOrKey; -import static google.registry.testing.DatabaseHelper.newContact; -import static google.registry.util.DateTimeUtils.END_OF_TIME; -import static google.registry.util.DateTimeUtils.START_OF_TIME; -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.fail; - -import com.google.appengine.api.datastore.DatastoreFailureException; -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.annotation.Id; -import com.googlecode.objectify.annotation.OnLoad; -import com.googlecode.objectify.annotation.OnSave; -import com.googlecode.objectify.annotation.Parent; -import google.registry.model.ImmutableObject; -import google.registry.model.contact.Contact; -import google.registry.model.contact.ContactHistory; -import google.registry.model.eppcommon.Trid; -import google.registry.model.reporting.HistoryEntry; -import google.registry.testing.AppEngineExtension; -import google.registry.testing.FakeClock; -import google.registry.util.SystemClock; -import java.util.ConcurrentModificationException; -import java.util.function.Supplier; -import org.joda.time.DateTime; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -/** Tests for our wrapper around Objectify. */ -@Disabled -public class OfyTest { - - private final FakeClock fakeClock = new FakeClock(DateTime.parse("2000-01-01TZ")); - - @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withCloudSql().withClock(fakeClock).build(); - - /** An entity to use in save and delete tests. */ - private HistoryEntry someObject; - - @BeforeEach - void beforeEach() { - someObject = - new ContactHistory.Builder() - .setRegistrarId("clientid") - .setModificationTime(START_OF_TIME) - .setType(HistoryEntry.Type.CONTACT_CREATE) - .setContact(newContact("parentContact")) - .setTrid(Trid.create("client", "server")) - .setXmlBytes("".getBytes(UTF_8)) - .build(); - // This can't be initialized earlier because namespaces need the AppEngineExtension to work. - } - - @Test - void testSavingKeyTwiceInOneCall() { - assertThrows( - IllegalArgumentException.class, - () -> ofy().transact(() -> auditedOfy().save().entities(someObject, someObject))); - } - - /** Simple entity class with lifecycle callbacks. */ - @com.googlecode.objectify.annotation.Entity - public static class LifecycleObject extends ImmutableObject { - - @Parent Key parent = getCrossTldKey(); - - @Id long id = 1; - - boolean onLoadCalled; - boolean onSaveCalled; - - @OnLoad - public void load() { - onLoadCalled = true; - } - - @OnSave - public void save() { - onSaveCalled = true; - } - } - - @Test - void testLifecycleCallbacks_loadFromEntity() { - auditedOfy().factory().register(LifecycleObject.class); - LifecycleObject object = new LifecycleObject(); - Entity entity = auditedOfy().save().toEntity(object); - assertThat(object.onSaveCalled).isTrue(); - assertThat(auditedOfy().load().fromEntity(entity).onLoadCalled).isTrue(); - } - - @Test - void testLifecycleCallbacks_loadFromDatastore() { - auditedOfy().factory().register(LifecycleObject.class); - final LifecycleObject object = new LifecycleObject(); - ofy().transact(() -> auditedOfy().save().entity(object).now()); - assertThat(object.onSaveCalled).isTrue(); - auditedOfy().clearSessionCache(); - assertThat(auditedOfy().load().entity(object).now().onLoadCalled).isTrue(); - } - - /** Avoid regressions of b/21309102 where transaction time did not change on each retry. */ - @Test - void testTransact_getsNewTimestampOnEachTry() { - ofy() - .transact( - new Runnable() { - - DateTime firstAttemptTime; - - @Override - public void run() { - if (firstAttemptTime == null) { - // Sleep a bit to ensure that the next attempt is at a new millisecond. - firstAttemptTime = ofy().getTransactionTime(); - sleepUninterruptibly(java.time.Duration.ofMillis(10)); - throw new ConcurrentModificationException(); - } - assertThat(ofy().getTransactionTime()).isGreaterThan(firstAttemptTime); - } - }); - } - - @Test - void testTransact_transientFailureException_retries() { - assertThat( - ofy() - .transact( - new Supplier() { - - int count = 0; - - @Override - public Integer get() { - count++; - if (count == 3) { - return count; - } - throw new TransientFailureException(""); - } - })) - .isEqualTo(3); - } - - @Test - void testTransact_datastoreTimeoutException_noManifest_retries() { - assertThat( - ofy() - .transact( - new Supplier() { - - int count = 0; - - @Override - public Integer get() { - // We don't write anything in this transaction, so there is no commit log - // manifest. - // Therefore it's always safe to retry since nothing got written. - count++; - if (count == 3) { - return count; - } - throw new DatastoreTimeoutException(""); - } - })) - .isEqualTo(3); - } - - @Test - void testTransact_datastoreTimeoutException_manifestNotWrittenToDatastore_retries() { - assertThat( - ofy() - .transact( - new Supplier() { - - int count = 0; - - @Override - public Integer get() { - // There will be something in the manifest now, but it won't be committed if - // we throw. - auditedOfy().save().entity(someObject.asHistoryEntry()); - count++; - if (count == 3) { - return count; - } - throw new DatastoreTimeoutException(""); - } - })) - .isEqualTo(3); - } - - @Test - void testTransact_datastoreTimeoutException_manifestWrittenToDatastore_returnsSuccess() { - // A work unit that throws if it is ever retried. - Supplier work = - new Supplier() { - boolean firstCallToVrun = true; - - @Override - public Void get() { - if (firstCallToVrun) { - firstCallToVrun = false; - auditedOfy().save().entity(someObject.asHistoryEntry()); - return null; - } - fail("Shouldn't have retried."); - return null; - } - }; - // A commit logged work that throws on the first attempt to get its result. - CommitLoggedWork commitLoggedWork = - new CommitLoggedWork(work, new SystemClock()) { - boolean firstCallToGetResult = true; - - @Override - public Void getResult() { - if (firstCallToGetResult) { - firstCallToGetResult = false; - throw new DatastoreTimeoutException(""); - } - return null; - } - }; - // Despite the DatastoreTimeoutException in the first call to getResult(), this should succeed - // without retrying. If a retry is triggered, the test should fail due to the call to fail(). - auditedOfy().transactCommitLoggedWork(commitLoggedWork); - } - - void doReadOnlyRetryTest(final RuntimeException e) { - assertThat( - ofy() - .transactNewReadOnly( - new Supplier() { - - int count = 0; - - @Override - public Integer get() { - count++; - if (count == 3) { - return count; - } - throw new TransientFailureException(""); - } - })) - .isEqualTo(3); - } - - @Test - void testTransactNewReadOnly_transientFailureException_retries() { - doReadOnlyRetryTest(new TransientFailureException("")); - } - - @Test - void testTransactNewReadOnly_datastoreTimeoutException_retries() { - doReadOnlyRetryTest(new DatastoreTimeoutException("")); - } - - @Test - void testTransactNewReadOnly_datastoreFailureException_retries() { - doReadOnlyRetryTest(new DatastoreFailureException("")); - } - - @Test - void test_getBaseEntityClassFromEntityOrKey_regularEntity() { - Contact contact = newContact("testcontact"); - assertThat(getBaseEntityClassFromEntityOrKey(contact)).isEqualTo(Contact.class); - assertThat(getBaseEntityClassFromEntityOrKey(Key.create(contact))).isEqualTo(Contact.class); - } - - @Test - void test_getBaseEntityClassFromEntityOrKey_unregisteredEntity() { - IllegalStateException thrown = - assertThrows( - IllegalStateException.class, - () -> getBaseEntityClassFromEntityOrKey(new SystemClock())); - assertThat(thrown).hasMessageThat().contains("SystemClock"); - } - - @Test - void test_getBaseEntityClassFromEntityOrKey_unregisteredEntityKey() { - IllegalArgumentException thrown = - assertThrows( - IllegalArgumentException.class, - () -> - getBaseEntityClassFromEntityOrKey( - Key.create( - com.google.appengine.api.datastore.KeyFactory.createKey( - "UnknownKind", 1)))); - assertThat(thrown).hasMessageThat().contains("UnknownKind"); - } - - @Test - void test_doWithFreshSessionCache() { - auditedOfy().saveWithoutBackup().entity(someObject.asHistoryEntry()).now(); - final HistoryEntry modifiedObject = - someObject.asBuilder().setModificationTime(END_OF_TIME).build(); - // Mutate the saved objected, bypassing the Objectify session cache. - getDatastoreService() - .put(auditedOfy().saveWithoutBackup().toEntity(modifiedObject.asHistoryEntry())); - // Normal loading should come from the session cache and shouldn't reflect the mutation. - assertThat(auditedOfy().load().entity(someObject).now()).isEqualTo(someObject.asHistoryEntry()); - // Loading inside doWithFreshSessionCache() should reflect the mutation. - boolean ran = - auditedOfy() - .doWithFreshSessionCache( - () -> { - assertAboutImmutableObjects() - .that(auditedOfy().load().entity(someObject).now()) - .isEqualExceptFields(modifiedObject, "contactBase"); - return true; - }); - assertThat(ran).isTrue(); - // Test the normal loading again to verify that we've restored the original session unchanged. - assertThat(auditedOfy().load().entity(someObject).now()).isEqualTo(someObject.asHistoryEntry()); - } -} diff --git a/core/src/test/java/google/registry/persistence/DomainHistoryVKeyTest.java b/core/src/test/java/google/registry/persistence/DomainHistoryVKeyTest.java index 0d1c7b912..1ee271790 100644 --- a/core/src/test/java/google/registry/persistence/DomainHistoryVKeyTest.java +++ b/core/src/test/java/google/registry/persistence/DomainHistoryVKeyTest.java @@ -15,20 +15,16 @@ package google.registry.persistence; import static com.google.common.truth.Truth.assertThat; -import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; -import com.googlecode.objectify.annotation.Parent; import google.registry.model.ImmutableObject; -import google.registry.model.common.EntityGroupRoot; import google.registry.model.domain.Domain; import google.registry.model.domain.DomainHistory.DomainHistoryId; import google.registry.model.reporting.HistoryEntry; import google.registry.testing.AppEngineExtension; -import javax.persistence.Transient; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -74,7 +70,6 @@ class DomainHistoryVKeyTest { @Entity @javax.persistence.Entity(name = "TestEntity") private static class TestEntity extends ImmutableObject { - @Transient @Parent Key parent = getCrossTldKey(); @Id @javax.persistence.Id String id = "id"; diff --git a/core/src/test/java/google/registry/persistence/VKeyTest.java b/core/src/test/java/google/registry/persistence/VKeyTest.java index f254ddd62..5a04c0392 100644 --- a/core/src/test/java/google/registry/persistence/VKeyTest.java +++ b/core/src/test/java/google/registry/persistence/VKeyTest.java @@ -162,18 +162,14 @@ class VKeyTest { void testStringify_sqlAndOfyVKey() { assertThat( VKey.create(TestObject.class, "foo", Key.create(TestObject.create("foo"))).stringify()) - .isEqualTo( - "kind:TestObject@sql:rO0ABXQAA2Zvbw@ofy:agR0ZXN0cjELEg9FbnRpdH" - + "lHcm91cFJvb3QiCWNyb3NzLXRsZAwLEgpUZXN0T2JqZWN0IgNmb28M"); + .isEqualTo("kind:TestObject@sql:rO0ABXQAA2Zvbw@ofy:agR0ZXN0chMLEgpUZXN0T2JqZWN0IgNmb28M"); } @Test void testStringify_asymmetricVKey() { assertThat( VKey.create(TestObject.class, "test", Key.create(TestObject.create("foo"))).stringify()) - .isEqualTo( - "kind:TestObject@sql:rO0ABXQABHRlc3Q@ofy:agR0ZXN0cjELEg9FbnRpd" - + "HlHcm91cFJvb3QiCWNyb3NzLXRsZAwLEgpUZXN0T2JqZWN0IgNmb28M"); + .isEqualTo("kind:TestObject@sql:rO0ABXQABHRlc3Q@ofy:agR0ZXN0chMLEgpUZXN0T2JqZWN0IgNmb28M"); } /** Test create() via different vkey string representations. */ diff --git a/core/src/test/java/google/registry/testing/TestObject.java b/core/src/test/java/google/registry/testing/TestObject.java index 7491a8a26..127d6904d 100644 --- a/core/src/test/java/google/registry/testing/TestObject.java +++ b/core/src/test/java/google/registry/testing/TestObject.java @@ -14,25 +14,18 @@ package google.registry.testing; -import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; - import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; -import com.googlecode.objectify.annotation.Parent; import google.registry.model.ImmutableObject; import google.registry.model.annotations.VirtualEntity; -import google.registry.model.common.EntityGroupRoot; import google.registry.persistence.VKey; -import javax.persistence.Transient; /** A test model object that can be persisted in any entity group. */ @Entity @javax.persistence.Entity public class TestObject extends ImmutableObject { - @Parent @Transient Key parent; - @Id @javax.persistence.Id String id; String field; @@ -58,14 +51,9 @@ public class TestObject extends ImmutableObject { } public static TestObject create(String id, String field) { - return create(id, field, getCrossTldKey()); - } - - public static TestObject create(String id, String field, Key parent) { TestObject instance = new TestObject(); instance.id = id; instance.field = field; - instance.parent = parent; return instance; } diff --git a/core/src/test/resources/google/registry/model/schema.txt b/core/src/test/resources/google/registry/model/schema.txt index 7ca42ceff..296ab0256 100644 --- a/core/src/test/resources/google/registry/model/schema.txt +++ b/core/src/test/resources/google/registry/model/schema.txt @@ -1,6 +1,3 @@ -class google.registry.model.common.EntityGroupRoot { - @Id java.lang.String id; -} class google.registry.model.common.GaeUserIdConverter { @Id long id; com.google.appengine.api.users.User user; @@ -391,7 +388,6 @@ enum google.registry.model.reporting.HistoryEntry$Type { } class google.registry.model.server.ServerSecret { @Id long id; - @Parent com.googlecode.objectify.Key parent; long leastSignificant; long mostSignificant; }