Create *InfoData objects instead of reusing *Resource objects

This is probably best from a code-cleanliness perspective anyways,
but the rationale is that tightly coupling the resources to the
info responses was a straightjacket that required all status
values and fields to be directly available on the resource. With
this change, I already was able to get rid of the preMarshal()
hackery, and I will be able to get rid of cloneWithLinkedStatus()
and most of the contents of cloneProjectedAtTime() for non-domains.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=144252924
This commit is contained in:
cgoldfeder 2017-01-11 14:49:10 -08:00 committed by Ben McIlwain
parent 96a71ded91
commit b0bcc1bb3d
22 changed files with 586 additions and 230 deletions

View file

@ -25,6 +25,7 @@ import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.model.contact.ContactInfoData;
import google.registry.model.contact.ContactResource;
import google.registry.model.eppcommon.AuthInfo;
import google.registry.model.eppoutput.EppResponse;
@ -59,9 +60,27 @@ public final class ContactInfoFlow implements Flow {
validateClientIsLoggedIn(clientId);
ContactResource contact = loadAndVerifyExistence(ContactResource.class, targetId, now);
verifyOptionalAuthInfo(authInfo, contact);
if (!clientId.equals(contact.getCurrentSponsorClientId()) && !authInfo.isPresent()) {
contact = contact.asBuilder().setAuthInfo(null).build();
}
return responseBuilder.setResData(cloneResourceWithLinkedStatus(contact, now)).build();
contact = (ContactResource) cloneResourceWithLinkedStatus(contact, now);
boolean includeAuthInfo =
clientId.equals(contact.getCurrentSponsorClientId()) || authInfo.isPresent();
return responseBuilder
.setResData(ContactInfoData.newBuilder()
.setContactId(contact.getContactId())
.setRepoId(contact.getRepoId())
.setStatusValues(contact.getStatusValues())
.setPostalInfos(contact.getPostalInfosAsList())
.setVoiceNumber(contact.getVoiceNumber())
.setFaxNumber(contact.getFaxNumber())
.setEmailAddress(contact.getEmailAddress())
.setCurrentSponsorClientId(contact.getCurrentSponsorClientId())
.setCreationClientId(contact.getCreationClientId())
.setCreationTime(contact.getCreationTime())
.setLastEppUpdateClientId(contact.getLastEppUpdateClientId())
.setLastEppUpdateTime(contact.getLastEppUpdateTime())
.setLastTransferTime(contact.getLastTransferTime())
.setAuthInfo(includeAuthInfo ? contact.getAuthInfo() : null)
.setDisclose(contact.getDisclose())
.build())
.build();
}
}

View file

@ -20,8 +20,11 @@ import static google.registry.flows.ResourceFlowUtils.verifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
import static google.registry.flows.domain.DomainFlowUtils.addSecDnsExtensionIfPresent;
import static google.registry.flows.domain.DomainFlowUtils.loadForeignKeyedDesignatedContacts;
import static google.registry.flows.domain.DomainFlowUtils.prefetchReferencedResources;
import static google.registry.flows.domain.DomainFlowUtils.verifyApplicationDomainMatchesTargetId;
import static google.registry.model.EppResourceUtils.loadDomainApplication;
import static google.registry.model.ofy.ObjectifyService.ofy;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
@ -35,6 +38,7 @@ import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.model.domain.DomainApplication;
import google.registry.model.domain.DomainCommand.Info;
import google.registry.model.domain.DomainInfoData;
import google.registry.model.domain.launch.LaunchInfoExtension;
import google.registry.model.domain.launch.LaunchInfoResponseExtension;
import google.registry.model.eppcommon.AuthInfo;
@ -95,8 +99,23 @@ public final class DomainApplicationInfoFlow implements Flow {
}
// We don't support authInfo for applications, so if it's another registrar always fail.
verifyResourceOwnership(clientId, application);
application = getResourceInfo(application);
prefetchReferencedResources(application);
return responseBuilder
.setResData(getResourceInfo(application))
.setResData(DomainInfoData.newBuilder()
.setFullyQualifiedDomainName(application.getFullyQualifiedDomainName())
.setRepoId(application.getRepoId())
.setStatusValues(application.getStatusValues())
.setRegistrant(ofy().load().key(application.getRegistrant()).now().getContactId())
.setContacts(loadForeignKeyedDesignatedContacts(application.getContacts()))
.setNameservers(application.loadNameserverFullyQualifiedHostNames())
.setCurrentSponsorClientId(application.getCurrentSponsorClientId())
.setCreationClientId(application.getCreationClientId())
.setCreationTime(application.getCreationTime())
.setLastEppUpdateClientId(application.getLastEppUpdateClientId())
.setLastEppUpdateTime(application.getLastEppUpdateTime())
.setAuthInfo(application.getAuthInfo())
.build())
.setExtensions(getDomainResponseExtensions(application, launchInfo, now))
.build();
}

View file

@ -70,6 +70,7 @@ import google.registry.model.domain.DomainCommand.CreateOrUpdate;
import google.registry.model.domain.DomainCommand.InvalidReferencesException;
import google.registry.model.domain.DomainCommand.Update;
import google.registry.model.domain.DomainResource;
import google.registry.model.domain.ForeignKeyedDesignatedContact;
import google.registry.model.domain.LrpTokenEntity;
import google.registry.model.domain.Period;
import google.registry.model.domain.fee.Credit;
@ -896,6 +897,23 @@ public class DomainFlowUtils {
.build();
}
/** Bulk-load all referenced resources on a domain so they are in the session cache. */
static void prefetchReferencedResources(DomainBase domain) {
// Calling values() on the result blocks until loading is done.
ofy().load().values(union(domain.getNameservers(), domain.getReferencedContacts())).values();
}
static ImmutableSet<ForeignKeyedDesignatedContact> loadForeignKeyedDesignatedContacts(
ImmutableSet<DesignatedContact> contacts) {
ImmutableSet.Builder<ForeignKeyedDesignatedContact> builder = new ImmutableSet.Builder<>();
for (DesignatedContact contact : contacts) {
builder.add(ForeignKeyedDesignatedContact.create(
contact.getType(),
ofy().load().key(contact.getContactKey()).now().getContactId()));
}
return builder.build();
}
/** Resource linked to this domain does not exist. */
static class LinkedResourcesDoNotExistException extends ObjectDoesNotExistException {
public LinkedResourcesDoNotExistException(Class<?> type, ImmutableSet<String> resourceIds) {

View file

@ -19,6 +19,9 @@ import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
import static google.registry.flows.domain.DomainFlowUtils.addSecDnsExtensionIfPresent;
import static google.registry.flows.domain.DomainFlowUtils.handleFeeRequest;
import static google.registry.flows.domain.DomainFlowUtils.loadForeignKeyedDesignatedContacts;
import static google.registry.flows.domain.DomainFlowUtils.prefetchReferencedResources;
import static google.registry.model.ofy.ObjectifyService.ofy;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
@ -35,6 +38,7 @@ import google.registry.flows.custom.DomainInfoFlowCustomLogic.BeforeResponsePara
import google.registry.flows.custom.DomainInfoFlowCustomLogic.BeforeResponseReturnData;
import google.registry.model.domain.DomainCommand.Info;
import google.registry.model.domain.DomainCommand.Info.HostsRequest;
import google.registry.model.domain.DomainInfoData;
import google.registry.model.domain.DomainResource;
import google.registry.model.domain.DomainResource.Builder;
import google.registry.model.domain.fee06.FeeInfoCommandExtensionV06;
@ -97,8 +101,26 @@ public final class DomainInfoFlow implements Flow {
.setResData(getResourceInfo(domain))
.setResponseExtensions(getDomainResponseExtensions(domain, now))
.build());
domain = responseData.resData();
prefetchReferencedResources(domain);
return responseBuilder
.setResData(responseData.resData())
.setResData(DomainInfoData.newBuilder()
.setFullyQualifiedDomainName(domain.getFullyQualifiedDomainName())
.setRepoId(domain.getRepoId())
.setStatusValues(domain.getStatusValues())
.setRegistrant(ofy().load().key(domain.getRegistrant()).now().getContactId())
.setContacts(loadForeignKeyedDesignatedContacts(domain.getContacts()))
.setNameservers(domain.loadNameserverFullyQualifiedHostNames())
.setSubordinateHosts(domain.getSubordinateHosts())
.setCurrentSponsorClientId(domain.getCurrentSponsorClientId())
.setCreationClientId(domain.getCreationClientId())
.setCreationTime(domain.getCreationTime())
.setLastEppUpdateClientId(domain.getLastEppUpdateClientId())
.setLastEppUpdateTime(domain.getLastEppUpdateTime())
.setRegistrationExpirationTime(domain.getRegistrationExpirationTime())
.setLastTransferTime(domain.getLastTransferTime())
.setAuthInfo(domain.getAuthInfo())
.build())
.setExtensions(responseData.responseExtensions())
.build();
}

View file

@ -25,6 +25,7 @@ import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.model.eppoutput.EppResponse;
import google.registry.model.host.HostInfoData;
import google.registry.model.host.HostResource;
import google.registry.util.Clock;
import javax.inject.Inject;
@ -53,10 +54,24 @@ public final class HostInfoFlow implements Flow {
@Override
public EppResponse run() throws EppException {
extensionManager.validate(); // There are no legal extensions for this flow.
validateClientIsLoggedIn(clientId);
validateClientIsLoggedIn(clientId);
validateHostName(targetId);
DateTime now = clock.nowUtc();
HostResource host = loadAndVerifyExistence(HostResource.class, targetId, now);
return responseBuilder.setResData(cloneResourceWithLinkedStatus(host, now)).build();
host = (HostResource) cloneResourceWithLinkedStatus(host, now);
return responseBuilder
.setResData(HostInfoData.newBuilder()
.setFullyQualifiedHostName(host.getFullyQualifiedHostName())
.setRepoId(host.getRepoId())
.setStatusValues(host.getStatusValues())
.setInetAddresses(host.getInetAddresses())
.setCurrentSponsorClientId(host.getCurrentSponsorClientId())
.setCreationClientId(host.getCreationClientId())
.setCreationTime(host.getCreationTime())
.setLastEppUpdateClientId(host.getLastEppUpdateClientId())
.setLastEppUpdateTime(host.getLastEppUpdateTime())
.setLastTransferTime(host.getLastTransferTime())
.build())
.build();
}
}