mirror of
https://github.com/google/nomulus.git
synced 2025-04-30 12:07:51 +02:00
Delete EppResourceIndex and EppResourceIndexBucket (#1774)
This commit is contained in:
parent
b8f1b2fc4f
commit
e6fde54966
17 changed files with 22 additions and 290 deletions
|
@ -44,7 +44,7 @@ import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hard deletes load-test Contacts, Hosts, their subordinate history entries, and the associated
|
* Hard deletes load-test Contacts, Hosts, their subordinate history entries, and the associated
|
||||||
* ForeignKey and EppResourceIndex entities.
|
* ForeignKey entities.
|
||||||
*
|
*
|
||||||
* <p>This only deletes contacts and hosts, NOT domains. To delete domains, use {@link
|
* <p>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
|
* DeleteProberDataAction} and pass it the TLD(s) that the load test domains were created on. Note
|
||||||
|
|
|
@ -53,7 +53,7 @@ import org.joda.time.Duration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all prober {@link Domain}s and their subordinate history entries, poll messages, and
|
* 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(
|
@Action(
|
||||||
service = Action.Service.BACKEND,
|
service = Action.Service.BACKEND,
|
||||||
|
|
|
@ -1482,11 +1482,6 @@ public final class RegistryConfig {
|
||||||
return CONFIG_SETTINGS.get().registryPolicy.defaultRegistrarWhoisServer;
|
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}. */
|
/** Returns the base retry duration that gets doubled after each failure within {@code Ofy}. */
|
||||||
public static Duration getBaseOfyRetryDuration() {
|
public static Duration getBaseOfyRetryDuration() {
|
||||||
return Duration.millis(CONFIG_SETTINGS.get().datastore.baseOfyRetryMillis);
|
return Duration.millis(CONFIG_SETTINGS.get().datastore.baseOfyRetryMillis);
|
||||||
|
|
|
@ -108,7 +108,6 @@ public class RegistryConfigSettings {
|
||||||
|
|
||||||
/** Configuration for Cloud Datastore. */
|
/** Configuration for Cloud Datastore. */
|
||||||
public static class Datastore {
|
public static class Datastore {
|
||||||
public int eppResourceIndexBucketsNum;
|
|
||||||
public int baseOfyRetryMillis;
|
public int baseOfyRetryMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,10 +183,6 @@ registryPolicy:
|
||||||
requireSslCertificates: true
|
requireSslCertificates: true
|
||||||
|
|
||||||
datastore:
|
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
|
# Milliseconds that Objectify waits to retry a Datastore transaction (this
|
||||||
# doubles after each failure).
|
# doubles after each failure).
|
||||||
baseOfyRetryMillis: 100
|
baseOfyRetryMillis: 100
|
||||||
|
|
|
@ -23,7 +23,6 @@ import static google.registry.model.IdService.allocateId;
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import google.registry.config.RegistryConfig.Config;
|
import google.registry.config.RegistryConfig.Config;
|
||||||
import google.registry.flows.EppException;
|
import google.registry.flows.EppException;
|
||||||
import google.registry.flows.ExtensionManager;
|
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.eppinput.ResourceCommand;
|
||||||
import google.registry.model.eppoutput.CreateData.ContactCreateData;
|
import google.registry.model.eppoutput.CreateData.ContactCreateData;
|
||||||
import google.registry.model.eppoutput.EppResponse;
|
import google.registry.model.eppoutput.EppResponse;
|
||||||
import google.registry.model.index.EppResourceIndex;
|
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
|
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -95,11 +93,7 @@ public final class ContactCreateFlow implements TransactionalFlow {
|
||||||
.setType(HistoryEntry.Type.CONTACT_CREATE)
|
.setType(HistoryEntry.Type.CONTACT_CREATE)
|
||||||
.setXmlBytes(null) // We don't want to store contact details in the history entry.
|
.setXmlBytes(null) // We don't want to store contact details in the history entry.
|
||||||
.setContact(newContact);
|
.setContact(newContact);
|
||||||
tm().insertAll(
|
tm().insertAll(ImmutableSet.of(newContact, historyBuilder.build()));
|
||||||
ImmutableSet.of(
|
|
||||||
newContact,
|
|
||||||
historyBuilder.build(),
|
|
||||||
EppResourceIndex.create(Key.create(newContact))));
|
|
||||||
return responseBuilder
|
return responseBuilder
|
||||||
.setResData(ContactCreateData.create(newContact.getContactId(), now))
|
.setResData(ContactCreateData.create(newContact.getContactId(), now))
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -59,7 +59,6 @@ import com.google.auto.value.AutoValue;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.net.InternetDomainName;
|
import com.google.common.net.InternetDomainName;
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import google.registry.dns.DnsQueue;
|
import google.registry.dns.DnsQueue;
|
||||||
import google.registry.flows.EppException;
|
import google.registry.flows.EppException;
|
||||||
import google.registry.flows.EppException.CommandUseErrorException;
|
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.eppinput.ResourceCommand;
|
||||||
import google.registry.model.eppoutput.CreateData.DomainCreateData;
|
import google.registry.model.eppoutput.CreateData.DomainCreateData;
|
||||||
import google.registry.model.eppoutput.EppResponse;
|
import google.registry.model.eppoutput.EppResponse;
|
||||||
import google.registry.model.index.EppResourceIndex;
|
|
||||||
import google.registry.model.poll.PendingActionNotificationResponse.DomainPendingActionNotificationResponse;
|
import google.registry.model.poll.PendingActionNotificationResponse.DomainPendingActionNotificationResponse;
|
||||||
import google.registry.model.poll.PollMessage;
|
import google.registry.model.poll.PollMessage;
|
||||||
import google.registry.model.poll.PollMessage.Autorenew;
|
import google.registry.model.poll.PollMessage.Autorenew;
|
||||||
|
@ -404,10 +402,7 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
||||||
entitiesToSave.add(
|
entitiesToSave.add(
|
||||||
createNameCollisionOneTimePollMessage(targetId, domainHistory, registrarId, now));
|
createNameCollisionOneTimePollMessage(targetId, domainHistory, registrarId, now));
|
||||||
}
|
}
|
||||||
entitiesToSave.add(
|
entitiesToSave.add(domain, domainHistory);
|
||||||
domain,
|
|
||||||
domainHistory,
|
|
||||||
EppResourceIndex.create(Key.create(domain)));
|
|
||||||
if (allocationToken.isPresent()
|
if (allocationToken.isPresent()
|
||||||
&& TokenType.SINGLE_USE.equals(allocationToken.get().getTokenType())) {
|
&& TokenType.SINGLE_USE.equals(allocationToken.get().getTokenType())) {
|
||||||
entitiesToSave.add(
|
entitiesToSave.add(
|
||||||
|
|
|
@ -27,7 +27,6 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
|
||||||
import static google.registry.util.CollectionUtils.isNullOrEmpty;
|
import static google.registry.util.CollectionUtils.isNullOrEmpty;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import google.registry.config.RegistryConfig.Config;
|
import google.registry.config.RegistryConfig.Config;
|
||||||
import google.registry.dns.DnsQueue;
|
import google.registry.dns.DnsQueue;
|
||||||
import google.registry.flows.EppException;
|
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.Host;
|
||||||
import google.registry.model.host.HostCommand.Create;
|
import google.registry.model.host.HostCommand.Create;
|
||||||
import google.registry.model.host.HostHistory;
|
import google.registry.model.host.HostHistory;
|
||||||
import google.registry.model.index.EppResourceIndex;
|
|
||||||
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
|
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -106,7 +104,7 @@ public final class HostCreateFlow implements TransactionalFlow {
|
||||||
DateTime now = tm().getTransactionTime();
|
DateTime now = tm().getTransactionTime();
|
||||||
verifyResourceDoesNotExist(Host.class, targetId, now, registrarId);
|
verifyResourceDoesNotExist(Host.class, targetId, now, registrarId);
|
||||||
// The superordinate domain of the host object if creating an in-bailiwick host, or null if
|
// 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.
|
// we can detect error conditions earlier.
|
||||||
Optional<Domain> superordinateDomain =
|
Optional<Domain> superordinateDomain =
|
||||||
lookupSuperordinateDomain(validateHostName(targetId), now);
|
lookupSuperordinateDomain(validateHostName(targetId), now);
|
||||||
|
@ -130,11 +128,7 @@ public final class HostCreateFlow implements TransactionalFlow {
|
||||||
.setSuperordinateDomain(superordinateDomain.map(Domain::createVKey).orElse(null))
|
.setSuperordinateDomain(superordinateDomain.map(Domain::createVKey).orElse(null))
|
||||||
.build();
|
.build();
|
||||||
historyBuilder.setType(HOST_CREATE).setHost(newHost);
|
historyBuilder.setType(HOST_CREATE).setHost(newHost);
|
||||||
ImmutableSet<ImmutableObject> entitiesToSave =
|
ImmutableSet<ImmutableObject> entitiesToSave = ImmutableSet.of(newHost, historyBuilder.build());
|
||||||
ImmutableSet.of(
|
|
||||||
newHost,
|
|
||||||
historyBuilder.build(),
|
|
||||||
EppResourceIndex.create(Key.create(newHost)));
|
|
||||||
if (superordinateDomain.isPresent()) {
|
if (superordinateDomain.isPresent()) {
|
||||||
tm().update(
|
tm().update(
|
||||||
superordinateDomain
|
superordinateDomain
|
||||||
|
@ -152,14 +146,14 @@ public final class HostCreateFlow implements TransactionalFlow {
|
||||||
|
|
||||||
/** Subordinate hosts must have an ip address. */
|
/** Subordinate hosts must have an ip address. */
|
||||||
static class SubordinateHostMustHaveIpException extends RequiredParameterMissingException {
|
static class SubordinateHostMustHaveIpException extends RequiredParameterMissingException {
|
||||||
public SubordinateHostMustHaveIpException() {
|
SubordinateHostMustHaveIpException() {
|
||||||
super("Subordinate hosts must have an ip address");
|
super("Subordinate hosts must have an ip address");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** External hosts must not have ip addresses. */
|
/** External hosts must not have ip addresses. */
|
||||||
static class UnexpectedExternalHostIpException extends ParameterValueRangeErrorException {
|
static class UnexpectedExternalHostIpException extends ParameterValueRangeErrorException {
|
||||||
public UnexpectedExternalHostIpException() {
|
UnexpectedExternalHostIpException() {
|
||||||
super("External hosts must not have ip addresses");
|
super("External hosts must not have ip addresses");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,6 @@ import google.registry.model.domain.Domain;
|
||||||
import google.registry.model.domain.DomainHistory;
|
import google.registry.model.domain.DomainHistory;
|
||||||
import google.registry.model.host.Host;
|
import google.registry.model.host.Host;
|
||||||
import google.registry.model.host.HostHistory;
|
import google.registry.model.host.HostHistory;
|
||||||
import google.registry.model.index.EppResourceIndex;
|
|
||||||
import google.registry.model.index.EppResourceIndexBucket;
|
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
/** Sets of classes of the Objectify-registered entities in use throughout the model. */
|
/** Sets of classes of the Objectify-registered entities in use throughout the model. */
|
||||||
|
@ -38,8 +36,6 @@ public final class EntityClasses {
|
||||||
ContactHistory.class,
|
ContactHistory.class,
|
||||||
Domain.class,
|
Domain.class,
|
||||||
DomainHistory.class,
|
DomainHistory.class,
|
||||||
EppResourceIndex.class,
|
|
||||||
EppResourceIndexBucket.class,
|
|
||||||
GaeUserIdConverter.class,
|
GaeUserIdConverter.class,
|
||||||
HistoryEntry.class,
|
HistoryEntry.class,
|
||||||
Host.class,
|
Host.class,
|
||||||
|
|
|
@ -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<EppResourceIndexBucket> bucket;
|
|
||||||
|
|
||||||
/** Although this field holds a {@link Key} it is named "reference" for historical reasons. */
|
|
||||||
Key<? extends EppResource> reference;
|
|
||||||
|
|
||||||
@Index String kind;
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKind() {
|
|
||||||
return kind;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Key<? extends EppResource> getKey() {
|
|
||||||
return reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public Key<EppResourceIndexBucket> getBucket() {
|
|
||||||
return bucket;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public static <T extends EppResource> EppResourceIndex create(
|
|
||||||
Key<EppResourceIndexBucket> bucket, Key<T> 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 <T extends EppResource> EppResourceIndex create(Key<T> resourceKey) {
|
|
||||||
return create(EppResourceIndexBucket.getBucketKey(resourceKey), resourceKey);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<? extends EppResource> 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<EppResourceIndexBucket> getBucketKey(Key<? extends EppResource> resourceKey) {
|
|
||||||
return Key.create(EppResourceIndexBucket.class, getBucketIdFromEppResource(resourceKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the specified numbered bucket key. */
|
|
||||||
public static Key<EppResourceIndexBucket> getBucketKey(int bucketId) {
|
|
||||||
return Key.create(EppResourceIndexBucket.class, bucketId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the keys to all buckets. */
|
|
||||||
public static Iterable<Key<EppResourceIndexBucket>> getAllBuckets() {
|
|
||||||
ImmutableList.Builder<Key<EppResourceIndexBucket>> builder = new ImmutableList.Builder<>();
|
|
||||||
for (int bucketId = 1; bucketId <= getEppResourceIndexBucketCount(); bucketId++) {
|
|
||||||
builder.add(getBucketKey(bucketId));
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -30,7 +30,6 @@ import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Streams;
|
import com.google.common.collect.Streams;
|
||||||
import com.google.common.flogger.FluentLogger;
|
import com.google.common.flogger.FluentLogger;
|
||||||
import google.registry.model.ImmutableObject;
|
import google.registry.model.ImmutableObject;
|
||||||
import google.registry.model.index.EppResourceIndex;
|
|
||||||
import google.registry.persistence.JpaRetries;
|
import google.registry.persistence.JpaRetries;
|
||||||
import google.registry.persistence.VKey;
|
import google.registry.persistence.VKey;
|
||||||
import google.registry.util.Clock;
|
import google.registry.util.Clock;
|
||||||
|
@ -74,14 +73,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||||
private static final Retrier retrier = new Retrier(new SystemSleeper(), 3);
|
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<Class<? extends ImmutableObject>> IGNORED_ENTITY_CLASSES =
|
|
||||||
ImmutableSet.of(EppResourceIndex.class);
|
|
||||||
|
|
||||||
// EntityManagerFactory is thread safe.
|
// EntityManagerFactory is thread safe.
|
||||||
private final EntityManagerFactory emf;
|
private final EntityManagerFactory emf;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
@ -267,9 +258,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||||
@Override
|
@Override
|
||||||
public void insert(Object entity) {
|
public void insert(Object entity) {
|
||||||
checkArgumentNotNull(entity, "entity must be specified");
|
checkArgumentNotNull(entity, "entity must be specified");
|
||||||
if (isEntityOfIgnoredClass(entity)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
assertInTransaction();
|
assertInTransaction();
|
||||||
transactionInfo.get().insertObject(entity);
|
transactionInfo.get().insertObject(entity);
|
||||||
}
|
}
|
||||||
|
@ -289,9 +277,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||||
@Override
|
@Override
|
||||||
public void put(Object entity) {
|
public void put(Object entity) {
|
||||||
checkArgumentNotNull(entity, "entity must be specified");
|
checkArgumentNotNull(entity, "entity must be specified");
|
||||||
if (isEntityOfIgnoredClass(entity)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
assertInTransaction();
|
assertInTransaction();
|
||||||
transactionInfo.get().updateObject(entity);
|
transactionInfo.get().updateObject(entity);
|
||||||
}
|
}
|
||||||
|
@ -315,9 +300,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||||
@Override
|
@Override
|
||||||
public void update(Object entity) {
|
public void update(Object entity) {
|
||||||
checkArgumentNotNull(entity, "entity must be specified");
|
checkArgumentNotNull(entity, "entity must be specified");
|
||||||
if (isEntityOfIgnoredClass(entity)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
assertInTransaction();
|
assertInTransaction();
|
||||||
checkArgument(exists(entity), "Given entity does not exist");
|
checkArgument(exists(entity), "Given entity does not exist");
|
||||||
transactionInfo.get().updateObject(entity);
|
transactionInfo.get().updateObject(entity);
|
||||||
|
@ -472,9 +454,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||||
private int internalDelete(VKey<?> key) {
|
private int internalDelete(VKey<?> key) {
|
||||||
checkArgumentNotNull(key, "key must be specified");
|
checkArgumentNotNull(key, "key must be specified");
|
||||||
assertInTransaction();
|
assertInTransaction();
|
||||||
if (IGNORED_ENTITY_CLASSES.contains(key.getKind())) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EntityType<?> entityType = getEntityType(key.getKind());
|
EntityType<?> entityType = getEntityType(key.getKind());
|
||||||
ImmutableSet<EntityId> entityIds = getEntityIdsFromSqlKey(entityType, key.getSqlKey());
|
ImmutableSet<EntityId> entityIds = getEntityIdsFromSqlKey(entityType, key.getSqlKey());
|
||||||
String sql =
|
String sql =
|
||||||
|
@ -498,9 +477,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||||
@Override
|
@Override
|
||||||
public <T> T delete(T entity) {
|
public <T> T delete(T entity) {
|
||||||
checkArgumentNotNull(entity, "entity must be specified");
|
checkArgumentNotNull(entity, "entity must be specified");
|
||||||
if (isEntityOfIgnoredClass(entity)) {
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
assertInTransaction();
|
assertInTransaction();
|
||||||
T managedEntity = entity;
|
T managedEntity = entity;
|
||||||
if (!getEntityManager().contains(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<EntityId> getEntityIdsFromEntity(
|
private static ImmutableSet<EntityId> getEntityIdsFromEntity(
|
||||||
EntityType<?> entityType, Object entity) {
|
EntityType<?> entityType, Object entity) {
|
||||||
if (entityType.hasSingleIdAttribute()) {
|
if (entityType.hasSingleIdAttribute()) {
|
||||||
|
@ -615,12 +587,12 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the field definition from clazz or any superclass. */
|
/** 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 {
|
try {
|
||||||
// Note that we have to use getDeclaredField() for this, getField() just finds public fields.
|
// Note that we have to use getDeclaredField() for this, getField() just finds public fields.
|
||||||
return clazz.getDeclaredField(fieldName);
|
return clazz.getDeclaredField(fieldName);
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
Class base = clazz.getSuperclass();
|
Class<?> base = clazz.getSuperclass();
|
||||||
if (base != null) {
|
if (base != null) {
|
||||||
return getField(base, fieldName);
|
return getField(base, fieldName);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -48,7 +48,6 @@ import google.registry.model.common.Cursor.CursorType;
|
||||||
import google.registry.model.contact.Contact;
|
import google.registry.model.contact.Contact;
|
||||||
import google.registry.model.domain.Domain;
|
import google.registry.model.domain.Domain;
|
||||||
import google.registry.model.host.Host;
|
import google.registry.model.host.Host;
|
||||||
import google.registry.model.index.EppResourceIndex;
|
|
||||||
import google.registry.model.rde.RdeMode;
|
import google.registry.model.rde.RdeMode;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
import google.registry.persistence.PersistenceModule.JpaTransactionManagerType;
|
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
|
* the initial query for the history entry running at {@code READ_COMMITTED} transaction isolation
|
||||||
* level.
|
* level.
|
||||||
*
|
*
|
||||||
* <p>This is also true in Datastore because:
|
|
||||||
*
|
|
||||||
* <ol>
|
|
||||||
* <li>{@code EppResource} queries are strongly consistent thanks to {@link EppResourceIndex}
|
|
||||||
* <li>{@code EppResource} entities are rewinded to the point-in-time of the watermark
|
|
||||||
* </ol>
|
|
||||||
*
|
|
||||||
* <p>Here's what's not deterministic:
|
* <p>Here's what's not deterministic:
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
|
|
|
@ -18,7 +18,6 @@ import static com.google.common.truth.Truth.assertThat;
|
||||||
import static com.google.common.truth.Truth.assertWithMessage;
|
import static com.google.common.truth.Truth.assertWithMessage;
|
||||||
import static com.google.common.truth.Truth8.assertThat;
|
import static com.google.common.truth.Truth8.assertThat;
|
||||||
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
|
||||||
import static google.registry.testing.DatabaseHelper.createTld;
|
import static google.registry.testing.DatabaseHelper.createTld;
|
||||||
import static google.registry.testing.DatabaseHelper.loadByEntitiesIfPresent;
|
import static google.registry.testing.DatabaseHelper.loadByEntitiesIfPresent;
|
||||||
import static google.registry.testing.DatabaseHelper.loadByEntity;
|
import static google.registry.testing.DatabaseHelper.loadByEntity;
|
||||||
|
@ -30,12 +29,10 @@ import static google.registry.testing.DatabaseHelper.persistResource;
|
||||||
import static google.registry.testing.DatabaseHelper.persistSimpleResource;
|
import static google.registry.testing.DatabaseHelper.persistSimpleResource;
|
||||||
import static google.registry.testing.TaskQueueHelper.assertDnsTasksEnqueued;
|
import static google.registry.testing.TaskQueueHelper.assertDnsTasksEnqueued;
|
||||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
|
||||||
import static org.joda.time.DateTimeZone.UTC;
|
import static org.joda.time.DateTimeZone.UTC;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import google.registry.config.RegistryEnvironment;
|
import google.registry.config.RegistryEnvironment;
|
||||||
import google.registry.dns.DnsQueue;
|
import google.registry.dns.DnsQueue;
|
||||||
import google.registry.model.ImmutableObject;
|
import google.registry.model.ImmutableObject;
|
||||||
|
@ -43,8 +40,6 @@ import google.registry.model.billing.BillingEvent;
|
||||||
import google.registry.model.billing.BillingEvent.Reason;
|
import google.registry.model.billing.BillingEvent.Reason;
|
||||||
import google.registry.model.domain.Domain;
|
import google.registry.model.domain.Domain;
|
||||||
import google.registry.model.domain.DomainHistory;
|
import google.registry.model.domain.DomainHistory;
|
||||||
import google.registry.model.index.EppResourceIndex;
|
|
||||||
import google.registry.model.index.ForeignKeyIndex;
|
|
||||||
import google.registry.model.poll.PollMessage;
|
import google.registry.model.poll.PollMessage;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
import google.registry.model.tld.Registry;
|
import google.registry.model.tld.Registry;
|
||||||
|
@ -279,8 +274,7 @@ class DeleteProberDataActionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persists and returns a domain and a descendant history entry, billing event, and poll message,
|
* Persists and returns a domain and a descendant history entry, billing event, and poll message.
|
||||||
* along with the ForeignKeyIndex and EppResourceIndex.
|
|
||||||
*/
|
*/
|
||||||
private static Set<ImmutableObject> persistDomainAndDescendants(String fqdn) {
|
private static Set<ImmutableObject> persistDomainAndDescendants(String fqdn) {
|
||||||
Domain domain = persistDeletedDomain(fqdn, DELETION_TIME);
|
Domain domain = persistDeletedDomain(fqdn, DELETION_TIME);
|
||||||
|
@ -318,11 +312,6 @@ class DeleteProberDataActionTest {
|
||||||
.add(historyEntry)
|
.add(historyEntry)
|
||||||
.add(billingEvent)
|
.add(billingEvent)
|
||||||
.add(pollMessage);
|
.add(pollMessage);
|
||||||
if (tm().isOfy()) {
|
|
||||||
builder
|
|
||||||
.add(ForeignKeyIndex.load(Domain.class, fqdn, START_OF_TIME))
|
|
||||||
.add(loadByEntity(EppResourceIndex.create(Key.create(domain))));
|
|
||||||
}
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,6 @@ import google.registry.model.contact.Contact;
|
||||||
import google.registry.model.domain.Domain;
|
import google.registry.model.domain.Domain;
|
||||||
import google.registry.model.domain.DomainHistory;
|
import google.registry.model.domain.DomainHistory;
|
||||||
import google.registry.model.host.Host;
|
import google.registry.model.host.Host;
|
||||||
import google.registry.model.index.EppResourceIndex;
|
|
||||||
import google.registry.model.index.EppResourceIndexBucket;
|
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
import google.registry.testing.TestObject;
|
import google.registry.testing.TestObject;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -43,11 +41,8 @@ public class ClassPathManagerTest {
|
||||||
assertThat(ClassPathManager.getClass("Host")).isEqualTo(Host.class);
|
assertThat(ClassPathManager.getClass("Host")).isEqualTo(Host.class);
|
||||||
assertThat(ClassPathManager.getClass("Contact")).isEqualTo(Contact.class);
|
assertThat(ClassPathManager.getClass("Contact")).isEqualTo(Contact.class);
|
||||||
assertThat(ClassPathManager.getClass("GaeUserIdConverter")).isEqualTo(GaeUserIdConverter.class);
|
assertThat(ClassPathManager.getClass("GaeUserIdConverter")).isEqualTo(GaeUserIdConverter.class);
|
||||||
assertThat(ClassPathManager.getClass("EppResourceIndexBucket"))
|
|
||||||
.isEqualTo(EppResourceIndexBucket.class);
|
|
||||||
assertThat(ClassPathManager.getClass("Domain")).isEqualTo(Domain.class);
|
assertThat(ClassPathManager.getClass("Domain")).isEqualTo(Domain.class);
|
||||||
assertThat(ClassPathManager.getClass("HistoryEntry")).isEqualTo(HistoryEntry.class);
|
assertThat(ClassPathManager.getClass("HistoryEntry")).isEqualTo(HistoryEntry.class);
|
||||||
assertThat(ClassPathManager.getClass("EppResourceIndex")).isEqualTo(EppResourceIndex.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -84,11 +79,8 @@ public class ClassPathManagerTest {
|
||||||
assertThat(ClassPathManager.getClassName(Contact.class)).isEqualTo("Contact");
|
assertThat(ClassPathManager.getClassName(Contact.class)).isEqualTo("Contact");
|
||||||
assertThat(ClassPathManager.getClassName(GaeUserIdConverter.class))
|
assertThat(ClassPathManager.getClassName(GaeUserIdConverter.class))
|
||||||
.isEqualTo("GaeUserIdConverter");
|
.isEqualTo("GaeUserIdConverter");
|
||||||
assertThat(ClassPathManager.getClassName(EppResourceIndexBucket.class))
|
|
||||||
.isEqualTo("EppResourceIndexBucket");
|
|
||||||
assertThat(ClassPathManager.getClassName(Domain.class)).isEqualTo("Domain");
|
assertThat(ClassPathManager.getClassName(Domain.class)).isEqualTo("Domain");
|
||||||
assertThat(ClassPathManager.getClassName(HistoryEntry.class)).isEqualTo("HistoryEntry");
|
assertThat(ClassPathManager.getClassName(HistoryEntry.class)).isEqualTo("HistoryEntry");
|
||||||
assertThat(ClassPathManager.getClassName(EppResourceIndex.class)).isEqualTo("EppResourceIndex");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -51,7 +51,6 @@ import static org.joda.money.CurrencyUnit.USD;
|
||||||
|
|
||||||
import com.google.common.base.Ascii;
|
import com.google.common.base.Ascii;
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Supplier;
|
|
||||||
import com.google.common.collect.ImmutableCollection;
|
import com.google.common.collect.ImmutableCollection;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -59,7 +58,6 @@ import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableSortedMap;
|
import com.google.common.collect.ImmutableSortedMap;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.net.InetAddresses;
|
import com.google.common.net.InetAddresses;
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import google.registry.dns.writer.VoidDnsWriter;
|
import google.registry.dns.writer.VoidDnsWriter;
|
||||||
import google.registry.model.Buildable;
|
import google.registry.model.Buildable;
|
||||||
import google.registry.model.EppResource;
|
import google.registry.model.EppResource;
|
||||||
|
@ -88,8 +86,6 @@ import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
|
||||||
import google.registry.model.eppcommon.StatusValue;
|
import google.registry.model.eppcommon.StatusValue;
|
||||||
import google.registry.model.eppcommon.Trid;
|
import google.registry.model.eppcommon.Trid;
|
||||||
import google.registry.model.host.Host;
|
import google.registry.model.host.Host;
|
||||||
import google.registry.model.index.EppResourceIndex;
|
|
||||||
import google.registry.model.index.EppResourceIndexBucket;
|
|
||||||
import google.registry.model.poll.PollMessage;
|
import google.registry.model.poll.PollMessage;
|
||||||
import google.registry.model.pricing.StaticPremiumListPricingEngine;
|
import google.registry.model.pricing.StaticPremiumListPricingEngine;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
|
@ -119,6 +115,7 @@ import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import org.joda.money.CurrencyUnit;
|
import org.joda.money.CurrencyUnit;
|
||||||
import org.joda.money.Money;
|
import org.joda.money.Money;
|
||||||
|
@ -127,7 +124,7 @@ import org.joda.time.DateTimeZone;
|
||||||
import org.joda.time.Duration;
|
import org.joda.time.Duration;
|
||||||
|
|
||||||
/** Static utils for setting up test resources. */
|
/** Static utils for setting up test resources. */
|
||||||
public class DatabaseHelper {
|
public final class DatabaseHelper {
|
||||||
|
|
||||||
// If the clock is defined, it will always be advanced by one millsecond after a transaction.
|
// If the clock is defined, it will always be advanced by one millsecond after a transaction.
|
||||||
private static FakeClock clock;
|
private static FakeClock clock;
|
||||||
|
@ -321,10 +318,8 @@ public class DatabaseHelper {
|
||||||
/** Persists a domain and enqueues a LORDN task of the appropriate type for it. */
|
/** Persists a domain and enqueues a LORDN task of the appropriate type for it. */
|
||||||
public static Domain persistDomainAndEnqueueLordn(final Domain domain) {
|
public static Domain persistDomainAndEnqueueLordn(final Domain domain) {
|
||||||
final Domain persistedDomain = persistResource(domain);
|
final Domain persistedDomain = persistResource(domain);
|
||||||
/**
|
// Calls {@link LordnTaskUtils#enqueueDomainTask} wrapped in a transaction so that the
|
||||||
* Calls {@link LordnTaskUtils#enqueueDomainTask} wrapped in a transaction so that the
|
// transaction time is set correctly.
|
||||||
* transaction time is set correctly.
|
|
||||||
*/
|
|
||||||
tm().transactNew(() -> LordnTaskUtils.enqueueDomainTask(persistedDomain));
|
tm().transactNew(() -> LordnTaskUtils.enqueueDomainTask(persistedDomain));
|
||||||
maybeAdvanceClock();
|
maybeAdvanceClock();
|
||||||
return persistedDomain;
|
return persistedDomain;
|
||||||
|
@ -995,8 +990,7 @@ public class DatabaseHelper {
|
||||||
saver.accept(resource);
|
saver.accept(resource);
|
||||||
if (resource instanceof EppResource) {
|
if (resource instanceof EppResource) {
|
||||||
EppResource eppResource = (EppResource) resource;
|
EppResource eppResource = (EppResource) resource;
|
||||||
persistEppResourceExtras(
|
persistEppResourceExtras(eppResource, saver);
|
||||||
eppResource, EppResourceIndex.create(Key.create(eppResource)), saver);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tm().put(resource);
|
tm().put(resource);
|
||||||
|
@ -1004,11 +998,10 @@ public class DatabaseHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <R extends EppResource> void persistEppResourceExtras(
|
private static <R extends EppResource> void persistEppResourceExtras(
|
||||||
R resource, EppResourceIndex index, Consumer<ImmutableObject> saver) {
|
R resource, Consumer<ImmutableObject> saver) {
|
||||||
assertWithMessage("Cannot persist an EppResource with a missing repoId in tests")
|
assertWithMessage("Cannot persist an EppResource with a missing repoId in tests")
|
||||||
.that(resource.getRepoId())
|
.that(resource.getRepoId())
|
||||||
.isNotEmpty();
|
.isNotEmpty();
|
||||||
saver.accept(index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Persists an object in the DB for tests. */
|
/** Persists an object in the DB for tests. */
|
||||||
|
@ -1026,25 +1019,6 @@ public class DatabaseHelper {
|
||||||
return tm().transact(() -> tm().loadByEntity(resource));
|
return tm().transact(() -> tm().loadByEntity(resource));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Persists an EPP resource with the {@link EppResourceIndex} always going into bucket one. */
|
|
||||||
public static <R extends EppResource> R persistEppResourceInFirstBucket(final R resource) {
|
|
||||||
final EppResourceIndex eppResourceIndex =
|
|
||||||
EppResourceIndex.create(Key.create(EppResourceIndexBucket.class, 1), Key.create(resource));
|
|
||||||
tm().transact(
|
|
||||||
() -> {
|
|
||||||
if (tm().isOfy()) {
|
|
||||||
Consumer<ImmutableObject> saver = tm()::put;
|
|
||||||
saver.accept(resource);
|
|
||||||
persistEppResourceExtras(resource, eppResourceIndex, saver);
|
|
||||||
} else {
|
|
||||||
tm().put(resource);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
maybeAdvanceClock();
|
|
||||||
tm().clearSessionCache();
|
|
||||||
return tm().transact(() -> tm().loadByEntity(resource));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Persists the specified resources to the DB. */
|
/** Persists the specified resources to the DB. */
|
||||||
public static <R extends ImmutableObject> void persistResources(final Iterable<R> resources) {
|
public static <R extends ImmutableObject> void persistResources(final Iterable<R> resources) {
|
||||||
for (R resource : resources) {
|
for (R resource : resources) {
|
||||||
|
@ -1070,7 +1044,7 @@ public class DatabaseHelper {
|
||||||
* <p><b>Warning:</b> If you call this multiple times in a single test, you need to inject Ofy's
|
* <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.
|
* clock field and forward it by a millisecond between each subsequent call.
|
||||||
*
|
*
|
||||||
* @see #persistResource(Object)
|
* @see #persistResource(ImmutableObject)
|
||||||
*/
|
*/
|
||||||
public static <R extends EppResource> R persistEppResource(final R resource) {
|
public static <R extends EppResource> R persistEppResource(final R resource) {
|
||||||
checkState(!tm().inTransaction());
|
checkState(!tm().inTransaction());
|
||||||
|
@ -1095,7 +1069,7 @@ public class DatabaseHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all of the history entries that are parented off the given EppResource, casted to the
|
* Returns all of the history entries that are parented off the given EppResource, cast to the
|
||||||
* corresponding subclass.
|
* corresponding subclass.
|
||||||
*/
|
*/
|
||||||
public static <T extends HistoryEntry> List<T> getHistoryEntries(
|
public static <T extends HistoryEntry> List<T> getHistoryEntries(
|
||||||
|
@ -1116,7 +1090,7 @@ public class DatabaseHelper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all of the history entries that are parented off the given EppResource with the given
|
* Returns all of the history entries that are parented off the given EppResource with the given
|
||||||
* type and casted to the corresponding subclass.
|
* type and cast to the corresponding subclass.
|
||||||
*/
|
*/
|
||||||
public static <T extends HistoryEntry> ImmutableList<T> getHistoryEntriesOfType(
|
public static <T extends HistoryEntry> ImmutableList<T> getHistoryEntriesOfType(
|
||||||
EppResource resource, final HistoryEntry.Type type, Class<T> subclazz) {
|
EppResource resource, final HistoryEntry.Type type, Class<T> subclazz) {
|
||||||
|
@ -1135,8 +1109,8 @@ public class DatabaseHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the only history entry of the given type, casted to the corresponding subtype, and
|
* Returns the only history entry of the given type, cast to the corresponding subtype, and throws
|
||||||
* throws an AssertionError if there are zero or more than one.
|
* an AssertionError if there are zero or more than one.
|
||||||
*/
|
*/
|
||||||
public static <T extends HistoryEntry> T getOnlyHistoryEntryOfType(
|
public static <T extends HistoryEntry> T getOnlyHistoryEntryOfType(
|
||||||
EppResource resource, final HistoryEntry.Type type, Class<T> subclazz) {
|
EppResource resource, final HistoryEntry.Type type, Class<T> subclazz) {
|
||||||
|
|
|
@ -138,15 +138,6 @@ class google.registry.model.host.HostHistory {
|
||||||
java.lang.String reason;
|
java.lang.String reason;
|
||||||
org.joda.time.DateTime modificationTime;
|
org.joda.time.DateTime modificationTime;
|
||||||
}
|
}
|
||||||
class google.registry.model.index.EppResourceIndex {
|
|
||||||
@Id java.lang.String id;
|
|
||||||
@Parent com.googlecode.objectify.Key<google.registry.model.index.EppResourceIndexBucket> bucket;
|
|
||||||
com.googlecode.objectify.Key<? extends google.registry.model.EppResource> reference;
|
|
||||||
java.lang.String kind;
|
|
||||||
}
|
|
||||||
class google.registry.model.index.EppResourceIndexBucket {
|
|
||||||
@Id long bucketId;
|
|
||||||
}
|
|
||||||
class google.registry.model.reporting.HistoryEntry {
|
class google.registry.model.reporting.HistoryEntry {
|
||||||
@Id java.lang.Long id;
|
@Id java.lang.Long id;
|
||||||
@Parent com.googlecode.objectify.Key<? extends google.registry.model.EppResource> parent;
|
@Parent com.googlecode.objectify.Key<? extends google.registry.model.EppResource> parent;
|
||||||
|
|
Loading…
Add table
Reference in a new issue