diff --git a/core/src/main/java/google/registry/batch/DeleteLoadTestDataAction.java b/core/src/main/java/google/registry/batch/DeleteLoadTestDataAction.java index cb2b87edd..c8f2307af 100644 --- a/core/src/main/java/google/registry/batch/DeleteLoadTestDataAction.java +++ b/core/src/main/java/google/registry/batch/DeleteLoadTestDataAction.java @@ -44,7 +44,7 @@ import javax.inject.Inject; /** * Hard deletes load-test Contacts, Hosts, their subordinate history entries, and the associated - * ForeignKey and EppResourceIndex entities. + * ForeignKey entities. * *

This only deletes contacts and hosts, NOT domains. To delete domains, use {@link * DeleteProberDataAction} and pass it the TLD(s) that the load test domains were created on. Note diff --git a/core/src/main/java/google/registry/batch/DeleteProberDataAction.java b/core/src/main/java/google/registry/batch/DeleteProberDataAction.java index d4f8bbeaf..a58a68beb 100644 --- a/core/src/main/java/google/registry/batch/DeleteProberDataAction.java +++ b/core/src/main/java/google/registry/batch/DeleteProberDataAction.java @@ -53,7 +53,7 @@ import org.joda.time.Duration; /** * Deletes all prober {@link Domain}s and their subordinate history entries, poll messages, and - * billing events, along with their ForeignKeyDomainIndex and EppResourceIndex entities. + * billing events, along with their ForeignKeyDomainIndex entities. */ @Action( service = Action.Service.BACKEND, diff --git a/core/src/main/java/google/registry/config/RegistryConfig.java b/core/src/main/java/google/registry/config/RegistryConfig.java index 773222ced..53459d42e 100644 --- a/core/src/main/java/google/registry/config/RegistryConfig.java +++ b/core/src/main/java/google/registry/config/RegistryConfig.java @@ -1482,11 +1482,6 @@ public final class RegistryConfig { return CONFIG_SETTINGS.get().registryPolicy.defaultRegistrarWhoisServer; } - /** Returns the number of {@code EppResourceIndex} buckets to be used. */ - public static int getEppResourceIndexBucketCount() { - return CONFIG_SETTINGS.get().datastore.eppResourceIndexBucketsNum; - } - /** Returns the base retry duration that gets doubled after each failure within {@code Ofy}. */ public static Duration getBaseOfyRetryDuration() { return Duration.millis(CONFIG_SETTINGS.get().datastore.baseOfyRetryMillis); diff --git a/core/src/main/java/google/registry/config/RegistryConfigSettings.java b/core/src/main/java/google/registry/config/RegistryConfigSettings.java index e027d2884..e9ab135f7 100644 --- a/core/src/main/java/google/registry/config/RegistryConfigSettings.java +++ b/core/src/main/java/google/registry/config/RegistryConfigSettings.java @@ -108,7 +108,6 @@ public class RegistryConfigSettings { /** Configuration for Cloud Datastore. */ public static class Datastore { - public int eppResourceIndexBucketsNum; public int baseOfyRetryMillis; } diff --git a/core/src/main/java/google/registry/config/files/default-config.yaml b/core/src/main/java/google/registry/config/files/default-config.yaml index 65fee09e3..e43252e60 100644 --- a/core/src/main/java/google/registry/config/files/default-config.yaml +++ b/core/src/main/java/google/registry/config/files/default-config.yaml @@ -183,10 +183,6 @@ registryPolicy: requireSslCertificates: true datastore: - # Number of EPP resource index buckets in Datastore. Don’t change after - # initial install. - eppResourceIndexBucketsNum: 997 - # Milliseconds that Objectify waits to retry a Datastore transaction (this # doubles after each failure). baseOfyRetryMillis: 100 diff --git a/core/src/main/java/google/registry/flows/contact/ContactCreateFlow.java b/core/src/main/java/google/registry/flows/contact/ContactCreateFlow.java index 47a50a79b..da5020954 100644 --- a/core/src/main/java/google/registry/flows/contact/ContactCreateFlow.java +++ b/core/src/main/java/google/registry/flows/contact/ContactCreateFlow.java @@ -23,7 +23,6 @@ import static google.registry.model.IdService.allocateId; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import com.google.common.collect.ImmutableSet; -import com.googlecode.objectify.Key; import google.registry.config.RegistryConfig.Config; import google.registry.flows.EppException; import google.registry.flows.ExtensionManager; @@ -40,7 +39,6 @@ import google.registry.model.domain.metadata.MetadataExtension; import google.registry.model.eppinput.ResourceCommand; import google.registry.model.eppoutput.CreateData.ContactCreateData; import google.registry.model.eppoutput.EppResponse; -import google.registry.model.index.EppResourceIndex; import google.registry.model.reporting.HistoryEntry; import google.registry.model.reporting.IcannReportingTypes.ActivityReportField; import javax.inject.Inject; @@ -95,11 +93,7 @@ public final class ContactCreateFlow implements TransactionalFlow { .setType(HistoryEntry.Type.CONTACT_CREATE) .setXmlBytes(null) // We don't want to store contact details in the history entry. .setContact(newContact); - tm().insertAll( - ImmutableSet.of( - newContact, - historyBuilder.build(), - EppResourceIndex.create(Key.create(newContact)))); + tm().insertAll(ImmutableSet.of(newContact, historyBuilder.build())); return responseBuilder .setResData(ContactCreateData.create(newContact.getContactId(), now)) .build(); diff --git a/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java b/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java index 1ddc34ae0..0bf91e8ff 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java @@ -59,7 +59,6 @@ import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.net.InternetDomainName; -import com.googlecode.objectify.Key; import google.registry.dns.DnsQueue; import google.registry.flows.EppException; import google.registry.flows.EppException.CommandUseErrorException; @@ -105,7 +104,6 @@ import google.registry.model.eppinput.EppInput; import google.registry.model.eppinput.ResourceCommand; import google.registry.model.eppoutput.CreateData.DomainCreateData; import google.registry.model.eppoutput.EppResponse; -import google.registry.model.index.EppResourceIndex; import google.registry.model.poll.PendingActionNotificationResponse.DomainPendingActionNotificationResponse; import google.registry.model.poll.PollMessage; import google.registry.model.poll.PollMessage.Autorenew; @@ -404,10 +402,7 @@ public final class DomainCreateFlow implements TransactionalFlow { entitiesToSave.add( createNameCollisionOneTimePollMessage(targetId, domainHistory, registrarId, now)); } - entitiesToSave.add( - domain, - domainHistory, - EppResourceIndex.create(Key.create(domain))); + entitiesToSave.add(domain, domainHistory); if (allocationToken.isPresent() && TokenType.SINGLE_USE.equals(allocationToken.get().getTokenType())) { entitiesToSave.add( diff --git a/core/src/main/java/google/registry/flows/host/HostCreateFlow.java b/core/src/main/java/google/registry/flows/host/HostCreateFlow.java index 8149e3b29..b1c170f31 100644 --- a/core/src/main/java/google/registry/flows/host/HostCreateFlow.java +++ b/core/src/main/java/google/registry/flows/host/HostCreateFlow.java @@ -27,7 +27,6 @@ import static google.registry.persistence.transaction.TransactionManagerFactory. import static google.registry.util.CollectionUtils.isNullOrEmpty; import com.google.common.collect.ImmutableSet; -import com.googlecode.objectify.Key; import google.registry.config.RegistryConfig.Config; import google.registry.dns.DnsQueue; import google.registry.flows.EppException; @@ -49,7 +48,6 @@ import google.registry.model.eppoutput.EppResponse; import google.registry.model.host.Host; import google.registry.model.host.HostCommand.Create; import google.registry.model.host.HostHistory; -import google.registry.model.index.EppResourceIndex; import google.registry.model.reporting.IcannReportingTypes.ActivityReportField; import java.util.Optional; import javax.inject.Inject; @@ -106,7 +104,7 @@ public final class HostCreateFlow implements TransactionalFlow { DateTime now = tm().getTransactionTime(); verifyResourceDoesNotExist(Host.class, targetId, now, registrarId); // The superordinate domain of the host object if creating an in-bailiwick host, or null if - // creating an external host. This is looked up before we actually create the Host object so + // creating an external host. This is looked up before we actually create the Host object, so // we can detect error conditions earlier. Optional superordinateDomain = lookupSuperordinateDomain(validateHostName(targetId), now); @@ -130,11 +128,7 @@ public final class HostCreateFlow implements TransactionalFlow { .setSuperordinateDomain(superordinateDomain.map(Domain::createVKey).orElse(null)) .build(); historyBuilder.setType(HOST_CREATE).setHost(newHost); - ImmutableSet entitiesToSave = - ImmutableSet.of( - newHost, - historyBuilder.build(), - EppResourceIndex.create(Key.create(newHost))); + ImmutableSet entitiesToSave = ImmutableSet.of(newHost, historyBuilder.build()); if (superordinateDomain.isPresent()) { tm().update( superordinateDomain @@ -152,14 +146,14 @@ public final class HostCreateFlow implements TransactionalFlow { /** Subordinate hosts must have an ip address. */ static class SubordinateHostMustHaveIpException extends RequiredParameterMissingException { - public SubordinateHostMustHaveIpException() { + SubordinateHostMustHaveIpException() { super("Subordinate hosts must have an ip address"); } } /** External hosts must not have ip addresses. */ static class UnexpectedExternalHostIpException extends ParameterValueRangeErrorException { - public UnexpectedExternalHostIpException() { + UnexpectedExternalHostIpException() { super("External hosts must not have ip addresses"); } } diff --git a/core/src/main/java/google/registry/model/EntityClasses.java b/core/src/main/java/google/registry/model/EntityClasses.java index 1879c6278..8594b8436 100644 --- a/core/src/main/java/google/registry/model/EntityClasses.java +++ b/core/src/main/java/google/registry/model/EntityClasses.java @@ -23,8 +23,6 @@ import google.registry.model.domain.Domain; import google.registry.model.domain.DomainHistory; import google.registry.model.host.Host; import google.registry.model.host.HostHistory; -import google.registry.model.index.EppResourceIndex; -import google.registry.model.index.EppResourceIndexBucket; import google.registry.model.reporting.HistoryEntry; /** Sets of classes of the Objectify-registered entities in use throughout the model. */ @@ -38,8 +36,6 @@ public final class EntityClasses { ContactHistory.class, Domain.class, DomainHistory.class, - EppResourceIndex.class, - EppResourceIndexBucket.class, GaeUserIdConverter.class, HistoryEntry.class, Host.class, diff --git a/core/src/main/java/google/registry/model/index/EppResourceIndex.java b/core/src/main/java/google/registry/model/index/EppResourceIndex.java deleted file mode 100644 index 8b78a3bc5..000000000 --- a/core/src/main/java/google/registry/model/index/EppResourceIndex.java +++ /dev/null @@ -1,79 +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.index; - -import static google.registry.util.TypeUtils.instantiate; - -import com.google.common.annotations.VisibleForTesting; -import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Entity; -import com.googlecode.objectify.annotation.Id; -import com.googlecode.objectify.annotation.Index; -import com.googlecode.objectify.annotation.Parent; -import google.registry.model.BackupGroupRoot; -import google.registry.model.EppResource; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.model.annotations.ReportedOn; -import google.registry.persistence.VKey; - -/** An index that allows for quick enumeration of all EppResource entities (e.g. via map reduce). */ -@ReportedOn -@Entity -@DeleteAfterMigration -public class EppResourceIndex extends BackupGroupRoot { - - @Id String id; - - @Parent Key bucket; - - /** Although this field holds a {@link Key} it is named "reference" for historical reasons. */ - Key reference; - - @Index String kind; - - public String getId() { - return id; - } - - public String getKind() { - return kind; - } - - public Key getKey() { - return reference; - } - - @VisibleForTesting - public Key getBucket() { - return bucket; - } - - @VisibleForTesting - public static EppResourceIndex create( - Key bucket, Key resourceKey) { - EppResourceIndex instance = instantiate(EppResourceIndex.class); - instance.reference = resourceKey; - instance.kind = resourceKey.getKind(); - // creates a web-safe key string, this value is never used - // TODO(b/211785379): remove unused id - instance.id = VKey.from(resourceKey).stringify(); - instance.bucket = bucket; - return instance; - } - - public static EppResourceIndex create(Key resourceKey) { - return create(EppResourceIndexBucket.getBucketKey(resourceKey), resourceKey); - } -} diff --git a/core/src/main/java/google/registry/model/index/EppResourceIndexBucket.java b/core/src/main/java/google/registry/model/index/EppResourceIndexBucket.java deleted file mode 100644 index 2f33d4299..000000000 --- a/core/src/main/java/google/registry/model/index/EppResourceIndexBucket.java +++ /dev/null @@ -1,68 +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.index; - -import static google.registry.config.RegistryConfig.getEppResourceIndexBucketCount; - -import com.google.common.collect.ImmutableList; -import com.google.common.hash.Hashing; -import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Entity; -import com.googlecode.objectify.annotation.Id; -import google.registry.model.EppResource; -import google.registry.model.ImmutableObject; -import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.model.annotations.VirtualEntity; - -/** A virtual entity to represent buckets to which EppResourceIndex objects are randomly added. */ -@Entity -@VirtualEntity -@DeleteAfterMigration -public class EppResourceIndexBucket extends ImmutableObject { - - @SuppressWarnings("unused") - @Id - private long bucketId; - - /** - * Deterministic function that returns a bucket id based on the resource's roid. - * NB: At the moment, nothing depends on this being deterministic, so we have the ability to - * change the number of buckets and utilize a random distribution once we do. - */ - private static long getBucketIdFromEppResource(Key resourceKey) { - int numBuckets = getEppResourceIndexBucketCount(); - // IDs can't be 0, so add 1 to the hash. - return Hashing.consistentHash(resourceKey.getName().hashCode(), numBuckets) + 1L; - } - - /** Gets a bucket key as a function of an EppResource to be indexed. */ - public static Key getBucketKey(Key resourceKey) { - return Key.create(EppResourceIndexBucket.class, getBucketIdFromEppResource(resourceKey)); - } - - /** Gets the specified numbered bucket key. */ - public static Key getBucketKey(int bucketId) { - return Key.create(EppResourceIndexBucket.class, bucketId); - } - - /** Returns the keys to all buckets. */ - public static Iterable> getAllBuckets() { - ImmutableList.Builder> builder = new ImmutableList.Builder<>(); - for (int bucketId = 1; bucketId <= getEppResourceIndexBucketCount(); bucketId++) { - builder.add(getBucketKey(bucketId)); - } - return builder.build(); - } -} diff --git a/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java b/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java index 28c33ed45..c2ea38d95 100644 --- a/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java +++ b/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java @@ -30,7 +30,6 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Streams; import com.google.common.flogger.FluentLogger; import google.registry.model.ImmutableObject; -import google.registry.model.index.EppResourceIndex; import google.registry.persistence.JpaRetries; import google.registry.persistence.VKey; import google.registry.util.Clock; @@ -74,14 +73,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private static final Retrier retrier = new Retrier(new SystemSleeper(), 3); - // The entity of classes in this set will be simply ignored when passed to modification - // operations, i.e. insert, put, update and delete. This is to help maintain a single code path - // when we switch from ofy to tm() for the database migration as we don't need have a condition - // to exclude the Datastore specific entities when the underlying tm() is jpaTm(). - // TODO(b/176108270): Remove this property after database migration. - private static final ImmutableSet> IGNORED_ENTITY_CLASSES = - ImmutableSet.of(EppResourceIndex.class); - // EntityManagerFactory is thread safe. private final EntityManagerFactory emf; private final Clock clock; @@ -267,9 +258,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager { @Override public void insert(Object entity) { checkArgumentNotNull(entity, "entity must be specified"); - if (isEntityOfIgnoredClass(entity)) { - return; - } assertInTransaction(); transactionInfo.get().insertObject(entity); } @@ -289,9 +277,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager { @Override public void put(Object entity) { checkArgumentNotNull(entity, "entity must be specified"); - if (isEntityOfIgnoredClass(entity)) { - return; - } assertInTransaction(); transactionInfo.get().updateObject(entity); } @@ -315,9 +300,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager { @Override public void update(Object entity) { checkArgumentNotNull(entity, "entity must be specified"); - if (isEntityOfIgnoredClass(entity)) { - return; - } assertInTransaction(); checkArgument(exists(entity), "Given entity does not exist"); transactionInfo.get().updateObject(entity); @@ -472,9 +454,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager { private int internalDelete(VKey key) { checkArgumentNotNull(key, "key must be specified"); assertInTransaction(); - if (IGNORED_ENTITY_CLASSES.contains(key.getKind())) { - return 0; - } EntityType entityType = getEntityType(key.getKind()); ImmutableSet entityIds = getEntityIdsFromSqlKey(entityType, key.getSqlKey()); String sql = @@ -498,9 +477,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager { @Override public T delete(T entity) { checkArgumentNotNull(entity, "entity must be specified"); - if (isEntityOfIgnoredClass(entity)) { - return entity; - } assertInTransaction(); T managedEntity = entity; if (!getEntityManager().contains(entity)) { @@ -549,10 +525,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager { } } - private static boolean isEntityOfIgnoredClass(Object entity) { - return IGNORED_ENTITY_CLASSES.contains(entity.getClass()); - } - private static ImmutableSet getEntityIdsFromEntity( EntityType entityType, Object entity) { if (entityType.hasSingleIdAttribute()) { @@ -615,12 +587,12 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager { } /** Gets the field definition from clazz or any superclass. */ - private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException { + private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException { try { // Note that we have to use getDeclaredField() for this, getField() just finds public fields. return clazz.getDeclaredField(fieldName); } catch (NoSuchFieldException e) { - Class base = clazz.getSuperclass(); + Class base = clazz.getSuperclass(); if (base != null) { return getField(base, fieldName); } else { diff --git a/core/src/main/java/google/registry/rde/RdeStagingAction.java b/core/src/main/java/google/registry/rde/RdeStagingAction.java index 1e788dc36..a5c0c9ed5 100644 --- a/core/src/main/java/google/registry/rde/RdeStagingAction.java +++ b/core/src/main/java/google/registry/rde/RdeStagingAction.java @@ -48,7 +48,6 @@ import google.registry.model.common.Cursor.CursorType; import google.registry.model.contact.Contact; import google.registry.model.domain.Domain; import google.registry.model.host.Host; -import google.registry.model.index.EppResourceIndex; import google.registry.model.rde.RdeMode; import google.registry.model.registrar.Registrar; import google.registry.persistence.PersistenceModule.JpaTransactionManagerType; @@ -169,13 +168,6 @@ import org.joda.time.Duration; * the initial query for the history entry running at {@code READ_COMMITTED} transaction isolation * level. * - *

This is also true in Datastore because: - * - *

    - *
  1. {@code EppResource} queries are strongly consistent thanks to {@link EppResourceIndex} - *
  2. {@code EppResource} entities are rewinded to the point-in-time of the watermark - *
- * *

Here's what's not deterministic: * *