mirror of
https://github.com/google/nomulus.git
synced 2025-04-30 03:57:51 +02:00
Remove Ofy support from Registry (#1688)
Also made some code quality changes based on IntelliJ suggestions on modified files.
This commit is contained in:
parent
9665ddbe70
commit
cb1957f01a
12 changed files with 57 additions and 163 deletions
|
@ -37,7 +37,6 @@ import google.registry.model.replay.ReplayGap;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
import google.registry.model.server.Lock;
|
import google.registry.model.server.Lock;
|
||||||
import google.registry.model.server.ServerSecret;
|
import google.registry.model.server.ServerSecret;
|
||||||
import google.registry.model.tld.Registry;
|
|
||||||
|
|
||||||
/** 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. */
|
||||||
@DeleteAfterMigration
|
@DeleteAfterMigration
|
||||||
|
@ -72,7 +71,6 @@ public final class EntityClasses {
|
||||||
PollMessage.OneTime.class,
|
PollMessage.OneTime.class,
|
||||||
RdeRevision.class,
|
RdeRevision.class,
|
||||||
Registrar.class,
|
Registrar.class,
|
||||||
Registry.class,
|
|
||||||
ReplayGap.class,
|
ReplayGap.class,
|
||||||
ServerSecret.class);
|
ServerSecret.class);
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ public final class Registries {
|
||||||
EntityManager entityManager = jpaTm().getEntityManager();
|
EntityManager entityManager = jpaTm().getEntityManager();
|
||||||
Stream<?> resultStream =
|
Stream<?> resultStream =
|
||||||
entityManager
|
entityManager
|
||||||
.createQuery("SELECT tldStrId, tldType FROM Tld")
|
.createQuery("SELECT tldStr, tldType FROM Tld")
|
||||||
.getResultStream();
|
.getResultStream();
|
||||||
return resultStream
|
return resultStream
|
||||||
.map(e -> ((Object[]) e))
|
.map(e -> ((Object[]) e))
|
||||||
|
|
|
@ -16,12 +16,9 @@ package google.registry.model.tld;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Predicates.equalTo;
|
|
||||||
import static com.google.common.base.Predicates.not;
|
|
||||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||||
import static com.google.common.collect.Maps.toMap;
|
import static com.google.common.collect.Maps.toMap;
|
||||||
import static google.registry.config.RegistryConfig.getSingletonCacheRefreshDuration;
|
import static google.registry.config.RegistryConfig.getSingletonCacheRefreshDuration;
|
||||||
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
|
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||||
|
@ -29,34 +26,22 @@ import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||||
import static org.joda.money.CurrencyUnit.USD;
|
import static org.joda.money.CurrencyUnit.USD;
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.CacheLoader;
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
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.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Ordering;
|
import com.google.common.collect.Ordering;
|
||||||
import com.google.common.collect.Range;
|
import com.google.common.collect.Range;
|
||||||
import com.google.common.net.InternetDomainName;
|
import com.google.common.net.InternetDomainName;
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import com.googlecode.objectify.annotation.Embed;
|
|
||||||
import com.googlecode.objectify.annotation.Entity;
|
|
||||||
import com.googlecode.objectify.annotation.Id;
|
|
||||||
import com.googlecode.objectify.annotation.Mapify;
|
|
||||||
import com.googlecode.objectify.annotation.OnSave;
|
|
||||||
import com.googlecode.objectify.annotation.Parent;
|
|
||||||
import google.registry.model.Buildable;
|
import google.registry.model.Buildable;
|
||||||
import google.registry.model.CacheUtils;
|
import google.registry.model.CacheUtils;
|
||||||
import google.registry.model.CacheUtils.AppEngineEnvironmentCacheLoader;
|
|
||||||
import google.registry.model.CreateAutoTimestamp;
|
import google.registry.model.CreateAutoTimestamp;
|
||||||
import google.registry.model.ImmutableObject;
|
import google.registry.model.ImmutableObject;
|
||||||
import google.registry.model.UnsafeSerializable;
|
import google.registry.model.UnsafeSerializable;
|
||||||
import google.registry.model.annotations.DeleteAfterMigration;
|
|
||||||
import google.registry.model.annotations.InCrossTld;
|
|
||||||
import google.registry.model.annotations.ReportedOn;
|
|
||||||
import google.registry.model.common.EntityGroupRoot;
|
|
||||||
import google.registry.model.common.TimedTransitionProperty;
|
import google.registry.model.common.TimedTransitionProperty;
|
||||||
import google.registry.model.common.TimedTransitionProperty.TimedTransition;
|
import google.registry.model.common.TimedTransitionProperty.TimedTransition;
|
||||||
import google.registry.model.domain.fee.BaseFee.FeeType;
|
import google.registry.model.domain.fee.BaseFee.FeeType;
|
||||||
|
@ -71,12 +56,14 @@ import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
import javax.persistence.Enumerated;
|
import javax.persistence.Enumerated;
|
||||||
import javax.persistence.PostLoad;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Transient;
|
import javax.persistence.PostPersist;
|
||||||
import org.hibernate.annotations.Columns;
|
import org.hibernate.annotations.Columns;
|
||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
import org.joda.money.CurrencyUnit;
|
import org.joda.money.CurrencyUnit;
|
||||||
|
@ -85,35 +72,16 @@ import org.joda.time.DateTime;
|
||||||
import org.joda.time.Duration;
|
import org.joda.time.Duration;
|
||||||
|
|
||||||
/** Persisted per-TLD configuration data. */
|
/** Persisted per-TLD configuration data. */
|
||||||
@ReportedOn
|
@Entity(name = "Tld")
|
||||||
@Entity
|
|
||||||
@javax.persistence.Entity(name = "Tld")
|
|
||||||
@InCrossTld
|
|
||||||
public class Registry extends ImmutableObject implements Buildable, UnsafeSerializable {
|
public class Registry extends ImmutableObject implements Buildable, UnsafeSerializable {
|
||||||
|
|
||||||
@Parent @Transient Key<EntityGroupRoot> parent = getCrossTldKey();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The canonical string representation of the TLD associated with this {@link Registry}, which is
|
* The canonical string representation of the TLD associated with this {@link Registry}, which is
|
||||||
* the standard ASCII for regular TLDs and punycoded ASCII for IDN TLDs.
|
* the standard ASCII for regular TLDs and punycoded ASCII for IDN TLDs.
|
||||||
*/
|
*/
|
||||||
@Id
|
@Id
|
||||||
@javax.persistence.Id
|
|
||||||
@Column(name = "tld_name", nullable = false)
|
@Column(name = "tld_name", nullable = false)
|
||||||
String tldStrId;
|
String tldStr;
|
||||||
|
|
||||||
/**
|
|
||||||
* A duplicate of {@link #tldStrId}, to simplify BigQuery reporting since the id field becomes
|
|
||||||
* {@code __key__.name} rather than being exported as a named field.
|
|
||||||
*/
|
|
||||||
@Transient String tldStr;
|
|
||||||
|
|
||||||
/** Sets the Datastore specific field, tldStr, when the entity is loaded from Cloud SQL */
|
|
||||||
@PostLoad
|
|
||||||
@DeleteAfterMigration
|
|
||||||
void postLoad() {
|
|
||||||
tldStr = tldStrId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The suffix that identifies roids as belonging to this specific tld, e.g. -HOW for .how. */
|
/** The suffix that identifies roids as belonging to this specific tld, e.g. -HOW for .how. */
|
||||||
String roidSuffix;
|
String roidSuffix;
|
||||||
|
@ -190,8 +158,8 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
* A transition to a TLD state at a specific time, for use in a TimedTransitionProperty. Public
|
* A transition to a TLD state at a specific time, for use in a TimedTransitionProperty. Public
|
||||||
* because App Engine's security manager requires this for instantiation via reflection.
|
* because App Engine's security manager requires this for instantiation via reflection.
|
||||||
*/
|
*/
|
||||||
@Embed
|
|
||||||
public static class TldStateTransition extends TimedTransition<TldState> {
|
public static class TldStateTransition extends TimedTransition<TldState> {
|
||||||
|
|
||||||
/** The TLD state. */
|
/** The TLD state. */
|
||||||
private TldState tldState;
|
private TldState tldState;
|
||||||
|
|
||||||
|
@ -211,8 +179,8 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
*
|
*
|
||||||
* <p>Public because App Engine's security manager requires this for instantiation via reflection.
|
* <p>Public because App Engine's security manager requires this for instantiation via reflection.
|
||||||
*/
|
*/
|
||||||
@Embed
|
|
||||||
public static class BillingCostTransition extends TimedTransition<Money> {
|
public static class BillingCostTransition extends TimedTransition<Money> {
|
||||||
|
|
||||||
/** The billing cost value. */
|
/** The billing cost value. */
|
||||||
private Money billingCost;
|
private Money billingCost;
|
||||||
|
|
||||||
|
@ -229,23 +197,24 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
|
|
||||||
/** Returns the registry for a given TLD, throwing if none exists. */
|
/** Returns the registry for a given TLD, throwing if none exists. */
|
||||||
public static Registry get(String tld) {
|
public static Registry get(String tld) {
|
||||||
Registry registry = CACHE.get(tld).orElse(null);
|
Registry maybeRegistry = CACHE.get(tld);
|
||||||
if (registry == null) {
|
if (maybeRegistry == null) {
|
||||||
throw new RegistryNotFoundException(tld);
|
throw new RegistryNotFoundException(tld);
|
||||||
|
} else {
|
||||||
|
return maybeRegistry;
|
||||||
}
|
}
|
||||||
return registry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the registry entities for the given TLD strings, throwing if any don't exist. */
|
/** Returns the registry entities for the given TLD strings, throwing if any don't exist. */
|
||||||
public static ImmutableSet<Registry> get(Set<String> tlds) {
|
public static ImmutableSet<Registry> get(Set<String> tlds) {
|
||||||
Map<String, Optional<Registry>> registries = CACHE.getAll(tlds);
|
Map<String, Registry> registries = CACHE.getAll(tlds);
|
||||||
ImmutableSet<String> missingRegistries =
|
ImmutableSet<String> missingRegistries =
|
||||||
registries.entrySet().stream()
|
registries.entrySet().stream()
|
||||||
.filter(e -> !e.getValue().isPresent())
|
.filter(e -> e.getValue() == null)
|
||||||
.map(Map.Entry::getKey)
|
.map(Map.Entry::getKey)
|
||||||
.collect(toImmutableSet());
|
.collect(toImmutableSet());
|
||||||
if (missingRegistries.isEmpty()) {
|
if (missingRegistries.isEmpty()) {
|
||||||
return registries.values().stream().map(Optional::get).collect(toImmutableSet());
|
return registries.values().stream().collect(toImmutableSet());
|
||||||
} else {
|
} else {
|
||||||
throw new RegistryNotFoundException(missingRegistries);
|
throw new RegistryNotFoundException(missingRegistries);
|
||||||
}
|
}
|
||||||
|
@ -257,45 +226,38 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
* <p>This is called automatically when the registry is saved. One should also call it when a
|
* <p>This is called automatically when the registry is saved. One should also call it when a
|
||||||
* registry is deleted.
|
* registry is deleted.
|
||||||
*/
|
*/
|
||||||
@OnSave
|
@PostPersist
|
||||||
public void invalidateInCache() {
|
public void invalidateInCache() {
|
||||||
CACHE.invalidate(tldStr);
|
CACHE.invalidate(tldStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A cache that loads the {@link Registry} for a given tld. */
|
/** A cache that loads the {@link Registry} for a given tld. */
|
||||||
private static final LoadingCache<String, Optional<Registry>> CACHE =
|
private static final LoadingCache<String, Registry> CACHE =
|
||||||
CacheUtils.newCacheBuilder(getSingletonCacheRefreshDuration())
|
CacheUtils.newCacheBuilder(getSingletonCacheRefreshDuration())
|
||||||
.build(
|
.build(
|
||||||
new AppEngineEnvironmentCacheLoader<String, Optional<Registry>>() {
|
new CacheLoader<String, Registry>() {
|
||||||
@Override
|
@Override
|
||||||
public Optional<Registry> load(final String tld) {
|
public Registry load(final String tld) {
|
||||||
// Enter a transaction-less context briefly; we don't want to enroll every TLD in
|
return tm().transact(() -> tm().loadByKeyIfPresent(createVKey(tld))).orElse(null);
|
||||||
// a transaction that might be wrapping this call.
|
|
||||||
return tm().doTransactionless(() -> tm().loadByKeyIfPresent(createVKey(tld)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Optional<Registry>> loadAll(Iterable<? extends String> tlds) {
|
public Map<String, Registry> loadAll(Iterable<? extends String> tlds) {
|
||||||
ImmutableMap<String, VKey<Registry>> keysMap =
|
ImmutableMap<String, VKey<Registry>> keysMap =
|
||||||
toMap(ImmutableSet.copyOf(tlds), Registry::createVKey);
|
toMap(ImmutableSet.copyOf(tlds), Registry::createVKey);
|
||||||
Map<VKey<? extends Registry>, Registry> entities =
|
Map<VKey<? extends Registry>, Registry> entities =
|
||||||
tm().doTransactionless(() -> tm().loadByKeys(keysMap.values()));
|
tm().transact(() -> tm().loadByKeysIfPresent(keysMap.values()));
|
||||||
return Maps.transformEntries(
|
return Maps.transformEntries(keysMap, (k, v) -> entities.getOrDefault(v, null));
|
||||||
keysMap, (k, v) -> Optional.ofNullable(entities.getOrDefault(v, null)));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
public static VKey<Registry> createVKey(String tld) {
|
public static VKey<Registry> createVKey(String tld) {
|
||||||
return VKey.create(Registry.class, tld, Key.create(getCrossTldKey(), Registry.class, tld));
|
return VKey.createSql(Registry.class, tld);
|
||||||
}
|
|
||||||
|
|
||||||
public static VKey<Registry> createVKey(Key<Registry> key) {
|
|
||||||
return createVKey(key.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VKey<Registry> createVKey() {
|
public VKey<Registry> createVKey() {
|
||||||
return VKey.createSql(Registry.class, this.tldStrId);
|
return VKey.createSql(Registry.class, tldStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -305,7 +267,7 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
* Map<String, PricingEngine>}.
|
* Map<String, PricingEngine>}.
|
||||||
*
|
*
|
||||||
* <p>Note that it used to be the canonical class name, hence the name of this field, but this
|
* <p>Note that it used to be the canonical class name, hence the name of this field, but this
|
||||||
* restriction has since been relaxed and it may now be any unique string.
|
* restriction has since been relaxed, and it may now be any unique string.
|
||||||
*/
|
*/
|
||||||
String pricingEngineClassName;
|
String pricingEngineClassName;
|
||||||
|
|
||||||
|
@ -323,7 +285,7 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
/**
|
/**
|
||||||
* The number of locks we allow at once for {@link google.registry.dns.PublishDnsUpdatesAction}.
|
* The number of locks we allow at once for {@link google.registry.dns.PublishDnsUpdatesAction}.
|
||||||
*
|
*
|
||||||
* <p>This should always be a positive integer- use 1 for TLD-wide locks. All {@link Registry}
|
* <p>This should always be a positive integer -- use 1 for TLD-wide locks. All {@link Registry}
|
||||||
* objects have this value default to 1.
|
* objects have this value default to 1.
|
||||||
*
|
*
|
||||||
* <p>WARNING: changing this parameter changes the lock name for subsequent DNS updates, and thus
|
* <p>WARNING: changing this parameter changes the lock name for subsequent DNS updates, and thus
|
||||||
|
@ -361,7 +323,7 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
String tldUnicode;
|
String tldUnicode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Id of the folder in drive used to public (export) information for this TLD.
|
* ID of the folder in drive used to public (export) information for this TLD.
|
||||||
*
|
*
|
||||||
* <p>This is optional; if not configured, then information won't be exported for this TLD.
|
* <p>This is optional; if not configured, then information won't be exported for this TLD.
|
||||||
*/
|
*/
|
||||||
|
@ -379,14 +341,13 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
* TLD. This applies to {@link TldType#TEST} TLDs as well.
|
* TLD. This applies to {@link TldType#TEST} TLDs as well.
|
||||||
*/
|
*/
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
boolean invoicingEnabled = false;
|
boolean invoicingEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A property that transitions to different TldStates at different times. Stored as a list of
|
* A property that transitions to different {@link TldState}s at different times. Stored as a list
|
||||||
* TldStateTransition embedded objects using the @Mapify annotation.
|
* of {@link TldStateTransition} embedded objects using the @Mapify annotation.
|
||||||
*/
|
*/
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
@Mapify(TimedTransitionProperty.TimeMapper.class)
|
|
||||||
TimedTransitionProperty<TldState, TldStateTransition> tldStateTransitions =
|
TimedTransitionProperty<TldState, TldStateTransition> tldStateTransitions =
|
||||||
TimedTransitionProperty.forMapify(DEFAULT_TLD_STATE, TldStateTransition.class);
|
TimedTransitionProperty.forMapify(DEFAULT_TLD_STATE, TldStateTransition.class);
|
||||||
|
|
||||||
|
@ -418,7 +379,7 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
* registry, the database should be queried for the entity with this name that has the largest
|
* registry, the database should be queried for the entity with this name that has the largest
|
||||||
* revision ID.
|
* revision ID.
|
||||||
*/
|
*/
|
||||||
@Column(name = "premium_list_name", nullable = true)
|
@Column(name = "premium_list_name")
|
||||||
String premiumListName;
|
String premiumListName;
|
||||||
|
|
||||||
/** Should RDE upload a nightly escrow deposit for this TLD? */
|
/** Should RDE upload a nightly escrow deposit for this TLD? */
|
||||||
|
@ -442,7 +403,7 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
Duration anchorTenantAddGracePeriodLength = DEFAULT_ANCHOR_TENANT_ADD_GRACE_PERIOD;
|
Duration anchorTenantAddGracePeriodLength = DEFAULT_ANCHOR_TENANT_ADD_GRACE_PERIOD;
|
||||||
|
|
||||||
/** The length of the auto renew grace period for this TLD. */
|
/** The length of the autorenew grace period for this TLD. */
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
Duration autoRenewGracePeriodLength = DEFAULT_AUTO_RENEW_GRACE_PERIOD;
|
Duration autoRenewGracePeriodLength = DEFAULT_AUTO_RENEW_GRACE_PERIOD;
|
||||||
|
|
||||||
|
@ -515,13 +476,11 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
* renewal to ensure transfers have a cost.
|
* renewal to ensure transfers have a cost.
|
||||||
*/
|
*/
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
@Mapify(TimedTransitionProperty.TimeMapper.class)
|
|
||||||
TimedTransitionProperty<Money, BillingCostTransition> renewBillingCostTransitions =
|
TimedTransitionProperty<Money, BillingCostTransition> renewBillingCostTransitions =
|
||||||
TimedTransitionProperty.forMapify(DEFAULT_RENEW_BILLING_COST, BillingCostTransition.class);
|
TimedTransitionProperty.forMapify(DEFAULT_RENEW_BILLING_COST, BillingCostTransition.class);
|
||||||
|
|
||||||
/** A property that tracks the EAP fee schedule (if any) for the TLD. */
|
/** A property that tracks the EAP fee schedule (if any) for the TLD. */
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
@Mapify(TimedTransitionProperty.TimeMapper.class)
|
|
||||||
TimedTransitionProperty<Money, BillingCostTransition> eapFeeSchedule =
|
TimedTransitionProperty<Money, BillingCostTransition> eapFeeSchedule =
|
||||||
TimedTransitionProperty.forMapify(DEFAULT_EAP_BILLING_COST, BillingCostTransition.class);
|
TimedTransitionProperty.forMapify(DEFAULT_EAP_BILLING_COST, BillingCostTransition.class);
|
||||||
|
|
||||||
|
@ -532,10 +491,10 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
DateTime claimsPeriodEnd = END_OF_TIME;
|
DateTime claimsPeriodEnd = END_OF_TIME;
|
||||||
|
|
||||||
/** An allow list of clients allowed to be used on domains on this TLD (ignored if empty). */
|
/** An allowlist of clients allowed to be used on domains on this TLD (ignored if empty). */
|
||||||
@Nullable Set<String> allowedRegistrantContactIds;
|
@Nullable Set<String> allowedRegistrantContactIds;
|
||||||
|
|
||||||
/** An allow list of hosts allowed to be used on domains on this TLD (ignored if empty). */
|
/** An allowlist of hosts allowed to be used on domains on this TLD (ignored if empty). */
|
||||||
@Nullable Set<String> allowedFullyQualifiedHostNames;
|
@Nullable Set<String> allowedFullyQualifiedHostNames;
|
||||||
|
|
||||||
public String getTldStr() {
|
public String getTldStr() {
|
||||||
|
@ -583,6 +542,7 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
return dnsPaused;
|
return dnsPaused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public String getDriveFolderId() {
|
public String getDriveFolderId() {
|
||||||
return driveFolderId;
|
return driveFolderId;
|
||||||
}
|
}
|
||||||
|
@ -628,7 +588,7 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use <code>PricingEngineProxy.getDomainCreateCost</code> instead of this to find the cost for a
|
* Use {@code PricingEngineProxy.getDomainCreateCost} instead of this to find the cost for a
|
||||||
* domain create.
|
* domain create.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@ -645,8 +605,8 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use <code>PricingEngineProxy.getDomainRenewCost</code> instead of this to find the cost for a
|
* Use {@code PricingEngineProxy.getDomainRenewCost} instead of this to find the cost for a domain
|
||||||
* domain renewal, and all derived costs (i.e. autorenews, transfers, and the per-domain part of a
|
* renewal, and all derived costs (i.e. autorenews, transfers, and the per-domain part of a
|
||||||
* restore cost).
|
* restore cost).
|
||||||
*/
|
*/
|
||||||
public Money getStandardRenewCost(DateTime now) {
|
public Money getStandardRenewCost(DateTime now) {
|
||||||
|
@ -756,7 +716,9 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
checkArgument(
|
checkArgument(
|
||||||
Ordering.natural()
|
Ordering.natural()
|
||||||
.isStrictlyOrdered(
|
.isStrictlyOrdered(
|
||||||
Iterables.filter(tldStatesMap.values(), not(equalTo(TldState.QUIET_PERIOD)))),
|
tldStatesMap.values().stream()
|
||||||
|
.filter(state -> !TldState.QUIET_PERIOD.equals(state))
|
||||||
|
.collect(Collectors.toList())),
|
||||||
"The TLD states are chronologically out of order");
|
"The TLD states are chronologically out of order");
|
||||||
getInstance().tldStateTransitions =
|
getInstance().tldStateTransitions =
|
||||||
TimedTransitionProperty.fromValueMap(tldStatesMap, TldStateTransition.class);
|
TimedTransitionProperty.fromValueMap(tldStatesMap, TldStateTransition.class);
|
||||||
|
@ -900,7 +862,7 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setPremiumList(@Nullable PremiumList premiumList) {
|
public Builder setPremiumList(@Nullable PremiumList premiumList) {
|
||||||
getInstance().premiumListName = (premiumList == null) ? null : premiumList.getName();
|
getInstance().premiumListName = premiumList == null ? null : premiumList.getName();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,7 +902,7 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Pattern ROID_SUFFIX_PATTERN = Pattern.compile("^[A-Z0-9_]{1,8}$");
|
private static final Pattern ROID_SUFFIX_PATTERN = Pattern.compile("^[A-Z\\d_]{1,8}$");
|
||||||
|
|
||||||
public Builder setRoidSuffix(String roidSuffix) {
|
public Builder setRoidSuffix(String roidSuffix) {
|
||||||
checkArgument(
|
checkArgument(
|
||||||
|
@ -1037,7 +999,7 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
checkArgument(
|
checkArgument(
|
||||||
instance.numDnsPublishLocks > 0,
|
instance.numDnsPublishLocks > 0,
|
||||||
"Number of DNS publish locks must be positive. Use 1 for TLD-wide locks.");
|
"Number of DNS publish locks must be positive. Use 1 for TLD-wide locks.");
|
||||||
instance.tldStrId = tldName;
|
instance.tldStr = tldName;
|
||||||
instance.tldUnicode = Idn.toUnicode(tldName);
|
instance.tldUnicode = Idn.toUnicode(tldName);
|
||||||
return super.build();
|
return super.build();
|
||||||
}
|
}
|
||||||
|
@ -1045,6 +1007,7 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
|
|
||||||
/** Exception to throw when no Registry entity is found for given TLD string(s). */
|
/** Exception to throw when no Registry entity is found for given TLD string(s). */
|
||||||
public static class RegistryNotFoundException extends RuntimeException {
|
public static class RegistryNotFoundException extends RuntimeException {
|
||||||
|
|
||||||
RegistryNotFoundException(ImmutableSet<String> tlds) {
|
RegistryNotFoundException(ImmutableSet<String> tlds) {
|
||||||
super("No registry object(s) found for " + Joiner.on(", ").join(tlds));
|
super("No registry object(s) found for " + Joiner.on(", ").join(tlds));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
SELECT b, r FROM BillingEvent b
|
SELECT b, r FROM BillingEvent b
|
||||||
JOIN Registrar r ON b.clientId = r.clientIdentifier
|
JOIN Registrar r ON b.clientId = r.clientIdentifier
|
||||||
JOIN Domain d ON b.domainRepoId = d.repoId
|
JOIN Domain d ON b.domainRepoId = d.repoId
|
||||||
JOIN Tld t ON t.tldStrId = d.tld
|
JOIN Tld t ON t.tldStr = d.tld
|
||||||
LEFT JOIN BillingCancellation c ON b.id = c.refOneTime.billingId
|
LEFT JOIN BillingCancellation c ON b.id = c.refOneTime.billingId
|
||||||
LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent = cr.refRecurring.billingId
|
LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent = cr.refRecurring.billingId
|
||||||
WHERE r.billingAccountMap IS NOT NULL
|
WHERE r.billingAccountMap IS NOT NULL
|
||||||
|
|
|
@ -371,7 +371,7 @@ class InvoicingPipelineTest {
|
||||||
+ "SELECT b, r FROM BillingEvent b\n"
|
+ "SELECT b, r FROM BillingEvent b\n"
|
||||||
+ "JOIN Registrar r ON b.clientId = r.clientIdentifier\n"
|
+ "JOIN Registrar r ON b.clientId = r.clientIdentifier\n"
|
||||||
+ "JOIN Domain d ON b.domainRepoId = d.repoId\n"
|
+ "JOIN Domain d ON b.domainRepoId = d.repoId\n"
|
||||||
+ "JOIN Tld t ON t.tldStrId = d.tld\n"
|
+ "JOIN Tld t ON t.tldStr = d.tld\n"
|
||||||
+ "LEFT JOIN BillingCancellation c ON b.id = c.refOneTime.billingId\n"
|
+ "LEFT JOIN BillingCancellation c ON b.id = c.refOneTime.billingId\n"
|
||||||
+ "LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent ="
|
+ "LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent ="
|
||||||
+ " cr.refRecurring.billingId\n"
|
+ " cr.refRecurring.billingId\n"
|
||||||
|
|
|
@ -39,7 +39,6 @@ import google.registry.model.replay.ReplayGap;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
import google.registry.model.server.Lock;
|
import google.registry.model.server.Lock;
|
||||||
import google.registry.model.server.ServerSecret;
|
import google.registry.model.server.ServerSecret;
|
||||||
import google.registry.model.tld.Registry;
|
|
||||||
import google.registry.testing.TestObject;
|
import google.registry.testing.TestObject;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@ -72,7 +71,6 @@ public class ClassPathManagerTest {
|
||||||
assertThat(ClassPathManager.getClass("GaeUserIdConverter")).isEqualTo(GaeUserIdConverter.class);
|
assertThat(ClassPathManager.getClass("GaeUserIdConverter")).isEqualTo(GaeUserIdConverter.class);
|
||||||
assertThat(ClassPathManager.getClass("EppResourceIndexBucket"))
|
assertThat(ClassPathManager.getClass("EppResourceIndexBucket"))
|
||||||
.isEqualTo(EppResourceIndexBucket.class);
|
.isEqualTo(EppResourceIndexBucket.class);
|
||||||
assertThat(ClassPathManager.getClass("Registry")).isEqualTo(Registry.class);
|
|
||||||
assertThat(ClassPathManager.getClass("EntityGroupRoot")).isEqualTo(EntityGroupRoot.class);
|
assertThat(ClassPathManager.getClass("EntityGroupRoot")).isEqualTo(EntityGroupRoot.class);
|
||||||
assertThat(ClassPathManager.getClass("Lock")).isEqualTo(Lock.class);
|
assertThat(ClassPathManager.getClass("Lock")).isEqualTo(Lock.class);
|
||||||
assertThat(ClassPathManager.getClass("DomainBase")).isEqualTo(DomainBase.class);
|
assertThat(ClassPathManager.getClass("DomainBase")).isEqualTo(DomainBase.class);
|
||||||
|
@ -132,7 +130,6 @@ public class ClassPathManagerTest {
|
||||||
.isEqualTo("GaeUserIdConverter");
|
.isEqualTo("GaeUserIdConverter");
|
||||||
assertThat(ClassPathManager.getClassName(EppResourceIndexBucket.class))
|
assertThat(ClassPathManager.getClassName(EppResourceIndexBucket.class))
|
||||||
.isEqualTo("EppResourceIndexBucket");
|
.isEqualTo("EppResourceIndexBucket");
|
||||||
assertThat(ClassPathManager.getClassName(Registry.class)).isEqualTo("Registry");
|
|
||||||
assertThat(ClassPathManager.getClassName(EntityGroupRoot.class)).isEqualTo("EntityGroupRoot");
|
assertThat(ClassPathManager.getClassName(EntityGroupRoot.class)).isEqualTo("EntityGroupRoot");
|
||||||
assertThat(ClassPathManager.getClassName(Lock.class)).isEqualTo("Lock");
|
assertThat(ClassPathManager.getClassName(Lock.class)).isEqualTo("Lock");
|
||||||
assertThat(ClassPathManager.getClassName(DomainBase.class)).isEqualTo("DomainBase");
|
assertThat(ClassPathManager.getClassName(DomainBase.class)).isEqualTo("DomainBase");
|
||||||
|
|
|
@ -28,7 +28,7 @@ import static google.registry.testing.DatabaseHelper.persistPremiumList;
|
||||||
import static google.registry.testing.DatabaseHelper.persistReservedList;
|
import static google.registry.testing.DatabaseHelper.persistReservedList;
|
||||||
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 google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
import static java.math.BigDecimal.ROUND_UNNECESSARY;
|
import static java.math.RoundingMode.UNNECESSARY;
|
||||||
import static org.joda.money.CurrencyUnit.EUR;
|
import static org.joda.money.CurrencyUnit.EUR;
|
||||||
import static org.joda.money.CurrencyUnit.USD;
|
import static org.joda.money.CurrencyUnit.USD;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
@ -77,8 +77,7 @@ public final class RegistryTest extends EntityTestCase {
|
||||||
Registry registry =
|
Registry registry =
|
||||||
Registry.get("tld").asBuilder().setReservedLists(rl15).setPremiumList(pl).build();
|
Registry.get("tld").asBuilder().setReservedLists(rl15).setPremiumList(pl).build();
|
||||||
tm().transact(() -> tm().put(registry));
|
tm().transact(() -> tm().put(registry));
|
||||||
Registry persisted =
|
Registry persisted = tm().transact(() -> tm().loadByKey(Registry.createVKey(registry.tldStr)));
|
||||||
tm().transact(() -> tm().loadByKey(Registry.createVKey(registry.tldStrId)));
|
|
||||||
assertThat(persisted).isEqualTo(registry);
|
assertThat(persisted).isEqualTo(registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,8 +93,7 @@ public final class RegistryTest extends EntityTestCase {
|
||||||
ReservedList rl15 = persistReservedList("tld-reserved15", "potato,FULLY_BLOCKED");
|
ReservedList rl15 = persistReservedList("tld-reserved15", "potato,FULLY_BLOCKED");
|
||||||
Registry registry = Registry.get("tld").asBuilder().setReservedLists(rl15).build();
|
Registry registry = Registry.get("tld").asBuilder().setReservedLists(rl15).build();
|
||||||
tm().transact(() -> tm().put(registry));
|
tm().transact(() -> tm().put(registry));
|
||||||
Registry persisted =
|
Registry persisted = tm().transact(() -> tm().loadByKey(Registry.createVKey(registry.tldStr)));
|
||||||
tm().transact(() -> tm().loadByKey(Registry.createVKey(registry.tldStrId)));
|
|
||||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,7 +580,7 @@ public final class RegistryTest extends EntityTestCase {
|
||||||
@TestOfyAndSql
|
@TestOfyAndSql
|
||||||
void testEapFee_undefined() {
|
void testEapFee_undefined() {
|
||||||
assertThat(Registry.get("tld").getEapFeeFor(fakeClock.nowUtc()).getCost())
|
assertThat(Registry.get("tld").getEapFeeFor(fakeClock.nowUtc()).getCost())
|
||||||
.isEqualTo(BigDecimal.ZERO.setScale(2, ROUND_UNNECESSARY));
|
.isEqualTo(BigDecimal.ZERO.setScale(2, UNNECESSARY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestOfyAndSql
|
@TestOfyAndSql
|
||||||
|
@ -602,7 +600,7 @@ public final class RegistryTest extends EntityTestCase {
|
||||||
assertThat(registry.getEapFeeFor(fakeClock.nowUtc()).getCost())
|
assertThat(registry.getEapFeeFor(fakeClock.nowUtc()).getCost())
|
||||||
.isEqualTo(new BigDecimal("100.00"));
|
.isEqualTo(new BigDecimal("100.00"));
|
||||||
assertThat(registry.getEapFeeFor(fakeClock.nowUtc().minusDays(2)).getCost())
|
assertThat(registry.getEapFeeFor(fakeClock.nowUtc().minusDays(2)).getCost())
|
||||||
.isEqualTo(BigDecimal.ZERO.setScale(2, ROUND_UNNECESSARY));
|
.isEqualTo(BigDecimal.ZERO.setScale(2, UNNECESSARY));
|
||||||
assertThat(registry.getEapFeeFor(fakeClock.nowUtc().plusDays(2)).getCost())
|
assertThat(registry.getEapFeeFor(fakeClock.nowUtc().plusDays(2)).getCost())
|
||||||
.isEqualTo(new BigDecimal("50.00"));
|
.isEqualTo(new BigDecimal("50.00"));
|
||||||
}
|
}
|
||||||
|
@ -626,7 +624,7 @@ public final class RegistryTest extends EntityTestCase {
|
||||||
assertThrows(
|
assertThrows(
|
||||||
IllegalArgumentException.class,
|
IllegalArgumentException.class,
|
||||||
() -> Registry.get("tld").asBuilder().setRoidSuffix("123456789"));
|
() -> Registry.get("tld").asBuilder().setRoidSuffix("123456789"));
|
||||||
assertThat(e).hasMessageThat().isEqualTo("ROID suffix must be in format ^[A-Z0-9_]{1,8}$");
|
assertThat(e).hasMessageThat().isEqualTo("ROID suffix must be in format ^[A-Z\\d_]{1,8}$");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestOfyAndSql
|
@TestOfyAndSql
|
||||||
|
|
|
@ -330,9 +330,7 @@ class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
|
||||||
"--registrar=blobio",
|
"--registrar=blobio",
|
||||||
"--email=contact@email.com",
|
"--email=contact@email.com",
|
||||||
"--certfile=" + getCertFilename()));
|
"--certfile=" + getCertFilename()));
|
||||||
assertThat(thrown)
|
assertThat(thrown).hasMessageThat().contains("VKey<Registry>(sql:blobio-sunrise)");
|
||||||
.hasMessageThat()
|
|
||||||
.contains("VKey<Registry>(sql:blobio-sunrise,ofy:blobio-sunrise)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -16,4 +16,3 @@ PollMessage
|
||||||
RdeRevision
|
RdeRevision
|
||||||
Recurring
|
Recurring
|
||||||
Registrar
|
Registrar
|
||||||
Registry
|
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
Registrar
|
Registrar
|
||||||
Registry
|
|
||||||
ServerSecret
|
ServerSecret
|
||||||
|
|
|
@ -13,4 +13,3 @@ OneTime
|
||||||
PollMessage
|
PollMessage
|
||||||
Recurring
|
Recurring
|
||||||
Registrar
|
Registrar
|
||||||
Registry
|
|
||||||
|
|
|
@ -652,63 +652,6 @@ class google.registry.model.server.ServerSecret {
|
||||||
long leastSignificant;
|
long leastSignificant;
|
||||||
long mostSignificant;
|
long mostSignificant;
|
||||||
}
|
}
|
||||||
class google.registry.model.tld.Registry {
|
|
||||||
@Id java.lang.String tldStrId;
|
|
||||||
@Parent com.googlecode.objectify.Key<google.registry.model.common.EntityGroupRoot> parent;
|
|
||||||
boolean dnsPaused;
|
|
||||||
boolean escrowEnabled;
|
|
||||||
boolean invoicingEnabled;
|
|
||||||
google.registry.model.CreateAutoTimestamp creationTime;
|
|
||||||
google.registry.model.common.TimedTransitionProperty<google.registry.model.tld.Registry$TldState, google.registry.model.tld.Registry$TldStateTransition> tldStateTransitions;
|
|
||||||
google.registry.model.common.TimedTransitionProperty<org.joda.money.Money, google.registry.model.tld.Registry$BillingCostTransition> eapFeeSchedule;
|
|
||||||
google.registry.model.common.TimedTransitionProperty<org.joda.money.Money, google.registry.model.tld.Registry$BillingCostTransition> renewBillingCostTransitions;
|
|
||||||
google.registry.model.tld.Registry$TldType tldType;
|
|
||||||
int numDnsPublishLocks;
|
|
||||||
java.lang.String driveFolderId;
|
|
||||||
java.lang.String lordnUsername;
|
|
||||||
java.lang.String premiumListName;
|
|
||||||
java.lang.String pricingEngineClassName;
|
|
||||||
java.lang.String roidSuffix;
|
|
||||||
java.lang.String tldStr;
|
|
||||||
java.lang.String tldUnicode;
|
|
||||||
java.util.Set<java.lang.String> allowedFullyQualifiedHostNames;
|
|
||||||
java.util.Set<java.lang.String> allowedRegistrantContactIds;
|
|
||||||
java.util.Set<java.lang.String> dnsWriters;
|
|
||||||
java.util.Set<java.lang.String> reservedListNames;
|
|
||||||
org.joda.money.CurrencyUnit currency;
|
|
||||||
org.joda.money.Money createBillingCost;
|
|
||||||
org.joda.money.Money registryLockOrUnlockBillingCost;
|
|
||||||
org.joda.money.Money restoreBillingCost;
|
|
||||||
org.joda.money.Money serverStatusChangeBillingCost;
|
|
||||||
org.joda.time.DateTime claimsPeriodEnd;
|
|
||||||
org.joda.time.Duration addGracePeriodLength;
|
|
||||||
org.joda.time.Duration anchorTenantAddGracePeriodLength;
|
|
||||||
org.joda.time.Duration autoRenewGracePeriodLength;
|
|
||||||
org.joda.time.Duration automaticTransferLength;
|
|
||||||
org.joda.time.Duration pendingDeleteLength;
|
|
||||||
org.joda.time.Duration redemptionGracePeriodLength;
|
|
||||||
org.joda.time.Duration renewGracePeriodLength;
|
|
||||||
org.joda.time.Duration transferGracePeriodLength;
|
|
||||||
}
|
|
||||||
class google.registry.model.tld.Registry$BillingCostTransition {
|
|
||||||
org.joda.money.Money billingCost;
|
|
||||||
org.joda.time.DateTime transitionTime;
|
|
||||||
}
|
|
||||||
enum google.registry.model.tld.Registry$TldState {
|
|
||||||
GENERAL_AVAILABILITY;
|
|
||||||
PDT;
|
|
||||||
PREDELEGATION;
|
|
||||||
QUIET_PERIOD;
|
|
||||||
START_DATE_SUNRISE;
|
|
||||||
}
|
|
||||||
class google.registry.model.tld.Registry$TldStateTransition {
|
|
||||||
google.registry.model.tld.Registry$TldState tldState;
|
|
||||||
org.joda.time.DateTime transitionTime;
|
|
||||||
}
|
|
||||||
enum google.registry.model.tld.Registry$TldType {
|
|
||||||
REAL;
|
|
||||||
TEST;
|
|
||||||
}
|
|
||||||
class google.registry.model.transfer.ContactTransferData {
|
class google.registry.model.transfer.ContactTransferData {
|
||||||
google.registry.model.eppcommon.Trid transferRequestTrid;
|
google.registry.model.eppcommon.Trid transferRequestTrid;
|
||||||
google.registry.model.transfer.TransferStatus transferStatus;
|
google.registry.model.transfer.TransferStatus transferStatus;
|
||||||
|
|
Loading…
Add table
Reference in a new issue