1
0
mirror of https://github.com/google/nomulus synced 2026-02-11 07:11:40 +00:00

Delete EntityGroupRoot (#1776)

This commit is contained in:
Lai Jiang
2022-09-08 12:54:10 -04:00
committed by GitHub
parent 49ade014ab
commit 312bc143d5
16 changed files with 5 additions and 562 deletions

View File

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

View File

@@ -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.
*
* <p>This means that the entity's <code>@Parent</code> field has to have the value of {@link
* EntityGroupRoot#getCrossTldKey}.
*/
@DeleteAfterMigration
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Inherited
public @interface InCrossTld {}

View File

@@ -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<EntityGroupRoot> parent = getCrossTldKey();
}

View File

@@ -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.
*
* <p>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.
*
* <p>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<EntityGroupRoot> 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");
}
}

View File

@@ -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 <T> VKey<T> restoreOfyFrom(Key<Domain> domainKey, VKey<T> 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<String> getSubordinateHosts() {
return nullToEmptyImmutableCopy(subordinateHosts);
}

View File

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

View File

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

View File

@@ -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.
*
* <p>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.
* <p>The resulting list is empty if there are no entities of this type.
*/
<T> ImmutableList<T> loadAllOf(Class<T> clazz);
/**
* Returns a stream of all entities of the given type that exist in the database.
*
* <p>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.
* <p>The resulting stream is empty if there are no entities of this type.
*/
<T> Stream<T> loadAllOfStream(Class<T> clazz);

View File

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

View File

@@ -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.
*
* <p>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 <T> void batchSave(Class<T> clazz) {
System.out.printf("Re-saving %s entities.\n", clazz.getSimpleName());
for (final Iterable<Key<T>> 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);
}
}
}