mirror of
https://github.com/google/nomulus.git
synced 2025-05-17 09:57:17 +02:00
Remove nearly all uses of ReferenceUnion
ReferenceUnion is a hack to work around the mismatch between how we store references (by roid) and how they are represented in EPP (by foreign key). If it ever needed to exist (not entirely clear...) it should have remained tightly scoped within the domain commands and resources. Instead it has leaked everywhere in the project, causing lots of boilerplate. This CL hides all of that behind standard Refs, and should be followed by work to remove ReferenceUnion completely. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=122424416
This commit is contained in:
parent
56c8bb0f2a
commit
9a2afc7a9b
59 changed files with 448 additions and 454 deletions
|
@ -36,7 +36,6 @@ import google.registry.model.EppResource.Builder;
|
|||
import google.registry.model.EppResource.ForeignKeyedEppResource;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.ReferenceUnion;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.index.ForeignKeyIndex;
|
||||
|
@ -139,12 +138,12 @@ public final class EppResourceUtils {
|
|||
latestOf(now, resource.getUpdateAutoTimestamp().getTimestamp()));
|
||||
}
|
||||
|
||||
/** Loads returns the hosts specified by the given ReferenceUnions. */
|
||||
/** Loads and returns the hosts specified by the given reference. */
|
||||
public static ImmutableSet<HostResource> loadReferencedNameservers(
|
||||
Set<ReferenceUnion<HostResource>> hostRefs) {
|
||||
Set<Ref<HostResource>> hostRefs) {
|
||||
ImmutableSet.Builder<HostResource> builder = new ImmutableSet.Builder<>();
|
||||
for (ReferenceUnion<HostResource> hostRef : hostRefs) {
|
||||
HostResource host = hostRef.getLinked().get();
|
||||
for (Ref<HostResource> hostRef : hostRefs) {
|
||||
HostResource host = hostRef.get();
|
||||
if (host != null) {
|
||||
builder.add(host);
|
||||
}
|
||||
|
@ -152,12 +151,12 @@ public final class EppResourceUtils {
|
|||
return builder.build();
|
||||
}
|
||||
|
||||
/** Loads and returns the contacts specified by the given ReferenceUnions. */
|
||||
/** Loads and returns the contacts specified by the given references. */
|
||||
public static ImmutableSet<ContactResource> loadReferencedContacts(
|
||||
Set<ReferenceUnion<ContactResource>> contactRefs) {
|
||||
Set<Ref<ContactResource>> contactRefs) {
|
||||
ImmutableSet.Builder<ContactResource> builder = new ImmutableSet.Builder<>();
|
||||
for (ReferenceUnion<ContactResource> contactRef : contactRefs) {
|
||||
builder.add(contactRef.getLinked().get());
|
||||
for (Ref<ContactResource> contactRef : contactRefs) {
|
||||
builder.add(contactRef.get());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ package google.registry.model.domain;
|
|||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import com.googlecode.objectify.Ref;
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
|
||||
|
@ -50,10 +51,10 @@ public class DesignatedContact extends ImmutableObject {
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static DesignatedContact create(Type type, ReferenceUnion<ContactResource> contact) {
|
||||
public static DesignatedContact create(Type type, Ref<ContactResource> contact) {
|
||||
DesignatedContact instance = new DesignatedContact();
|
||||
instance.type = type;
|
||||
instance.contactId = contact;
|
||||
instance.contactId = ReferenceUnion.create(contact);
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
@ -62,13 +63,14 @@ public class DesignatedContact extends ImmutableObject {
|
|||
|
||||
@Index
|
||||
@XmlValue
|
||||
//TODO(b/28713909): Make this a Ref<ContactResource>.
|
||||
ReferenceUnion<ContactResource> contactId;
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public ReferenceUnion<ContactResource> getContactId() {
|
||||
return contactId;
|
||||
public Ref<ContactResource> getContactRef() {
|
||||
return contactId.getLinked();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ package google.registry.model.domain;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.googlecode.objectify.Ref;
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
|
||||
import google.registry.model.EppResource;
|
||||
|
@ -38,9 +39,9 @@ public class DomainAuthInfo extends AuthInfo {
|
|||
checkNotNull(getPw());
|
||||
if (getRepoId() != null) {
|
||||
// Make sure the repo id matches one of the contacts on the domain.
|
||||
ReferenceUnion<ContactResource> foundContact = null;
|
||||
for (ReferenceUnion<ContactResource> contact : domain.getReferencedContacts()) {
|
||||
String contactRepoId = contact.getLinked().getKey().getName();
|
||||
Ref<ContactResource> foundContact = null;
|
||||
for (Ref<ContactResource> contact : domain.getReferencedContacts()) {
|
||||
String contactRepoId = contact.getKey().getName();
|
||||
if (getRepoId().equals(contactRepoId)) {
|
||||
foundContact = contact;
|
||||
break;
|
||||
|
@ -50,7 +51,7 @@ public class DomainAuthInfo extends AuthInfo {
|
|||
throw new BadAuthInfoException();
|
||||
}
|
||||
// Check if the password provided matches the password on the referenced contact.
|
||||
if (!foundContact.getLinked().get().getAuthInfo().getPw().getValue().equals(
|
||||
if (!foundContact.get().getAuthInfo().getPw().getValue().equals(
|
||||
getPw().getValue())) {
|
||||
throw new BadAuthInfoException();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import static com.google.common.base.Strings.isNullOrEmpty;
|
|||
import static com.google.common.collect.Sets.difference;
|
||||
import static com.google.common.collect.Sets.union;
|
||||
import static google.registry.model.domain.DesignatedContact.Type.REGISTRANT;
|
||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy;
|
||||
import static google.registry.util.CollectionUtils.union;
|
||||
|
@ -27,6 +28,7 @@ import static google.registry.util.DomainNameUtils.getTldFromSld;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
|
||||
import com.googlecode.objectify.Ref;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.IgnoreSave;
|
||||
|
@ -74,6 +76,7 @@ public abstract class DomainBase extends EppResource {
|
|||
/** References to hosts that are the nameservers for the domain. */
|
||||
@XmlElementWrapper(name = "ns")
|
||||
@XmlElement(name = "hostObj")
|
||||
//TODO(b/28713909): Make this a Set<Ref<HostResource>>.
|
||||
Set<ReferenceUnion<HostResource>> nameservers;
|
||||
|
||||
/**
|
||||
|
@ -102,6 +105,7 @@ public abstract class DomainBase extends EppResource {
|
|||
* both stored in {@link DomainBase#allContacts} to allow for more efficient queries.
|
||||
*/
|
||||
@Ignore
|
||||
//TODO(b/28713909): Make this a Ref<ContactResource>.
|
||||
ReferenceUnion<ContactResource> registrant;
|
||||
|
||||
/** Authorization info (aka transfer secret) of the domain. */
|
||||
|
@ -149,8 +153,12 @@ public abstract class DomainBase extends EppResource {
|
|||
return idnTableName;
|
||||
}
|
||||
|
||||
public ImmutableSet<ReferenceUnion<HostResource>> getNameservers() {
|
||||
return nullToEmptyImmutableCopy(nameservers);
|
||||
public ImmutableSet<Ref<HostResource>> getNameservers() {
|
||||
ImmutableSet.Builder<Ref<HostResource>> builder = new ImmutableSet.Builder<>();
|
||||
for (ReferenceUnion<HostResource> union : nullToEmptyImmutableCopy(nameservers)) {
|
||||
builder.add(union.getLinked());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/** Loads and returns all linked nameservers. */
|
||||
|
@ -158,12 +166,12 @@ public abstract class DomainBase extends EppResource {
|
|||
return EppResourceUtils.loadReferencedNameservers(getNameservers());
|
||||
}
|
||||
|
||||
public ReferenceUnion<ContactResource> getRegistrant() {
|
||||
return registrant;
|
||||
public Ref<ContactResource> getRegistrant() {
|
||||
return registrant == null ? null : registrant.getLinked();
|
||||
}
|
||||
|
||||
public ContactResource loadRegistrant() {
|
||||
return registrant.getLinked().get();
|
||||
return getRegistrant().get();
|
||||
}
|
||||
|
||||
public ImmutableSet<DesignatedContact> getContacts() {
|
||||
|
@ -175,11 +183,11 @@ public abstract class DomainBase extends EppResource {
|
|||
}
|
||||
|
||||
/** Returns all referenced contacts from this domain or application. */
|
||||
public ImmutableSet<ReferenceUnion<ContactResource>> getReferencedContacts() {
|
||||
ImmutableSet.Builder<ReferenceUnion<ContactResource>> contactsBuilder =
|
||||
public ImmutableSet<Ref<ContactResource>> getReferencedContacts() {
|
||||
ImmutableSet.Builder<Ref<ContactResource>> contactsBuilder =
|
||||
new ImmutableSet.Builder<>();
|
||||
for (DesignatedContact designated : nullToEmptyImmutableCopy(allContacts)) {
|
||||
contactsBuilder.add(designated.getContactId());
|
||||
contactsBuilder.add(designated.getContactRef());
|
||||
}
|
||||
return contactsBuilder.build();
|
||||
}
|
||||
|
@ -202,7 +210,7 @@ public abstract class DomainBase extends EppResource {
|
|||
ImmutableSet.Builder<DesignatedContact> contactsBuilder = new ImmutableSet.Builder<>();
|
||||
for (DesignatedContact contact : nullToEmptyImmutableCopy(allContacts)) {
|
||||
if (REGISTRANT.equals(contact.getType())){
|
||||
registrant = contact.getContactId();
|
||||
registrant = ReferenceUnion.create(contact.getContactRef());
|
||||
} else {
|
||||
contactsBuilder.add(contact);
|
||||
}
|
||||
|
@ -229,8 +237,11 @@ public abstract class DomainBase extends EppResource {
|
|||
checkState(
|
||||
!isNullOrEmpty(instance.fullyQualifiedDomainName), "Missing fullyQualifiedDomainName");
|
||||
instance.tld = getTldFromSld(instance.fullyQualifiedDomainName);
|
||||
instance.allContacts = instance.registrant == null ? instance.contacts : union(
|
||||
instance.getContacts(), DesignatedContact.create(REGISTRANT, instance.registrant));
|
||||
instance.allContacts = instance.registrant == null
|
||||
? instance.contacts
|
||||
: union(
|
||||
instance.getContacts(),
|
||||
DesignatedContact.create(REGISTRANT, instance.registrant.getLinked()));
|
||||
return super.build();
|
||||
}
|
||||
|
||||
|
@ -244,8 +255,8 @@ public abstract class DomainBase extends EppResource {
|
|||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setRegistrant(ReferenceUnion<ContactResource> registrant) {
|
||||
getInstance().registrant = registrant;
|
||||
public B setRegistrant(Ref<ContactResource> registrant) {
|
||||
getInstance().registrant = ReferenceUnion.create(registrant);
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
|
@ -254,17 +265,21 @@ public abstract class DomainBase extends EppResource {
|
|||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setNameservers(ImmutableSet<ReferenceUnion<HostResource>> nameservers) {
|
||||
getInstance().nameservers = nameservers;
|
||||
public B setNameservers(ImmutableSet<Ref<HostResource>> nameservers) {
|
||||
ImmutableSet.Builder<ReferenceUnion<HostResource>> builder = new ImmutableSet.Builder<>();
|
||||
for (Ref<HostResource> ref : nullToEmpty(nameservers)) {
|
||||
builder.add(ReferenceUnion.create(ref));
|
||||
}
|
||||
getInstance().nameservers = builder.build();
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B addNameservers(ImmutableSet<ReferenceUnion<HostResource>> nameservers) {
|
||||
public B addNameservers(ImmutableSet<Ref<HostResource>> nameservers) {
|
||||
return setNameservers(
|
||||
ImmutableSet.copyOf(union(getInstance().getNameservers(), nameservers)));
|
||||
}
|
||||
|
||||
public B removeNameservers(ImmutableSet<ReferenceUnion<HostResource>> nameservers) {
|
||||
public B removeNameservers(ImmutableSet<Ref<HostResource>> nameservers) {
|
||||
return setNameservers(
|
||||
ImmutableSet.copyOf(difference(getInstance().getNameservers(), nameservers)));
|
||||
}
|
||||
|
|
|
@ -74,12 +74,25 @@ public class DomainCommand {
|
|||
public static class DomainCreateOrChange<B extends DomainBase.Builder<?, ?>>
|
||||
extends ImmutableObject implements ResourceCreateOrChange<B> {
|
||||
|
||||
/** A reference to the registrant who registered this domain. */
|
||||
ReferenceUnion<ContactResource> registrant;
|
||||
/** The contactId of the registrant who registered this domain. */
|
||||
@XmlElement(name = "registrant")
|
||||
String registrantContactId;
|
||||
|
||||
/** A resolved reference to the registrant who registered this domain. */
|
||||
@XmlTransient
|
||||
Ref<ContactResource> registrant;
|
||||
|
||||
/** Authorization info (aka transfer secret) of the domain. */
|
||||
DomainAuthInfo authInfo;
|
||||
|
||||
public String getRegistrantContactId() {
|
||||
return registrantContactId;
|
||||
}
|
||||
|
||||
public Ref<ContactResource> getRegistrant() {
|
||||
return registrant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(B builder) {
|
||||
if (registrant != null) {
|
||||
|
@ -97,7 +110,12 @@ public class DomainCommand {
|
|||
*/
|
||||
@XmlRootElement
|
||||
@XmlType(propOrder = {
|
||||
"fullyQualifiedDomainName", "period", "nameservers", "registrant", "contacts", "authInfo" })
|
||||
"fullyQualifiedDomainName",
|
||||
"period",
|
||||
"nameserverFullyQualifiedHostNames",
|
||||
"registrantContactId",
|
||||
"foreignKeyedDesignatedContacts",
|
||||
"authInfo"})
|
||||
public static class Create
|
||||
extends DomainCreateOrChange<DomainBase.Builder<?, ?>>
|
||||
implements CreateOrUpdate<Create> {
|
||||
|
@ -106,13 +124,21 @@ public class DomainCommand {
|
|||
@XmlElement(name = "name")
|
||||
String fullyQualifiedDomainName;
|
||||
|
||||
/** References to hosts that are the nameservers for the domain. */
|
||||
/** Fully qualified host names of the hosts that are the nameservers for the domain. */
|
||||
@XmlElementWrapper(name = "ns")
|
||||
@XmlElement(name = "hostObj")
|
||||
Set<ReferenceUnion<HostResource>> nameservers;
|
||||
Set<String> nameserverFullyQualifiedHostNames;
|
||||
|
||||
/** Associated contacts for the domain (other than registrant). */
|
||||
/** Resolved references to hosts that are the nameservers for the domain. */
|
||||
@XmlTransient
|
||||
Set<Ref<HostResource>> nameservers;
|
||||
|
||||
/** Foreign keyed associated contacts for the domain (other than registrant). */
|
||||
@XmlElement(name = "contact")
|
||||
Set<ForeignKeyedDesignatedContact> foreignKeyedDesignatedContacts;
|
||||
|
||||
/** Resolved references to associated contacts for the domain (other than registrant). */
|
||||
@XmlTransient
|
||||
Set<DesignatedContact> contacts;
|
||||
|
||||
/** The period that this domain's state was set to last for (e.g. 1-10 years). */
|
||||
|
@ -131,7 +157,11 @@ public class DomainCommand {
|
|||
return fullyQualifiedDomainName;
|
||||
}
|
||||
|
||||
public ImmutableSet<ReferenceUnion<HostResource>> getNameservers() {
|
||||
public ImmutableSet<String> getNameserverFullyQualifiedHostNames() {
|
||||
return nullSafeImmutableCopy(nameserverFullyQualifiedHostNames);
|
||||
}
|
||||
|
||||
public ImmutableSet<Ref<HostResource>> getNameservers() {
|
||||
return nullSafeImmutableCopy(nameservers);
|
||||
}
|
||||
|
||||
|
@ -139,11 +169,7 @@ public class DomainCommand {
|
|||
return nullSafeImmutableCopy(contacts);
|
||||
}
|
||||
|
||||
public ReferenceUnion<ContactResource> getRegistrant() {
|
||||
return registrant;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public AuthInfo getAuthInfo() {
|
||||
return authInfo;
|
||||
}
|
||||
|
@ -166,10 +192,10 @@ public class DomainCommand {
|
|||
@Override
|
||||
public Create cloneAndLinkReferences(DateTime now) throws InvalidReferenceException {
|
||||
Create clone = clone(this);
|
||||
clone.nameservers = linkHosts(clone.nameservers, now);
|
||||
clone.contacts = linkContacts(clone.contacts, now);
|
||||
clone.registrant = clone.registrant == null
|
||||
? null : linkReference(clone.registrant, ContactResource.class, now);
|
||||
clone.nameservers = linkHosts(clone.nameserverFullyQualifiedHostNames, now);
|
||||
clone.contacts = linkContacts(clone.foreignKeyedDesignatedContacts, now);
|
||||
clone.registrant = clone.registrantContactId == null
|
||||
? null : loadReference(clone.registrantContactId, ContactResource.class, now);
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
@ -317,18 +343,33 @@ public class DomainCommand {
|
|||
}
|
||||
|
||||
/** The inner change type on a domain update command. */
|
||||
@XmlType(propOrder = {"nameservers", "contacts", "statusValues"})
|
||||
@XmlType(propOrder = {
|
||||
"nameserverFullyQualifiedHostNames",
|
||||
"foreignKeyedDesignatedContacts",
|
||||
"statusValues"})
|
||||
public static class AddRemove extends ResourceUpdate.AddRemove {
|
||||
/** References to hosts that are the nameservers for the domain. */
|
||||
/** Fully qualified host names of the hosts that are the nameservers for the domain. */
|
||||
@XmlElementWrapper(name = "ns")
|
||||
@XmlElement(name = "hostObj")
|
||||
Set<ReferenceUnion<HostResource>> nameservers;
|
||||
Set<String> nameserverFullyQualifiedHostNames;
|
||||
|
||||
/** Associated contacts for the domain. */
|
||||
/** Resolved references to hosts that are the nameservers for the domain. */
|
||||
@XmlTransient
|
||||
Set<Ref<HostResource>> nameservers;
|
||||
|
||||
/** Foreign keyed associated contacts for the domain (other than registrant). */
|
||||
@XmlElement(name = "contact")
|
||||
Set<ForeignKeyedDesignatedContact> foreignKeyedDesignatedContacts;
|
||||
|
||||
/** Resolved references to associated contacts for the domain (other than registrant). */
|
||||
@XmlTransient
|
||||
Set<DesignatedContact> contacts;
|
||||
|
||||
public ImmutableSet<ReferenceUnion<HostResource>> getNameservers() {
|
||||
public ImmutableSet<String> getNameserverFullyQualifiedHostNames() {
|
||||
return nullSafeImmutableCopy(nameserverFullyQualifiedHostNames);
|
||||
}
|
||||
|
||||
public ImmutableSet<Ref<HostResource>> getNameservers() {
|
||||
return nullToEmptyImmutableCopy(nameservers);
|
||||
}
|
||||
|
||||
|
@ -339,25 +380,20 @@ public class DomainCommand {
|
|||
/** Creates a copy of this {@link AddRemove} with hard links to hosts and contacts. */
|
||||
private AddRemove cloneAndLinkReferences(DateTime now) throws InvalidReferenceException {
|
||||
AddRemove clone = clone(this);
|
||||
clone.nameservers = linkHosts(clone.nameservers, now);
|
||||
clone.contacts = linkContacts(clone.contacts, now);
|
||||
clone.nameservers = linkHosts(clone.nameserverFullyQualifiedHostNames, now);
|
||||
clone.contacts = linkContacts(clone.foreignKeyedDesignatedContacts, now);
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
/** The inner change type on a domain update command. */
|
||||
@XmlType(propOrder = {"registrant", "authInfo"})
|
||||
@XmlType(propOrder = {"registrantContactId", "authInfo"})
|
||||
public static class Change extends DomainCreateOrChange<DomainBase.Builder<?, ?>> {
|
||||
|
||||
public ReferenceUnion<ContactResource> getRegistrant() {
|
||||
return registrant;
|
||||
}
|
||||
|
||||
/** Creates a copy of this {@link Change} with hard links to hosts and contacts. */
|
||||
Change cloneAndLinkReferences(DateTime now) throws InvalidReferenceException {
|
||||
Change clone = clone(this);
|
||||
clone.registrant = clone.registrant == null
|
||||
? null : linkReference(clone.registrant, ContactResource.class, now);
|
||||
clone.registrant = clone.registrantContactId == null
|
||||
? null : loadReference(clone.registrantContactId, ContactResource.class, now);
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
@ -396,50 +432,59 @@ public class DomainCommand {
|
|||
}
|
||||
}
|
||||
|
||||
private static Set<ReferenceUnion<HostResource>> linkHosts(
|
||||
Set<ReferenceUnion<HostResource>> hosts,
|
||||
DateTime now) throws InvalidReferenceException {
|
||||
if (hosts == null) {
|
||||
private static Set<Ref<HostResource>> linkHosts(
|
||||
Set<String> fullyQualifiedHostNames, DateTime now) throws InvalidReferenceException {
|
||||
if (fullyQualifiedHostNames == null) {
|
||||
return null;
|
||||
}
|
||||
ImmutableSet.Builder<ReferenceUnion<HostResource>> linked = new ImmutableSet.Builder<>();
|
||||
for (ReferenceUnion<HostResource> host : hosts) {
|
||||
linked.add(linkReference(host, HostResource.class, now));
|
||||
ImmutableSet.Builder<Ref<HostResource>> linked = new ImmutableSet.Builder<>();
|
||||
for (String fullyQualifiedHostName : fullyQualifiedHostNames) {
|
||||
linked.add(loadReference(fullyQualifiedHostName, HostResource.class, now));
|
||||
}
|
||||
return linked.build();
|
||||
}
|
||||
|
||||
private static Set<DesignatedContact> linkContacts(
|
||||
Set<DesignatedContact> contacts, DateTime now) throws InvalidReferenceException {
|
||||
Set<ForeignKeyedDesignatedContact> contacts, DateTime now) throws InvalidReferenceException {
|
||||
if (contacts == null) {
|
||||
return null;
|
||||
}
|
||||
ImmutableSet.Builder<DesignatedContact> linkedContacts = new ImmutableSet.Builder<>();
|
||||
for (DesignatedContact contact : contacts) {
|
||||
for (ForeignKeyedDesignatedContact contact : contacts) {
|
||||
linkedContacts.add(DesignatedContact.create(
|
||||
contact.getType(),
|
||||
linkReference(contact.getContactId(), ContactResource.class, now)));
|
||||
contact.type, loadReference(contact.contactId, ContactResource.class, now)));
|
||||
}
|
||||
return linkedContacts.build();
|
||||
}
|
||||
|
||||
/** Turn a foreign-keyed {@link ReferenceUnion} into a linked one. */
|
||||
private static <T extends EppResource> ReferenceUnion<T> linkReference(
|
||||
final ReferenceUnion<T> reference, final Class<T> clazz, final DateTime now)
|
||||
/** Load a reference to a resource by its foreign key. */
|
||||
private static <T extends EppResource> Ref<T> loadReference(
|
||||
final String foreignKey, final Class<T> clazz, final DateTime now)
|
||||
throws InvalidReferenceException {
|
||||
if (reference.getForeignKey() == null) {
|
||||
return reference;
|
||||
}
|
||||
Ref<T> ref = ofy().doTransactionless(new Work<Ref<T>>() {
|
||||
@Override
|
||||
public Ref<T> run() {
|
||||
return loadAndGetReference(clazz, reference.getForeignKey(), now);
|
||||
return loadAndGetReference(clazz, foreignKey, now);
|
||||
}
|
||||
});
|
||||
if (ref == null) {
|
||||
throw new InvalidReferenceException(clazz, reference.getForeignKey());
|
||||
throw new InvalidReferenceException(clazz, foreignKey);
|
||||
}
|
||||
return ReferenceUnion.create(ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* EPP-inputable version of XML type for contact identifiers associated with a domain, which can
|
||||
* be converted to a storable (and EPP-outputable) {@link DesignatedContact}.
|
||||
*
|
||||
* @see "http://tools.ietf.org/html/rfc5731#section-2.2"
|
||||
*/
|
||||
static class ForeignKeyedDesignatedContact extends ImmutableObject {
|
||||
@XmlAttribute(required = true)
|
||||
DesignatedContact.Type type;
|
||||
|
||||
@XmlValue
|
||||
String contactId;
|
||||
}
|
||||
|
||||
/** Exception to throw when a referenced object does not exist. */
|
||||
|
|
|
@ -16,7 +16,6 @@ package google.registry.model.domain;
|
|||
|
||||
import com.googlecode.objectify.Ref;
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
|
||||
import google.registry.model.EppResource;
|
||||
|
@ -24,81 +23,50 @@ import google.registry.model.ImmutableObject;
|
|||
import google.registry.model.contact.ContactResource;
|
||||
import google.registry.model.host.HostResource;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
/**
|
||||
* A "union" type to represent referenced objects as either a foreign key or as a link to another
|
||||
* object in the datastore.
|
||||
* Legacy shell of a "union" type to represent referenced objects as either a foreign key or as a
|
||||
* link to another object in the datastore. In its current form it merely wraps a {@link Ref}.
|
||||
* <p>
|
||||
* This type always marshals as the "foreign key". When it is explicitly storing a foreign key it
|
||||
* gets the value from its own string field. When it is linked to another object, it gets the value
|
||||
* from the other object.
|
||||
* <p>
|
||||
* When a {@link ReferenceUnion} comes in from Epp, either in an update or a delete, it fills in the
|
||||
* "foreign key" string field, but as soon as the relevant Flow runs it deletes that field and
|
||||
* replaces it with a linked {@link Ref} to the object named by that string. We can't do this in a
|
||||
* {@code XmlJavaTypeAdapter} because failing a lookup is a business logic error, not a failure to
|
||||
* parse the XML.
|
||||
* This type always marshals as the "foreign key". We no longer use this type for unmarshalling.
|
||||
*
|
||||
* @param <T> the type being referenced
|
||||
*/
|
||||
@Embed
|
||||
public class ReferenceUnion<T extends EppResource> extends ImmutableObject implements Serializable {
|
||||
public class ReferenceUnion<T extends EppResource> extends ImmutableObject {
|
||||
|
||||
@Index
|
||||
Ref<T> linked;
|
||||
|
||||
/** This is never persisted, and only ever populated to marshal or unmarshal to or from XML. */
|
||||
@Ignore
|
||||
String foreignKey;
|
||||
|
||||
public Ref<T> getLinked() {
|
||||
return linked;
|
||||
}
|
||||
|
||||
public String getForeignKey() {
|
||||
return foreignKey;
|
||||
}
|
||||
|
||||
/** An adapter that is aware of the union inside {@link ReferenceUnion}. */
|
||||
/** An adapter that marshals the linked {@link Ref} as its loaded foreign key. */
|
||||
public static class Adapter<T extends EppResource>
|
||||
extends XmlAdapter<String, ReferenceUnion<T>> {
|
||||
|
||||
@Override
|
||||
public ReferenceUnion<T> unmarshal(String foreignKey) throws Exception {
|
||||
return ReferenceUnion.<T>create(foreignKey);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String marshal(ReferenceUnion<T> reference) throws Exception {
|
||||
return reference.getForeignKey() == null
|
||||
? reference.getLinked().get().getForeignKey()
|
||||
: reference.getForeignKey();
|
||||
return reference.getLinked().get().getForeignKey();
|
||||
}
|
||||
}
|
||||
|
||||
/** An adapter for references to contacts. */
|
||||
static class ContactReferenceUnionAdapter extends ReferenceUnion.Adapter<ContactResource>{}
|
||||
static class ContactReferenceUnionAdapter extends Adapter<ContactResource>{}
|
||||
|
||||
/** An adapter for references to hosts. */
|
||||
static class HostReferenceUnionAdapter extends ReferenceUnion.Adapter<HostResource>{}
|
||||
|
||||
public static <T extends EppResource> ReferenceUnion<T> create(String foreignKey) {
|
||||
ReferenceUnion<T> instance = new ReferenceUnion<>();
|
||||
instance.foreignKey = foreignKey;
|
||||
return instance;
|
||||
}
|
||||
static class HostReferenceUnionAdapter extends Adapter<HostResource>{}
|
||||
|
||||
public static <T extends EppResource> ReferenceUnion<T> create(Ref<T> linked) {
|
||||
ReferenceUnion<T> instance = new ReferenceUnion<>();
|
||||
instance.linked = linked;
|
||||
return instance;
|
||||
}
|
||||
|
||||
/** Convenience method. */
|
||||
public static <T extends EppResource> ReferenceUnion<T> create(T resource) {
|
||||
return create(Ref.create(resource));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue