Key to VKey conversion for Nameserver (#476)

* Key to VKey conversion for Nameserver

This change illustrates the conversion of a single key in the system
(Key<HostResource> as used in the "nameservers" field of DomainBase) to a
VKey.

It currently builds, but had some curious (possibly unrelated?) test failures
that I have not fully investigated.

* Latest round of changes, all tests pass.

* Changes requested in review.

* Fix problems with null check in VKey accessors

Add maybeGet versions of getSqlKey() and getOfyKey() that return Optional
objects and make the nameserver management routines use those instead.
This commit is contained in:
Michael Muller 2020-03-26 17:13:30 -04:00 committed by GitHub
parent c0d5c941d5
commit a5ea445c90
41 changed files with 555 additions and 249 deletions

View file

@ -30,6 +30,7 @@ import google.registry.model.EppResource;
import google.registry.model.ImmutableObject;
import google.registry.model.eppcommon.Trid;
import google.registry.model.host.HostResource;
import google.registry.persistence.VKey;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.Retrier;
import javax.inject.Inject;
@ -148,12 +149,12 @@ public final class AsyncTaskEnqueuer {
/** Enqueues a task to asynchronously refresh DNS for a renamed host. */
public void enqueueAsyncDnsRefresh(HostResource host, DateTime now) {
Key<HostResource> hostKey = Key.create(host);
VKey<HostResource> hostKey = host.createKey();
logger.atInfo().log("Enqueuing async DNS refresh for renamed host %s.", hostKey);
addTaskToQueueWithRetry(
asyncDnsRefreshPullQueue,
TaskOptions.Builder.withMethod(Method.PULL)
.param(PARAM_HOST_KEY, hostKey.getString())
.param(PARAM_HOST_KEY, hostKey.getOfyKey().getString())
.param(PARAM_REQUESTED_TIME, now.toString()));
}

View file

@ -85,6 +85,7 @@ import google.registry.model.poll.PendingActionNotificationResponse.HostPendingA
import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.server.Lock;
import google.registry.persistence.VKey;
import google.registry.request.Action;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
@ -284,7 +285,9 @@ public class DeleteContactsAndHostsAction implements Runnable {
if (resourceKey.getKind().equals(KIND_CONTACT)) {
return domain.getReferencedContacts().contains(resourceKey);
} else if (resourceKey.getKind().equals(KIND_HOST)) {
return domain.getNameservers().contains(resourceKey);
return domain
.getNameservers()
.contains(VKey.createOfy(HostResource.class, (Key<HostResource>) resourceKey));
} else {
throw new IllegalStateException("EPP resource key of unknown type: " + resourceKey);
}

View file

@ -52,6 +52,7 @@ import google.registry.mapreduce.inputs.NullInput;
import google.registry.model.domain.DomainBase;
import google.registry.model.host.HostResource;
import google.registry.model.server.Lock;
import google.registry.persistence.VKey;
import google.registry.request.Action;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
@ -206,7 +207,9 @@ public class RefreshDnsOnHostRenameAction implements Runnable {
Key<HostResource> referencingHostKey = null;
for (DnsRefreshRequest request : refreshRequests) {
if (isActive(domain, request.lastUpdateTime())
&& domain.getNameservers().contains(request.hostKey())) {
&& domain
.getNameservers()
.contains(VKey.createOfy(HostResource.class, request.hostKey()))) {
referencingHostKey = request.hostKey();
break;
}

View file

@ -80,11 +80,9 @@ public final class ResourceFlowUtils {
final Function<DomainBase, ImmutableSet<?>> getPotentialReferences) throws EppException {
// Enter a transactionless context briefly.
EppException failfastException =
tm()
.doTransactionless(
tm().doTransactionless(
() -> {
final ForeignKeyIndex<R> fki =
ForeignKeyIndex.load(resourceClass, targetId, now);
final ForeignKeyIndex<R> fki = ForeignKeyIndex.load(resourceClass, targetId, now);
if (fki == null) {
return new ResourceDoesNotExistException(resourceClass, targetId);
}
@ -99,8 +97,7 @@ public final class ResourceFlowUtils {
.limit(FAILFAST_CHECK_COUNT)
.keys();
Predicate<DomainBase> predicate =
domain ->
getPotentialReferences.apply(domain).contains(fki.getResourceKey());
domain -> getPotentialReferences.apply(domain).contains(fki.getResourceKey());
return ofy().load().keys(keys).values().stream().anyMatch(predicate)
? new ResourceToDeleteIsReferencedException()
: null;

View file

@ -14,6 +14,7 @@
package google.registry.flows.domain;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.flows.FlowUtils.persistEntityChanges;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyResourceDoesNotExist;
@ -95,6 +96,7 @@ import google.registry.model.eppinput.EppInput;
import google.registry.model.eppinput.ResourceCommand;
import google.registry.model.eppoutput.CreateData.DomainCreateData;
import google.registry.model.eppoutput.EppResponse;
import google.registry.model.host.HostResource;
import google.registry.model.index.EppResourceIndex;
import google.registry.model.index.ForeignKeyIndex;
import google.registry.model.ofy.ObjectifyService;
@ -108,6 +110,7 @@ import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
import google.registry.persistence.VKey;
import google.registry.tmch.LordnTaskUtils;
import java.util.Optional;
import javax.inject.Inject;
@ -352,7 +355,11 @@ public class DomainCreateFlow implements TransactionalFlow {
.setRegistrant(command.getRegistrant())
.setAuthInfo(command.getAuthInfo())
.setFullyQualifiedDomainName(targetId)
.setNameservers(command.getNameservers())
.setNameservers(
(ImmutableSet<VKey<HostResource>>)
command.getNameservers().stream()
.map(key -> VKey.createOfy(HostResource.class, key))
.collect(toImmutableSet()))
.setStatusValues(statuses.build())
.setContacts(command.getContacts())
.addGracePeriod(GracePeriod.forBillingEvent(GracePeriodStatus.ADD, createBillingEvent))

View file

@ -14,7 +14,6 @@
package google.registry.flows.domain;
import static com.google.common.collect.Sets.union;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
@ -23,6 +22,7 @@ import static google.registry.flows.domain.DomainFlowUtils.handleFeeRequest;
import static google.registry.flows.domain.DomainFlowUtils.loadForeignKeyedDesignatedContacts;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@ -102,8 +102,9 @@ public final class DomainInfoFlow implements Flow {
flowCustomLogic.afterValidation(
AfterValidationParameters.newBuilder().setDomain(domain).build());
// Prefetch all referenced resources. Calling values() blocks until loading is done.
ofy().load()
.values(union(domain.getNameservers(), domain.getReferencedContacts())).values();
// We do nameservers separately since they've been converted to VKey.
tm().load(domain.getNameservers());
ofy().load().values(domain.getReferencedContacts()).values();
// Registrars can only see a few fields on unauthorized domains.
// This is a policy decision that is left up to us by the rfcs.
DomainInfoData.Builder infoBuilder = DomainInfoData.newBuilder()

View file

@ -15,6 +15,7 @@
package google.registry.flows.domain;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.Sets.symmetricDifference;
import static com.google.common.collect.Sets.union;
import static google.registry.flows.FlowUtils.persistEntityChanges;
@ -71,9 +72,11 @@ import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppinput.ResourceCommand;
import google.registry.model.eppoutput.EppResponse;
import google.registry.model.host.HostResource;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
import google.registry.persistence.VKey;
import java.util.Optional;
import javax.inject.Inject;
import org.joda.time.DateTime;
@ -243,8 +246,14 @@ public final class DomainUpdateFlow implements TransactionalFlow {
.setLastEppUpdateClientId(clientId)
.addStatusValues(add.getStatusValues())
.removeStatusValues(remove.getStatusValues())
.addNameservers(add.getNameservers())
.removeNameservers(remove.getNameservers())
.addNameservers(
add.getNameservers().stream()
.map(key -> VKey.createOfy(HostResource.class, key))
.collect(toImmutableSet()))
.removeNameservers(
remove.getNameservers().stream()
.map(key -> VKey.createOfy(HostResource.class, key))
.collect(toImmutableSet()))
.addContacts(add.getContacts())
.removeContacts(remove.getContacts())
.setRegistrant(firstNonNull(change.getRegistrant(), domain.getRegistrant()))

View file

@ -14,6 +14,7 @@
package google.registry.flows.host;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.failfastForAsyncDelete;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
@ -81,6 +82,17 @@ public final class HostDeleteFlow implements TransactionalFlow {
@Inject EppResponse.Builder responseBuilder;
@Inject HostDeleteFlow() {}
/**
* Hack to convert DomainBase's nameserver VKey's to Ofy Key's.
*
* <p>We currently need this because {@code failfastForAsyncDelete()} checks to see if a name is
* in the ofy keys and is used for both nameservers and contacts. When we convert contacts to
* VKey's, we can remove this and do the conversion in {@code failfastForAsyncDelete()}.
*/
private static ImmutableSet<Key<HostResource>> getNameserverOfyKeys(DomainBase domain) {
return domain.getNameservers().stream().map(key -> key.getOfyKey()).collect(toImmutableSet());
}
@Override
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
@ -88,7 +100,7 @@ public final class HostDeleteFlow implements TransactionalFlow {
validateClientIsLoggedIn(clientId);
DateTime now = tm().getTransactionTime();
validateHostName(targetId);
failfastForAsyncDelete(targetId, now, HostResource.class, DomainBase::getNameservers);
failfastForAsyncDelete(targetId, now, HostResource.class, HostDeleteFlow::getNameserverOfyKeys);
HostResource existingHost = loadAndVerifyExistence(HostResource.class, targetId, now);
verifyNoDisallowedStatuses(existingHost, DISALLOWED_STATUSES);
if (!isSuperuser) {

View file

@ -42,8 +42,10 @@ import com.google.common.collect.Ordering;
import com.google.common.collect.Streams;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.IgnoreSave;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.OnLoad;
import com.googlecode.objectify.condition.IfNull;
import google.registry.flows.ResourceFlowUtils;
import google.registry.model.EppResource;
@ -63,6 +65,7 @@ import google.registry.model.poll.PollMessage;
import google.registry.model.registry.Registry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import google.registry.util.CollectionUtils;
import java.util.HashSet;
import java.util.Objects;
@ -130,9 +133,16 @@ public class DomainBase extends EppResource
@Index
String tld;
/** References to hosts that are the nameservers for the domain. */
/**
* References to hosts that are the nameservers for the domain.
*
* <p>This is a legacy field: we have to preserve it because it is still persisted and indexed in
* the datastore, but all external references go through nsHostVKeys.
*/
@Index @ElementCollection @Transient Set<Key<HostResource>> nsHosts;
@Ignore @Transient Set<VKey<HostResource>> nsHostVKeys;
/**
* The union of the contacts visible via {@link #getContacts} and {@link #getRegistrant}.
*
@ -240,6 +250,14 @@ public class DomainBase extends EppResource
*/
DateTime lastTransferTime;
@OnLoad
void load() {
nsHostVKeys =
nullToEmptyImmutableCopy(nsHosts).stream()
.map(hostKey -> VKey.createOfy(HostResource.class, hostKey))
.collect(toImmutableSet());
}
public ImmutableSet<String> getSubordinateHosts() {
return nullToEmptyImmutableCopy(subordinateHosts);
}
@ -299,8 +317,10 @@ public class DomainBase extends EppResource
return idnTableName;
}
public ImmutableSet<Key<HostResource>> getNameservers() {
return nullToEmptyImmutableCopy(nsHosts);
public ImmutableSet<VKey<HostResource>> getNameservers() {
// Since nsHostVKeys gets initialized both from setNameservers() and the OnLoad method, this
// should always be valid.
return nullToEmptyImmutableCopy(nsHostVKeys);
}
public final String getCurrentSponsorClientId() {
@ -482,7 +502,7 @@ public class DomainBase extends EppResource
public ImmutableSortedSet<String> loadNameserverFullyQualifiedHostNames() {
return ofy()
.load()
.keys(getNameservers())
.keys(getNameservers().stream().map(VKey::getOfyKey).collect(toImmutableSet()))
.values()
.stream()
.map(HostResource::getFullyQualifiedHostName)
@ -542,6 +562,14 @@ public class DomainBase extends EppResource
Builder(DomainBase instance) {
super(instance);
// Convert nsHosts to nsHostVKeys.
if (instance.nsHosts != null) {
instance.nsHostVKeys =
instance.nsHosts.stream()
.map(key -> VKey.createOfy(HostResource.class, key))
.collect(toImmutableSet());
}
}
@Override
@ -591,30 +619,45 @@ public class DomainBase extends EppResource
return thisCastToDerived();
}
public Builder setNameservers(Key<HostResource> nameserver) {
getInstance().nsHosts = ImmutableSet.of(nameserver);
public Builder setNameservers(VKey<HostResource> nameserver) {
Optional<Key<HostResource>> nsKey = nameserver.maybeGetOfyKey();
if (nsKey.isPresent()) {
getInstance().nsHosts = ImmutableSet.of(nsKey.get());
} else {
getInstance().nsHosts = null;
}
getInstance().nsHostVKeys = ImmutableSet.of(nameserver);
return thisCastToDerived();
}
public Builder setNameservers(ImmutableSet<Key<HostResource>> nameservers) {
getInstance().nsHosts = forceEmptyToNull(nameservers);
public Builder setNameservers(ImmutableSet<VKey<HostResource>> nameservers) {
// If we have all of the ofy keys, we can set nsHosts. Otherwise, make it null.
if (nameservers != null
&& nameservers.stream().allMatch(key -> key.maybeGetOfyKey().isPresent())) {
getInstance().nsHosts =
nameservers.stream().map(key -> key.getOfyKey()).collect(toImmutableSet());
} else {
getInstance().nsHosts = null;
}
getInstance().nsHostVKeys = forceEmptyToNull(nameservers);
return thisCastToDerived();
}
public Builder addNameserver(Key<HostResource> nameserver) {
public Builder addNameserver(VKey<HostResource> nameserver) {
return addNameservers(ImmutableSet.of(nameserver));
}
public Builder addNameservers(ImmutableSet<Key<HostResource>> nameservers) {
public Builder addNameservers(ImmutableSet<VKey<HostResource>> nameservers) {
return setNameservers(
ImmutableSet.copyOf(union(getInstance().getNameservers(), nameservers)));
}
public Builder removeNameserver(Key<HostResource> nameserver) {
public Builder removeNameserver(VKey<HostResource> nameserver) {
return removeNameservers(ImmutableSet.of(nameserver));
}
public Builder removeNameservers(ImmutableSet<Key<HostResource>> nameservers) {
public Builder removeNameservers(ImmutableSet<VKey<HostResource>> nameservers) {
return setNameservers(
ImmutableSet.copyOf(difference(getInstance().getNameservers(), nameservers)));
}

View file

@ -33,6 +33,7 @@ import google.registry.model.annotations.ExternalMessagingName;
import google.registry.model.annotations.ReportedOn;
import google.registry.model.domain.DomainBase;
import google.registry.model.transfer.TransferData;
import google.registry.persistence.VKey;
import java.net.InetAddress;
import java.util.Optional;
import java.util.Set;
@ -117,6 +118,10 @@ public class HostResource extends EppResource implements ForeignKeyedEppResource
return fullyQualifiedHostName;
}
public VKey<HostResource> createKey() {
return VKey.createOfy(HostResource.class, Key.create(this));
}
@Deprecated
@Override
public HostResource cloneProjectedAtTime(DateTime now) {

View file

@ -18,10 +18,13 @@ import static google.registry.model.ofy.ObjectifyService.ofy;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key;
import google.registry.persistence.VKey;
import google.registry.persistence.transaction.TransactionManager;
import java.util.Iterator;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.StreamSupport;
import org.joda.time.DateTime;
/** Datastore implementation of {@link TransactionManager}. */
@ -128,9 +131,22 @@ public class DatastoreTransactionManager implements TransactionManager {
throw new UnsupportedOperationException("Not available in the Datastore transaction manager");
}
// TODO: add tests for these methods. They currently have some degree of test coverage because
// they are used when retrieving the nameservers which require these, as they are now loaded by
// VKey instead of by ofy Key. But ideally, there should be one set of TransactionManager
// interface tests that are applied to both the datastore and SQL implementations.
@Override
public <T> Optional<T> load(VKey<T> key) {
throw new UnsupportedOperationException("Not available in the Datastore transaction manager");
return Optional.of(getOfy().load().key(key.getOfyKey()).now());
}
@Override
public <T> ImmutableList<T> load(Iterable<VKey<T>> keys) {
Iterator<Key<T>> iter =
StreamSupport.stream(keys.spliterator(), false).map(key -> key.getOfyKey()).iterator();
// The lambda argument to keys() effectively converts Iterator -> Iterable.
return ImmutableList.copyOf(getOfy().load().keys(() -> iter).values());
}
@Override

View file

@ -36,6 +36,7 @@ import com.googlecode.objectify.impl.translate.opt.joda.MoneyStringTranslatorFac
import google.registry.config.RegistryEnvironment;
import google.registry.model.EntityClasses;
import google.registry.model.ImmutableObject;
import google.registry.model.host.HostResource;
import google.registry.model.translators.BloomFilterOfStringTranslatorFactory;
import google.registry.model.translators.CidrAddressBlockTranslatorFactory;
import google.registry.model.translators.CommitLogRevisionsTranslatorFactory;
@ -45,6 +46,7 @@ import google.registry.model.translators.DurationTranslatorFactory;
import google.registry.model.translators.InetAddressTranslatorFactory;
import google.registry.model.translators.ReadableInstantUtcTranslatorFactory;
import google.registry.model.translators.UpdateAutoTimestampTranslatorFactory;
import google.registry.model.translators.VKeyTranslatorFactory;
import java.util.concurrent.atomic.AtomicLong;
/**
@ -117,17 +119,19 @@ public class ObjectifyService {
/** Register translators that allow less common types to be stored directly in Datastore. */
private static void registerTranslators() {
for (TranslatorFactory<?> translatorFactory : ImmutableList.of(
new BloomFilterOfStringTranslatorFactory(),
new CidrAddressBlockTranslatorFactory(),
new CommitLogRevisionsTranslatorFactory(),
new CreateAutoTimestampTranslatorFactory(),
new CurrencyUnitTranslatorFactory(),
new DurationTranslatorFactory(),
new InetAddressTranslatorFactory(),
new MoneyStringTranslatorFactory(),
new ReadableInstantUtcTranslatorFactory(),
new UpdateAutoTimestampTranslatorFactory())) {
for (TranslatorFactory<?> translatorFactory :
ImmutableList.of(
new BloomFilterOfStringTranslatorFactory(),
new CidrAddressBlockTranslatorFactory(),
new CommitLogRevisionsTranslatorFactory(),
new CreateAutoTimestampTranslatorFactory(),
new CurrencyUnitTranslatorFactory(),
new DurationTranslatorFactory(),
new InetAddressTranslatorFactory(),
new MoneyStringTranslatorFactory(),
new ReadableInstantUtcTranslatorFactory(),
new VKeyTranslatorFactory<HostResource>(HostResource.class),
new UpdateAutoTimestampTranslatorFactory())) {
factory().getTranslators().add(translatorFactory);
}
}

View file

@ -0,0 +1,84 @@
// Copyright 2020 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.translators;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.googlecode.objectify.Key;
import google.registry.persistence.VKey;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* Translator factory for VKey.
*
* <p>These get translated to a string containing the URL safe encoding of the objectify key
* followed by a (url-unsafe) ampersand delimiter and the SQL key.
*/
public class VKeyTranslatorFactory<T> extends AbstractSimpleTranslatorFactory<VKey, String> {
private final Class<T> refClass;
public VKeyTranslatorFactory(Class<T> refClass) {
super(VKey.class);
this.refClass = refClass;
}
@Override
public SimpleTranslator<VKey, String> createTranslator() {
return new SimpleTranslator<VKey, String>() {
@Override
public VKey loadValue(String datastoreValue) {
int pos = datastoreValue.indexOf('&');
Key ofyKey = null;
String sqlKey = null;
if (pos > 0) {
// We have an objectify key.
ofyKey = Key.create(datastoreValue.substring(0, pos));
}
if (pos < datastoreValue.length() - 1) {
// We have an SQL key.
sqlKey = decode(datastoreValue.substring(pos + 1));
}
return VKey.create(refClass, sqlKey, ofyKey);
}
@Override
public String saveValue(VKey key) {
return ((key.getOfyKey() == null) ? "" : key.getOfyKey().getString())
+ "&"
+ ((key.getSqlKey() == null) ? "" : encode(key.getSqlKey().toString()));
}
};
}
private static String encode(String val) {
try {
return URLEncoder.encode(val, UTF_8.toString());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
private static String decode(String encoded) {
try {
return URLDecoder.decode(encoded, UTF_8.toString());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}

View file

@ -14,7 +14,10 @@
package google.registry.persistence;
import static com.google.common.base.Preconditions.checkState;
import google.registry.model.ImmutableObject;
import java.util.Optional;
/**
* VKey is an abstraction that encapsulates the key concept.
@ -25,12 +28,12 @@ import google.registry.model.ImmutableObject;
public class VKey<T> extends ImmutableObject {
// The primary key for the referenced entity.
private Object primaryKey;
private final Object primaryKey;
// The objectify key for the referenced entity.
private com.googlecode.objectify.Key<T> ofyKey;
private final com.googlecode.objectify.Key<T> ofyKey;
private Class<? extends T> kind;
private final Class<? extends T> kind;
private VKey(Class<? extends T> kind, com.googlecode.objectify.Key<T> ofyKey, Object primaryKey) {
this.kind = kind;
@ -52,17 +55,34 @@ public class VKey<T> extends ImmutableObject {
return new VKey(kind, ofyKey, null);
}
public static <T> VKey<T> create(
Class<? extends T> kind, Object primaryKey, com.googlecode.objectify.Key ofyKey) {
return new VKey(kind, ofyKey, primaryKey);
}
public Class<? extends T> getKind() {
return this.kind;
}
/** Returns the SQL primary key. */
public Object getSqlKey() {
checkState(primaryKey != null, "Attempting obtain a null SQL key.");
return this.primaryKey;
}
/** Returns the SQL primary key if it exists. */
public Optional<Object> maybeGetSqlKey() {
return Optional.of(this.primaryKey);
}
/** Returns the objectify key. */
public com.googlecode.objectify.Key<T> getOfyKey() {
checkState(ofyKey != null, "Attempting obtain a null Objectify key.");
return this.ofyKey;
}
/** Returns the objectify key if it exists. */
public Optional<com.googlecode.objectify.Key<T>> maybeGetOfyKey() {
return Optional.of(this.ofyKey);
}
}

View file

@ -15,6 +15,7 @@
package google.registry.persistence.transaction;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import static java.util.stream.Collectors.joining;
@ -26,8 +27,10 @@ import com.google.common.flogger.FluentLogger;
import google.registry.persistence.VKey;
import google.registry.util.Clock;
import java.lang.reflect.Field;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.StreamSupport;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
@ -235,6 +238,23 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
return Optional.ofNullable(getEntityManager().find(key.getKind(), key.getSqlKey()));
}
@Override
public <T> ImmutableList<T> load(Iterable<VKey<T>> keys) {
checkArgumentNotNull(keys, "keys must be specified");
assertInTransaction();
return StreamSupport.stream(keys.spliterator(), false)
.map(
key -> {
T entity = getEntityManager().find(key.getKind(), key.getSqlKey());
if (entity == null) {
throw new NoSuchElementException(
key.getKind().getName() + " with key " + key.getSqlKey() + " not found.");
}
return entity;
})
.collect(toImmutableList());
}
@Override
public <T> ImmutableList<T> loadAll(Class<T> clazz) {
checkArgumentNotNull(clazz, "clazz must be specified");

View file

@ -110,6 +110,13 @@ public interface TransactionManager {
/** Loads the entity by its id, returns empty if the entity doesn't exist. */
<T> Optional<T> load(VKey<T> key);
/**
* Leads the set of entities by their key id.
*
* @throws NoSuchElementException if any of the keys are not found.
*/
<T> ImmutableList<T> load(Iterable<VKey<T>> keys);
/** Loads all entities of the given type, returns empty if there is no such entity. */
<T> ImmutableList<T> loadAll(Class<T> clazz);

View file

@ -21,6 +21,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
import static google.registry.model.EppResourceUtils.isLinked;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.rdap.RdapIcannStandardInformation.CONTACT_REDACTED_VALUE;
import static google.registry.util.CollectionUtils.union;
@ -341,8 +342,8 @@ public class RdapJsonFormatter {
// Kick off the database loads of the nameservers that we will need, so it can load
// asynchronously while we load and process the contacts.
Map<Key<HostResource>, HostResource> loadedHosts =
ofy().load().keys(domainBase.getNameservers());
ImmutableSet<HostResource> loadedHosts =
ImmutableSet.copyOf(tm().load(domainBase.getNameservers()));
// Load the registrant and other contacts and add them to the data.
Map<Key<ContactResource>, ContactResource> loadedContacts =
ofy().load().keys(domainBase.getReferencedContacts());
@ -378,8 +379,7 @@ public class RdapJsonFormatter {
}
// Add the nameservers to the data; the load was kicked off above for efficiency.
// RDAP Response Profile 2.9: we MUST have the nameservers
for (HostResource hostResource :
HOST_RESOURCE_ORDERING.immutableSortedCopy(loadedHosts.values())) {
for (HostResource hostResource : HOST_RESOURCE_ORDERING.immutableSortedCopy(loadedHosts)) {
builder.nameserversBuilder().add(createRdapNameserver(hostResource, OutputDataType.INTERNAL));
}

View file

@ -19,7 +19,7 @@ import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.collect.Sets.difference;
import static google.registry.model.EppResourceUtils.checkResourcesExist;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.PreconditionsUtils.checkArgumentPresent;
import static org.joda.time.DateTimeZone.UTC;
@ -149,7 +149,7 @@ final class UniformRapidSuspensionCommand extends MutatingEppToolCommand {
private ImmutableSortedSet<String> getExistingNameservers(DomainBase domain) {
ImmutableSortedSet.Builder<String> nameservers = ImmutableSortedSet.naturalOrder();
for (HostResource host : ofy().load().keys(domain.getNameservers()).values()) {
for (HostResource host : tm().load(domain.getNameservers())) {
nameservers.add(host.getForeignKey());
}
return nameservers.build();

View file

@ -20,7 +20,7 @@ import static com.google.common.collect.Iterators.filter;
import static com.google.common.io.BaseEncoding.base16;
import static google.registry.mapreduce.inputs.EppResourceInputs.createEntityInput;
import static google.registry.model.EppResourceUtils.loadAtPointInTime;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.request.Action.Method.POST;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.joda.time.DateTimeZone.UTC;
@ -214,7 +214,7 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA
private void emitForSubordinateHosts(DomainBase domain) {
ImmutableSet<String> subordinateHosts = domain.getSubordinateHosts();
if (!subordinateHosts.isEmpty()) {
for (HostResource unprojectedHost : ofy().load().keys(domain.getNameservers()).values()) {
for (HostResource unprojectedHost : tm().load(domain.getNameservers())) {
HostResource host = loadAtPointInTime(unprojectedHost, exportTime).now();
// A null means the host was deleted (or not created) at this time.
if ((host != null) && subordinateHosts.contains(host.getFullyQualifiedHostName())) {
@ -283,7 +283,7 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA
Duration dnsDefaultDsTtl) {
StringBuilder result = new StringBuilder();
String domainLabel = stripTld(domain.getFullyQualifiedDomainName(), domain.getTld());
for (HostResource nameserver : ofy().load().keys(domain.getNameservers()).values()) {
for (HostResource nameserver : tm().load(domain.getNameservers())) {
result.append(String.format(
NS_FORMAT,
domainLabel,

View file

@ -614,7 +614,7 @@ public class DeleteContactsAndHostsActionTest
.hasDeletionTime(END_OF_TIME);
DomainBase domain =
loadByForeignKey(DomainBase.class, "example.tld", clock.nowUtc()).get();
assertThat(domain.getNameservers()).contains(Key.create(hostAfter));
assertThat(domain.getNameservers()).contains(hostAfter.createKey());
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(hostAfter, HOST_DELETE_FAILURE);
assertPollMessageFor(
historyEntry,
@ -684,7 +684,7 @@ public class DeleteContactsAndHostsActionTest
persistResource(
newDomainBase("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.setDeletionTime(clock.nowUtc().minusDays(5))
.build());
enqueuer.enqueueAsyncDelete(
@ -943,7 +943,7 @@ public class DeleteContactsAndHostsActionTest
return persistResource(
newDomainBase(domainName, contact)
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
}

View file

@ -38,12 +38,12 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.net.InetAddresses;
import com.google.common.util.concurrent.RateLimiter;
import com.googlecode.objectify.Key;
import google.registry.dns.writer.clouddns.CloudDnsWriter.ZoneStateException;
import google.registry.model.domain.DomainBase;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.persistence.VKey;
import google.registry.testing.AppEngineRule;
import google.registry.util.Retrier;
import google.registry.util.SystemClock;
@ -292,9 +292,9 @@ public class CloudDnsWriterTest {
dsDataBuilder.add(DelegationSignerData.create(i, 3, 1, base16().decode("1234567890ABCDEF")));
}
ImmutableSet.Builder<Key<HostResource>> hostResourceRefBuilder = new ImmutableSet.Builder<>();
ImmutableSet.Builder<VKey<HostResource>> hostResourceRefBuilder = new ImmutableSet.Builder<>();
for (HostResource nameserver : nameservers) {
hostResourceRefBuilder.add(Key.create(nameserver));
hostResourceRefBuilder.add(nameserver.createKey());
}
return newDomainBase(domainName)

View file

@ -36,7 +36,6 @@ import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InetAddresses;
import com.googlecode.objectify.Key;
import google.registry.model.domain.DomainBase;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.StatusValue;
@ -106,7 +105,7 @@ public class DnsUpdateWriterTest {
DomainBase domain =
persistActiveDomain("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host1), Key.create(host2)))
.setNameservers(ImmutableSet.of(host1.createKey(), host2.createKey()))
.build();
persistResource(domain);
@ -127,7 +126,7 @@ public class DnsUpdateWriterTest {
DomainBase domain1 =
persistActiveDomain("example1.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host1)))
.setNameservers(ImmutableSet.of(host1.createKey()))
.build();
persistResource(domain1);
@ -135,7 +134,7 @@ public class DnsUpdateWriterTest {
DomainBase domain2 =
persistActiveDomain("example2.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host2)))
.setNameservers(ImmutableSet.of(host2.createKey()))
.build();
persistResource(domain2);
@ -151,7 +150,7 @@ public class DnsUpdateWriterTest {
DomainBase domain1 =
persistActiveDomain("example1.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host1)))
.setNameservers(ImmutableSet.of(host1.createKey()))
.build();
persistResource(domain1);
@ -159,7 +158,7 @@ public class DnsUpdateWriterTest {
DomainBase domain2 =
persistActiveDomain("example2.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host2)))
.setNameservers(ImmutableSet.of(host2.createKey()))
.build();
persistResource(domain2);
@ -182,7 +181,7 @@ public class DnsUpdateWriterTest {
DomainBase domain =
persistActiveDomain("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(persistActiveHost("ns1.example.tld"))))
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createKey()))
.setDsData(
ImmutableSet.of(
DelegationSignerData.create(1, 3, 1, base16().decode("0123456789ABCDEF"))))
@ -207,7 +206,7 @@ public class DnsUpdateWriterTest {
persistActiveDomain("example.tld")
.asBuilder()
.addStatusValue(StatusValue.SERVER_HOLD)
.setNameservers(ImmutableSet.of(Key.create(persistActiveHost("ns1.example.tld"))))
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createKey()))
.build();
persistResource(domain);
@ -251,7 +250,7 @@ public class DnsUpdateWriterTest {
newDomainBase("example.tld")
.asBuilder()
.addSubordinateHost("ns1.example.tld")
.addNameserver(Key.create(host))
.addNameserver(host.createKey())
.build());
writer.publishHost("ns1.example.tld");
@ -290,7 +289,7 @@ public class DnsUpdateWriterTest {
persistResource(
persistActiveDomain("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(persistActiveHost("ns1.example.com"))))
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.com").createKey()))
.build());
writer.publishHost("ns1.example.tld");
@ -324,7 +323,7 @@ public class DnsUpdateWriterTest {
.asBuilder()
.addSubordinateHost("ns1.example.tld")
.addNameservers(
ImmutableSet.of(Key.create(externalNameserver), Key.create(inBailiwickNameserver)))
ImmutableSet.of(externalNameserver.createKey(), inBailiwickNameserver.createKey()))
.build());
writer.publishDomain("example.tld");
@ -359,7 +358,7 @@ public class DnsUpdateWriterTest {
.asBuilder()
.addSubordinateHost("ns1.example.tld")
.addSubordinateHost("foo.example.tld")
.addNameserver(Key.create(inBailiwickNameserver))
.addNameserver(inBailiwickNameserver.createKey())
.build());
writer.publishDomain("example.tld");
@ -383,7 +382,7 @@ public class DnsUpdateWriterTest {
DomainBase domain =
persistActiveDomain("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(persistActiveHost("ns1.example.tld"))))
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createKey()))
.build();
persistResource(domain);
when(mockResolver.send(any(Message.class))).thenReturn(messageWithResponseCode(Rcode.SERVFAIL));

View file

@ -693,7 +693,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
loadByForeignKey(DomainBase.class, getUniqueIdFromCommand(), clock.nowUtc())
.get()
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
// Persist another domain that's already been deleted and references this contact and host.
persistResource(
@ -701,7 +701,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
.asBuilder()
.setRegistrant(
Key.create(loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc()).get()))
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.setDeletionTime(START_OF_TIME)
.build());
clock.advanceOneMilli();

View file

@ -118,7 +118,7 @@ public class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Dom
DesignatedContact.create(Type.ADMIN, Key.create(contact)),
DesignatedContact.create(Type.TECH, Key.create(contact))))
.setNameservers(
inactive ? null : ImmutableSet.of(Key.create(host1), Key.create(host2)))
inactive ? null : ImmutableSet.of(host1.createKey(), host2.createKey()))
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("2fooBAR")))
.build());
// Set the superordinate domain of ns1.example.com to example.com. In reality, this would have
@ -294,7 +294,7 @@ public class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Dom
ImmutableSet.of(
DelegationSignerData.create(
12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC"))))
.setNameservers(ImmutableSet.of(Key.create(host1), Key.create(host3)))
.setNameservers(ImmutableSet.of(host1.createKey(), host3.createKey()))
.build());
doSuccessfulTest("domain_info_response_dsdata.xml", false);
}
@ -843,7 +843,9 @@ public class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Dom
Key.getKind(ContactResource.class),
Key.getKind(HostResource.class)))))
.count();
assertThat(numReadsWithContactsOrHosts).isEqualTo(1);
// Nameserver keys now get persisted twice (because they are stored in nsHostsVKeys), so we
// check for two loads instead of 1.
assertThat(numReadsWithContactsOrHosts).isEqualTo(2);
}
@Test

View file

@ -88,6 +88,7 @@ import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.persistence.VKey;
import org.joda.money.Money;
import org.junit.Before;
import org.junit.Test;
@ -138,7 +139,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
DesignatedContact.create(Type.ADMIN, Key.create(mak21Contact)),
DesignatedContact.create(Type.BILLING, Key.create(mak21Contact))))
.setRegistrant(Key.create(mak21Contact))
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
historyEntryDomainCreate =
persistResource(
@ -161,7 +162,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
ImmutableSet.of(
DesignatedContact.create(Type.TECH, Key.create(sh8013Contact)),
DesignatedContact.create(Type.ADMIN, Key.create(unusedContact))))
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
historyEntryDomainCreate =
persistResource(
@ -255,14 +256,14 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
}
private void modifyDomainToHave13Nameservers() throws Exception {
ImmutableSet.Builder<Key<HostResource>> nameservers = new ImmutableSet.Builder<>();
ImmutableSet.Builder<VKey<HostResource>> nameservers = new ImmutableSet.Builder<>();
for (int i = 1; i < 15; i++) {
if (i != 2) { // Skip 2 since that's the one that the tests will add.
nameservers.add(
Key.create(
loadByForeignKey(
HostResource.class, String.format("ns%d.example.foo", i), clock.nowUtc())
.get()));
loadByForeignKey(
HostResource.class, String.format("ns%d.example.foo", i), clock.nowUtc())
.get()
.createKey());
}
}
persistResource(
@ -285,11 +286,11 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
persistDomain();
setEppInput("domain_update_max_everything.xml");
// Create 26 hosts and 8 contacts. Start the domain with half of them.
ImmutableSet.Builder<Key<HostResource>> nameservers = new ImmutableSet.Builder<>();
ImmutableSet.Builder<VKey<HostResource>> nameservers = new ImmutableSet.Builder<>();
for (int i = 0; i < 26; i++) {
HostResource host = persistActiveHost(String.format("max_test_%d.example.tld", i));
if (i < 13) {
nameservers.add(Key.create(host));
nameservers.add(host.createKey());
}
}
ImmutableList.Builder<DesignatedContact> contactsBuilder = new ImmutableList.Builder<>();
@ -376,15 +377,15 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.addSubordinateHost("ns2.example.tld")
.setNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc())
.get())))
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc())
.get()
.createKey()))
.build());
clock.advanceOneMilli();
assertTransactionalFlow(true);
runFlowAssertResponse(loadFile("generic_success_response.xml"));
domain = reloadResourceByForeignKey();
assertThat(domain.getNameservers()).containsExactly(Key.create(addedHost));
assertThat(domain.getNameservers()).containsExactly(addedHost.createKey());
assertThat(domain.getSubordinateHosts()).containsExactly("ns1.example.tld", "ns2.example.tld");
HostResource existingHost =
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc()).get();
@ -1058,9 +1059,9 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.asBuilder()
.setNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())
.get())))
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())
.get()
.createKey()))
.build());
EppException thrown = assertThrows(AddRemoveSameValueException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
@ -1198,13 +1199,15 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.build());
assertThat(reloadResourceByForeignKey().getNameservers())
.doesNotContain(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()));
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())
.get()
.createKey());
runFlow();
assertThat(reloadResourceByForeignKey().getNameservers())
.contains(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()));
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())
.get()
.createKey());
}
@Test
@ -1275,8 +1278,9 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
reloadResourceByForeignKey()
.asBuilder()
.addNameserver(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()))
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())
.get()
.createKey())
.build());
persistResource(
Registry.get("tld")
@ -1286,8 +1290,9 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.build());
assertThat(reloadResourceByForeignKey().getNameservers())
.contains(
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc()).get()));
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())
.get()
.createKey());
clock.advanceOneMilli();
runFlow();
assertThat(reloadResourceByForeignKey().getNameservers())

View file

@ -284,7 +284,7 @@ public class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, Hos
persistResource(
newDomainBase("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(persistActiveHost("ns1.example.tld"))))
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createKey()))
.build());
EppException thrown = assertThrows(ResourceToDeleteIsReferencedException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();

View file

@ -92,7 +92,7 @@ public class HostInfoFlowTest extends ResourceFlowTestCase<HostInfoFlow, HostRes
persistResource(
newDomainBase("example.foobar")
.asBuilder()
.addNameserver(Key.create(persistHostResource()))
.addNameserver(persistHostResource().createKey())
.build());
assertTransactionalFlow(false);
// Check that the persisted host info was returned.

View file

@ -195,7 +195,7 @@ public class HostUpdateFlowTest extends ResourceFlowTestCase<HostUpdateFlow, Hos
newDomainBase("test.xn--q9jyb4c")
.asBuilder()
.setDeletionTime(END_OF_TIME)
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
HostResource renamedHost = doSuccessfulTest();
assertThat(renamedHost.isSubordinate()).isTrue();

View file

@ -54,6 +54,7 @@ import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.junit.Before;
@ -65,19 +66,20 @@ public class DomainBaseTest extends EntityTestCase {
private DomainBase domain;
private Key<BillingEvent.OneTime> oneTimeBillKey;
private Key<BillingEvent.Recurring> recurringBillKey;
private Key<DomainBase> domainKey;
@Before
public void setUp() {
createTld("com");
Key<DomainBase> domainKey = Key.create(null, DomainBase.class, "4-COM");
Key<HostResource> hostKey =
Key.create(
persistResource(
domainKey = Key.create(null, DomainBase.class, "4-COM");
VKey<HostResource> hostKey =
persistResource(
new HostResource.Builder()
.setFullyQualifiedHostName("ns1.example.com")
.setSuperordinateDomain(domainKey)
.setRepoId("1-COM")
.build()));
.build())
.createKey();
Key<ContactResource> contact1Key =
Key.create(
persistResource(
@ -219,7 +221,7 @@ public class DomainBaseTest extends EntityTestCase {
assertThat(
newDomainBase("example.com")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(newHostResource("foo.example.tld"))))
.setNameservers(ImmutableSet.of(newHostResource("foo.example.tld").createKey()))
.build()
.nsHosts)
.isNotNull();
@ -266,8 +268,8 @@ public class DomainBaseTest extends EntityTestCase {
@Test
public void testImplicitStatusValues() {
ImmutableSet<Key<HostResource>> nameservers =
ImmutableSet.of(Key.create(newHostResource("foo.example.tld")));
ImmutableSet<VKey<HostResource>> nameservers =
ImmutableSet.of(newHostResource("foo.example.tld").createKey());
StatusValue[] statuses = {StatusValue.OK};
// OK is implicit if there's no other statuses but there are nameservers.
assertAboutDomains()
@ -769,4 +771,60 @@ public class DomainBaseTest extends EntityTestCase {
assertThat(getOnlyElement(clone.getGracePeriods()).getType())
.isEqualTo(GracePeriodStatus.TRANSFER);
}
private static ImmutableSet<Key<HostResource>> getOfyNameservers(DomainBase domain) {
return domain.getNameservers().stream().map(key -> key.getOfyKey()).collect(toImmutableSet());
}
@Test
public void testNameservers_nsHostsOfyKeys() {
assertThat(domain.nsHosts).isEqualTo(getOfyNameservers(domain));
// Test the setNameserver that functions on a function.
VKey<HostResource> host1Key =
persistResource(
new HostResource.Builder()
.setFullyQualifiedHostName("ns2.example.com")
.setSuperordinateDomain(domainKey)
.setRepoId("2-COM")
.build())
.createKey();
DomainBase dom = new DomainBase.Builder(domain).setNameservers(host1Key).build();
assertThat(dom.getNameservers()).isEqualTo(ImmutableSet.of(host1Key));
assertThat(getOfyNameservers(dom)).isEqualTo(ImmutableSet.of(host1Key.getOfyKey()));
// Test that setting to a single host of null throws an NPE.
assertThrows(
NullPointerException.class,
() -> new DomainBase.Builder(domain).setNameservers((VKey<HostResource>) null));
// Test that setting to a set of values works.
VKey<HostResource> host2Key =
persistResource(
new HostResource.Builder()
.setFullyQualifiedHostName("ns3.example.com")
.setSuperordinateDomain(domainKey)
.setRepoId("3-COM")
.build())
.createKey();
dom =
new DomainBase.Builder(domain).setNameservers(ImmutableSet.of(host1Key, host2Key)).build();
assertThat(dom.getNameservers()).isEqualTo(ImmutableSet.of(host1Key, host2Key));
assertThat(getOfyNameservers(dom))
.isEqualTo(ImmutableSet.of(host1Key.getOfyKey(), host2Key.getOfyKey()));
// Set of values, passing null.
dom =
new DomainBase.Builder(domain)
.setNameservers((ImmutableSet<VKey<HostResource>>) null)
.build();
assertThat(dom.nsHostVKeys).isNull();
assertThat(dom.nsHosts).isNull();
// Empty set of values gets translated to null.
dom = new DomainBase.Builder(domain).setNameservers(ImmutableSet.of()).build();
assertThat(dom.nsHostVKeys).isNull();
assertThat(dom.nsHosts).isNull();
}
}

View file

@ -45,6 +45,7 @@ import google.registry.model.host.HostResource;
import google.registry.model.registrar.Registrar;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.persistence.VKey;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.rdap.RdapMetrics.SearchType;
import google.registry.rdap.RdapMetrics.WildcardType;
@ -409,7 +410,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
private void createManyDomainsAndHosts(
int numActiveDomains, int numTotalDomainsPerActiveDomain, int numHosts) {
ImmutableSet.Builder<Key<HostResource>> hostKeysBuilder = new ImmutableSet.Builder<>();
ImmutableSet.Builder<VKey<HostResource>> hostKeysBuilder = new ImmutableSet.Builder<>();
ImmutableSet.Builder<String> subordinateHostnamesBuilder = new ImmutableSet.Builder<>();
String mainDomainName = String.format("domain%d.lol", numTotalDomainsPerActiveDomain);
for (int i = numHosts; i >= 1; i--) {
@ -417,9 +418,9 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
subordinateHostnamesBuilder.add(hostName);
HostResource host = makeAndPersistHostResource(
hostName, String.format("5.5.%d.%d", 5 + i / 250, i % 250), clock.nowUtc().minusYears(1));
hostKeysBuilder.add(Key.create(host));
hostKeysBuilder.add(host.createKey());
}
ImmutableSet<Key<HostResource>> hostKeys = hostKeysBuilder.build();
ImmutableSet<VKey<HostResource>> hostKeys = hostKeysBuilder.build();
// Create all the domains at once, then persist them in parallel, for increased efficiency.
ImmutableList.Builder<DomainBase> domainsBuilder = new ImmutableList.Builder<>();
for (int i = numActiveDomains * numTotalDomainsPerActiveDomain; i >= 1; i--) {

View file

@ -80,8 +80,8 @@ import org.junit.runners.JUnit4;
/**
* Unit tests for {@link DomainBaseToXjcConverter}.
*
* <p>This tests the mapping between {@link DomainBase} and {@link XjcRdeDomain} as well as
* some exceptional conditions.
* <p>This tests the mapping between {@link DomainBase} and {@link XjcRdeDomain} as well as some
* exceptional conditions.
*/
@RunWith(JUnit4.class)
public class DomainBaseToXjcConverterTest {
@ -99,14 +99,12 @@ public class DomainBaseToXjcConverterTest {
@Test
public void testConvertThick() {
XjcRdeDomain bean =
DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.FULL);
XjcRdeDomain bean = DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.FULL);
assertThat(bean.getClID()).isEqualTo("GetTheeBack");
assertThat(
bean.getContacts()
.stream()
bean.getContacts().stream()
.map(input -> String.format("%s %s", input.getType().toString(), input.getValue())))
.containsExactly("ADMIN 5372808-IRL", "TECH 5372808-TRL");
@ -182,8 +180,7 @@ public class DomainBaseToXjcConverterTest {
@Test
public void testConvertThin() {
XjcRdeDomain bean =
DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.THIN);
XjcRdeDomain bean = DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.THIN);
assertThat(bean.getRegistrant()).isNull();
assertThat(bean.getContacts()).isEmpty();
assertThat(bean.getSecDNS()).isNull();
@ -191,15 +188,13 @@ public class DomainBaseToXjcConverterTest {
@Test
public void testMarshalThick() throws Exception {
XjcRdeDomain bean =
DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.FULL);
XjcRdeDomain bean = DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.FULL);
wrapDeposit(bean).marshal(new ByteArrayOutputStream(), UTF_8);
}
@Test
public void testMarshalThin() throws Exception {
XjcRdeDomain bean =
DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.THIN);
XjcRdeDomain bean = DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.THIN);
wrapDeposit(bean).marshal(new ByteArrayOutputStream(), UTF_8);
}
@ -225,17 +220,18 @@ public class DomainBaseToXjcConverterTest {
newDomainBase("example.xn--q9jyb4c").asBuilder().setRepoId("2-Q9JYB4C").build();
HistoryEntry historyEntry =
persistResource(new HistoryEntry.Builder().setParent(domain).build());
BillingEvent.OneTime billingEvent = persistResource(
new BillingEvent.OneTime.Builder()
.setReason(Reason.CREATE)
.setTargetId("example.xn--q9jyb4c")
.setClientId("TheRegistrar")
.setCost(Money.of(USD, 26))
.setPeriodYears(2)
.setEventTime(DateTime.parse("1910-01-01T00:00:00Z"))
.setBillingTime(DateTime.parse("1910-01-01T00:00:00Z"))
.setParent(historyEntry)
.build());
BillingEvent.OneTime billingEvent =
persistResource(
new BillingEvent.OneTime.Builder()
.setReason(Reason.CREATE)
.setTargetId("example.xn--q9jyb4c")
.setClientId("TheRegistrar")
.setCost(Money.of(USD, 26))
.setPeriodYears(2)
.setEventTime(DateTime.parse("1910-01-01T00:00:00Z"))
.setBillingTime(DateTime.parse("1910-01-01T00:00:00Z"))
.setParent(historyEntry)
.build());
domain =
domain
.asBuilder()
@ -272,11 +268,10 @@ public class DomainBaseToXjcConverterTest {
.setLastEppUpdateTime(DateTime.parse("1920-01-01T00:00:00Z"))
.setNameservers(
ImmutableSet.of(
Key.create(
makeHostResource(clock, "3-Q9JYB4C", "bird.or.devil.みんな", "1.2.3.4")),
Key.create(
makeHostResource(
clock, "4-Q9JYB4C", "ns2.cat.みんな", "bad:f00d:cafe::15:beef"))))
makeHostResource(clock, "3-Q9JYB4C", "bird.or.devil.みんな", "1.2.3.4")
.createKey(),
makeHostResource(clock, "4-Q9JYB4C", "ns2.cat.みんな", "bad:f00d:cafe::15:beef")
.createKey()))
.setRegistrant(
Key.create(
makeContactResource(
@ -383,27 +378,24 @@ public class DomainBaseToXjcConverterTest {
.setPersistedCurrentSponsorClientId("GetTheeBack")
.setCreationClientId("GetTheeBack")
.setCreationTimeForTest(END_OF_TIME)
.setInternationalizedPostalInfo(new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName(name)
.setOrg("SINNERS INCORPORATED")
.setAddress(new ContactAddress.Builder()
.setStreet(ImmutableList.of("123 Example Boulevard"))
.setCity("KOKOMO")
.setState("BM")
.setZip("31337")
.setCountryCode("US")
.setInternationalizedPostalInfo(
new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName(name)
.setOrg("SINNERS INCORPORATED")
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of("123 Example Boulevard"))
.setCity("KOKOMO")
.setState("BM")
.setZip("31337")
.setCountryCode("US")
.build())
.build())
.build())
.setRepoId(repoId)
.setVoiceNumber(
new ContactPhoneNumber.Builder()
.setPhoneNumber("+1.2126660420")
.build())
.setFaxNumber(
new ContactPhoneNumber.Builder()
.setPhoneNumber("+1.2126660421")
.build())
new ContactPhoneNumber.Builder().setPhoneNumber("+1.2126660420").build())
.setFaxNumber(new ContactPhoneNumber.Builder().setPhoneNumber("+1.2126660421").build())
.build());
}

View file

@ -58,27 +58,30 @@ import org.joda.time.DateTime;
final class RdeFixtures {
static DomainBase makeDomainBase(FakeClock clock, String tld) {
DomainBase domain = new DomainBase.Builder()
.setFullyQualifiedDomainName("example." + tld)
.setRepoId(generateNewDomainRoid(tld))
.setRegistrant(Key.create(
makeContactResource(clock,
"5372808-ERL", "(◕‿◕) nevermore", "prophet@evil.みんな")))
.build();
DomainBase domain =
new DomainBase.Builder()
.setFullyQualifiedDomainName("example." + tld)
.setRepoId(generateNewDomainRoid(tld))
.setRegistrant(
Key.create(
makeContactResource(
clock, "5372808-ERL", "(◕‿◕) nevermore", "prophet@evil.みんな")))
.build();
HistoryEntry historyEntry =
persistResource(new HistoryEntry.Builder().setParent(domain).build());
clock.advanceOneMilli();
BillingEvent.OneTime billingEvent = persistResourceWithCommitLog(
new BillingEvent.OneTime.Builder()
.setReason(Reason.CREATE)
.setTargetId("example." + tld)
.setClientId("TheRegistrar")
.setCost(Money.of(USD, 26))
.setPeriodYears(2)
.setEventTime(DateTime.parse("1990-01-01T00:00:00Z"))
.setBillingTime(DateTime.parse("1990-01-01T00:00:00Z"))
.setParent(historyEntry)
.build());
BillingEvent.OneTime billingEvent =
persistResourceWithCommitLog(
new BillingEvent.OneTime.Builder()
.setReason(Reason.CREATE)
.setTargetId("example." + tld)
.setClientId("TheRegistrar")
.setCost(Money.of(USD, 26))
.setPeriodYears(2)
.setEventTime(DateTime.parse("1990-01-01T00:00:00Z"))
.setBillingTime(DateTime.parse("1990-01-01T00:00:00Z"))
.setParent(historyEntry)
.build());
domain =
domain
.asBuilder()
@ -114,8 +117,8 @@ final class RdeFixtures {
.setIdnTableName("extended_latin")
.setNameservers(
ImmutableSet.of(
Key.create(makeHostResource(clock, "bird.or.devil.みんな", "1.2.3.4")),
Key.create(makeHostResource(clock, "ns2.cat.みんな", "bad:f00d:cafe::15:beef"))))
makeHostResource(clock, "bird.or.devil.みんな", "1.2.3.4").createKey(),
makeHostResource(clock, "ns2.cat.みんな", "bad:f00d:cafe::15:beef").createKey()))
.setRegistrationExpirationTime(DateTime.parse("1994-01-01T00:00:00Z"))
.setGracePeriods(
ImmutableSet.of(
@ -220,26 +223,23 @@ final class RdeFixtures {
.setPersistedCurrentSponsorClientId("GetTheeBack")
.setCreationClientId("GetTheeBack")
.setCreationTimeForTest(clock.nowUtc())
.setInternationalizedPostalInfo(new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName(name)
.setOrg("DOGE INCORPORATED")
.setAddress(new ContactAddress.Builder()
.setStreet(ImmutableList.of("123 Example Boulevard"))
.setCity("KOKOMO")
.setState("BM")
.setZip("31337")
.setCountryCode("US")
.setInternationalizedPostalInfo(
new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName(name)
.setOrg("DOGE INCORPORATED")
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of("123 Example Boulevard"))
.setCity("KOKOMO")
.setState("BM")
.setZip("31337")
.setCountryCode("US")
.build())
.build())
.build())
.setVoiceNumber(
new ContactPhoneNumber.Builder()
.setPhoneNumber("+1.5558675309")
.build())
.setFaxNumber(
new ContactPhoneNumber.Builder()
.setPhoneNumber("+1.5558675310")
.build())
new ContactPhoneNumber.Builder().setPhoneNumber("+1.5558675309").build())
.setFaxNumber(new ContactPhoneNumber.Builder().setPhoneNumber("+1.5558675310").build())
.build());
}

View file

@ -35,7 +35,6 @@ import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.MediaType;
import com.googlecode.objectify.Key;
import google.registry.model.domain.DomainBase;
import google.registry.model.host.HostResource;
import google.registry.reporting.spec11.soy.Spec11EmailSoyInfo;
@ -375,7 +374,9 @@ public class Spec11EmailUtilsTest {
private static DomainBase persistDomainWithHost(String domainName, HostResource host) {
return persistResource(
newDomainBase(domainName).asBuilder().setNameservers(ImmutableSet.of(Key.create(host)))
newDomainBase(domainName)
.asBuilder()
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
}
}

View file

@ -123,28 +123,34 @@ public enum Fixture {
.build());
persistResource(
newDomainBase("love.xn--q9jyb4c", justine).asBuilder()
.setContacts(ImmutableSet.of(
DesignatedContact.create(ADMIN, Key.create(robert)),
DesignatedContact.create(BILLING, Key.create(google)),
DesignatedContact.create(TECH, Key.create(justine))))
.setNameservers(ImmutableSet.of(
Key.create(persistActiveHost("ns1.love.xn--q9jyb4c")),
Key.create(persistActiveHost("ns2.love.xn--q9jyb4c"))))
newDomainBase("love.xn--q9jyb4c", justine)
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(ADMIN, Key.create(robert)),
DesignatedContact.create(BILLING, Key.create(google)),
DesignatedContact.create(TECH, Key.create(justine))))
.setNameservers(
ImmutableSet.of(
persistActiveHost("ns1.love.xn--q9jyb4c").createKey(),
persistActiveHost("ns2.love.xn--q9jyb4c").createKey()))
.build());
persistResource(
newDomainBase("moogle.example", justine).asBuilder()
.setContacts(ImmutableSet.of(
DesignatedContact.create(ADMIN, Key.create(robert)),
DesignatedContact.create(BILLING, Key.create(google)),
DesignatedContact.create(TECH, Key.create(justine))))
.setNameservers(ImmutableSet.of(
Key.create(persistActiveHost("ns1.linode.com")),
Key.create(persistActiveHost("ns2.linode.com")),
Key.create(persistActiveHost("ns3.linode.com")),
Key.create(persistActiveHost("ns4.linode.com")),
Key.create(persistActiveHost("ns5.linode.com"))))
newDomainBase("moogle.example", justine)
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(ADMIN, Key.create(robert)),
DesignatedContact.create(BILLING, Key.create(google)),
DesignatedContact.create(TECH, Key.create(justine))))
.setNameservers(
ImmutableSet.of(
persistActiveHost("ns1.linode.com").createKey(),
persistActiveHost("ns2.linode.com").createKey(),
persistActiveHost("ns3.linode.com").createKey(),
persistActiveHost("ns4.linode.com").createKey(),
persistActiveHost("ns5.linode.com").createKey()))
.build());
persistResource(

View file

@ -138,7 +138,7 @@ public class DatastoreHelper {
public static DomainBase newDomainBase(String domainName, HostResource host) {
return newDomainBase(domainName)
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build();
}

View file

@ -40,6 +40,7 @@ import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarAddress;
import google.registry.model.registrar.RegistrarContact;
import google.registry.model.reporting.HistoryEntry;
import google.registry.persistence.VKey;
import google.registry.util.Idn;
import java.net.InetAddress;
import java.util.List;
@ -374,12 +375,12 @@ public final class FullFieldsTestEntityHelper {
builder.setContacts(contactsBuilder.build());
}
if ((ns1 != null) || (ns2 != null)) {
ImmutableSet.Builder<Key<HostResource>> nsBuilder = new ImmutableSet.Builder<>();
ImmutableSet.Builder<VKey<HostResource>> nsBuilder = new ImmutableSet.Builder<>();
if (ns1 != null) {
nsBuilder.add(Key.create(ns1));
nsBuilder.add(ns1.createKey());
}
if (ns2 != null) {
nsBuilder.add(Key.create(ns2));
nsBuilder.add(ns2.createKey());
}
builder.setNameservers(nsBuilder.build());
}

View file

@ -32,7 +32,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.net.InetAddresses;
import com.googlecode.objectify.Key;
import google.registry.model.domain.DomainBase;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.StatusValue;
@ -144,15 +143,23 @@ public class GenerateDnsReportCommandTest extends CommandTestCase<GenerateDnsRep
.build());
nameserver3 = persistActiveHost("ns1.google.com");
nameserver4 = persistActiveHost("ns2.google.com");
domain1 = persistResource(newDomainBase("example.xn--q9jyb4c").asBuilder()
.setNameservers(ImmutableSet.of(Key.create(nameserver1), Key.create(nameserver2)))
.setDsData(ImmutableSet.of(
DelegationSignerData.create(12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC")),
DelegationSignerData.create(56789, 2, 4, base16().decode("69FD46E6C4A45C55D4AC"))))
.build());
persistResource(newDomainBase("foobar.xn--q9jyb4c").asBuilder()
.setNameservers(ImmutableSet.of(Key.create(nameserver3), Key.create(nameserver4)))
.build());
domain1 =
persistResource(
newDomainBase("example.xn--q9jyb4c")
.asBuilder()
.setNameservers(ImmutableSet.of(nameserver1.createKey(), nameserver2.createKey()))
.setDsData(
ImmutableSet.of(
DelegationSignerData.create(
12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC")),
DelegationSignerData.create(
56789, 2, 4, base16().decode("69FD46E6C4A45C55D4AC"))))
.build());
persistResource(
newDomainBase("foobar.xn--q9jyb4c")
.asBuilder()
.setNameservers(ImmutableSet.of(nameserver3.createKey(), nameserver4.createKey()))
.build());
// Persist a domain in a different tld that should be ignored.
persistActiveDomain("should-be-ignored.example");
}

View file

@ -24,10 +24,10 @@ import static org.junit.Assert.assertThrows;
import com.beust.jcommander.ParameterException;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.persistence.VKey;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import org.junit.Before;
import org.junit.Test;
@ -53,9 +53,9 @@ public class UniformRapidSuspensionCommandTest
}
private void persistDomainWithHosts(HostResource... hosts) {
ImmutableSet.Builder<Key<HostResource>> hostRefs = new ImmutableSet.Builder<>();
ImmutableSet.Builder<VKey<HostResource>> hostRefs = new ImmutableSet.Builder<>();
for (HostResource host : hosts) {
hostRefs.add(Key.create(host));
hostRefs.add(host.createKey());
}
persistResource(newDomainBase("evil.tld").asBuilder()
.setNameservers(hostRefs.build())

View file

@ -31,6 +31,7 @@ import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.persistence.VKey;
import org.junit.Test;
/** Unit tests for {@link UpdateDomainCommand}. */
@ -116,12 +117,12 @@ public class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomain
persistResource(
newDomainBase("example.abc")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host1)))
.setNameservers(ImmutableSet.of(host1.createKey()))
.build());
persistResource(
newDomainBase("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host2)))
.setNameservers(ImmutableSet.of(host2.createKey()))
.build());
runCommandForced(
"--client=NewRegistrar", nsParam, "example.abc", "example.tld");
@ -171,8 +172,8 @@ public class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomain
public void testSuccess_setNameservers() throws Exception {
HostResource host1 = persistActiveHost("ns1.zdns.google");
HostResource host2 = persistActiveHost("ns2.zdns.google");
ImmutableSet<Key<HostResource>> nameservers =
ImmutableSet.of(Key.create(host1), Key.create(host2));
ImmutableSet<VKey<HostResource>> nameservers =
ImmutableSet.of(host1.createKey(), host2.createKey());
persistResource(
newDomainBase("example.tld").asBuilder().setNameservers(nameservers).build());
runCommandForced(
@ -213,7 +214,7 @@ public class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomain
@Test
public void testSuccess_setStatuses() throws Exception {
HostResource host = persistActiveHost("ns1.zdns.google");
ImmutableSet<Key<HostResource>> nameservers = ImmutableSet.of(Key.create(host));
ImmutableSet<VKey<HostResource>> nameservers = ImmutableSet.of(host.createKey());
persistResource(
newDomainBase("example.tld")
.asBuilder()
@ -257,7 +258,7 @@ public class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomain
@Test
public void testFailure_cantUpdateRegistryLockedDomainEvenAsSuperuser() {
HostResource host = persistActiveHost("ns1.zdns.google");
ImmutableSet<Key<HostResource>> nameservers = ImmutableSet.of(Key.create(host));
ImmutableSet<VKey<HostResource>> nameservers = ImmutableSet.of(host.createKey());
persistResource(
newDomainBase("example.tld")
.asBuilder()

View file

@ -34,10 +34,10 @@ import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.persistence.VKey;
import google.registry.testing.FakeClock;
import google.registry.testing.mapreduce.MapreduceTestCase;
import java.net.InetAddress;
@ -67,8 +67,8 @@ public class GenerateZoneFilesActionTest extends MapreduceTestCase<GenerateZoneF
HostResource host2 =
persistResource(newHostResource("ns.bar.tld").asBuilder().addInetAddresses(ips).build());
ImmutableSet<Key<HostResource>> nameservers =
ImmutableSet.of(Key.create(host1), Key.create(host2));
ImmutableSet<VKey<HostResource>> nameservers =
ImmutableSet.of(host1.createKey(), host2.createKey());
// This domain will have glue records, because it has a subordinate host which is its own
// nameserver. None of the other domains should have glue records, because their nameservers are
// subordinate to different domains.

View file

@ -37,6 +37,7 @@ import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarContact;
import google.registry.persistence.VKey;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.whois.WhoisResponse.WhoisResponseResults;
@ -220,8 +221,8 @@ public class DomainWhoisResponseTest {
.setEmailAddress("EMAIL@EXAMPLE.tld")
.build());
Key<HostResource> hostResource1Key = Key.create(hostResource1);
Key<HostResource> hostResource2Key = Key.create(hostResource2);
VKey<HostResource> hostResource1Key = hostResource1.createKey();
VKey<HostResource> hostResource2Key = hostResource2.createKey();
Key<ContactResource> registrantResourceKey = Key.create(registrant);
Key<ContactResource> adminResourceKey = Key.create(adminContact);
Key<ContactResource> techResourceKey = Key.create(techContact);