1
0
mirror of https://github.com/google/nomulus synced 2026-02-21 12:29:11 +00:00

Compare commits

..

7 Commits

Author SHA1 Message Date
gbrodman
ee8746c857 Remove Contact and ContactHistory Java objects and related code (#2964)
This doesn't remove everything -- there are still other contact-related
objects that we'll need to remove (e.g.
ContactPendingActionNotificationResponse) and simplifications we'll need to make
(e.g. only domains can be transferred now, so all transfer data can move
there instead of being generic)

But this removes the bulk of the remaining contact-related code. We'll
keep around the XML request objects, since it's still nice to route them
to the appropriate (exception-throwing but logging) flow class.
2026-02-20 16:22:29 +00:00
gbrodman
c7f2db177b Forbid contacts earlier in the domain EPP parsing process (#2962)
This will make testing easier, as well as allow us to remove contact
code from other parts of the codebase.
2026-02-19 21:33:29 +00:00
Weimin Yu
6747cc894d Activate Fee tag normalization in Non-Prod (#2963)
For all flows that use Fee extensions, normalize the fee tags in all
non-prod environments.

For flows that do not use fee extensions but with fee tags in the
header, e.g., HostInfo flows, normalization is not performed.
2026-02-19 20:04:27 +00:00
gbrodman
e4c4149033 Remove more unused contact references (#2961)
This avoids changing any functionality, including the bits of
DomainCommand (representations of XML files) that reference contacts.
Currently, we "allow" parsing of contacts in DomainCommands and fail
later as part of the domain flow,  even though in practice the parsing itself will fail now that no
contacts exist in the database.

Because we wish to keep the "contacts aren't allowed in flows" tests
active (e.g.
DomainUpdateFlowTest::testFailure_minimumDataset_whenAddingNewContacts)
we have to keep the usages of contacts in DomainCommand active for now.
2026-02-19 19:35:43 +00:00
Weimin Yu
e24c90fea6 Use bash in the Nomulus image (#2959)
/bin/bash comes with the base image, jetty:jdk-??.
Use it in start.sh for safe scripting.
2026-02-18 17:26:51 +00:00
Weimin Yu
8ff4d7dc8a Fix Jetty start script (#2958)
Script broken by inlined comment in multi-line command with backslash.

Refactored into comment-safe format.
2026-02-17 18:17:58 +00:00
gbrodman
88906f1bd9 Remove more references to contacts in infrastructure (#2950)
This is a bit scattered, but we remove contact references from domain
commands, RDAP, and a bit of config infrastructure.
2026-02-17 13:38:37 +00:00
140 changed files with 829 additions and 4790 deletions

View File

@@ -29,7 +29,6 @@ import com.google.common.flogger.FluentLogger;
import google.registry.flows.poll.PollFlowUtils;
import google.registry.model.EppResource;
import google.registry.model.EppResourceUtils;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.host.Host;
import google.registry.model.poll.PollMessage;
@@ -94,7 +93,6 @@ public class DeleteLoadTestDataAction implements Runnable {
TRANSACTION_REPEATABLE_READ,
() -> {
LOAD_TEST_REGISTRARS.forEach(this::deletePollMessages);
tm().loadAllOfStream(Contact.class).forEach(this::deleteContact);
tm().loadAllOfStream(Host.class).forEach(this::deleteHost);
});
}
@@ -110,21 +108,6 @@ public class DeleteLoadTestDataAction implements Runnable {
}
}
private void deleteContact(Contact contact) {
if (!LOAD_TEST_REGISTRARS.contains(contact.getPersistedCurrentSponsorRegistrarId())) {
return;
}
// We cannot remove contacts from domains in the general case, so we cannot delete contacts
// that are linked to domains (since it would break the foreign keys)
if (EppResourceUtils.isLinked(contact.createVKey(), clock.nowUtc())) {
logger.atWarning().log(
"Cannot delete contact with repo ID %s since it is referenced from a domain.",
contact.getRepoId());
return;
}
deleteResource(contact);
}
private void deleteHost(Host host) {
if (!LOAD_TEST_REGISTRARS.contains(host.getPersistedCurrentSponsorRegistrarId())) {
return;

View File

@@ -25,7 +25,6 @@ import com.google.common.collect.Streams;
import google.registry.beam.common.RegistryJpaIO;
import google.registry.beam.common.RegistryJpaIO.Read;
import google.registry.model.EppResource;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainBase;
import google.registry.model.host.Host;
@@ -56,7 +55,7 @@ import org.joda.time.DateTime;
public class ResaveAllEppResourcesPipeline implements Serializable {
private static final ImmutableSet<Class<? extends EppResource>> EPP_RESOURCE_CLASSES =
ImmutableSet.of(Contact.class, Domain.class, Host.class);
ImmutableSet.of(Domain.class, Host.class);
/**
* There exist three possible situations where we know we'll want to project domains to the
@@ -92,25 +91,12 @@ public class ResaveAllEppResourcesPipeline implements Serializable {
void setupPipeline(Pipeline pipeline) {
if (options.getFast()) {
fastResaveContacts(pipeline);
fastResaveDomains(pipeline);
} else {
EPP_RESOURCE_CLASSES.forEach(clazz -> forceResaveAllResources(pipeline, clazz));
}
}
/** Projects to the current time and saves any contacts with expired transfers. */
private void fastResaveContacts(Pipeline pipeline) {
Read<String, String> repoIdRead =
RegistryJpaIO.read(
"SELECT repoId FROM Contact WHERE transferData.transferStatus = 'PENDING' AND"
+ " transferData.pendingTransferExpirationTime < current_timestamp()",
String.class,
r -> r)
.withCoder(StringUtf8Coder.of());
projectAndResaveResources(pipeline, Contact.class, repoIdRead);
}
/**
* Projects to the current time and saves any domains with expired pending actions (e.g.
* transfers, grace periods).

View File

@@ -143,15 +143,15 @@ public final class RegistryConfig {
}
/**
* Returns the roid suffix to be used for the roids of all contacts and hosts. E.g. a value of
* "ROID" would end up creating roids that look like "ABC123-ROID".
* Returns the roid suffix to be used for the roids of all hosts. E.g. a value of "ROID" would
* end up creating roids that look like "ABC123-ROID".
*
* @see <a href="http://www.iana.org/assignments/epp-repository-ids/epp-repository-ids.xhtml">
* Extensible Provisioning Protocol (EPP) Repository Identifiers</a>
*/
@Provides
@Config("contactAndHostRoidSuffix")
public static String provideContactAndHostRoidSuffix(RegistryConfigSettings config) {
@Config("hostRoidSuffix")
public static String provideHostRoidSuffix(RegistryConfigSettings config) {
return config.registryPolicy.contactAndHostRoidSuffix;
}
@@ -1024,18 +1024,6 @@ public final class RegistryConfig {
return Duration.standardSeconds(config.monitoring.writeIntervalSeconds);
}
/**
* The global automatic transfer length for contacts. After this amount of time has elapsed, the
* transfer is automatically approved.
*
* @see google.registry.flows.contact.ContactTransferRequestFlow
*/
@Provides
@Config("contactAutomaticTransferLength")
public static Duration provideContactAutomaticTransferLength(RegistryConfigSettings config) {
return Duration.standardDays(config.registryPolicy.contactAutomaticTransferDays);
}
/**
* Returns the maximum number of entities that can be checked at one time in an EPP check flow.
*/
@@ -1623,15 +1611,11 @@ public final class RegistryConfig {
return CONFIG_SETTINGS.get().hibernate.jdbcFetchSize;
}
/** Returns the roid suffix to be used for the roids of all contacts and hosts. */
public static String getContactAndHostRoidSuffix() {
/** Returns the roid suffix to be used for the roids of all hosts. */
public static String getHostRoidSuffix() {
return CONFIG_SETTINGS.get().registryPolicy.contactAndHostRoidSuffix;
}
/** Returns the global automatic transfer length for contacts. */
public static Duration getContactAutomaticTransferLength() {
return Duration.standardDays(CONFIG_SETTINGS.get().registryPolicy.contactAutomaticTransferDays);
}
/** A discount for all sunrise domain creates, between 0.0 (no discount) and 1.0 (free). */
public static double getSunriseDomainCreateDiscount() {

View File

@@ -86,7 +86,6 @@ public class RegistryConfigSettings {
public String productName;
public String customLogicFactoryClass;
public String dnsCountQueryCoordinatorClass;
public int contactAutomaticTransferDays;
public String greetingServerId;
public List<String> registrarChangesNotificationEmailAddresses;
public String defaultRegistrarWhoisServer;

View File

@@ -63,9 +63,6 @@ registryPolicy:
# See reporting/icann/DnsCountQueryCoordinator.java
dnsCountQueryCoordinatorClass: google.registry.reporting.icann.DummyDnsCountQueryCoordinator
# Length of time after which contact transfers automatically conclude.
contactAutomaticTransferDays: 5
# Server ID used in the 'svID' element of an EPP 'greeting'.
greetingServerId: Nomulus Registry

View File

@@ -34,7 +34,6 @@ import google.registry.flows.exceptions.ResourceToDeleteIsReferencedException;
import google.registry.flows.exceptions.TooManyResourceChecksException;
import google.registry.model.EppResource;
import google.registry.model.EppResource.ForeignKeyedEppResource;
import google.registry.model.EppResource.ResourceWithTransferData;
import google.registry.model.ForeignKeyUtils;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainBase;
@@ -42,6 +41,7 @@ import google.registry.model.domain.Period;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.eppcommon.AuthInfo;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.Host;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import java.util.List;
@@ -63,30 +63,26 @@ public final class ResourceFlowUtils {
}
}
/**
* Check whether if there are domains linked to the resource to be deleted. Throws an exception if
* so.
*/
public static <R extends EppResource> void checkLinkedDomains(
final String targetId, final DateTime now, final Class<R> resourceClass) throws EppException {
VKey<R> key =
ForeignKeyUtils.loadKey(resourceClass, targetId, now)
.orElseThrow(() -> new ResourceDoesNotExistException(resourceClass, targetId));
/** Check if there are domains linked to the host to be deleted. Throws an exception if so. */
public static void checkLinkedDomains(final String targetId, final DateTime now)
throws EppException {
VKey<Host> key =
ForeignKeyUtils.loadKey(Host.class, targetId, now)
.orElseThrow(() -> new ResourceDoesNotExistException(Host.class, targetId));
if (isLinked(key, now)) {
throw new ResourceToDeleteIsReferencedException();
}
}
public static <R extends EppResource & ResourceWithTransferData> void verifyHasPendingTransfer(
R resource) throws NotPendingTransferException {
if (resource.getTransferData().getTransferStatus() != TransferStatus.PENDING) {
throw new NotPendingTransferException(resource.getForeignKey());
public static void verifyHasPendingTransfer(Domain domain) throws NotPendingTransferException {
if (domain.getTransferData().getTransferStatus() != TransferStatus.PENDING) {
throw new NotPendingTransferException(domain.getForeignKey());
}
}
public static <R extends EppResource & ResourceWithTransferData> void verifyTransferInitiator(
String registrarId, R resource) throws NotTransferInitiatorException {
if (!resource.getTransferData().getGainingRegistrarId().equals(registrarId)) {
public static void verifyTransferInitiator(String registrarId, Domain domain)
throws NotTransferInitiatorException {
if (!domain.getTransferData().getGainingRegistrarId().equals(registrarId)) {
throw new NotTransferInitiatorException();
}
}

View File

@@ -67,14 +67,11 @@ import google.registry.flows.EppException.ParameterValueSyntaxErrorException;
import google.registry.flows.EppException.RequiredParameterMissingException;
import google.registry.flows.EppException.StatusProhibitsOperationException;
import google.registry.flows.EppException.UnimplementedOptionException;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.flows.exceptions.ResourceHasClientUpdateProhibitedException;
import google.registry.model.EppResource;
import google.registry.model.billing.BillingBase.Flag;
import google.registry.model.billing.BillingBase.Reason;
import google.registry.model.billing.BillingRecurrence;
import google.registry.model.contact.Contact;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainCommand.Create;
import google.registry.model.domain.DomainCommand.CreateOrUpdate;
@@ -421,33 +418,6 @@ public class DomainFlowUtils {
}
}
/** Enforces absence of contact data on creation as part of the Minimum Dataset requirements. */
static void enforceContactAbsencesOnCreate(Create create)
throws ParameterValuePolicyErrorException {
enforceContactAbsences(create.getRegistrant(), create.getContacts());
}
/** Enforces absence of contact data on update as part of the Minimum Dataset requirements. */
static void enforceContactAbsencesOnUpdate(Update update)
throws ParameterValuePolicyErrorException {
Set<DesignatedContact> allDesignatedContacts =
Sets.union(update.getInnerAdd().getContacts(), update.getInnerRemove().getContacts());
enforceContactAbsences(update.getInnerChange().getRegistrant(), allDesignatedContacts);
}
/** Enforces the absence of contact data as part of the Minimum Dataset requirements. */
static void enforceContactAbsences(
Optional<VKey<Contact>> registrant, Set<DesignatedContact> contacts)
throws ParameterValuePolicyErrorException {
if (registrant.isPresent()) {
throw new RegistrantProhibitedException();
}
if (!contacts.isEmpty()) {
throw new ContactsProhibitedException();
}
}
static void validateNameserversAllowedOnTld(String tld, Set<String> fullyQualifiedHostNames)
throws EppException {
ImmutableSet<String> allowedHostNames = Tld.get(tld).getAllowedFullyQualifiedHostNames();
@@ -971,7 +941,6 @@ public class DomainFlowUtils {
Create command, Tld tld, InternetDomainName domainName) throws EppException {
verifyNotInPendingDelete(command.getNameservers());
String tldStr = tld.getTldStr();
enforceContactAbsencesOnCreate(command);
ImmutableSet<String> hostNames = command.getNameserverHostNames();
validateNameserversCountForTld(tldStr, domainName, hostNames.size());
validateNameserversAllowedOnTld(tldStr, hostNames);
@@ -1252,7 +1221,7 @@ public class DomainFlowUtils {
}
/** Having a registrant is prohibited by registry policy. */
static class RegistrantProhibitedException extends ParameterValuePolicyErrorException {
public static class RegistrantProhibitedException extends ParameterValuePolicyErrorException {
public RegistrantProhibitedException() {
super("Having a registrant is prohibited by registry policy");
}

View File

@@ -29,7 +29,6 @@ import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.cloneAndLinkReferences;
import static google.registry.flows.domain.DomainFlowUtils.enforceContactAbsencesOnUpdate;
import static google.registry.flows.domain.DomainFlowUtils.updateDsData;
import static google.registry.flows.domain.DomainFlowUtils.validateDsData;
import static google.registry.flows.domain.DomainFlowUtils.validateFeesAckedIfPresent;
@@ -249,8 +248,6 @@ public final class DomainUpdateFlow implements MutatingFlow {
ext.getRemove().map(Remove::getDsData).orElse(ImmutableSet.of()));
}
Change change = command.getInnerChange();
enforceContactAbsencesOnUpdate(command);
Domain.Builder domainBuilder =
domain
.asBuilder()

View File

@@ -87,7 +87,7 @@ public final class HostCreateFlow implements MutatingFlow {
@Inject EppResponse.Builder responseBuilder;
@Inject
@Config("contactAndHostRoidSuffix")
@Config("hostRoidSuffix")
String roidSuffix;
@Inject

View File

@@ -84,7 +84,7 @@ public final class HostDeleteFlow implements MutatingFlow {
extensionManager.validate();
DateTime now = tm().getTransactionTime();
validateHostName(targetId);
checkLinkedDomains(targetId, now, Host.class);
checkLinkedDomains(targetId, now);
Host existingHost = loadAndVerifyExistence(Host.class, targetId, now);
verifyNoDisallowedStatuses(existingHost, ImmutableSet.of(StatusValue.PENDING_DELETE));
if (!isSuperuser) {

View File

@@ -23,17 +23,14 @@ import static google.registry.util.DateTimeUtils.isBeforeOrAt;
import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger;
import google.registry.model.EppResource.BuilderWithTransferData;
import google.registry.model.EppResource.ResourceWithTransferData;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainBase;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.Host;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.HistoryEntryDao;
import google.registry.model.tld.Tld;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import jakarta.persistence.Query;
@@ -48,14 +45,6 @@ public final class EppResourceUtils {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private static final String CONTACT_LINKED_DOMAIN_QUERY =
"SELECT repoId FROM Domain "
+ "WHERE (adminContact = :fkRepoId "
+ "OR billingContact = :fkRepoId "
+ "OR techContact = :fkRepoId "
+ "OR registrantContact = :fkRepoId) "
+ "AND deletionTime > :now";
// We have to use the native SQL query here because DomainHost table doesn't have its entity
// class, so we cannot reference its property like domainHost.hostRepoId in a JPQL query.
private static final String HOST_LINKED_DOMAIN_QUERY =
@@ -105,41 +94,34 @@ public final class EppResourceUtils {
return !isActive(resource, time);
}
/** Process an automatic transfer on a resource. */
public static <
T extends TransferData,
B extends EppResource.Builder<?, B> & BuilderWithTransferData<T, B>>
void setAutomaticTransferSuccessProperties(B builder, TransferData transferData) {
/** Process an automatic transfer on a domain. */
public static void setAutomaticTransferSuccessProperties(
DomainBase.Builder<?, ?> builder, DomainTransferData transferData) {
checkArgument(TransferStatus.PENDING.equals(transferData.getTransferStatus()));
TransferData.Builder transferDataBuilder = transferData.asBuilder();
DomainTransferData.Builder transferDataBuilder = transferData.asBuilder();
transferDataBuilder.setTransferStatus(TransferStatus.SERVER_APPROVED);
transferDataBuilder.setServerApproveEntities(null, null, null);
if (transferData instanceof DomainTransferData) {
((DomainTransferData.Builder) transferDataBuilder)
.setServerApproveBillingEvent(null)
.setServerApproveAutorenewEvent(null)
.setServerApproveAutorenewPollMessage(null);
}
transferDataBuilder
.setServerApproveEntities(null, null, null)
.setServerApproveBillingEvent(null)
.setServerApproveAutorenewEvent(null)
.setServerApproveAutorenewPollMessage(null);
builder
.removeStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData((T) transferDataBuilder.build())
.setTransferData(transferDataBuilder.build())
.setLastTransferTime(transferData.getPendingTransferExpirationTime())
.setPersistedCurrentSponsorRegistrarId(transferData.getGainingRegistrarId());
}
/**
* Perform common operations for projecting an {@link EppResource} at a given time:
* Perform common operations for projecting a {@link Domain} at a given time:
*
* <ul>
* <li>Process an automatic transfer.
* </ul>
*/
public static <
T extends TransferData,
E extends EppResource & ResourceWithTransferData<T>,
B extends EppResource.Builder<?, B> & BuilderWithTransferData<T, B>>
void projectResourceOntoBuilderAtTime(E resource, B builder, DateTime now) {
T transferData = resource.getTransferData();
public static void projectResourceOntoBuilderAtTime(
DomainBase domain, DomainBase.Builder<?, ?> builder, DateTime now) {
DomainTransferData transferData = domain.getTransferData();
// If there's a pending transfer that has expired, process it.
DateTime expirationTime = transferData.getPendingTransferExpirationTime();
if (TransferStatus.PENDING.equals(transferData.getTransferStatus())
@@ -207,36 +189,21 @@ public final class EppResourceUtils {
}
/**
* Returns a set of {@link VKey} for domains that reference a specified contact or host.
*
* <p>This is an eventually consistent query if used for the database.
* Returns a set of {@link VKey} for domains that reference a specified host.
*
* @param key the referent key
* @param now the logical time of the check
* @param limit the maximum number of returned keys, unlimited if null
*/
public static ImmutableSet<VKey<Domain>> getLinkedDomainKeys(
VKey<? extends EppResource> key, DateTime now, @Nullable Integer limit) {
checkArgument(
key.getKind().equals(Contact.class) || key.getKind().equals(Host.class),
"key must be either VKey<Contact> or VKey<Host>, but it is %s",
key);
boolean isContactKey = key.getKind().equals(Contact.class);
VKey<Host> key, DateTime now, @Nullable Integer limit) {
return tm().reTransact(
() -> {
Query query;
if (isContactKey) {
query =
tm().query(CONTACT_LINKED_DOMAIN_QUERY, String.class)
.setParameter("fkRepoId", key)
.setParameter("now", now);
} else {
query =
tm().getEntityManager()
.createNativeQuery(HOST_LINKED_DOMAIN_QUERY)
.setParameter("fkRepoId", key.getKey())
.setParameter("now", now.toDate());
}
Query query =
tm().getEntityManager()
.createNativeQuery(HOST_LINKED_DOMAIN_QUERY)
.setParameter("fkRepoId", key.getKey())
.setParameter("now", now.toDate());
if (limit != null) {
query.setMaxResults(limit);
}
@@ -252,12 +219,12 @@ public final class EppResourceUtils {
}
/**
* Returns whether the given contact or host is linked to (that is, referenced by) a domain.
* Returns whether the given host is linked to (that is, referenced by) a domain.
*
* @param key the referent key
* @param now the logical time of the check
*/
public static boolean isLinked(VKey<? extends EppResource> key, DateTime now) {
public static boolean isLinked(VKey<Host> key, DateTime now) {
return !getLinkedDomainKeys(key, now, 1).isEmpty();
}

View File

@@ -29,7 +29,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import google.registry.config.RegistryConfig;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.host.Host;
import google.registry.persistence.VKey;
@@ -60,7 +59,6 @@ public final class ForeignKeyUtils {
private static final ImmutableMap<Class<? extends EppResource>, String>
RESOURCE_TYPE_TO_FK_PROPERTY =
ImmutableMap.of(
Contact.class, "contactId",
Domain.class, "domainName",
Host.class, "hostName");

View File

@@ -16,32 +16,26 @@ package google.registry.model;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import google.registry.model.EppResource.BuilderWithTransferData;
import google.registry.model.EppResource.ResourceWithTransferData;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppcommon.Trid;
import google.registry.model.poll.PendingActionNotificationResponse;
import google.registry.model.poll.PendingActionNotificationResponse.ContactPendingActionNotificationResponse;
import google.registry.model.poll.PendingActionNotificationResponse.DomainPendingActionNotificationResponse;
import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferResponse;
import google.registry.model.transfer.TransferResponse.ContactTransferResponse;
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
import google.registry.model.transfer.TransferStatus;
import org.joda.time.DateTime;
/** Static utility functions for resource transfers. */
/** Static utility functions for domain transfers. */
public final class ResourceTransferUtils {
private ResourceTransferUtils() {}
@@ -50,109 +44,81 @@ public final class ResourceTransferUtils {
private static final ImmutableSet<TransferStatus> ADD_EXDATE_STATUSES = Sets.immutableEnumSet(
TransferStatus.PENDING, TransferStatus.CLIENT_APPROVED, TransferStatus.SERVER_APPROVED);
/**
* Create a transfer response using the id and type of this resource and the specified {@link
* TransferData}.
*/
/** Create a transfer response using the domain and the specified {@link DomainTransferData}. */
public static TransferResponse createTransferResponse(
EppResource eppResource, TransferData transferData) {
assertIsContactOrDomain(eppResource);
@SuppressWarnings("NonCanonicalType")
TransferResponse.Builder<? extends TransferResponse, ?> builder;
if (eppResource instanceof Contact) {
builder = new ContactTransferResponse.Builder().setContactId(eppResource.getForeignKey());
} else {
DomainTransferData domainTransferData = (DomainTransferData) transferData;
builder =
new DomainTransferResponse.Builder()
.setDomainName(eppResource.getForeignKey())
.setExtendedRegistrationExpirationTime(
ADD_EXDATE_STATUSES.contains(domainTransferData.getTransferStatus())
? domainTransferData.getTransferredRegistrationExpirationTime()
: null);
}
builder
Domain domain, DomainTransferData transferData) {
return new DomainTransferResponse.Builder()
.setDomainName(domain.getForeignKey())
.setExtendedRegistrationExpirationTime(
ADD_EXDATE_STATUSES.contains(transferData.getTransferStatus())
? transferData.getTransferredRegistrationExpirationTime()
: null)
.setGainingRegistrarId(transferData.getGainingRegistrarId())
.setLosingRegistrarId(transferData.getLosingRegistrarId())
.setPendingTransferExpirationTime(transferData.getPendingTransferExpirationTime())
.setTransferRequestTime(transferData.getTransferRequestTime())
.setTransferStatus(transferData.getTransferStatus());
return builder.build();
.setTransferStatus(transferData.getTransferStatus())
.build();
}
/**
* Create a pending action notification response indicating the resolution of a transfer.
*
* <p>The returned object will use the id and type of this resource, the trid of the resource's
* last transfer request, and the specified status and date.
* <p>The returned object will use the trid of the domain's last transfer request, and the
* specified status and date.
*/
public static PendingActionNotificationResponse createPendingTransferNotificationResponse(
EppResource eppResource,
Trid transferRequestTrid,
boolean actionResult,
DateTime processedDate) {
assertIsContactOrDomain(eppResource);
return eppResource instanceof Contact
? ContactPendingActionNotificationResponse.create(
eppResource.getForeignKey(), actionResult, transferRequestTrid, processedDate)
: DomainPendingActionNotificationResponse.create(
eppResource.getForeignKey(), actionResult, transferRequestTrid, processedDate);
}
private static void assertIsContactOrDomain(EppResource eppResource) {
checkState(eppResource instanceof Contact || eppResource instanceof Domain);
Domain domain, Trid transferRequestTrid, boolean actionResult, DateTime processedDate) {
return DomainPendingActionNotificationResponse.create(
domain.getDomainName(), actionResult, transferRequestTrid, processedDate);
}
/** If there is a transfer out, delete the server-approve entities and enqueue a poll message. */
public static <R extends EppResource & ResourceWithTransferData>
void handlePendingTransferOnDelete(
R resource, R newResource, DateTime now, HistoryEntry historyEntry) {
if (resource.getStatusValues().contains(StatusValue.PENDING_TRANSFER)) {
TransferData oldTransferData = resource.getTransferData();
tm().delete(oldTransferData.getServerApproveEntities());
tm().put(
new PollMessage.OneTime.Builder()
.setRegistrarId(oldTransferData.getGainingRegistrarId())
.setEventTime(now)
.setMsg(TransferStatus.SERVER_CANCELLED.getMessage())
.setResponseData(
ImmutableList.of(
createTransferResponse(newResource, newResource.getTransferData()),
createPendingTransferNotificationResponse(
resource, oldTransferData.getTransferRequestTrid(), false, now)))
.setHistoryEntry(historyEntry)
.build());
public static void handlePendingTransferOnDelete(
Domain domain, Domain newDomain, DateTime now, HistoryEntry historyEntry) {
if (!domain.getStatusValues().contains(StatusValue.PENDING_TRANSFER)) {
return;
}
TransferData oldTransferData = domain.getTransferData();
tm().delete(oldTransferData.getServerApproveEntities());
tm().put(
new PollMessage.OneTime.Builder()
.setRegistrarId(oldTransferData.getGainingRegistrarId())
.setEventTime(now)
.setMsg(TransferStatus.SERVER_CANCELLED.getMessage())
.setResponseData(
ImmutableList.of(
createTransferResponse(newDomain, newDomain.getTransferData()),
createPendingTransferNotificationResponse(
domain, oldTransferData.getTransferRequestTrid(), false, now)))
.setHistoryEntry(historyEntry)
.build());
}
/**
* Turn a resource into a builder with its pending transfer resolved.
* Turn a domain into a builder with its pending transfer resolved.
*
* <p>This removes the {@link StatusValue#PENDING_TRANSFER} status, sets the {@link
* TransferStatus}, clears all the server-approve fields on the {@link TransferData}, and sets the
* expiration time of the last pending transfer to now.
*/
private static <
R extends EppResource & ResourceWithTransferData,
B extends EppResource.Builder<R, B> & BuilderWithTransferData<TransferData, B>>
B resolvePendingTransfer(R resource, TransferStatus transferStatus, DateTime now) {
private static Domain.Builder resolvePendingTransfer(
Domain domain, TransferStatus transferStatus, DateTime now) {
checkArgument(
resource.getStatusValues().contains(StatusValue.PENDING_TRANSFER),
"Resource is not in pending transfer status.");
checkArgument(!resource.getTransferData().isEmpty(), "No old transfer data to resolve.");
@SuppressWarnings("unchecked")
B builder = (B) resource.asBuilder();
domain.getStatusValues().contains(StatusValue.PENDING_TRANSFER),
"Domain is not in pending transfer status.");
checkArgument(!domain.getTransferData().isEmpty(), "No old transfer data to resolve.");
return builder
return domain
.asBuilder()
.removeStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(
(TransferData)
resource
.getTransferData()
.copyConstantFieldsToBuilder()
.setTransferStatus(transferStatus)
.setPendingTransferExpirationTime(checkNotNull(now))
.build());
domain
.getTransferData()
.copyConstantFieldsToBuilder()
.setTransferStatus(transferStatus)
.setPendingTransferExpirationTime(checkNotNull(now))
.build());
}
/**
@@ -163,15 +129,13 @@ public final class ResourceTransferUtils {
* client id, and sets the last transfer time and the expiration time of the last pending transfer
* to now.
*/
public static <
R extends EppResource & ResourceWithTransferData,
B extends EppResource.Builder<R, B> & BuilderWithTransferData<TransferData, B>>
R approvePendingTransfer(R resource, TransferStatus transferStatus, DateTime now) {
public static Domain approvePendingTransfer(
Domain domain, TransferStatus transferStatus, DateTime now) {
checkArgument(transferStatus.isApproved(), "Not an approval transfer status");
B builder = resolvePendingTransfer(resource, transferStatus, now);
Domain.Builder builder = resolvePendingTransfer(domain, transferStatus, now);
return builder
.setLastTransferTime(now)
.setPersistedCurrentSponsorRegistrarId(resource.getTransferData().getGainingRegistrarId())
.setPersistedCurrentSponsorRegistrarId(domain.getTransferData().getGainingRegistrarId())
.build();
}
@@ -183,10 +147,10 @@ public final class ResourceTransferUtils {
* expiration time of the last pending transfer to now, sets the last EPP update time to now, and
* sets the last EPP update client id to the given client id.
*/
public static <R extends EppResource & ResourceWithTransferData> R denyPendingTransfer(
R resource, TransferStatus transferStatus, DateTime now, String lastEppUpdateRegistrarId) {
public static Domain denyPendingTransfer(
Domain domain, TransferStatus transferStatus, DateTime now, String lastEppUpdateRegistrarId) {
checkArgument(transferStatus.isDenied(), "Not a denial transfer status");
return resolvePendingTransfer(resource, transferStatus, now)
return resolvePendingTransfer(domain, transferStatus, now)
.setLastEppUpdateTime(now)
.setLastEppUpdateRegistrarId(lastEppUpdateRegistrarId)
.build();

View File

@@ -1,102 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.contact;
import google.registry.model.EppResource.ForeignKeyedEppResource;
import google.registry.model.annotations.ExternalMessagingName;
import google.registry.persistence.VKey;
import google.registry.persistence.WithVKey;
import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.Table;
import org.joda.time.DateTime;
/**
* A persistable contact resource including mutable and non-mutable fields.
*
* @see <a href="https://tools.ietf.org/html/rfc5733">RFC 5733</a>
*/
@Entity
@Table(
name = "Contact",
indexes = {
@Index(columnList = "creationTime"),
@Index(columnList = "currentSponsorRegistrarId"),
@Index(columnList = "deletionTime"),
@Index(columnList = "contactId"),
@Index(columnList = "searchName")
})
@ExternalMessagingName("contact")
@WithVKey(String.class)
@Access(AccessType.FIELD)
public class Contact extends ContactBase implements ForeignKeyedEppResource {
@Override
public VKey<Contact> createVKey() {
return VKey.create(Contact.class, getRepoId());
}
@Override
@Id
@Access(AccessType.PROPERTY)
public String getRepoId() {
return super.getRepoId();
}
@Override
public Contact cloneProjectedAtTime(DateTime now) {
return ContactBase.cloneContactProjectedAtTime(this, now);
}
@Override
public Builder asBuilder() {
return new Builder(clone(this));
}
/** A builder for constructing {@link Contact}, since it is immutable. */
public static class Builder extends ContactBase.Builder<Contact, Builder> {
public Builder() {}
private Builder(Contact instance) {
super(instance);
}
public Builder copyFrom(ContactBase contactBase) {
return this.setAuthInfo(contactBase.getAuthInfo())
.setContactId(contactBase.getContactId())
.setCreationRegistrarId(contactBase.getCreationRegistrarId())
.setCreationTime(contactBase.getCreationTime())
.setDeletionTime(contactBase.getDeletionTime())
.setDisclose(contactBase.getDisclose())
.setEmailAddress(contactBase.getEmailAddress())
.setFaxNumber(contactBase.getFaxNumber())
.setInternationalizedPostalInfo(contactBase.getInternationalizedPostalInfo())
.setLastTransferTime(contactBase.getLastTransferTime())
.setLastEppUpdateRegistrarId(contactBase.getLastEppUpdateRegistrarId())
.setLastEppUpdateTime(contactBase.getLastEppUpdateTime())
.setLocalizedPostalInfo(contactBase.getLocalizedPostalInfo())
.setPersistedCurrentSponsorRegistrarId(
contactBase.getPersistedCurrentSponsorRegistrarId())
.setRepoId(contactBase.getRepoId())
.setStatusValues(contactBase.getStatusValues())
.setTransferData(contactBase.getTransferData())
.setVoiceNumber(contactBase.getVoiceNumber());
}
}
}

View File

@@ -1,398 +0,0 @@
// 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.contact;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static google.registry.model.EppResourceUtils.projectResourceOntoBuilderAtTime;
import com.google.common.collect.ImmutableList;
import google.registry.model.EppResource;
import google.registry.model.EppResource.ResourceWithTransferData;
import google.registry.model.transfer.ContactTransferData;
import google.registry.persistence.VKey;
import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.AttributeOverrides;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Embedded;
import jakarta.persistence.MappedSuperclass;
import jakarta.xml.bind.annotation.XmlElement;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
import org.joda.time.DateTime;
/**
* A persistable contact resource including mutable and non-mutable fields.
*
* <p>This class deliberately does not include an {@link jakarta.persistence.Id} so that any
* foreign-keyed fields can refer to the proper parent entity's ID, whether we're storing this in
* the DB itself or as part of another entity
*
* @see <a href="https://tools.ietf.org/html/rfc5733">RFC 5733</a>
*/
@MappedSuperclass
@Embeddable
@Access(AccessType.FIELD)
public class ContactBase extends EppResource
implements ResourceWithTransferData<ContactTransferData> {
/**
* Unique identifier for this contact.
*
* <p>This is only unique in the sense that for any given lifetime specified as the time range
* from (creationTime, deletionTime) there can only be one contact in the database with this id.
* However, there can be many contacts with the same id and non-overlapping lifetimes.
*/
String contactId;
/**
* Localized postal info for the contact. All contained values must be representable in the 7-bit
* US-ASCII character set. Personal info; cleared by {@link Contact.Builder#wipeOut}.
*/
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "name", column = @Column(name = "addr_local_name")),
@AttributeOverride(name = "org", column = @Column(name = "addr_local_org")),
@AttributeOverride(name = "type", column = @Column(name = "addr_local_type")),
@AttributeOverride(
name = "address.streetLine1",
column = @Column(name = "addr_local_street_line1")),
@AttributeOverride(
name = "address.streetLine2",
column = @Column(name = "addr_local_street_line2")),
@AttributeOverride(
name = "address.streetLine3",
column = @Column(name = "addr_local_street_line3")),
@AttributeOverride(name = "address.city", column = @Column(name = "addr_local_city")),
@AttributeOverride(name = "address.state", column = @Column(name = "addr_local_state")),
@AttributeOverride(name = "address.zip", column = @Column(name = "addr_local_zip")),
@AttributeOverride(
name = "address.countryCode",
column = @Column(name = "addr_local_country_code"))
})
PostalInfo localizedPostalInfo;
/**
* Internationalized postal info for the contact. Personal info; cleared by {@link
* Contact.Builder#wipeOut}.
*/
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "name", column = @Column(name = "addr_i18n_name")),
@AttributeOverride(name = "org", column = @Column(name = "addr_i18n_org")),
@AttributeOverride(name = "type", column = @Column(name = "addr_i18n_type")),
@AttributeOverride(
name = "address.streetLine1",
column = @Column(name = "addr_i18n_street_line1")),
@AttributeOverride(
name = "address.streetLine2",
column = @Column(name = "addr_i18n_street_line2")),
@AttributeOverride(
name = "address.streetLine3",
column = @Column(name = "addr_i18n_street_line3")),
@AttributeOverride(name = "address.city", column = @Column(name = "addr_i18n_city")),
@AttributeOverride(name = "address.state", column = @Column(name = "addr_i18n_state")),
@AttributeOverride(name = "address.zip", column = @Column(name = "addr_i18n_zip")),
@AttributeOverride(
name = "address.countryCode",
column = @Column(name = "addr_i18n_country_code"))
})
PostalInfo internationalizedPostalInfo;
/**
* Contact name used for name searches. This is set automatically to be the internationalized
* postal name, or if null, the localized postal name, or if that is null as well, null. Personal
* info; cleared by {@link Contact.Builder#wipeOut}.
*/
String searchName;
/** Contacts voice number. Personal info; cleared by {@link Contact.Builder#wipeOut}. */
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "phoneNumber", column = @Column(name = "voice_phone_number")),
@AttributeOverride(name = "extension", column = @Column(name = "voice_phone_extension")),
})
ContactPhoneNumber voice;
/** Contacts fax number. Personal info; cleared by {@link Contact.Builder#wipeOut}. */
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "phoneNumber", column = @Column(name = "fax_phone_number")),
@AttributeOverride(name = "extension", column = @Column(name = "fax_phone_extension")),
})
ContactPhoneNumber fax;
/** Contacts email address. Personal info; cleared by {@link Contact.Builder#wipeOut}. */
String email;
/** Authorization info (aka transfer secret) of the contact. */
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "pw.value", column = @Column(name = "auth_info_value")),
@AttributeOverride(name = "pw.repoId", column = @Column(name = "auth_info_repo_id")),
})
ContactAuthInfo authInfo;
/** Data about any pending or past transfers on this contact. */
ContactTransferData transferData;
/**
* The time that this resource was last transferred.
*
* <p>Can be null if the resource has never been transferred.
*/
DateTime lastTransferTime;
// If any new fields are added which contain personal information, make sure they are cleared by
// the wipeOut() function, so that data is not kept around for deleted contacts.
/** Disclosure policy. */
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "name", column = @Column(name = "disclose_types_name")),
@AttributeOverride(name = "org", column = @Column(name = "disclose_types_org")),
@AttributeOverride(name = "addr", column = @Column(name = "disclose_types_addr")),
@AttributeOverride(name = "flag", column = @Column(name = "disclose_mode_flag")),
@AttributeOverride(name = "voice.marked", column = @Column(name = "disclose_show_voice")),
@AttributeOverride(name = "fax.marked", column = @Column(name = "disclose_show_fax")),
@AttributeOverride(name = "email.marked", column = @Column(name = "disclose_show_email"))
})
Disclose disclose;
@Override
public VKey<? extends ContactBase> createVKey() {
throw new UnsupportedOperationException(
"ContactBase is not an actual persisted entity you can create a key to;"
+ " use Contact instead");
}
public String getContactId() {
return contactId;
}
public PostalInfo getLocalizedPostalInfo() {
return localizedPostalInfo;
}
public PostalInfo getInternationalizedPostalInfo() {
return internationalizedPostalInfo;
}
public String getSearchName() {
return searchName;
}
public ContactPhoneNumber getVoiceNumber() {
return voice;
}
public ContactPhoneNumber getFaxNumber() {
return fax;
}
public String getEmailAddress() {
return email;
}
public ContactAuthInfo getAuthInfo() {
return authInfo;
}
public Disclose getDisclose() {
return disclose;
}
public String getCurrentSponsorRegistrarId() {
return getPersistedCurrentSponsorRegistrarId();
}
@Override
public ContactTransferData getTransferData() {
return Optional.ofNullable(transferData).orElse(ContactTransferData.EMPTY);
}
@Override
public DateTime getLastTransferTime() {
return lastTransferTime;
}
@Override
public String getForeignKey() {
return contactId;
}
/**
* Postal info for the contact.
*
* <p>The XML marshalling expects the {@link PostalInfo} objects in a list, but we can't actually
* persist them directly due to legacy reasons (Objectify can't handle collections of embedded
* objects that themselves contain collections, and there's a list of streets inside). This method
* transforms the persisted format to the XML format for marshalling.
*/
@XmlElement(name = "postalInfo")
public ImmutableList<PostalInfo> getPostalInfosAsList() {
return Stream.of(localizedPostalInfo, internationalizedPostalInfo)
.filter(Objects::nonNull)
.collect(toImmutableList());
}
@Override
public ContactBase cloneProjectedAtTime(DateTime now) {
return cloneContactProjectedAtTime(this, now);
}
/**
* Clones the contact (or subclass). A separate static method so that we can pass in and return a
* T without the compiler complaining.
*/
protected static <T extends ContactBase> T cloneContactProjectedAtTime(T contact, DateTime now) {
Builder builder = contact.asBuilder();
projectResourceOntoBuilderAtTime(contact, builder, now);
return (T) builder.build();
}
@Override
public Builder<? extends ContactBase, ?> asBuilder() {
return new Builder<>(clone(this));
}
/** A builder for constructing {@link Contact}, since it is immutable. */
public static class Builder<T extends ContactBase, B extends Builder<T, B>>
extends EppResource.Builder<T, B> implements BuilderWithTransferData<ContactTransferData, B> {
public Builder() {}
protected Builder(T instance) {
super(instance);
}
public B setContactId(String contactId) {
getInstance().contactId = contactId;
return thisCastToDerived();
}
public B setLocalizedPostalInfo(PostalInfo localizedPostalInfo) {
checkArgument(
localizedPostalInfo == null
|| PostalInfo.Type.LOCALIZED.equals(localizedPostalInfo.getType()));
getInstance().localizedPostalInfo = localizedPostalInfo;
return thisCastToDerived();
}
public B setInternationalizedPostalInfo(PostalInfo internationalizedPostalInfo) {
checkArgument(
internationalizedPostalInfo == null
|| PostalInfo.Type.INTERNATIONALIZED.equals(internationalizedPostalInfo.getType()));
getInstance().internationalizedPostalInfo = internationalizedPostalInfo;
return thisCastToDerived();
}
public B overlayLocalizedPostalInfo(PostalInfo localizedPostalInfo) {
return setLocalizedPostalInfo(
getInstance().localizedPostalInfo == null
? localizedPostalInfo
: getInstance().localizedPostalInfo.overlay(localizedPostalInfo));
}
public B overlayInternationalizedPostalInfo(PostalInfo internationalizedPostalInfo) {
return setInternationalizedPostalInfo(
getInstance().internationalizedPostalInfo == null
? internationalizedPostalInfo
: getInstance().internationalizedPostalInfo.overlay(internationalizedPostalInfo));
}
public B setVoiceNumber(ContactPhoneNumber voiceNumber) {
if (voiceNumber != null && voiceNumber.hasNullFields()) {
voiceNumber = null;
}
getInstance().voice = voiceNumber;
return thisCastToDerived();
}
public B setFaxNumber(ContactPhoneNumber faxNumber) {
if (faxNumber != null && faxNumber.hasNullFields()) {
faxNumber = null;
}
getInstance().fax = faxNumber;
return thisCastToDerived();
}
public B setEmailAddress(String emailAddress) {
getInstance().email = emailAddress;
return thisCastToDerived();
}
public B setAuthInfo(ContactAuthInfo authInfo) {
getInstance().authInfo = authInfo;
return thisCastToDerived();
}
public B setDisclose(Disclose disclose) {
getInstance().disclose = disclose;
return thisCastToDerived();
}
@Override
public B setTransferData(ContactTransferData transferData) {
getInstance().transferData = transferData;
return thisCastToDerived();
}
@Override
public B setLastTransferTime(DateTime lastTransferTime) {
getInstance().lastTransferTime = lastTransferTime;
return thisCastToDerived();
}
/**
* Remove all personally identifying information about a contact.
*
* <p>This should be used when deleting a contact so that the soft-deleted entity doesn't
* contain information that the registrant requested to be deleted.
*/
public B wipeOut() {
setEmailAddress(null);
setFaxNumber(null);
setInternationalizedPostalInfo(null);
setLocalizedPostalInfo(null);
setVoiceNumber(null);
return thisCastToDerived();
}
@Override
public T build() {
T instance = getInstance();
// If TransferData is totally empty, set it to null.
if (ContactTransferData.EMPTY.equals(instance.transferData)) {
setTransferData(null);
}
// Set the searchName using the internationalized and localized postal info names.
if ((instance.internationalizedPostalInfo != null)
&& (instance.internationalizedPostalInfo.getName() != null)) {
instance.searchName = instance.internationalizedPostalInfo.getName();
} else if ((instance.localizedPostalInfo != null)
&& (instance.localizedPostalInfo.getName() != null)) {
instance.searchName = instance.localizedPostalInfo.getName();
} else {
instance.searchName = null;
}
return super.build();
}
}
}

View File

@@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkState;
import static google.registry.util.CollectionUtils.nullToEmpty;
import com.google.common.collect.Maps;
import google.registry.model.EppResource;
import google.registry.model.ImmutableObject;
import google.registry.model.contact.PostalInfo.Type;
import google.registry.model.eppinput.ResourceCommand.AbstractSingleResourceCommand;
@@ -34,13 +35,13 @@ import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.List;
import java.util.Map;
/** A collection of {@link Contact} commands. */
/** A collection of (vestigial) Contact commands. */
public class ContactCommand {
/** The fields on "chgType" from <a href="http://tools.ietf.org/html/rfc5733">RFC5733</a>. */
@XmlTransient
public static class ContactCreateOrChange extends ImmutableObject
implements ResourceCreateOrChange<Contact.Builder> {
implements ResourceCreateOrChange<EppResource.Builder<?, ?>> {
/** Postal info for the contact. */
List<PostalInfo> postalInfo;
@@ -111,13 +112,13 @@ public class ContactCommand {
}
/**
* A create command for a {@link Contact}, mapping "createType" from <a
* A create command for a (vestigial) Contact, mapping "createType" from <a
* href="http://tools.ietf.org/html/rfc5733">RFC5733</a>}.
*/
@XmlType(propOrder = {"contactId", "postalInfo", "voice", "fax", "email", "authInfo", "disclose"})
@XmlRootElement
public static class Create extends ContactCreateOrChange
implements SingleResourceCommand, ResourceCreateOrChange<Contact.Builder> {
implements SingleResourceCommand, ResourceCreateOrChange<EppResource.Builder<?, ?>> {
/**
* Unique identifier for this contact.
*
@@ -139,29 +140,29 @@ public class ContactCommand {
}
}
/** A delete command for a {@link Contact}. */
/** A delete command for a (vestigial) Contact. */
@XmlRootElement
public static class Delete extends AbstractSingleResourceCommand {}
/** An info request for a {@link Contact}. */
/** An info request for a (vestigial) Contact. */
@XmlRootElement
@XmlType(propOrder = {"targetId", "authInfo"})
public static class Info extends AbstractContactAuthCommand {}
/** A check request for {@link Contact}. */
/** A check request for (vestigial) Contact. */
@XmlRootElement
public static class Check extends ResourceCheck {}
/** A transfer operation for a {@link Contact}. */
/** A transfer operation for a (vestigial) Contact. */
@XmlRootElement
@XmlType(propOrder = {"targetId", "authInfo"})
public static class Transfer extends AbstractContactAuthCommand {}
/** An update to a {@link Contact}. */
/** An update to a (vestigial) Contact. */
@XmlRootElement
@XmlType(propOrder = {"targetId", "innerAdd", "innerRemove", "innerChange"})
public static class Update
extends ResourceUpdate<Update.AddRemove, Contact.Builder, Update.Change> {
extends ResourceUpdate<Update.AddRemove, EppResource.Builder<?, ?>, Update.Change> {
@XmlElement(name = "chg")
protected Change innerChange;

View File

@@ -1,102 +0,0 @@
// 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.contact;
import google.registry.model.EppResource;
import google.registry.model.reporting.HistoryEntry;
import google.registry.persistence.VKey;
import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Index;
import jakarta.persistence.Table;
import java.util.Optional;
import javax.annotation.Nullable;
/**
* A persisted history entry representing an EPP modification to a contact.
*
* <p>In addition to the general history fields (e.g. action time, registrar ID) we also persist a
* copy of the contact entity at this point in time. We persist a raw {@link ContactBase} so that
* the foreign-keyed fields in that class can refer to this object.
*/
@Entity
@Table(
indexes = {
@Index(columnList = "creationTime"),
@Index(columnList = "historyRegistrarId"),
@Index(columnList = "historyType"),
@Index(columnList = "historyModificationTime")
})
@AttributeOverride(name = "repoId", column = @Column(name = "contactRepoId"))
@Access(AccessType.FIELD)
public class ContactHistory extends HistoryEntry {
// Store ContactBase instead of Contact, so we don't pick up its @Id
// @Nullable for the sake of pre-Registry-3.0 history objects
@Nullable ContactBase resource;
@Override
protected ContactBase getResource() {
return resource;
}
/**
* The values of all the fields on the {@link ContactBase} object after the action represented by
* this history object was executed.
*
* <p>Will be absent for objects created prior to the Registry 3.0 SQL migration.
*/
public Optional<ContactBase> getContactBase() {
return Optional.ofNullable(resource);
}
/** Creates a {@link VKey} instance for this entity. */
@Override
public VKey<ContactHistory> createVKey() {
return VKey.create(ContactHistory.class, getHistoryEntryId());
}
@Override
public Optional<? extends EppResource> getResourceAtPointInTime() {
return getContactBase().map(contactBase -> new Contact.Builder().copyFrom(contactBase).build());
}
@Override
public Builder asBuilder() {
return new Builder(clone(this));
}
public static class Builder extends HistoryEntry.Builder<ContactHistory, ContactHistory.Builder> {
public Builder() {}
public Builder(ContactHistory instance) {
super(instance);
}
public Builder setContact(ContactBase contactBase) {
getInstance().resource = contactBase;
return setRepoId(contactBase);
}
public Builder wipeOutPii() {
getInstance().resource = getInstance().resource.asBuilder().wipeOut().build();
return this;
}
}
}

View File

@@ -20,11 +20,9 @@ import jakarta.persistence.Embeddable;
/**
* EPP Contact Phone Number
*
* <p>This class is embedded inside a {@link Contact} hold the phone number of an EPP contact. The
* fields are all defined in the parent class {@link PhoneNumber}, but the subclass is still
* necessary to pick up the contact namespace.
*
* @see Contact
* <p>This class is embedded inside a (vestigial) Contact to hold the phone number of an EPP
* contact. The fields are all defined in the parent class {@link PhoneNumber}, but the subclass is
* still necessary to pick up the contact namespace.
*/
@Embeddable
public class ContactPhoneNumber extends PhoneNumber {

View File

@@ -1,80 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.domain;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import google.registry.model.ImmutableObject;
import google.registry.model.UnsafeSerializable;
import google.registry.model.contact.Contact;
import google.registry.persistence.VKey;
import jakarta.persistence.Embeddable;
import jakarta.xml.bind.annotation.XmlEnumValue;
/**
* Persisted type for storing a domain's contact associations.
*
* <p>A contact association on a domain consists of the contact key and the contact "type", which is
* the designated role of this contact with respect to this domain. When converting to and from EPP
* XML, we use {@link ForeignKeyedDesignatedContact} to replace the contact's primary key with its
* foreign key, since that is what EPP exposes.
*
* <p>Note one could in principle store contact foreign keys here in addition to keys, unlike the
* situation with hosts where client-side renames would make that data stale. However, we sometimes
* rename contacts internally ourselves, and it's easier to use the same model for both cases.
*
* <p>This entity type is not persisted in Cloud SQL. The different roles are represented as
* separate fields in the Domain table.
*
* @see <a href="http://tools.ietf.org/html/rfc5731#section-2.2">RFC 5731 - EPP Domain Name Mapping
* - Contact and Client Identifiers</a>
*/
@Embeddable
public class DesignatedContact extends ImmutableObject implements UnsafeSerializable {
/**
* XML type for contact types. This can be either: {@code "admin"}, {@code "billing"}, or
* {@code "tech"} and corresponds to {@code contactAttrType} in {@code domain-1.0.xsd}.
*/
public enum Type {
@XmlEnumValue("admin")
ADMIN,
@XmlEnumValue("billing")
BILLING,
@XmlEnumValue("tech")
TECH,
/** The registrant type is not reflected in XML and exists only for internal use. */
REGISTRANT
}
public static DesignatedContact create(Type type, VKey<Contact> contact) {
DesignatedContact instance = new DesignatedContact();
instance.type = type;
instance.contactVKey = checkArgumentNotNull(contact, "Must specify contact key");
return instance;
}
Type type;
VKey<Contact> contactVKey;
public Type getType() {
return type;
}
public VKey<Contact> getContactKey() {
return contactVKey;
}
}

View File

@@ -178,7 +178,6 @@ public class Domain extends DomainBase implements ForeignKeyedEppResource {
.setAutorenewPollMessage(domainBase.getAutorenewPollMessage())
.setAutorenewBillingEvent(domainBase.getAutorenewBillingEvent())
.setAutorenewEndTime(domainBase.getAutorenewEndTime())
.setContacts(domainBase.getContacts())
.setCreationRegistrarId(domainBase.getCreationRegistrarId())
.setCreationTime(domainBase.getCreationTime())
.setDomainName(domainBase.getDomainName())
@@ -193,7 +192,6 @@ public class Domain extends DomainBase implements ForeignKeyedEppResource {
.setLastEppUpdateTime(domainBase.getLastEppUpdateTime())
.setNameservers(domainBase.getNameservers())
.setPersistedCurrentSponsorRegistrarId(domainBase.getPersistedCurrentSponsorRegistrarId())
.setRegistrant(domainBase.getRegistrant())
.setRegistrationExpirationTime(domainBase.getRegistrationExpirationTime())
.setRepoId(domainBase.getRepoId())
.setSmdId(domainBase.getSmdId())

View File

@@ -45,8 +45,6 @@ import google.registry.flows.ResourceFlowUtils;
import google.registry.model.EppResource;
import google.registry.model.EppResource.ResourceWithTransferData;
import google.registry.model.billing.BillingRecurrence;
import google.registry.model.contact.Contact;
import google.registry.model.domain.DesignatedContact.Type;
import google.registry.model.domain.launch.LaunchNotice;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.domain.secdns.DomainDsData;
@@ -79,10 +77,8 @@ import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Transient;
import java.util.HashSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import javax.annotation.Nullable;
import org.hibernate.collection.spi.PersistentSet;
import org.joda.time.DateTime;
@@ -131,12 +127,12 @@ public class DomainBase extends EppResource
/** References to hosts that are the nameservers for the domain. */
@Expose @Transient Set<VKey<Host>> nsHosts;
/** Contacts. */
@Expose @Nullable VKey<Contact> adminContact;
/** Contacts keys are kept around for vestigial purposes for now. */
@Expose @Nullable String adminContact;
@Expose @Nullable VKey<Contact> billingContact;
@Expose @Nullable VKey<Contact> techContact;
@Expose @Nullable VKey<Contact> registrantContact;
@Expose @Nullable String billingContact;
@Expose @Nullable String techContact;
@Expose @Nullable String registrantContact;
/** Authorization info (aka transfer secret) of the domain. */
@Embedded
@@ -586,120 +582,21 @@ public class DomainBase extends EppResource
.collect(toImmutableSortedSet(Ordering.natural())));
}
/** A key to the registrant who registered this domain. */
public Optional<VKey<Contact>> getRegistrant() {
return Optional.ofNullable(registrantContact);
}
public Optional<VKey<Contact>> getAdminContact() {
return Optional.ofNullable(adminContact);
}
public Optional<VKey<Contact>> getBillingContact() {
return Optional.ofNullable(billingContact);
}
public Optional<VKey<Contact>> getTechContact() {
return Optional.ofNullable(techContact);
}
/**
* Associated contacts for the domain (other than registrant).
*
* <p>Note: This can be an empty set if no contacts are present for the domain.
*/
public ImmutableSet<DesignatedContact> getContacts() {
return getAllContacts(false);
}
/**
* Gets all associated contacts for the domain, including the registrant.
*
* <p>Note: This can be an empty set if no contacts are present for the domain.
*/
public ImmutableSet<DesignatedContact> getAllContacts() {
return getAllContacts(true);
}
@Nullable
public DomainAuthInfo getAuthInfo() {
return authInfo;
}
/**
* Returns all referenced contacts from this domain.
*
* <p>Note: This can be an empty set if no contacts are present for the domain.
*/
public ImmutableSet<VKey<Contact>> getReferencedContacts() {
return nullToEmptyImmutableCopy(getAllContacts(true)).stream()
.map(DesignatedContact::getContactKey)
.filter(Objects::nonNull)
.collect(toImmutableSet());
}
private ImmutableSet<DesignatedContact> getAllContacts(boolean includeRegistrant) {
ImmutableSet.Builder<DesignatedContact> builder = new ImmutableSet.Builder<>();
if (includeRegistrant) {
getRegistrant().ifPresent(c -> builder.add(DesignatedContact.create(Type.REGISTRANT, c)));
}
getAdminContact().ifPresent(c -> builder.add(DesignatedContact.create(Type.ADMIN, c)));
getBillingContact().ifPresent(c -> builder.add(DesignatedContact.create(Type.BILLING, c)));
getTechContact().ifPresent(c -> builder.add(DesignatedContact.create(Type.TECH, c)));
return builder.build();
}
public String getTld() {
return tld;
}
/**
* Sets the individual contact fields from {@code contacts}.
*
* <p>The registrant field is only set if {@code includeRegistrant} is true, as this field needs
* to be set in some circumstances but not in others.
*/
void setContactFields(Set<DesignatedContact> contacts, boolean includeRegistrant) {
// Set the individual contact fields.
billingContact = null;
techContact = null;
adminContact = null;
if (includeRegistrant) {
registrantContact = null;
}
HashSet<Type> contactsDiscovered = new HashSet<>();
for (DesignatedContact contact : contacts) {
checkArgument(
!contactsDiscovered.contains(contact.getType()),
"Duplicate contact type %s in designated contact set.",
contact.getType());
contactsDiscovered.add(contact.getType());
switch (contact.getType()) {
case BILLING -> billingContact = contact.getContactKey();
case TECH -> techContact = contact.getContactKey();
case ADMIN -> adminContact = contact.getContactKey();
case REGISTRANT -> {
if (includeRegistrant) {
registrantContact = contact.getContactKey();
}
}
default ->
throw new IllegalArgumentException(
"Unknown contact resource type: " + contact.getType());
}
}
}
@Override
public VKey<Domain> createVKey() {
throw new UnsupportedOperationException(
"DomainBase is not an actual persisted entity you can create a key to; use Domain instead");
}
/** Predicate to determine if a given {@link DesignatedContact} is the registrant. */
static final Predicate<DesignatedContact> IS_REGISTRANT =
(DesignatedContact contact) -> Type.REGISTRANT.equals(contact.type);
/** An override of {@link EppResource#asBuilder} with tighter typing. */
@Override
public Builder<? extends DomainBase, ?> asBuilder() {
@@ -764,12 +661,6 @@ public class DomainBase extends EppResource
return thisCastToDerived();
}
public B setRegistrant(Optional<VKey<Contact>> registrant) {
// Set the registrant field specifically.
getInstance().registrantContact = registrant.orElse(null);
return thisCastToDerived();
}
public B setAuthInfo(DomainAuthInfo authInfo) {
getInstance().authInfo = authInfo;
return thisCastToDerived();
@@ -805,26 +696,6 @@ public class DomainBase extends EppResource
ImmutableSet.copyOf(difference(getInstance().getNameservers(), nameservers)));
}
public B setContacts(DesignatedContact contact) {
return setContacts(ImmutableSet.of(contact));
}
public B setContacts(ImmutableSet<DesignatedContact> contacts) {
checkArgument(contacts.stream().noneMatch(IS_REGISTRANT), "Registrant cannot be a contact");
// Set the individual fields.
getInstance().setContactFields(contacts, false);
return thisCastToDerived();
}
public B addContacts(ImmutableSet<DesignatedContact> contacts) {
return setContacts(ImmutableSet.copyOf(Sets.union(getInstance().getContacts(), contacts)));
}
public B removeContacts(ImmutableSet<DesignatedContact> contacts) {
return setContacts(ImmutableSet.copyOf(difference(getInstance().getContacts(), contacts)));
}
public B setLaunchNotice(LaunchNotice launchNotice) {
getInstance().launchNotice = launchNotice;
return thisCastToDerived();

View File

@@ -16,23 +16,20 @@ package google.registry.model.domain;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.collect.Sets.difference;
import static google.registry.util.CollectionUtils.difference;
import static google.registry.util.CollectionUtils.forceEmptyToNull;
import static google.registry.util.CollectionUtils.isNullOrEmpty;
import static google.registry.util.CollectionUtils.nullSafeImmutableCopy;
import static google.registry.util.CollectionUtils.nullToEmpty;
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static google.registry.util.CollectionUtils.union;
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import google.registry.model.EppResource;
import google.registry.flows.EppException.ParameterValuePolicyErrorException;
import google.registry.flows.domain.DomainFlowUtils.RegistrantProhibitedException;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.model.ForeignKeyUtils;
import google.registry.model.ImmutableObject;
import google.registry.model.contact.Contact;
import google.registry.model.eppinput.ResourceCommand.AbstractSingleResourceCommand;
import google.registry.model.eppinput.ResourceCommand.ResourceCheck;
import google.registry.model.eppinput.ResourceCommand.ResourceCreateOrChange;
@@ -67,7 +64,8 @@ public class DomainCommand {
*/
public interface CreateOrUpdate<T extends CreateOrUpdate<T>> extends SingleResourceCommand {
/** Creates a copy of this command with hard links to hosts and contacts. */
T cloneAndLinkReferences(DateTime now) throws InvalidReferencesException;
T cloneAndLinkReferences(DateTime now)
throws InvalidReferencesException, ParameterValuePolicyErrorException;
}
/** The fields on "chgType" from <a href="http://tools.ietf.org/html/rfc5731">RFC5731</a>. */
@@ -80,9 +78,6 @@ public class DomainCommand {
@Nullable
String registrantContactId;
/** A resolved key to the registrant who registered this domain. */
@Nullable @XmlTransient VKey<Contact> registrant;
/** Authorization info (aka transfer secret) of the domain. */
DomainAuthInfo authInfo;
@@ -90,10 +85,6 @@ public class DomainCommand {
return Optional.ofNullable(registrantContactId);
}
public Optional<VKey<Contact>> getRegistrant() {
return Optional.ofNullable(registrant);
}
public DomainAuthInfo getAuthInfo() {
return authInfo;
}
@@ -132,10 +123,6 @@ public class DomainCommand {
@XmlElement(name = "contact")
Set<ForeignKeyedDesignatedContact> foreignKeyedDesignatedContacts;
/** Resolved keys 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). */
Period period;
@@ -160,10 +147,6 @@ public class DomainCommand {
return nullToEmptyImmutableCopy(nameservers);
}
public ImmutableSet<DesignatedContact> getContacts() {
return nullToEmptyImmutableCopy(contacts);
}
@Override
public DomainAuthInfo getAuthInfo() {
return authInfo;
@@ -171,26 +154,15 @@ public class DomainCommand {
/** Creates a copy of this {@link Create} with hard links to hosts and contacts. */
@Override
public Create cloneAndLinkReferences(DateTime now) throws InvalidReferencesException {
public Create cloneAndLinkReferences(DateTime now)
throws InvalidReferencesException, ParameterValuePolicyErrorException {
Create clone = clone(this);
clone.nameservers = linkHosts(clone.nameserverHostNames, now);
if (registrantContactId == null) {
clone.contacts = linkContacts(clone.foreignKeyedDesignatedContacts, now);
} else {
// Load the registrant and contacts in one shot.
ForeignKeyedDesignatedContact registrantPlaceholder = new ForeignKeyedDesignatedContact();
registrantPlaceholder.contactId = clone.registrantContactId;
registrantPlaceholder.type = DesignatedContact.Type.REGISTRANT;
Set<DesignatedContact> contacts = linkContacts(
union(nullToEmpty(clone.foreignKeyedDesignatedContacts), registrantPlaceholder),
now);
for (DesignatedContact contact : contacts) {
if (DesignatedContact.Type.REGISTRANT.equals(contact.getType())) {
clone.registrant = contact.getContactKey();
clone.contacts = forceEmptyToNull(difference(contacts, contact));
break;
}
}
if (registrantContactId != null) {
throw new RegistrantProhibitedException();
}
if (!isNullOrEmpty(foreignKeyedDesignatedContacts)) {
throw new ContactsProhibitedException();
}
return clone;
}
@@ -352,10 +324,6 @@ public class DomainCommand {
@XmlElement(name = "contact")
Set<ForeignKeyedDesignatedContact> foreignKeyedDesignatedContacts;
/** Resolved keys to associated contacts for the domain (other than registrant). */
@XmlTransient
Set<DesignatedContact> contacts;
public ImmutableSet<String> getNameserverHostNames() {
return nullSafeImmutableCopy(nameserverHostNames);
}
@@ -364,15 +332,14 @@ public class DomainCommand {
return nullToEmptyImmutableCopy(nameservers);
}
public ImmutableSet<DesignatedContact> getContacts() {
return nullToEmptyImmutableCopy(contacts);
}
/** Creates a copy of this {@link AddRemove} with hard links to hosts and contacts. */
private AddRemove cloneAndLinkReferences(DateTime now) throws InvalidReferencesException {
private AddRemove cloneAndLinkReferences(DateTime now)
throws InvalidReferencesException, ContactsProhibitedException {
AddRemove clone = clone(this);
clone.nameservers = linkHosts(clone.nameserverHostNames, now);
clone.contacts = linkContacts(clone.foreignKeyedDesignatedContacts, now);
if (!isNullOrEmpty(foreignKeyedDesignatedContacts)) {
throw new ContactsProhibitedException();
}
return clone;
}
}
@@ -380,16 +347,11 @@ public class DomainCommand {
/** The inner change type on a domain update command. */
@XmlType(propOrder = {"registrantContactId", "authInfo"})
public static class Change extends DomainCreateOrChange<Domain.Builder> {
/** Creates a copy of this {@link Change} with hard links to hosts and contacts. */
Change cloneAndLinkReferences(DateTime now) throws InvalidReferencesException {
Change cloneAndLinkReferences() throws RegistrantProhibitedException {
Change clone = clone(this);
clone.registrant =
Strings.isNullOrEmpty(clone.registrantContactId)
? null
: getOnlyElement(
loadByForeignKeysCached(
ImmutableSet.of(clone.registrantContactId), Contact.class, now)
.values());
if (clone.registrantContactId != null) {
throw new RegistrantProhibitedException();
}
return clone;
}
}
@@ -401,11 +363,12 @@ public class DomainCommand {
* of those classes, which is harmless because the getters do that anyways.
*/
@Override
public Update cloneAndLinkReferences(DateTime now) throws InvalidReferencesException {
public Update cloneAndLinkReferences(DateTime now)
throws InvalidReferencesException, ParameterValuePolicyErrorException {
Update clone = clone(this);
clone.innerAdd = clone.getInnerAdd().cloneAndLinkReferences(now);
clone.innerRemove = clone.getInnerRemove().cloneAndLinkReferences(now);
clone.innerChange = clone.getInnerChange().cloneAndLinkReferences(now);
clone.innerChange = clone.getInnerChange().cloneAndLinkReferences();
return clone;
}
}
@@ -415,37 +378,17 @@ public class DomainCommand {
if (hostNames == null) {
return null;
}
return ImmutableSet.copyOf(loadByForeignKeysCached(hostNames, Host.class, now).values());
return ImmutableSet.copyOf(loadByForeignKeysCached(hostNames, now).values());
}
private static Set<DesignatedContact> linkContacts(
Set<ForeignKeyedDesignatedContact> contacts, DateTime now) throws InvalidReferencesException {
if (contacts == null) {
return null;
}
ImmutableSet.Builder<String> foreignKeys = new ImmutableSet.Builder<>();
for (ForeignKeyedDesignatedContact contact : contacts) {
foreignKeys.add(contact.contactId);
}
ImmutableMap<String, VKey<Contact>> loadedContacts =
loadByForeignKeysCached(foreignKeys.build(), Contact.class, now);
ImmutableSet.Builder<DesignatedContact> linkedContacts = new ImmutableSet.Builder<>();
for (ForeignKeyedDesignatedContact contact : contacts) {
linkedContacts.add(
DesignatedContact.create(contact.type, loadedContacts.get(contact.contactId)));
}
return linkedContacts.build();
}
/** Loads keys to cached EPP resources by their foreign keys. */
private static <T extends EppResource> ImmutableMap<String, VKey<T>> loadByForeignKeysCached(
final Set<String> foreignKeys, final Class<T> clazz, final DateTime now)
throws InvalidReferencesException {
ImmutableMap<String, VKey<T>> fks =
ForeignKeyUtils.loadKeysByCacheIfEnabled(clazz, foreignKeys, now);
/** Loads host keys to cached EPP resources by their foreign keys. */
private static ImmutableMap<String, VKey<Host>> loadByForeignKeysCached(
final Set<String> foreignKeys, final DateTime now) throws InvalidReferencesException {
ImmutableMap<String, VKey<Host>> fks =
ForeignKeyUtils.loadKeysByCacheIfEnabled(Host.class, foreignKeys, now);
if (!fks.keySet().equals(foreignKeys)) {
throw new InvalidReferencesException(
clazz, ImmutableSet.copyOf(difference(foreignKeys, fks.keySet())));
Host.class, ImmutableSet.copyOf(difference(foreignKeys, fks.keySet())));
}
return fks;
}

View File

@@ -16,27 +16,42 @@ package google.registry.model.domain;
import google.registry.model.ImmutableObject;
import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlEnumValue;
import jakarta.xml.bind.annotation.XmlValue;
/**
* EPP-XML-serializable equivalent of {@link DesignatedContact}.
* Vestigial EPP-XML-serializable equivalent of a contact.
*
* <p>This type is used on the wire for EPP XML, where only the contact ID (foreign key) is exposed.
* This is converted to and from the persisted type, {@link DesignatedContact}, which stores the
* primary key instead of the foreign key.
* <p>This type was used on the wire for EPP XML, where only the contact ID (foreign key) was
* exposed.
*
* @see <a href="http://tools.ietf.org/html/rfc5731#section-2.2">RFC 5731 - EPP Domain Name Mapping
* - Contact and Client Identifiers</a>
*/
public class ForeignKeyedDesignatedContact extends ImmutableObject {
/**
* XML type for contact types. This can be either: {@code "admin"}, {@code "billing"}, or {@code
* "tech"} and corresponds to {@code contactAttrType} in {@code domain-1.0.xsd}.
*/
public enum Type {
@XmlEnumValue("admin")
ADMIN,
@XmlEnumValue("billing")
BILLING,
@XmlEnumValue("tech")
TECH,
/** The registrant type is not reflected in XML and exists only for internal use. */
REGISTRANT
}
@XmlAttribute(required = true)
DesignatedContact.Type type;
Type type;
@XmlValue
String contactId;
public static ForeignKeyedDesignatedContact create(
DesignatedContact.Type type, String contactId) {
public static ForeignKeyedDesignatedContact create(Type type, String contactId) {
ForeignKeyedDesignatedContact instance = new ForeignKeyedDesignatedContact();
instance.type = type;
instance.contactId = contactId;

View File

@@ -20,9 +20,14 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import google.registry.flows.FeeExtensionXmlTagNormalizer;
import google.registry.model.ImmutableObject;
import google.registry.model.domain.fee.FeeCheckResponseExtension;
import google.registry.model.domain.fee.FeeTransformResponseExtension;
import google.registry.model.domain.fee06.FeeInfoResponseExtensionV06;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppoutput.EppOutput;
import google.registry.model.eppoutput.EppResponse;
import google.registry.util.RegistryEnvironment;
import google.registry.xml.ValidationMode;
import google.registry.xml.XmlException;
@@ -98,8 +103,31 @@ public class EppXmlTransformer {
return byteArrayOutputStream.toByteArray();
}
private static boolean hasFeeExtension(EppOutput eppOutput) {
if (!eppOutput.isResponse()) {
return false;
}
return eppOutput.getResponse().getExtensions().stream()
.map(EppResponse.ResponseExtension::getClass)
.filter(EppXmlTransformer::isFeeExtension)
.findAny()
.isPresent();
}
@VisibleForTesting
static boolean isFeeExtension(Class<?> clazz) {
return FeeCheckResponseExtension.class.isAssignableFrom(clazz)
|| FeeTransformResponseExtension.class.isAssignableFrom(clazz)
|| FeeInfoResponseExtensionV06.class.isAssignableFrom(clazz);
}
public static byte[] marshal(EppOutput root, ValidationMode validation) throws XmlException {
return marshal(OUTPUT_TRANSFORMER, root, validation);
byte[] bytes = marshal(OUTPUT_TRANSFORMER, root, validation);
if (!RegistryEnvironment.PRODUCTION.equals(RegistryEnvironment.get())
&& hasFeeExtension(root)) {
return FeeExtensionXmlTagNormalizer.normalize(new String(bytes, UTF_8)).getBytes(UTF_8);
}
return bytes;
}
@VisibleForTesting

View File

@@ -22,8 +22,6 @@ import com.google.common.collect.ImmutableSet;
import google.registry.model.EppResource;
import google.registry.model.adapters.EnumToAttributeAdapter.EppEnum;
import google.registry.model.adapters.StatusValueAdapter;
import google.registry.model.contact.Contact;
import google.registry.model.contact.ContactBase;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainBase;
import google.registry.model.host.Host;
@@ -130,8 +128,6 @@ public enum StatusValue implements EppEnum {
/** Enum to help clearly list which resource types a status value is allowed to be present on. */
private enum AllowedOn {
ALL(
Contact.class,
ContactBase.class,
Domain.class,
DomainBase.class,
Host.class,

View File

@@ -164,7 +164,7 @@ public class EppInput extends ImmutableObject {
.findFirst();
}
/** A tag that goes inside of an EPP {@literal <command>}. */
/** A tag that goes inside an EPP {@literal <command>}. */
public static class InnerCommand extends ImmutableObject {}
/** A command that has an extension inside of it. */

View File

@@ -26,7 +26,6 @@ import google.registry.model.ImmutableObject;
import google.registry.model.UnsafeSerializable;
import google.registry.model.annotations.ExternalMessagingName;
import google.registry.model.annotations.IdAllocation;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainHistory;
import google.registry.model.domain.DomainRenewData;
@@ -98,7 +97,7 @@ public abstract class PollMessage extends ImmutableObject
/** Indicates the type of entity the poll message is for. */
public enum Type {
DOMAIN(1L, Domain.class),
CONTACT(2L, Contact.class),
// Contacts would be 2L but have since been removed. Host is kept at 3 for consistency.
HOST(3L, Host.class);
private final long id;
@@ -179,16 +178,6 @@ public abstract class PollMessage extends ImmutableObject
return domainRepoId;
}
/**
* Returns the contact repo id.
*
* <p>This may only be used on a {@link Contact} poll event.
*/
public String getContactRepoId() {
checkArgument(getType() == Type.CONTACT);
return contactRepoId;
}
/**
* Returns the host repo id.
*
@@ -215,7 +204,7 @@ public abstract class PollMessage extends ImmutableObject
}
public Type getType() {
return domainRepoId != null ? Type.DOMAIN : contactRepoId != null ? Type.CONTACT : Type.HOST;
return domainRepoId != null ? Type.DOMAIN : Type.HOST;
}
@Override

View File

@@ -27,7 +27,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.gson.annotations.Expose;
import google.registry.model.EppResource;
import google.registry.model.ImmutableObject;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.host.Host;
import google.registry.util.SerializeUtils;
@@ -51,7 +50,7 @@ public class VKey<T> extends ImmutableObject implements Serializable {
private static final String DELIMITER = "@";
private static final ImmutableMap<String, Class<? extends EppResource>> EPP_RESOURCE_CLASS_MAP =
ImmutableList.of(Domain.class, Host.class, Contact.class).stream()
ImmutableList.of(Domain.class, Host.class).stream()
.collect(toImmutableMap(Class::getSimpleName, identity()));
// The primary key for the referenced entity.

View File

@@ -1,192 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.rde;
import static google.registry.util.XmlEnumUtils.enumToXml;
import google.registry.model.contact.Contact;
import google.registry.model.contact.ContactAddress;
import google.registry.model.contact.ContactPhoneNumber;
import google.registry.model.contact.Disclose;
import google.registry.model.contact.Disclose.PostalInfoChoice;
import google.registry.model.contact.PostalInfo;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.transfer.TransferData;
import google.registry.xjc.contact.XjcContactAddrType;
import google.registry.xjc.contact.XjcContactDiscloseType;
import google.registry.xjc.contact.XjcContactE164Type;
import google.registry.xjc.contact.XjcContactIntLocType;
import google.registry.xjc.contact.XjcContactPostalInfoEnumType;
import google.registry.xjc.contact.XjcContactPostalInfoType;
import google.registry.xjc.contact.XjcContactStatusType;
import google.registry.xjc.contact.XjcContactStatusValueType;
import google.registry.xjc.eppcom.XjcEppcomTrStatusType;
import google.registry.xjc.rdecontact.XjcRdeContact;
import google.registry.xjc.rdecontact.XjcRdeContactElement;
import google.registry.xjc.rdecontact.XjcRdeContactTransferDataType;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
/** Utility class that turns {@link Contact} as {@link XjcRdeContactElement}. */
final class ContactToXjcConverter {
/** Converts {@link Contact} to {@link XjcRdeContactElement}. */
static XjcRdeContactElement convert(Contact host) {
return new XjcRdeContactElement(convertContact(host));
}
/** Converts {@link Contact} to {@link XjcRdeContact}. */
static XjcRdeContact convertContact(Contact model) {
XjcRdeContact bean = new XjcRdeContact();
bean.setRoid(model.getRepoId());
for (StatusValue status : model.getStatusValues()) {
bean.getStatuses().add(convertStatusValue(status));
}
PostalInfo localizedPostalInfo = model.getLocalizedPostalInfo();
if (localizedPostalInfo != null) {
bean.getPostalInfos().add(convertPostalInfo(localizedPostalInfo));
}
PostalInfo internationalizedPostalInfo = model.getInternationalizedPostalInfo();
if (internationalizedPostalInfo != null) {
bean.getPostalInfos().add(convertPostalInfo(internationalizedPostalInfo));
}
bean.setId(model.getContactId());
bean.setClID(model.getCurrentSponsorRegistrarId());
bean.setCrRr(RdeAdapter.convertRr(model.getCreationRegistrarId(), null));
bean.setUpRr(RdeAdapter.convertRr(model.getLastEppUpdateRegistrarId(), null));
bean.setCrDate(model.getCreationTime());
bean.setUpDate(model.getLastEppUpdateTime());
bean.setTrDate(model.getLastTransferTime());
bean.setVoice(convertPhoneNumber(model.getVoiceNumber()));
bean.setFax(convertPhoneNumber(model.getFaxNumber()));
bean.setEmail(model.getEmailAddress());
bean.setDisclose(convertDisclose(model.getDisclose()));
// o An OPTIONAL <trnData> element that contains the following child
// elements related to the last transfer request of the contact
// object:
//
// * A <trStatus> element that contains the state of the most recent
// transfer request.
//
// * A <reRr> element that contains the identifier of the registrar
// that requested the domain name object transfer. An OPTIONAL
// client attribute is used to specify the client that performed
// the operation.
//
// * An <acRr> element that contains the identifier of the registrar
// that SHOULD act upon a PENDING transfer request. For all other
// status types, the value identifies the registrar that took the
// indicated action. An OPTIONAL client attribute is used to
// specify the client that performed the operation.
//
// * A <reDate> element that contains the date and time that the
// transfer was requested.
//
// * An <acDate> element that contains the date and time of a
// required or completed response. For a PENDING request, the
// value identifies the date and time by which a response is
// required before an automated response action will be taken by
// the registry. For all other status types, the value identifies
// the date and time when the request was completed.
if (!model.getTransferData().isEmpty()) {
bean.setTrnData(convertTransferData(model.getTransferData()));
}
return bean;
}
/** Converts {@link TransferData} to {@link XjcRdeContactTransferDataType}. */
private static XjcRdeContactTransferDataType convertTransferData(TransferData model) {
XjcRdeContactTransferDataType bean = new XjcRdeContactTransferDataType();
bean.setTrStatus(XjcEppcomTrStatusType.fromValue(model.getTransferStatus().getXmlName()));
bean.setReRr(RdeUtils.makeXjcRdeRrType(model.getGainingRegistrarId()));
bean.setAcRr(RdeUtils.makeXjcRdeRrType(model.getLosingRegistrarId()));
bean.setReDate(model.getTransferRequestTime());
bean.setAcDate(model.getPendingTransferExpirationTime());
return bean;
}
/** Converts {@link ContactAddress} to {@link XjcContactAddrType}. */
private static XjcContactAddrType convertAddress(ContactAddress model) {
XjcContactAddrType bean = new XjcContactAddrType();
bean.getStreets().addAll(model.getStreet());
bean.setCity(model.getCity());
bean.setSp(model.getState());
bean.setPc(model.getZip());
bean.setCc(model.getCountryCode());
return bean;
}
/** Converts {@link Disclose} to {@link XjcContactDiscloseType}. */
@Nullable
@CheckForNull
static XjcContactDiscloseType convertDisclose(@Nullable Disclose model) {
if (model == null) {
return null;
}
XjcContactDiscloseType bean = new XjcContactDiscloseType();
bean.setFlag(model.getFlag());
for (PostalInfoChoice loc : model.getNames()) {
bean.getNames().add(convertPostalInfoChoice(loc));
}
for (PostalInfoChoice loc : model.getOrgs()) {
bean.getOrgs().add(convertPostalInfoChoice(loc));
}
for (PostalInfoChoice loc : model.getAddrs()) {
bean.getAddrs().add(convertPostalInfoChoice(loc));
}
return bean;
}
/** Converts {@link ContactPhoneNumber} to {@link XjcContactE164Type}. */
@Nullable
@CheckForNull
private static XjcContactE164Type convertPhoneNumber(@Nullable ContactPhoneNumber model) {
if (model == null) {
return null;
}
XjcContactE164Type bean = new XjcContactE164Type();
bean.setValue(model.getPhoneNumber());
bean.setX(model.getExtension());
return bean;
}
/** Converts {@link PostalInfoChoice} to {@link XjcContactIntLocType}. */
private static XjcContactIntLocType convertPostalInfoChoice(PostalInfoChoice model) {
XjcContactIntLocType bean = new XjcContactIntLocType();
bean.setType(XjcContactPostalInfoEnumType.fromValue(enumToXml(model.getType())));
return bean;
}
/** Converts {@link PostalInfo} to {@link XjcContactPostalInfoType}. */
private static XjcContactPostalInfoType convertPostalInfo(PostalInfo model) {
XjcContactPostalInfoType bean = new XjcContactPostalInfoType();
bean.setName(model.getName());
bean.setOrg(model.getOrg());
bean.setAddr(convertAddress(model.getAddress()));
bean.setType(XjcContactPostalInfoEnumType.fromValue(enumToXml(model.getType())));
return bean;
}
/** Converts {@link StatusValue} to {@link XjcContactStatusType}. */
private static XjcContactStatusType convertStatusValue(StatusValue model) {
XjcContactStatusType bean = new XjcContactStatusType();
bean.setS(XjcContactStatusValueType.fromValue(model.getXmlName()));
return bean;
}
private ContactToXjcConverter() {}
}

View File

@@ -14,14 +14,9 @@
package google.registry.rde;
import static com.google.common.base.Preconditions.checkState;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.common.base.Ascii;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import google.registry.model.contact.Contact;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.domain.secdns.DomainDsData;
@@ -29,10 +24,7 @@ import google.registry.model.eppcommon.StatusValue;
import google.registry.model.rde.RdeMode;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferData;
import google.registry.persistence.VKey;
import google.registry.util.Idn;
import google.registry.xjc.domain.XjcDomainContactAttrType;
import google.registry.xjc.domain.XjcDomainContactType;
import google.registry.xjc.domain.XjcDomainNsType;
import google.registry.xjc.domain.XjcDomainStatusType;
import google.registry.xjc.domain.XjcDomainStatusValueType;
@@ -44,7 +36,6 @@ import google.registry.xjc.rgp.XjcRgpStatusType;
import google.registry.xjc.rgp.XjcRgpStatusValueType;
import google.registry.xjc.secdns.XjcSecdnsDsDataType;
import google.registry.xjc.secdns.XjcSecdnsDsOrKeyType;
import java.util.Optional;
/** Utility class that turns {@link Domain} as {@link XjcRdeDomainElement}. */
final class DomainToXjcConverter {
@@ -152,8 +143,6 @@ final class DomainToXjcConverter {
switch (mode) {
case FULL:
String domainName = model.getDomainName();
// o Zero or more OPTIONAL <rgpStatus> element to represent
// "pendingDelete" sub-statuses, including "redemptionPeriod",
// "pendingRestore", and "pendingDelete", that a domain name can be
@@ -163,25 +152,6 @@ final class DomainToXjcConverter {
bean.getRgpStatuses().add(convertGracePeriodStatus(status));
}
// o An OPTIONAL <registrant> element that contain the identifier for
// the human or organizational social information object associated
// as the holder of the domain name object.
Optional<VKey<Contact>> registrant = model.getRegistrant();
if (registrant.isPresent()) {
Optional<Contact> registrantContact =
tm().transact(() -> tm().loadByKeyIfPresent(registrant.get()));
registrantContact.ifPresent(c -> bean.setRegistrant(c.getContactId()));
}
// o Zero or more OPTIONAL <contact> elements that contain identifiers
// for the human or organizational social information objects
// associated with the domain name object.
for (DesignatedContact contact : model.getContacts()) {
Optional<XjcDomainContactType> contactType =
convertDesignatedContact(contact, domainName);
contactType.ifPresent(c -> bean.getContacts().add(c));
}
// o An OPTIONAL <secDNS> element that contains the public key
// information associated with Domain Name System security (DNSSEC)
// extensions for the domain name as specified in [RFC5910].
@@ -289,23 +259,5 @@ final class DomainToXjcConverter {
return bean;
}
/** Converts {@link DesignatedContact} to {@link XjcDomainContactType}. */
private static Optional<XjcDomainContactType> convertDesignatedContact(
DesignatedContact model, String domainName) {
XjcDomainContactType bean = new XjcDomainContactType();
checkState(
model.getContactKey() != null,
"Contact key for type %s is null on domain %s",
model.getType(),
domainName);
Optional<Contact> contact = tm().transact(() -> tm().loadByKeyIfPresent(model.getContactKey()));
if (contact.isEmpty()) {
return Optional.empty();
}
bean.setType(XjcDomainContactAttrType.fromValue(Ascii.toLowerCase(model.getType().toString())));
bean.setValue(contact.get().getContactId());
return Optional.of(bean);
}
private DomainToXjcConverter() {}
}

View File

@@ -44,7 +44,6 @@ import google.registry.gcs.GcsUtils;
import google.registry.keyring.api.KeyModule.Key;
import google.registry.model.common.Cursor;
import google.registry.model.common.Cursor.CursorType;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.host.Host;
import google.registry.model.rde.RdeMode;
@@ -80,8 +79,8 @@ import org.joda.time.Duration;
* type and loads the embedded resource from it, which is then projected to watermark time to
* account for things like pending transfer.
*
* <p>Only {@link Contact}s and {@link Host}s that are referenced by an included {@link Domain} will
* be included in the corresponding pending deposit.
* <p>Only {@link Host}s that are referenced by an included {@link Domain} will be included in the
* corresponding pending deposit.
*
* <p>{@link Registrar} entities, both active and inactive, are included in all deposits. They are
* not rewound point-in-time.

View File

@@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkState;
import com.google.common.base.Ascii;
import google.registry.model.EppResource;
import google.registry.model.ForeignKeyUtils;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.host.Host;
import google.registry.persistence.VKey;
@@ -30,7 +29,6 @@ class CommandUtilities {
/** A useful parameter enum for commands that operate on {@link EppResource} objects. */
public enum ResourceType {
CONTACT(Contact.class),
HOST(Host.class),
DOMAIN(Domain.class);

View File

@@ -1,135 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.template.soy.data.SoyMapData;
import google.registry.tools.params.PhoneNumberParameter;
import google.registry.tools.soy.ContactCreateSoyInfo;
import google.registry.util.StringGenerator;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import java.util.List;
/** A command to create a new contact via EPP. */
@Parameters(separators = " =", commandDescription = "Create a new contact via EPP.")
final class CreateContactCommand extends MutatingEppToolCommand {
// TODO(b/19016175): Expand to allow full suite of contact flows.
@Parameter(
names = {"-c", "--client"},
description = "Client identifier of the registrar to execute the command as",
required = true)
String clientId;
@Parameter(
names = {"-i", "--id"},
description = "Contact ID.")
private String id;
@Parameter(
names = {"-n", "--name"},
description = "Contact name.")
private String name;
@Parameter(
names = {"-o", "--org"},
description = "Organization")
private String org;
@Parameter(
names = "--street",
description = "Street lines of address. Can take up to 3 lines.",
variableArity = true)
private List<String> street;
@Parameter(
names = "--city",
description = "City of address.")
private String city;
@Parameter(
names = "--state",
description = "State of address.")
private String state;
@Parameter(
names = {"-z", "--zip"},
description = "Postal code of address.")
private String zip;
@Parameter(
names = "--cc",
description = "Country code of address.")
private String cc;
@Parameter(
names = "--phone",
description = "E.164 phone number, e.g. +1.2125650666",
converter = PhoneNumberParameter.class,
validateWith = PhoneNumberParameter.class)
String phone;
@Parameter(
names = "--fax",
description = "E.164 fax number, e.g. +1.2125650666",
converter = PhoneNumberParameter.class,
validateWith = PhoneNumberParameter.class)
String fax;
@Parameter(
names = {"-e", "--email"},
description = "Email address.")
private String email;
@Parameter(
names = {"-p", "--password"},
description = "Password. Optional, randomly generated if not provided.")
private String password;
@Inject
@Named("base64StringGenerator")
StringGenerator passwordGenerator;
private static final int PASSWORD_LENGTH = 16;
@Override
protected void initMutatingEppToolCommand() {
if (isNullOrEmpty(password)) {
password = passwordGenerator.createString(PASSWORD_LENGTH);
}
checkArgument(street == null || street.size() <= 3,
"Addresses must contain at most 3 street lines.");
setSoyTemplate(ContactCreateSoyInfo.getInstance(), ContactCreateSoyInfo.CONTACTCREATE);
addSoyRecord(clientId, new SoyMapData(
"id", id,
"name", name,
"org", org,
"street", street,
"city", city,
"state", state,
"zip", zip,
"cc", cc,
"phone", phone,
"fax", fax,
"email", email,
"password", password));
}
}

View File

@@ -85,9 +85,6 @@ final class CreateDomainCommand extends CreateOrUpdateDomainCommand {
"domain", domain,
"period", period,
"nameservers", nameservers,
"registrant", registrant,
"admins", admins,
"techs", techs,
"password", password,
"currency", currency,
"price", cost,

View File

@@ -21,7 +21,6 @@ import com.beust.jcommander.Parameter;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
import google.registry.tools.params.NameserversParameter;
import google.registry.tools.params.StringListParameter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -47,24 +46,6 @@ abstract class CreateOrUpdateDomainCommand extends MutatingEppToolCommand {
validateWith = NameserversParameter.class)
Set<String> nameservers = new HashSet<>();
@Parameter(
names = {"-r", "--registrant"},
description = "Domain registrant."
)
String registrant;
@Parameter(
names = {"-a", "--admins"},
description = "Comma-separated list of admin contacts.",
listConverter = StringListParameter.class)
List<String> admins = new ArrayList<>();
@Parameter(
names = {"-t", "--techs"},
description = "Comma-separated list of technical contacts.",
listConverter = StringListParameter.class)
List<String> techs = new ArrayList<>();
@Parameter(
names = {"-p", "--password"},
description = "Password."

View File

@@ -1,41 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import google.registry.model.ForeignKeyUtils;
import google.registry.model.contact.Contact;
import java.util.List;
/** Command to show one or more contacts. */
@Parameters(separators = " =", commandDescription = "Show contact resource(s)")
final class GetContactCommand extends GetEppResourceCommand {
@Parameter(
description = "Contact id(s)",
required = true)
private List<String> mainParameters;
@Override
public void runAndPrint() {
for (String contactId : mainParameters) {
printResource(
"Contact",
contactId,
ForeignKeyUtils.loadResource(Contact.class, contactId, readTimestamp));
}
}
}

View File

@@ -44,7 +44,6 @@ public final class RegistryTool {
"create_cancellations_for_billing_events",
CreateCancellationsForBillingEventsCommand.class)
.put("create_cdns_tld", CreateCdnsTld.class)
.put("create_contact", CreateContactCommand.class)
.put("create_domain", CreateDomainCommand.class)
.put("create_host", CreateHostCommand.class)
.put("create_premium_list", CreatePremiumListCommand.class)
@@ -72,7 +71,6 @@ public final class RegistryTool {
.put("get_allocation_token", GetAllocationTokenCommand.class)
.put("get_bulk_pricing_package", GetBulkPricingPackageCommand.class)
.put("get_claims_list", GetClaimsListCommand.class)
.put("get_contact", GetContactCommand.class)
.put("get_domain", GetDomainCommand.class)
.put("get_feature_flag", GetFeatureFlagCommand.class)
.put("get_history_entries", GetHistoryEntriesCommand.class)

View File

@@ -83,8 +83,6 @@ interface RegistryToolComponent {
void inject(CreateCdnsTld command);
void inject(CreateContactCommand command);
void inject(CreateDomainCommand command);
void inject(CreateRegistrarCommand command);
@@ -107,8 +105,6 @@ interface RegistryToolComponent {
void inject(GetBulkPricingPackageCommand command);
void inject(GetContactCommand command);
void inject(GetDomainCommand command);
void inject(GetFeatureFlagCommand command);

View File

@@ -15,11 +15,9 @@
package google.registry.tools;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.model.domain.rgp.GracePeriodStatus.AUTO_RENEW;
import static google.registry.model.eppcommon.StatusValue.PENDING_DELETE;
import static google.registry.model.eppcommon.StatusValue.SERVER_UPDATE_PROHIBITED;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static java.util.function.Predicate.isEqual;
import com.beust.jcommander.Parameter;
@@ -30,7 +28,6 @@ import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
import com.google.template.soy.data.SoyMapData;
import google.registry.flows.ResourceFlowUtils;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.GracePeriodBase;
import google.registry.model.eppcommon.StatusValue;
@@ -66,15 +63,6 @@ final class UpdateDomainCommand extends CreateOrUpdateDomainCommand {
validateWith = NameserversParameter.class)
private Set<String> addNameservers = new HashSet<>();
// TODO(b/184067241): enforce only one of each type of contact
@Parameter(
names = "--add_admins",
description = "Admins to add. Cannot be set if --admins is set.")
private List<String> addAdmins = new ArrayList<>();
@Parameter(names = "--add_techs", description = "Techs to add. Cannot be set if --techs is set.")
private List<String> addTechs = new ArrayList<>();
@Parameter(
names = "--add_statuses",
description = "Statuses to add. Cannot be set if --statuses is set."
@@ -97,18 +85,6 @@ final class UpdateDomainCommand extends CreateOrUpdateDomainCommand {
validateWith = NameserversParameter.class)
private Set<String> removeNameservers = new HashSet<>();
@Parameter(
names = "--remove_admins",
description = "Admins to remove. Cannot be set if --admins is set."
)
private List<String> removeAdmins = new ArrayList<>();
@Parameter(
names = "--remove_techs",
description = "Techs to remove. Cannot be set if --techs is set."
)
private List<String> removeTechs = new ArrayList<>();
@Parameter(
names = "--remove_statuses",
description = "Statuses to remove. Cannot be set if --statuses is set."
@@ -154,16 +130,6 @@ final class UpdateDomainCommand extends CreateOrUpdateDomainCommand {
} else {
checkArgument(addNameservers.size() <= 13, "You can add at most 13 nameservers.");
}
if (!admins.isEmpty()) {
checkArgument(
addAdmins.isEmpty() && removeAdmins.isEmpty(),
"If you provide the admins flag, you cannot use the add_admins and remove_admins flags.");
}
if (!techs.isEmpty()) {
checkArgument(
addTechs.isEmpty() && removeTechs.isEmpty(),
"If you provide the techs flag, you cannot use the add_techs and remove_techs flags.");
}
if (!statuses.isEmpty()) {
checkArgument(
addStatuses.isEmpty() && removeStatuses.isEmpty(),
@@ -197,16 +163,12 @@ final class UpdateDomainCommand extends CreateOrUpdateDomainCommand {
domainName);
// Use TreeSets so that the results are always in the same order (this makes testing easier).
Set<String> addAdminsThisDomain = new TreeSet<>(addAdmins);
Set<String> removeAdminsThisDomain = new TreeSet<>(removeAdmins);
Set<String> addTechsThisDomain = new TreeSet<>(addTechs);
Set<String> removeTechsThisDomain = new TreeSet<>(removeTechs);
Set<String> addNameserversThisDomain = new TreeSet<>(addNameservers);
Set<String> removeNameserversThisDomain = new TreeSet<>(removeNameservers);
Set<String> addStatusesThisDomain = new TreeSet<>(addStatuses);
Set<String> removeStatusesThisDomain = new TreeSet<>(removeStatuses);
if (!nameservers.isEmpty() || !admins.isEmpty() || !techs.isEmpty() || !statuses.isEmpty()) {
if (!nameservers.isEmpty() || !statuses.isEmpty()) {
if (!nameservers.isEmpty()) {
ImmutableSortedSet<String> existingNameservers = domain.loadNameserverHostNames();
populateAddRemoveLists(
@@ -223,27 +185,7 @@ final class UpdateDomainCommand extends CreateOrUpdateDomainCommand {
"The resulting nameservers count for domain %s would be more than 13",
domainName);
}
if (!admins.isEmpty() || !techs.isEmpty()) {
ImmutableSet<String> existingAdmins =
getContactsOfType(domain, DesignatedContact.Type.ADMIN);
ImmutableSet<String> existingTechs =
getContactsOfType(domain, DesignatedContact.Type.TECH);
if (!admins.isEmpty()) {
populateAddRemoveLists(
ImmutableSet.copyOf(admins),
existingAdmins,
addAdminsThisDomain,
removeAdminsThisDomain);
}
if (!techs.isEmpty()) {
populateAddRemoveLists(
ImmutableSet.copyOf(techs),
existingTechs,
addTechsThisDomain,
removeTechsThisDomain);
}
}
if (!statuses.isEmpty()) {
Set<String> currentStatusValues = new HashSet<>();
for (StatusValue statusValue : domain.getStatusValues()) {
@@ -259,17 +201,13 @@ final class UpdateDomainCommand extends CreateOrUpdateDomainCommand {
boolean add =
(!addNameserversThisDomain.isEmpty()
|| !addAdminsThisDomain.isEmpty()
|| !addTechsThisDomain.isEmpty()
|| !addStatusesThisDomain.isEmpty());
boolean remove =
(!removeNameserversThisDomain.isEmpty()
|| !removeAdminsThisDomain.isEmpty()
|| !removeTechsThisDomain.isEmpty()
|| !removeStatusesThisDomain.isEmpty());
boolean change = (registrant != null || password != null);
boolean change = password != null;
boolean secDns =
(!addDsRecords.isEmpty()
|| !removeDsRecords.isEmpty()
@@ -297,16 +235,11 @@ final class UpdateDomainCommand extends CreateOrUpdateDomainCommand {
"domain", domainName,
"add", add,
"addNameservers", addNameserversThisDomain,
"addAdmins", addAdminsThisDomain,
"addTechs", addTechsThisDomain,
"addStatuses", addStatusesThisDomain,
"remove", remove,
"removeNameservers", removeNameserversThisDomain,
"removeAdmins", removeAdminsThisDomain,
"removeTechs", removeTechsThisDomain,
"removeStatuses", removeStatusesThisDomain,
"change", change,
"registrant", registrant,
"password", password,
"secdns", secDns,
"addDsRecords", DsRecord.convertToSoy(addDsRecords),
@@ -337,13 +270,4 @@ final class UpdateDomainCommand extends CreateOrUpdateDomainCommand {
addSet.addAll(Sets.difference(targetSet, oldSet));
removeSet.addAll(Sets.difference(oldSet, targetSet));
}
ImmutableSet<String> getContactsOfType(Domain domain, final DesignatedContact.Type contactType) {
return tm().transact(
() ->
domain.getContacts().stream()
.filter(contact -> contact.getType().equals(contactType))
.map(contact -> tm().loadByKey(contact.getContactKey()).getContactId())
.collect(toImmutableSet()));
}
}

View File

@@ -1,37 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools.params;
import google.registry.model.EppResource;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.host.Host;
/** Enum to make it easy for a command to accept a flag that specifies an EppResource subclass. */
public enum EppResourceTypeParameter {
CONTACT(Contact.class),
DOMAIN(Domain.class),
HOST(Host.class);
private final Class<? extends EppResource> type;
EppResourceTypeParameter(Class<? extends EppResource> type) {
this.type = type;
}
public Class<? extends EppResource> getType() {
return type;
}
}

View File

@@ -51,8 +51,6 @@
<class>google.registry.model.console.ConsoleUpdateHistory</class>
<class>google.registry.model.console.PasswordResetRequest</class>
<class>google.registry.model.console.User</class>
<class>google.registry.model.contact.ContactHistory</class>
<class>google.registry.model.contact.Contact</class>
<class>google.registry.model.domain.Domain</class>
<class>google.registry.model.domain.DomainHistory</class>
<class>google.registry.model.domain.GracePeriod</class>
@@ -94,7 +92,6 @@
<class>google.registry.model.billing.VKeyConverter_BillingCancellation</class>
<class>google.registry.model.billing.VKeyConverter_BillingEvent</class>
<class>google.registry.model.billing.VKeyConverter_BillingRecurrence</class>
<class>google.registry.model.contact.VKeyConverter_Contact</class>
<class>google.registry.model.domain.VKeyConverter_Domain</class>
<class>google.registry.model.domain.token.VKeyConverter_AllocationToken</class>
<class>google.registry.model.host.VKeyConverter_Host</class>

View File

@@ -20,16 +20,11 @@
{@param domain: string}
{@param add: bool}
{@param addNameservers: list<string>}
{@param addAdmins: list<string>}
{@param addTechs: list<string>}
{@param addStatuses: list<string>}
{@param remove: bool}
{@param removeNameservers: list<string>}
{@param removeAdmins: list<string>}
{@param removeTechs: list<string>}
{@param removeStatuses: list<string>}
{@param change: bool}
{@param? registrant: string|null}
{@param? password: string|null}
{@param secdns: bool}
{@param addDsRecords: list<[keyTag:int, alg:int, digestType:int, digest:string]>}
@@ -54,12 +49,6 @@
{/for}
</domain:ns>
{/if}
{for $admin in $addAdmins}
<domain:contact type="admin">{$admin}</domain:contact>
{/for}
{for $tech in $addTechs}
<domain:contact type="tech">{$tech}</domain:contact>
{/for}
{for $status in $addStatuses}
<domain:status s="{$status}"/>
{/for}
@@ -74,12 +63,6 @@
{/for}
</domain:ns>
{/if}
{for $admin in $removeAdmins}
<domain:contact type="admin">{$admin}</domain:contact>
{/for}
{for $tech in $removeTechs}
<domain:contact type="tech">{$tech}</domain:contact>
{/for}
{for $status in $removeStatuses}
<domain:status s="{$status}"/>
{/for}
@@ -87,9 +70,6 @@
{/if}
{if $change}
<domain:chg>
{if $registrant}
<domain:registrant>{$registrant}</domain:registrant>
{/if}
{if $password}
<domain:authInfo>
<domain:pw>{$password}</domain:pw>

View File

@@ -18,12 +18,12 @@ import static google.registry.batch.AsyncTaskEnqueuer.PARAM_REQUESTED_TIME;
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESAVE_TIMES;
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.TestLogHandlerUtils.assertLogMessage;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.common.collect.ImmutableSortedSet;
import google.registry.model.contact.Contact;
import google.registry.model.host.Host;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.CloudTasksHelper;
@@ -67,9 +67,9 @@ public class AsyncTaskEnqueuerTest {
@Test
void test_enqueueAsyncResave_success() {
Contact contact = persistActiveContact("jd23456");
Host host = persistActiveHost("ns1.example.tld");
asyncTaskEnqueuer.enqueueAsyncResave(
contact.createVKey(), clock.nowUtc(), ImmutableSortedSet.of(clock.nowUtc().plusDays(5)));
host.createVKey(), clock.nowUtc(), ImmutableSortedSet.of(clock.nowUtc().plusDays(5)));
cloudTasksHelper.assertTasksEnqueued(
QUEUE_ASYNC_ACTIONS,
new CloudTasksHelper.TaskMatcher()
@@ -77,17 +77,17 @@ public class AsyncTaskEnqueuerTest {
.method(HttpMethod.POST)
.service("backend")
.header("content-type", "application/x-www-form-urlencoded")
.param(PARAM_RESOURCE_KEY, contact.createVKey().stringify())
.param(PARAM_RESOURCE_KEY, host.createVKey().stringify())
.param(PARAM_REQUESTED_TIME, clock.nowUtc().toString())
.scheduleTime(clock.nowUtc().plus(Duration.standardDays(5))));
}
@Test
void test_enqueueAsyncResave_multipleResaves() {
Contact contact = persistActiveContact("jd23456");
Host host = persistActiveHost("ns1.example.tld");
DateTime now = clock.nowUtc();
asyncTaskEnqueuer.enqueueAsyncResave(
contact.createVKey(),
host.createVKey(),
now,
ImmutableSortedSet.of(now.plusHours(24), now.plusHours(50), now.plusHours(75)));
cloudTasksHelper.assertTasksEnqueued(
@@ -97,7 +97,7 @@ public class AsyncTaskEnqueuerTest {
.method(HttpMethod.POST)
.service("backend")
.header("content-type", "application/x-www-form-urlencoded")
.param(PARAM_RESOURCE_KEY, contact.createVKey().stringify())
.param(PARAM_RESOURCE_KEY, host.createVKey().stringify())
.param(PARAM_REQUESTED_TIME, now.toString())
.param(PARAM_RESAVE_TIMES, "2015-05-20T14:34:56.000Z,2015-05-21T15:34:56.000Z")
.scheduleTime(clock.nowUtc().plus(Duration.standardHours(24))));
@@ -106,9 +106,9 @@ public class AsyncTaskEnqueuerTest {
@MockitoSettings(strictness = Strictness.LENIENT)
@Test
void test_enqueueAsyncResave_ignoresTasksTooFarIntoFuture() {
Contact contact = persistActiveContact("jd23456");
Host host = persistActiveHost("ns1.example.tld");
asyncTaskEnqueuer.enqueueAsyncResave(
contact.createVKey(), clock.nowUtc(), ImmutableSortedSet.of(clock.nowUtc().plusDays(31)));
host.createVKey(), clock.nowUtc(), ImmutableSortedSet.of(clock.nowUtc().plusDays(31)));
cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS);
assertLogMessage(logHandler, Level.INFO, "Ignoring async re-save");
}

View File

@@ -65,23 +65,18 @@ public class BulkDomainTransferActionTest {
// The default registrar is TheRegistrar, which will be the losing registrar
activeDomain =
persistDomainWithDependentResources(
"active", "tld", null, now, now.minusDays(1), DateTimeUtils.END_OF_TIME);
"active", "tld", now, now.minusDays(1), DateTimeUtils.END_OF_TIME);
alreadyTransferredDomain =
persistResource(
persistDomainWithDependentResources(
"alreadytransferred",
"tld",
null,
now,
now.minusDays(1),
DateTimeUtils.END_OF_TIME)
"alreadytransferred", "tld", now, now.minusDays(1), DateTimeUtils.END_OF_TIME)
.asBuilder()
.setPersistedCurrentSponsorRegistrarId("NewRegistrar")
.build());
pendingDeleteDomain =
persistResource(
persistDomainWithDependentResources(
"pendingdelete", "tld", null, now, now.minusDays(1), now.plusMonths(1))
"pendingdelete", "tld", now, now.minusDays(1), now.plusMonths(1))
.asBuilder()
.setStatusValues(ImmutableSet.of(StatusValue.PENDING_DELETE))
.build());

View File

@@ -16,7 +16,6 @@ package google.registry.batch;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistEppResource;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.LogsSubject.assertAboutLogs;
@@ -32,7 +31,6 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.testing.TestLogHandler;
import google.registry.groups.GmailClient;
import google.registry.model.billing.BillingBase.RenewalPriceBehavior;
import google.registry.model.contact.Contact;
import google.registry.model.domain.fee.FeeQueryCommandExtensionItem.CommandName;
import google.registry.model.domain.token.AllocationToken;
import google.registry.model.domain.token.AllocationToken.TokenType;
@@ -79,7 +77,6 @@ public class CheckBulkComplianceActionTest {
private final Logger loggerToIntercept =
Logger.getLogger(CheckBulkComplianceAction.class.getCanonicalName());
private final GmailClient gmailClient = mock(GmailClient.class);
private Contact contact;
private BulkPricingPackage bulkPricingPackage;
private SendEmailUtils sendEmailUtils;
private ArgumentCaptor<EmailMessage> emailCaptor = ArgumentCaptor.forClass(EmailMessage.class);
@@ -125,8 +122,6 @@ public class CheckBulkComplianceActionTest {
.setNextBillingDate(DateTime.parse("2012-11-12T05:00:00Z"))
.setLastNotificationSent(DateTime.parse("2010-11-12T05:00:00Z"))
.build();
contact = persistActiveContact("contact1234");
}
@AfterEach
@@ -138,7 +133,7 @@ public class CheckBulkComplianceActionTest {
void testSuccess_noBulkPackageOverCreateLimit() {
tm().transact(() -> tm().put(bulkPricingPackage));
persistEppResource(
DatabaseHelper.newDomain("foo.tld", contact)
DatabaseHelper.newDomain("foo.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
@@ -156,12 +151,12 @@ public class CheckBulkComplianceActionTest {
tm().transact(() -> tm().put(bulkPricingPackage));
// Create limit is 1, creating 2 domains to go over the limit
persistEppResource(
DatabaseHelper.newDomain("foo.tld", contact)
DatabaseHelper.newDomain("foo.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
persistEppResource(
DatabaseHelper.newDomain("buzz.tld", contact)
DatabaseHelper.newDomain("buzz.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
@@ -189,12 +184,12 @@ public class CheckBulkComplianceActionTest {
tm().transact(() -> tm().put(bulkPricingPackage));
// Create limit is 1, creating 2 domains to go over the limit
persistEppResource(
DatabaseHelper.newDomain("foo.tld", contact)
DatabaseHelper.newDomain("foo.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
persistEppResource(
DatabaseHelper.newDomain("buzz.tld", contact)
DatabaseHelper.newDomain("buzz.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
@@ -223,12 +218,12 @@ public class CheckBulkComplianceActionTest {
tm().transact(() -> tm().put(bulkPricingPackage2));
persistEppResource(
DatabaseHelper.newDomain("foo2.tld", contact)
DatabaseHelper.newDomain("foo2.tld")
.asBuilder()
.setCurrentBulkToken(token2.createVKey())
.build());
persistEppResource(
DatabaseHelper.newDomain("buzz2.tld", contact)
DatabaseHelper.newDomain("buzz2.tld")
.asBuilder()
.setCurrentBulkToken(token2.createVKey())
.build());
@@ -282,12 +277,12 @@ public class CheckBulkComplianceActionTest {
// Create limit is 1, creating 2 domains to go over the limit
persistEppResource(
DatabaseHelper.newDomain("foo.tld", contact)
DatabaseHelper.newDomain("foo.tld")
.asBuilder()
.setCurrentBulkToken(token2.createVKey())
.build());
persistEppResource(
DatabaseHelper.newDomain("buzz.tld", contact)
DatabaseHelper.newDomain("buzz.tld")
.asBuilder()
.setCurrentBulkToken(token2.createVKey())
.build());
@@ -304,7 +299,7 @@ public class CheckBulkComplianceActionTest {
void testSuccess_noBulkPricingPackageOverActiveDomainsLimit() {
tm().transact(() -> tm().put(bulkPricingPackage));
persistEppResource(
DatabaseHelper.newDomain("foo.tld", contact)
DatabaseHelper.newDomain("foo.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
@@ -323,12 +318,12 @@ public class CheckBulkComplianceActionTest {
tm().transact(() -> tm().put(bulkPricingPackage));
// Domains limit is 1, creating 2 domains to go over the limit
persistEppResource(
DatabaseHelper.newDomain("foo.tld", contact)
DatabaseHelper.newDomain("foo.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
persistEppResource(
DatabaseHelper.newDomain("buzz.tld", contact)
DatabaseHelper.newDomain("buzz.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
@@ -356,7 +351,7 @@ public class CheckBulkComplianceActionTest {
.build();
tm().transact(() -> tm().put(bulkPricingPackage2));
persistEppResource(
DatabaseHelper.newDomain("foo2.tld", contact)
DatabaseHelper.newDomain("foo2.tld")
.asBuilder()
.setCurrentBulkToken(token2.createVKey())
.build());
@@ -390,12 +385,12 @@ public class CheckBulkComplianceActionTest {
tm().put(bulkPricingPackage.asBuilder().setMaxDomains(1).setMaxCreates(4).build()));
// Domains limit is 1, creating 2 domains to go over the limit
persistEppResource(
DatabaseHelper.newDomain("foo.tld", contact)
DatabaseHelper.newDomain("foo.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
persistEppResource(
DatabaseHelper.newDomain("buzz.tld", contact)
DatabaseHelper.newDomain("buzz.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
@@ -424,12 +419,12 @@ public class CheckBulkComplianceActionTest {
tm().transact(() -> tm().put(bulkPricingPackage2));
persistEppResource(
DatabaseHelper.newDomain("foo2.tld", contact)
DatabaseHelper.newDomain("foo2.tld")
.asBuilder()
.setCurrentBulkToken(token2.createVKey())
.build());
persistEppResource(
DatabaseHelper.newDomain("buzz2.tld", contact)
DatabaseHelper.newDomain("buzz2.tld")
.asBuilder()
.setCurrentBulkToken(token2.createVKey())
.build());
@@ -467,12 +462,12 @@ public class CheckBulkComplianceActionTest {
tm().transact(() -> tm().put(bulkPricingPackage));
// Domains limit is 1, creating 2 domains to go over the limit
persistEppResource(
DatabaseHelper.newDomain("foo.tld", contact)
DatabaseHelper.newDomain("foo.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
persistEppResource(
DatabaseHelper.newDomain("buzz.tld", contact)
DatabaseHelper.newDomain("buzz.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
@@ -508,12 +503,12 @@ public class CheckBulkComplianceActionTest {
tm().transact(() -> tm().put(bulkPricingPackage));
// Domains limit is 1, creating 2 domains to go over the limit
persistEppResource(
DatabaseHelper.newDomain("foo.tld", contact)
DatabaseHelper.newDomain("foo.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
persistEppResource(
DatabaseHelper.newDomain("buzz.tld", contact)
DatabaseHelper.newDomain("buzz.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
@@ -553,12 +548,12 @@ public class CheckBulkComplianceActionTest {
tm().transact(() -> tm().put(bulkPricingPackage));
// Domains limit is 1, creating 2 domains to go over the limit
persistEppResource(
DatabaseHelper.newDomain("foo.tld", contact)
DatabaseHelper.newDomain("foo.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());
persistEppResource(
DatabaseHelper.newDomain("buzz.tld", contact)
DatabaseHelper.newDomain("buzz.tld")
.asBuilder()
.setCurrentBulkToken(token.createVKey())
.build());

View File

@@ -21,7 +21,6 @@ import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.newDomain;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
import static google.registry.testing.DatabaseHelper.persistDomainWithPendingTransfer;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -87,7 +86,6 @@ public class ResaveEntityActionTest {
persistDomainWithDependentResources(
"domain",
"tld",
persistActiveContact("jd1234"),
DateTime.parse("2016-02-06T10:00:00Z"),
DateTime.parse("2016-02-06T10:00:00Z"),
DateTime.parse("2017-01-02T10:11:00Z")),

View File

@@ -15,7 +15,7 @@
package google.registry.beam.common;
import static google.registry.persistence.transaction.JpaTransactionManagerExtension.makeRegistrar1;
import static google.registry.testing.DatabaseHelper.newContact;
import static google.registry.testing.DatabaseHelper.newHost;
import static google.registry.testing.DatabaseHelper.newTld;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistResources;
@@ -27,8 +27,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import google.registry.beam.TestPipelineExtension;
import google.registry.beam.common.RegistryJpaIO.Read;
import google.registry.model.contact.Contact;
import google.registry.model.contact.ContactBase;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainAuthInfo;
import google.registry.model.domain.GracePeriod;
@@ -37,14 +35,14 @@ import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.domain.secdns.DomainDsData;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.Host;
import google.registry.model.host.HostBase;
import google.registry.model.registrar.Registrar;
import google.registry.model.tld.Tld;
import google.registry.model.transfer.ContactTransferData;
import google.registry.persistence.transaction.CriteriaQueryBuilder;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.FakeClock;
import java.util.Optional;
import org.apache.beam.sdk.coders.StringUtf8Coder;
import org.apache.beam.sdk.testing.PAssert;
import org.apache.beam.sdk.values.PCollection;
@@ -71,32 +69,33 @@ public class RegistryJpaReadTest {
final transient TestPipelineExtension testPipeline =
TestPipelineExtension.create().enableAbandonedNodeEnforcement(true);
private transient ImmutableList<Contact> contacts;
private transient ImmutableList<Host> hosts;
@BeforeEach
void beforeEach() {
Registrar ofyRegistrar = JpaIntegrationTestExtension.makeRegistrar2();
persistResource(ofyRegistrar);
ImmutableList.Builder<Contact> builder = new ImmutableList.Builder<>();
ImmutableList.Builder<Host> builder = new ImmutableList.Builder<>();
for (int i = 0; i < 3; i++) {
Contact contact = newContact("contact_" + i);
builder.add(contact);
Host host = newHost(String.format("ns%d.example.tld", i));
builder.add(host);
}
contacts = builder.build();
persistResources(contacts);
hosts = builder.build();
persistResources(hosts);
}
@Test
void readWithCriteriaQuery() {
Read<Contact, String> read =
Read<Host, String> read =
RegistryJpaIO.read(
() -> CriteriaQueryBuilder.create(Contact.class).build(), ContactBase::getContactId)
() -> CriteriaQueryBuilder.create(Host.class).build(), HostBase::getHostName)
.withCoder(StringUtf8Coder.of());
PCollection<String> repoIds = testPipeline.apply(read);
PAssert.that(repoIds).containsInAnyOrder("contact_0", "contact_1", "contact_2");
PAssert.that(repoIds)
.containsInAnyOrder("ns0.example.tld", "ns1.example.tld", "ns2.example.tld");
testPipeline.run();
}
@@ -170,13 +169,6 @@ public class RegistryJpaReadTest {
.setRegistrarId("registrar1")
.setEmailAddress("me@google.com")
.build();
Contact contact =
new Contact.Builder()
.setRepoId("contactid_1")
.setCreationRegistrarId(registrar.getRegistrarId())
.setTransferData(new ContactTransferData.Builder().build())
.setPersistedCurrentSponsorRegistrarId(registrar.getRegistrarId())
.build();
Domain domain =
new Domain.Builder()
.setDomainName("example.com")
@@ -193,8 +185,6 @@ public class RegistryJpaReadTest {
StatusValue.SERVER_UPDATE_PROHIBITED,
StatusValue.SERVER_RENEW_PROHIBITED,
StatusValue.SERVER_HOLD))
.setRegistrant(Optional.of(contact.createVKey()))
.setContacts(ImmutableSet.of())
.setSubordinateHosts(ImmutableSet.of("ns1.example.com"))
.setPersistedCurrentSponsorRegistrarId(registrar.getRegistrarId())
.setRegistrationExpirationTime(fakeClock.nowUtc().plusYears(1))
@@ -212,6 +202,6 @@ public class RegistryJpaReadTest {
null,
100L))
.build();
persistResources(registry, registrar, contact, domain);
persistResources(registry, registrar, domain);
}
}

View File

@@ -18,22 +18,18 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ImmutableObjectSubject.immutableObjectCorrespondence;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.loadAllOf;
import static google.registry.testing.DatabaseHelper.newContact;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static google.registry.testing.DatabaseHelper.newHost;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import google.registry.beam.TestPipelineExtension;
import google.registry.model.contact.Contact;
import google.registry.model.host.Host;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.persistence.transaction.JpaTransactionManagerExtension;
import google.registry.testing.FakeClock;
import java.io.Serializable;
import org.apache.beam.sdk.Pipeline.PipelineExecutionException;
import org.apache.beam.sdk.transforms.Create;
import org.joda.time.DateTime;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -53,42 +49,18 @@ class RegistryJpaWriteTest implements Serializable {
@Test
void writeToSql_twoWriters() {
tm().transact(() -> tm().put(JpaTransactionManagerExtension.makeRegistrar2()));
ImmutableList.Builder<Contact> contactsBuilder = new ImmutableList.Builder<>();
ImmutableList.Builder<Host> hostsBuilder = new ImmutableList.Builder<>();
for (int i = 0; i < 3; i++) {
contactsBuilder.add(newContact("contact_" + i));
hostsBuilder.add(newHost(String.format("ns%d.example.tld", i)));
}
ImmutableList<Contact> contacts = contactsBuilder.build();
ImmutableList<Host> hosts = hostsBuilder.build();
testPipeline
.apply(Create.of(contacts))
.apply(RegistryJpaIO.<Contact>write().withName("Contact").withBatchSize(4));
.apply(Create.of(hosts))
.apply(RegistryJpaIO.<Host>write().withName("Host").withBatchSize(4));
testPipeline.run().waitUntilFinish();
assertThat(loadAllOf(Contact.class))
assertThat(loadAllOf(Host.class))
.comparingElementsUsing(immutableObjectCorrespondence("revisions", "updateTimestamp"))
.containsExactlyElementsIn(contacts);
}
@Disabled("b/263502442")
@Test
void testFailure_writeExistingEntity() {
// RegistryJpaIO.Write actions should not write existing objects to the database because the
// object could have been mutated in between creation and when the Write actually occurs,
// causing a race condition
tm().transact(
() -> {
tm().put(JpaTransactionManagerExtension.makeRegistrar2());
tm().put(newContact("contact"));
});
Contact contact = Iterables.getOnlyElement(loadAllOf(Contact.class));
testPipeline
.apply(Create.of(contact))
.apply(RegistryJpaIO.<Contact>write().withName("Contact"));
// PipelineExecutionException caused by a RuntimeException caused by an IllegalArgumentException
assertThat(
assertThrows(
PipelineExecutionException.class, () -> testPipeline.run().waitUntilFinish()))
.hasCauseThat()
.hasCauseThat()
.isInstanceOf(IllegalArgumentException.class);
.containsExactlyElementsIn(hosts);
}
}

View File

@@ -81,7 +81,6 @@ import google.registry.testing.CloudTasksHelper.TaskMatcher;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeKeyringModule;
import java.io.IOException;
import java.util.Optional;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -239,8 +238,6 @@ public class RdePipelineTest {
newDomain("hello.soy")
.asBuilder()
.addNameserver(host1.createVKey())
.setRegistrant(Optional.empty())
.setContacts(ImmutableSet.of())
.build());
persistDomainHistory(helloDomain);
persistHostHistory(persistActiveHost("not-used-subordinate.hello.soy"));
@@ -253,8 +250,6 @@ public class RdePipelineTest {
newDomain("kitty.fun")
.asBuilder()
.addNameservers(ImmutableSet.of(host1.createVKey(), host2.createVKey()))
.setRegistrant(Optional.empty())
.setContacts(ImmutableSet.of())
.build());
persistDomainHistory(kittyDomain);
// Should not appear because the TLD is not included in a pending deposit.
@@ -348,7 +343,7 @@ public class RdePipelineTest {
"""
<rdeDomain:domain>
<rdeDomain:name>cat.fun</rdeDomain:name>
<rdeDomain:roid>10-FUN</rdeDomain:roid>
<rdeDomain:roid>F-FUN</rdeDomain:roid>
<rdeDomain:uName>cat.fun</rdeDomain:uName>
<rdeDomain:status s="ok"/>
<rdeDomain:ns>

View File

@@ -20,8 +20,8 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadAllOf;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
import static google.registry.testing.DatabaseHelper.persistDomainWithPendingTransfer;
import static google.registry.testing.DatabaseHelper.persistNewRegistrars;
@@ -31,10 +31,10 @@ import static org.mockito.Mockito.verify;
import google.registry.beam.TestPipelineExtension;
import google.registry.model.EppResource;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.GracePeriod;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.Host;
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
@@ -79,13 +79,13 @@ public class ResaveAllEppResourcesPipelineTest {
@Test
void testPipeline_unchangedEntity() {
Contact contact = persistActiveContact("test123");
DateTime creationTime = contact.getUpdateTimestamp().getTimestamp();
Host host = persistActiveHost("ns1.example.tld");
DateTime creationTime = host.getUpdateTimestamp().getTimestamp();
fakeClock.advanceOneMilli();
assertThat(loadByEntity(contact).getUpdateTimestamp().getTimestamp()).isEqualTo(creationTime);
assertThat(loadByEntity(host).getUpdateTimestamp().getTimestamp()).isEqualTo(creationTime);
fakeClock.advanceOneMilli();
runPipeline();
assertThat(loadByEntity(contact)).isEqualTo(contact);
assertThat(loadByEntity(host)).isEqualTo(host);
}
@Test
@@ -95,12 +95,7 @@ public class ResaveAllEppResourcesPipelineTest {
Domain domain =
persistDomainWithPendingTransfer(
persistDomainWithDependentResources(
"domain",
"tld",
persistActiveContact("jd1234"),
now.minusDays(5),
now.minusDays(5),
now.plusYears(2)),
"domain", "tld", now.minusDays(5), now.minusDays(5), now.plusYears(2)),
now.minusDays(4),
now.minusDays(1),
now.plusYears(2));
@@ -117,8 +112,7 @@ public class ResaveAllEppResourcesPipelineTest {
void testPipeline_autorenewedDomain() {
DateTime now = fakeClock.nowUtc();
Domain domain =
persistDomainWithDependentResources(
"domain", "tld", persistActiveContact("jd1234"), now, now, now.plusYears(1));
persistDomainWithDependentResources("domain", "tld", now, now, now.plusYears(1));
assertThat(domain.getRegistrationExpirationTime()).isEqualTo(now.plusYears(1));
fakeClock.advanceBy(Duration.standardDays(500));
runPipeline();
@@ -129,8 +123,7 @@ public class ResaveAllEppResourcesPipelineTest {
@Test
void testPipeline_expiredGracePeriod() {
DateTime now = fakeClock.nowUtc();
persistDomainWithDependentResources(
"domain", "tld", persistActiveContact("jd1234"), now, now, now.plusYears(1));
persistDomainWithDependentResources("domain", "tld", now, now, now.plusYears(1));
assertThat(loadAllOf(GracePeriod.class)).hasSize(1);
fakeClock.advanceBy(Duration.standardDays(500));
runPipeline();
@@ -140,8 +133,7 @@ public class ResaveAllEppResourcesPipelineTest {
@Test
void testPipeline_fastOnlySavesChanged() {
DateTime now = fakeClock.nowUtc();
Contact contact = persistActiveContact("jd1234");
persistDomainWithDependentResources("renewed", "tld", contact, now, now, now.plusYears(1));
persistDomainWithDependentResources("renewed", "tld", now, now, now.plusYears(1));
persistActiveDomain("nonrenewed.tld", now, now.plusYears(20));
// Spy the transaction manager so we can be sure we're only saving the renewed domain
JpaTransactionManager spy = spy(tm());
@@ -157,24 +149,22 @@ public class ResaveAllEppResourcesPipelineTest {
void testPipeline_notFastResavesAll() {
options.setFast(false);
DateTime now = fakeClock.nowUtc();
Contact contact = persistActiveContact("jd1234");
Domain renewed =
persistDomainWithDependentResources("renewed", "tld", contact, now, now, now.plusYears(1));
persistDomainWithDependentResources("renewed", "tld", now, now, now.plusYears(1));
Domain nonRenewed =
persistDomainWithDependentResources(
"nonrenewed", "tld", contact, now, now, now.plusYears(20));
persistDomainWithDependentResources("nonrenewed", "tld", now, now, now.plusYears(20));
// Spy the transaction manager so we can be sure we're attempting to save everything
JpaTransactionManager spy = spy(tm());
TransactionManagerFactory.setJpaTm(() -> spy);
ArgumentCaptor<EppResource> eppResourcePutCaptor = ArgumentCaptor.forClass(EppResource.class);
runPipeline();
// We should be attempting to put both domains (and the contact) in, even the unchanged ones
verify(spy, times(3)).put(eppResourcePutCaptor.capture());
// We should be attempting to put both domains in, even the unchanged one
verify(spy, times(2)).put(eppResourcePutCaptor.capture());
assertThat(
eppResourcePutCaptor.getAllValues().stream()
.map(EppResource::getRepoId)
.collect(toImmutableSet()))
.containsExactly(contact.getRepoId(), renewed.getRepoId(), nonRenewed.getRepoId());
.containsExactly(renewed.getRepoId(), nonRenewed.getRepoId());
}
private void runPipeline() {

View File

@@ -20,7 +20,6 @@ import static google.registry.model.ImmutableObjectSubject.immutableObjectCorres
import static google.registry.persistence.transaction.JpaTransactionManagerExtension.makeRegistrar1;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.mockito.ArgumentMatchers.any;
@@ -37,7 +36,6 @@ import com.google.common.truth.Correspondence.BinaryPredicate;
import google.registry.beam.TestPipelineExtension;
import google.registry.beam.spec11.SafeBrowsingTransforms.EvaluateSafeBrowsingFn;
import google.registry.beam.spec11.SafeBrowsingTransformsTest.HttpResponder;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainAuthInfo;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
@@ -54,7 +52,6 @@ import google.registry.util.Retrier;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
import org.apache.beam.sdk.coders.KvCoder;
import org.apache.beam.sdk.coders.SerializableCoder;
import org.apache.beam.sdk.options.PipelineOptionsFactory;
@@ -252,16 +249,11 @@ class Spec11PipelineTest {
createTld("bank");
createTld("dev");
Contact contact1 = persistActiveContact(registrar1.getRegistrarId());
Contact contact2 = persistActiveContact(registrar2.getRegistrarId());
Contact contact3 = persistActiveContact(registrar3.getRegistrarId());
persistResource(createDomain("111.com", "123456789-COM", registrar1, contact1));
persistResource(createDomain("party-night.net", "2244AABBC-NET", registrar2, contact2));
persistResource(createDomain("bitcoin.bank", "1C3D5E7F9-BANK", registrar1, contact1));
persistResource(createDomain("no-email.com", "2A4BA9BBC-COM", registrar2, contact2));
persistResource(
createDomain("anti-anti-anti-virus.dev", "555666888-DEV", registrar3, contact3));
persistResource(createDomain("111.com", "123456789-COM", registrar1));
persistResource(createDomain("party-night.net", "2244AABBC-NET", registrar2));
persistResource(createDomain("bitcoin.bank", "1C3D5E7F9-BANK", registrar1));
persistResource(createDomain("no-email.com", "2A4BA9BBC-COM", registrar2));
persistResource(createDomain("anti-anti-anti-virus.dev", "555666888-DEV", registrar3));
}
private void verifySaveToGcs() throws Exception {
@@ -289,8 +281,7 @@ class Spec11PipelineTest {
});
}
private Domain createDomain(
String domainName, String repoId, Registrar registrar, Contact contact) {
private Domain createDomain(String domainName, String repoId, Registrar registrar) {
return new Domain.Builder()
.setDomainName(domainName)
.setRepoId(repoId)
@@ -298,7 +289,6 @@ class Spec11PipelineTest {
.setLastEppUpdateTime(fakeClock.nowUtc())
.setLastEppUpdateRegistrarId(registrar.getRegistrarId())
.setLastTransferTime(fakeClock.nowUtc())
.setRegistrant(Optional.of(contact.createVKey()))
.setPersistedCurrentSponsorRegistrarId(registrar.getRegistrarId())
.setRegistrationExpirationTime(fakeClock.nowUtc().plusYears(1))
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("password")))

View File

@@ -20,7 +20,6 @@ import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableO
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadAllOf;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.joda.time.DateTimeZone.UTC;
@@ -86,8 +85,6 @@ class EppPointInTimeTest {
persistActiveHost("ns1.example.net");
persistActiveHost("ns2.example.net");
persistActiveContact("jd1234");
persistActiveContact("sh8013");
clock.advanceBy(standardDays(1));
DateTime timeAtCreate = clock.nowUtc();

View File

@@ -17,8 +17,10 @@ package google.registry.flows;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.flows.FeeExtensionXmlTagNormalizer.feeExtensionInUseRegex;
import static google.registry.flows.FeeExtensionXmlTagNormalizer.normalize;
import static google.registry.flows.FlowTestCase.verifyFeeTagNormalized;
import static google.registry.model.eppcommon.EppXmlTransformer.validateOutput;
import static google.registry.testing.TestDataHelper.loadFile;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
@@ -41,6 +43,13 @@ class FeeExtensionXmlTagNormalizerTest {
assertThat(normalized).isEqualTo(xml);
}
@Test
void normalize_greetingUnchanged() throws Exception {
String xml = loadFile(getClass(), "greeting.xml");
String normalized = normalize(xml);
assertThat(normalized).isEqualTo(xml);
}
@ParameterizedTest(name = "normalize_withFeeExtension-{0}")
@MethodSource("provideTestCombinations")
@SuppressWarnings("unused") // Parameter 'name' is part of test case name
@@ -55,6 +64,28 @@ class FeeExtensionXmlTagNormalizerTest {
assertThat(normalized).isEqualTo(expected);
}
// Piggyback tests for FlowTestCase.verifyFeeTagNormalized here.
@ParameterizedTest(name = "verifyFeeTagNormalized-{0}")
@MethodSource("provideTestCombinations")
@SuppressWarnings("unused") // Parameter 'name' is part of test case name
void verifyFeeTagNormalized_success(
String name, String inputXmlFilename, String expectedXmlFilename) throws Exception {
String original = loadFile(getClass(), inputXmlFilename);
String expected = loadFile(getClass(), expectedXmlFilename);
if (name.equals("v06")) {
// Fee-06 already uses 'fee'. Non-normalized tags only appear in header.
verifyFeeTagNormalized(original);
} else {
assertThrows(
AssertionError.class,
() -> {
verifyFeeTagNormalized(original);
});
}
verifyFeeTagNormalized(expected);
}
@SuppressWarnings("unused")
static Stream<Arguments> provideTestCombinations() {
return Stream.of(

View File

@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Sets.difference;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.flows.FlowUtils.marshalWithLenientRetry;
import static google.registry.model.eppcommon.EppXmlTransformer.marshal;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.stripBillingEventId;
@@ -55,6 +56,7 @@ import google.registry.xml.ValidationMode;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
@@ -284,6 +286,7 @@ public abstract class FlowTestCase<F extends Flow> {
Arrays.toString(marshal(output, ValidationMode.LENIENT))),
e);
}
verifyFeeTagNormalized(new String(marshalWithLenientRetry(output), UTF_8));
return output;
}
@@ -298,4 +301,14 @@ public abstract class FlowTestCase<F extends Flow> {
public EppOutput runFlowAssertResponse(String xml, String... ignoredPaths) throws Exception {
return runFlowAssertResponse(CommitMode.LIVE, UserPrivileges.NORMAL, xml, ignoredPaths);
}
// Pattern for non-normalized tags in use. Occurrences in namespace declarations ignored.
private static final Pattern NON_NORMALIZED_FEE_TAGS =
Pattern.compile("\\bfee11:|\\bfee12:|\\bfee_1_00:");
static void verifyFeeTagNormalized(String xml) {
assertWithMessage("Unexpected un-normalized Fee tags found in message.")
.that(NON_NORMALIZED_FEE_TAGS.matcher(xml).find())
.isFalse();
}
}

View File

@@ -44,7 +44,6 @@ import static google.registry.testing.DatabaseHelper.loadByKeyIfPresent;
import static google.registry.testing.DatabaseHelper.loadByKeysIfPresent;
import static google.registry.testing.DatabaseHelper.loadRegistrar;
import static google.registry.testing.DatabaseHelper.newHost;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistDeletedDomain;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -81,7 +80,6 @@ import google.registry.model.billing.BillingBase.Reason;
import google.registry.model.billing.BillingCancellation;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingRecurrence;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainHistory;
import google.registry.model.domain.GracePeriod;
@@ -104,7 +102,6 @@ import google.registry.testing.CloudTasksHelper.TaskMatcher;
import google.registry.testing.DatabaseHelper;
import google.registry.testing.LogsSubject;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Level;
import org.joda.money.Money;
import org.joda.time.DateTime;
@@ -160,14 +157,11 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
}
private void createReferencedEntities(DateTime expirationTime) throws Exception {
// Persist a linked contact.
Contact contact = persistActiveContact("sh8013");
domain =
persistResource(
DatabaseHelper.newDomain(getUniqueIdFromCommand())
.asBuilder()
.setCreationTimeForTest(TIME_BEFORE_FLOW)
.setRegistrant(Optional.of(contact.createVKey()))
.setRegistrationExpirationTime(expirationTime)
.build());
earlierHistoryEntry =
@@ -659,11 +653,10 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
.asBuilder()
.setNameservers(ImmutableSet.of(host.createVKey()))
.build());
// Persist another domain that's already been deleted and references this contact and host.
// Persist another domain that's already been deleted and references this host.
persistResource(
DatabaseHelper.newDomain("example1.tld")
.asBuilder()
.setRegistrant(ForeignKeyUtils.loadKey(Contact.class, "sh8013", clock.nowUtc()))
.setNameservers(ImmutableSet.of(host.createVKey()))
.setDeletionTime(START_OF_TIME)
.build());
@@ -762,7 +755,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
.setEventTime(now)
.setMsg(
"Domain example.tld was deleted by registry administrator with final deletion"
+ " effective: 2000-07-11T22:00:00.012Z")
+ " effective: 2000-07-11T22:00:00.010Z")
.setResponseData(
ImmutableList.of(
DomainPendingActionNotificationResponse.create(
@@ -771,7 +764,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
new PollMessage.OneTime.Builder()
.setRegistrarId("TheRegistrar")
.setHistoryEntry(deleteHistoryEntry)
.setEventTime(DateTime.parse("2000-07-11T22:00:00.012Z"))
.setEventTime(DateTime.parse("2000-07-11T22:00:00.010Z"))
.setMsg("Deleted by registry administrator.")
.setResponseData(
ImmutableList.of(
@@ -779,7 +772,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
"example.tld",
true,
deleteHistoryEntry.getTrid(),
DateTime.parse("2000-07-11T22:00:00.012Z"))))
DateTime.parse("2000-07-11T22:00:00.010Z"))))
.build());
}

View File

@@ -73,7 +73,6 @@ import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTransactionManagerExtension;
import google.registry.testing.DatabaseHelper;
import google.registry.xml.ValidationMode;
import java.util.Optional;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import org.joda.money.Money;
@@ -214,23 +213,9 @@ class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Domain> {
doSuccessfulTest("domain_info_response.xml");
}
@Test
void testSuccess_noRegistrant() throws Exception {
persistTestEntities(false);
domain = persistResource(domain.asBuilder().setRegistrant(Optional.empty()).build());
doSuccessfulTest("domain_info_response_no_registrant.xml", false);
}
@Test
void testSuccess_noContacts() throws Exception {
persistTestEntities(false);
domain =
persistResource(
domain
.asBuilder()
.setRegistrant(Optional.empty())
.setContacts(ImmutableSet.of())
.build());
doSuccessfulTest("domain_info_response_no_contacts.xml", false);
}

View File

@@ -105,7 +105,6 @@ abstract class DomainTransferFlowTestCase<F extends Flow, R extends EppResource>
persistDomainWithDependentResources(
label,
tld,
null,
clock.nowUtc(),
DateTime.parse("1999-04-03T22:00:00.0Z"),
REGISTRATION_EXPIRATION_TIME);

View File

@@ -42,7 +42,6 @@ import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType;
import static google.registry.testing.DatabaseHelper.getPollMessages;
import static google.registry.testing.DatabaseHelper.loadRegistrar;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.DatabaseHelper.persistActiveSubordinateHost;
@@ -92,9 +91,6 @@ import google.registry.flows.exceptions.ResourceStatusProhibitsOperationExceptio
import google.registry.model.ImmutableObject;
import google.registry.model.billing.BillingBase.Reason;
import google.registry.model.billing.BillingEvent;
import google.registry.model.contact.Contact;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.DesignatedContact.Type;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainAuthInfo;
import google.registry.model.domain.DomainHistory;
@@ -129,14 +125,9 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
"DIGEST_TYPE", "1",
"DIGEST", "A94A8FE5CCB19BA61C4C0873D391E987982FBBD3");
private Contact sh8013Contact;
private Contact mak21Contact;
private Contact unusedContact;
@BeforeEach
void beforeEach() {
createTld("tld");
// Note that "domain_update.xml" tests adding and removing the same contact type.
setEppInput("domain_update.xml");
}
@@ -144,33 +135,6 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
for (int i = 1; i <= 14; ++i) {
persistActiveHost(String.format("ns%d.example.foo", i));
}
sh8013Contact = persistActiveContact("sh8013");
mak21Contact = persistActiveContact("mak21");
unusedContact = persistActiveContact("unused");
}
private void persistDomainWithRegistrant() throws Exception {
Host host = loadResource(Host.class, "ns1.example.foo", clock.nowUtc()).get();
Domain domain =
persistResource(
DatabaseHelper.newDomain(getUniqueIdFromCommand())
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(Type.TECH, mak21Contact.createVKey()),
DesignatedContact.create(Type.ADMIN, mak21Contact.createVKey()),
DesignatedContact.create(Type.BILLING, mak21Contact.createVKey())))
.setRegistrant(Optional.of(mak21Contact.createVKey()))
.setNameservers(ImmutableSet.of(host.createVKey()))
.build());
persistResource(
new DomainHistory.Builder()
.setType(DOMAIN_CREATE)
.setModificationTime(clock.nowUtc())
.setRegistrarId(domain.getCreationRegistrarId())
.setDomain(domain)
.build());
clock.advanceOneMilli();
}
private Domain persistDomain() throws Exception {
@@ -179,10 +143,6 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
persistResource(
DatabaseHelper.newDomain(getUniqueIdFromCommand())
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(Type.TECH, sh8013Contact.createVKey()),
DesignatedContact.create(Type.ADMIN, unusedContact.createVKey())))
.setNameservers(ImmutableSet.of(host.createVKey()))
.build());
persistResource(
@@ -349,7 +309,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
persistReferencedEntities();
persistDomain();
setEppInput("domain_update_max_everything.xml");
// Create 26 hosts and 8 contacts. Start the domain with half of them.
// Create 26 hosts. Start the domain with half of them.
ImmutableSet.Builder<VKey<Host>> nameservers = new ImmutableSet.Builder<>();
for (int i = 0; i < 26; i++) {
Host host = persistActiveHost(String.format("max_test_%d.example.tld", i));
@@ -432,20 +392,6 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
assertThat(addedHost.getSuperordinateDomain()).isEqualTo(domain.createVKey());
}
@Test
void testSuccess_registrantMovedToTechContact() throws Exception {
setEppInput("domain_update_registrant_to_tech.xml");
persistReferencedEntities();
Contact sh8013 = loadResource(Contact.class, "sh8013", clock.nowUtc()).get();
persistResource(
DatabaseHelper.newDomain(getUniqueIdFromCommand())
.asBuilder()
.setRegistrant(Optional.of(sh8013.createVKey()))
.build());
clock.advanceOneMilli();
runFlowAssertResponse(loadFile("generic_success_response.xml"));
}
@Test
void testSuccess_removeClientUpdateProhibited() throws Exception {
setEppInput("domain_update_remove_client_update_prohibited.xml");
@@ -1107,8 +1053,6 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
@Test
void testFailure_missingHost() throws Exception {
persistActiveHost("ns1.example.foo");
persistActiveContact("sh8013");
persistActiveContact("mak21");
persistActiveDomain(getUniqueIdFromCommand());
LinkedResourcesDoNotExistException thrown =
assertThrows(LinkedResourcesDoNotExistException.class, this::runFlow);
@@ -1430,15 +1374,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
@Test
void testFailure_minimumDataset_addingNewRegistrantFails() throws Exception {
persistReferencedEntities();
persistResource(
DatabaseHelper.newDomain(getUniqueIdFromCommand())
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(Type.ADMIN, sh8013Contact.createVKey()),
DesignatedContact.create(Type.TECH, sh8013Contact.createVKey())))
.setRegistrant(Optional.empty())
.build());
persistResource(DatabaseHelper.newDomain(getUniqueIdFromCommand()));
// This EPP sets the registrant to sh8013, whereas in our test setup it is absent.
setEppInput("domain_update_registrant.xml");
RegistrantProhibitedException thrown =

View File

@@ -15,12 +15,10 @@
package google.registry.model;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.DatabaseHelper.persistResource;
import com.google.common.collect.ImmutableList;
import google.registry.model.contact.Contact;
import google.registry.model.host.Host;
import google.registry.testing.TestCacheExtension;
import java.time.Duration;
@@ -34,19 +32,6 @@ public class EppResourceTest extends EntityTestCase {
public final TestCacheExtension testCacheExtension =
new TestCacheExtension.Builder().withEppResourceCache(Duration.ofDays(1)).build();
@Test
void test_loadByCacheIfEnabled_ignoresContactChange() {
Contact originalContact = persistActiveContact("contact123");
assertThat(EppResource.loadByCacheIfEnabled(ImmutableList.of(originalContact.createVKey())))
.containsExactly(originalContact.createVKey(), originalContact);
Contact modifiedContact =
persistResource(originalContact.asBuilder().setEmailAddress("different@fake.lol").build());
assertThat(EppResource.loadByCacheIfEnabled(ImmutableList.of(originalContact.createVKey())))
.containsExactly(originalContact.createVKey(), originalContact);
assertThat(ForeignKeyUtils.loadResource(Contact.class, "contact123", fakeClock.nowUtc()))
.hasValue(modifiedContact);
}
@Test
void test_loadByCacheIfEnabled_ignoresHostChange() {
Host originalHost = persistActiveHost("ns1.example.com");

View File

@@ -16,7 +16,6 @@ package google.registry.model;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -24,7 +23,6 @@ import static org.joda.time.DateTimeZone.UTC;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.host.Host;
import google.registry.persistence.transaction.JpaTestExtensions;
@@ -72,13 +70,6 @@ class ForeignKeyUtilsTest {
.hasValue(domain.createVKey());
}
@Test
void testSuccess_loadContactKey() {
Contact contact = persistActiveContact("john-doe");
assertThat(ForeignKeyUtils.loadKey(Contact.class, "john-doe", fakeClock.nowUtc()))
.hasValue(contact.createVKey());
}
@Test
void testSuccess_loadKeyMostRecentResource() {
Host host = persistActiveHost("ns1.example.com");

View File

@@ -17,7 +17,6 @@ package google.registry.model.console;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -38,7 +37,6 @@ public class ConsoleUpdateHistoryTest extends EntityTestCase {
persistDomainWithDependentResources(
"example",
"tld",
persistActiveContact("contact1234"),
fakeClock.nowUtc(),
fakeClock.nowUtc(),
DateTimeUtils.END_OF_TIME);

View File

@@ -1,269 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.contact;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.testing.ContactSubject.assertAboutContacts;
import static google.registry.testing.DatabaseHelper.cloneAndSetAutoTimestamps;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.SqlHelper.assertThrowForeignKeyViolation;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import google.registry.model.EntityTestCase;
import google.registry.model.ForeignKeyUtils;
import google.registry.model.contact.Disclose.PostalInfoChoice;
import google.registry.model.contact.PostalInfo.Type;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.PresenceMarker;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppcommon.Trid;
import google.registry.model.transfer.ContactTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.util.SerializeUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link Contact}. */
public class ContactTest extends EntityTestCase {
private Contact originalContact;
private Contact contact;
ContactTest() {
super(JpaEntityCoverageCheck.ENABLED);
}
@BeforeEach
void setUp() {
createTld("foobar");
originalContact =
new Contact.Builder()
.setContactId("contact_id")
.setRepoId("1-FOOBAR")
.setCreationRegistrarId("TheRegistrar")
.setLastEppUpdateTime(fakeClock.nowUtc())
.setLastEppUpdateRegistrarId("NewRegistrar")
.setLastTransferTime(fakeClock.nowUtc())
.setPersistedCurrentSponsorRegistrarId("NewRegistrar")
.setLocalizedPostalInfo(
new PostalInfo.Builder()
.setType(Type.LOCALIZED)
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of("111 8th Ave", "4th Floor"))
.setCity("New York")
.setState("NY")
.setZip("10011")
.setCountryCode("US")
.build())
.build())
.setInternationalizedPostalInfo(
new PostalInfo.Builder()
.setType(Type.INTERNATIONALIZED)
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of("111 8th Ave", "4th Floor"))
.setCity("New York")
.setState("NY")
.setZip("10011")
.setCountryCode("US")
.build())
.build())
.setVoiceNumber(new ContactPhoneNumber.Builder().setPhoneNumber("867-5309").build())
.setFaxNumber(
new ContactPhoneNumber.Builder()
.setPhoneNumber("867-5309")
.setExtension("1000")
.build())
.setEmailAddress("jenny@example.com")
.setAuthInfo(ContactAuthInfo.create(PasswordAuth.create("passw0rd")))
.setDisclose(
new Disclose.Builder()
.setVoice(new PresenceMarker())
.setEmail(new PresenceMarker())
.setFax(new PresenceMarker())
.setFlag(true)
.setAddrs(ImmutableList.of(PostalInfoChoice.create(Type.INTERNATIONALIZED)))
.setNames(ImmutableList.of(PostalInfoChoice.create(Type.INTERNATIONALIZED)))
.setOrgs(ImmutableList.of(PostalInfoChoice.create(Type.INTERNATIONALIZED)))
.build())
.setStatusValues(ImmutableSet.of(StatusValue.OK))
.setTransferData(
new ContactTransferData.Builder()
.setGainingRegistrarId("TheRegistrar")
.setLosingRegistrarId("NewRegistrar")
.setPendingTransferExpirationTime(fakeClock.nowUtc())
.setTransferRequestTime(fakeClock.nowUtc())
.setTransferStatus(TransferStatus.SERVER_APPROVED)
.setTransferRequestTrid(Trid.create("client-trid", "server-trid"))
.build())
.build();
// Set up a new persisted Contact entity.
contact = persistResource(cloneAndSetAutoTimestamps(originalContact));
}
@Test
void testContactBaseToContact() {
assertAboutImmutableObjects()
.that(new Contact.Builder().copyFrom(contact).build())
.isEqualExceptFields(contact, "updateTimestamp", "revisions");
}
@Test
void testCloudSqlPersistence_failWhenViolateForeignKeyConstraint() {
assertThrowForeignKeyViolation(
() ->
persistResource(
originalContact
.asBuilder()
.setRepoId("2-FOOBAR")
.setCreationRegistrarId("nonexistent-registrar")
.build()));
}
@Test
void testCloudSqlPersistence_succeed() {
Contact persisted = loadByEntity(originalContact);
Contact fixed =
originalContact
.asBuilder()
.setCreationTime(persisted.getCreationTime())
.setTransferData(
originalContact
.getTransferData()
.asBuilder()
.setServerApproveEntities(null, null, null)
.build())
.build();
assertAboutImmutableObjects().that(persisted).isEqualExceptFields(fixed, "updateTimestamp");
}
@Test
void testPersistence() {
assertThat(
ForeignKeyUtils.loadResource(
Contact.class, contact.getForeignKey(), fakeClock.nowUtc()))
.hasValue(contact);
}
@Test
void testSerializable() {
Contact persisted =
ForeignKeyUtils.loadResource(Contact.class, contact.getForeignKey(), fakeClock.nowUtc())
.get();
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
}
@Test
void testEmptyStringsBecomeNull() {
assertThat(new Contact.Builder().setContactId(null).build().getContactId()).isNull();
assertThat(new Contact.Builder().setContactId("").build().getContactId()).isNull();
assertThat(new Contact.Builder().setContactId(" ").build().getContactId()).isNotNull();
// Nested ImmutableObjects should also be fixed
assertThat(
new Contact.Builder()
.setInternationalizedPostalInfo(
new PostalInfo.Builder().setType(Type.INTERNATIONALIZED).setName(null).build())
.build()
.getInternationalizedPostalInfo()
.getName())
.isNull();
assertThat(
new Contact.Builder()
.setInternationalizedPostalInfo(
new PostalInfo.Builder().setType(Type.INTERNATIONALIZED).setName("").build())
.build()
.getInternationalizedPostalInfo()
.getName())
.isNull();
assertThat(
new Contact.Builder()
.setInternationalizedPostalInfo(
new PostalInfo.Builder().setType(Type.INTERNATIONALIZED).setName(" ").build())
.build()
.getInternationalizedPostalInfo()
.getName())
.isNotNull();
}
@Test
void testEmptyTransferDataBecomesNull() {
Contact withNull = new Contact.Builder().setTransferData(null).build();
Contact withEmpty = withNull.asBuilder().setTransferData(ContactTransferData.EMPTY).build();
assertThat(withNull).isEqualTo(withEmpty);
assertThat(withEmpty.transferData).isNull();
}
@Test
void testImplicitStatusValues() {
// OK is implicit if there's no other statuses.
assertAboutContacts()
.that(new Contact.Builder().build())
.hasExactlyStatusValues(StatusValue.OK);
// If there are other status values, OK should be suppressed.
assertAboutContacts()
.that(
new Contact.Builder().setStatusValues(ImmutableSet.of(StatusValue.CLIENT_HOLD)).build())
.hasExactlyStatusValues(StatusValue.CLIENT_HOLD);
// When OK is suppressed, it should be removed even if it was originally there.
assertAboutContacts()
.that(
new Contact.Builder()
.setStatusValues(ImmutableSet.of(StatusValue.OK, StatusValue.CLIENT_HOLD))
.build())
.hasExactlyStatusValues(StatusValue.CLIENT_HOLD);
}
@Test
void testExpiredTransfer() {
Contact afterTransfer =
contact
.asBuilder()
.setTransferData(
contact
.getTransferData()
.asBuilder()
.setTransferStatus(TransferStatus.PENDING)
.setPendingTransferExpirationTime(fakeClock.nowUtc().plusDays(1))
.setGainingRegistrarId("winner")
.build())
.build()
.cloneProjectedAtTime(fakeClock.nowUtc().plusDays(1));
assertThat(afterTransfer.getTransferData().getTransferStatus())
.isEqualTo(TransferStatus.SERVER_APPROVED);
assertThat(afterTransfer.getCurrentSponsorRegistrarId()).isEqualTo("winner");
assertThat(afterTransfer.getLastTransferTime()).isEqualTo(fakeClock.nowUtc().plusDays(1));
}
@Test
void testSetCreationTime_cantBeCalledTwice() {
IllegalStateException thrown =
assertThrows(
IllegalStateException.class, () -> contact.asBuilder().setCreationTime(END_OF_TIME));
assertThat(thrown).hasMessageThat().contains("creationTime can only be set once");
}
@Test
void testToHydratedString_notCircular() {
// If there are circular references, this will overflow the stack.
contact.toHydratedString();
}
}

View File

@@ -14,9 +14,11 @@
package google.registry.model.domain;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static org.junit.Assert.assertThrows;
import google.registry.flows.domain.DomainFlowUtils.RegistrantProhibitedException;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.model.ResourceCommandTestCase;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppinput.EppInput.ResourceCommandWrapper;
@@ -29,6 +31,7 @@ class DomainCommandTest extends ResourceCommandTestCase {
@Test
void testCreate() throws Exception {
// This EPP command wouldn't be allowed for policy reasons, but should marshal/unmarshal fine.
doXmlRoundtripTest("domain_create.xml");
}
@@ -64,42 +67,48 @@ class DomainCommandTest extends ResourceCommandTestCase {
@Test
void testCreate_emptyCommand() throws Exception {
// This EPP command wouldn't be allowed for policy reasons, but should marshal/unmarshal fine.
doXmlRoundtripTest("domain_create_empty.xml");
}
@Test
void testCreate_missingNonRegistrantContacts() throws Exception {
// This EPP command wouldn't be allowed for policy reasons, but should marshal/unmarshal fine.
doXmlRoundtripTest("domain_create_missing_non_registrant_contacts.xml");
}
@Test
void testCreate_cloneAndLinkReferences() throws Exception {
void testCreate_cloneAndLinkReferences_withHosts() throws Exception {
persistActiveHost("ns1.example.net");
persistActiveHost("ns2.example.net");
persistActiveContact("sh8013");
persistActiveContact("jd1234");
DomainCommand.Create create =
(DomainCommand.Create) loadEppResourceCommand("domain_create.xml");
create.cloneAndLinkReferences(fakeClock.nowUtc());
}
@Test
void testCreate_emptyCommand_cloneAndLinkReferences() throws Exception {
// This EPP command wouldn't be allowed for policy reasons, but should clone-and-link fine.
void testCreate_cloneAndLinkReferences_failsWithContacts() throws Exception {
persistActiveHost("ns1.example.net");
persistActiveHost("ns2.example.net");
DomainCommand.Create create =
(DomainCommand.Create) loadEppResourceCommand("domain_create_empty.xml");
create.cloneAndLinkReferences(fakeClock.nowUtc());
(DomainCommand.Create) loadEppResourceCommand("domain_create_with_contacts.xml");
assertThrows(
RegistrantProhibitedException.class,
() -> create.cloneAndLinkReferences(fakeClock.nowUtc()));
}
@Test
void testCreate_missingNonRegistrantContacts_cloneAndLinkReferences() throws Exception {
persistActiveContact("jd1234");
// This EPP command wouldn't be allowed for policy reasons, but should clone-and-link fine.
void testCreate_cloneAndLinkReferences_failsWithRegistrant() throws Exception {
DomainCommand.Create create =
(DomainCommand.Create)
loadEppResourceCommand("domain_create_missing_non_registrant_contacts.xml");
assertThrows(
RegistrantProhibitedException.class,
() -> create.cloneAndLinkReferences(fakeClock.nowUtc()));
}
@Test
void testCreate_emptyCommand_cloneAndLinkReferences() throws Exception {
DomainCommand.Create create =
(DomainCommand.Create) loadEppResourceCommand("domain_create_empty.xml");
create.cloneAndLinkReferences(fakeClock.nowUtc());
}
@@ -120,16 +129,24 @@ class DomainCommandTest extends ResourceCommandTestCase {
}
@Test
void testUpdate_cloneAndLinkReferences() throws Exception {
void testUpdate_cloneAndLinkReferences_hosts() throws Exception {
persistActiveHost("ns1.example.com");
persistActiveHost("ns2.example.com");
persistActiveContact("mak21");
persistActiveContact("sh8013");
DomainCommand.Update update =
(DomainCommand.Update) loadEppResourceCommand("domain_update.xml");
update.cloneAndLinkReferences(fakeClock.nowUtc());
}
@Test
void testUpdate_cloneAndLinkReferences_failsWithContacts() throws Exception {
persistActiveHost("ns1.example.com");
persistActiveHost("ns2.example.com");
DomainCommand.Update update =
(DomainCommand.Update) loadEppResourceCommand("domain_update_with_contacts.xml");
assertThrows(
ContactsProhibitedException.class, () -> update.cloneAndLinkReferences(fakeClock.nowUtc()));
}
@Test
void testUpdate_emptyCommand_cloneAndLinkReferences() throws Exception {
// This EPP command wouldn't be allowed for policy reasons, but should clone-and-link fine.

View File

@@ -35,8 +35,6 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Sets;
import google.registry.model.billing.BillingBase.RenewalPriceBehavior;
import google.registry.model.contact.Contact;
import google.registry.model.domain.DesignatedContact.Type;
import google.registry.model.domain.fee.FeeQueryCommandExtensionItem.CommandName;
import google.registry.model.domain.launch.LaunchNotice;
import google.registry.model.domain.rgp.GracePeriodStatus;
@@ -46,14 +44,12 @@ import google.registry.model.domain.token.AllocationToken.TokenStatus;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.Host;
import google.registry.model.transfer.ContactTransferData;
import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.FakeClock;
import google.registry.util.SerializeUtils;
import java.util.Arrays;
import java.util.Optional;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.joda.time.DateTime;
@@ -71,12 +67,8 @@ public class DomainSqlTest {
new JpaTestExtensions.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
private Domain domain;
private Optional<VKey<Contact>> contactKey;
private VKey<Contact> contact2Key;
private VKey<Host> host1VKey;
private Host host;
private Contact contact;
private Contact contact2;
private AllocationToken allocationToken;
@BeforeEach
@@ -84,9 +76,6 @@ public class DomainSqlTest {
saveRegistrar("registrar1");
saveRegistrar("registrar2");
saveRegistrar("registrar3");
contactKey = Optional.of(createKey(Contact.class, "contact_id1"));
contact2Key = createKey(Contact.class, "contact_id2");
host1VKey = createKey(Host.class, "host1");
domain =
@@ -106,8 +95,6 @@ public class DomainSqlTest {
StatusValue.SERVER_UPDATE_PROHIBITED,
StatusValue.SERVER_RENEW_PROHIBITED,
StatusValue.SERVER_HOLD))
.setRegistrant(contactKey)
.setContacts(ImmutableSet.of(DesignatedContact.create(Type.ADMIN, contact2Key)))
.setSubordinateHosts(ImmutableSet.of("ns1.example.com"))
.setPersistedCurrentSponsorRegistrarId("registrar3")
.setRegistrationExpirationTime(fakeClock.nowUtc().plusYears(1))
@@ -128,8 +115,6 @@ public class DomainSqlTest {
.setCreationRegistrarId("registrar1")
.setPersistedCurrentSponsorRegistrarId("registrar2")
.build();
contact = makeContact("contact_id1");
contact2 = makeContact("contact_id2");
allocationToken =
new AllocationToken.Builder()
@@ -168,7 +153,7 @@ public class DomainSqlTest {
@Test
void testHostForeignKeyConstraints() {
// Persist the domain without the associated host object.
assertThrowForeignKeyViolation(() -> persistResources(contact, contact2, domain));
assertThrowForeignKeyViolation(() -> persistResources(domain));
}
@Test
@@ -357,7 +342,7 @@ public class DomainSqlTest {
@Test
void testSerializable() {
createTld("com");
persistResources(contact, contact2, domain, host);
persistResources(domain, host);
Domain persisted = tm().transact(() -> tm().loadByEntity(domain));
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
}
@@ -365,7 +350,7 @@ public class DomainSqlTest {
@Test
void testUpdates() {
createTld("com");
persistResources(contact, contact2, domain, host);
persistResources(domain, host);
domain = domain.asBuilder().setNameservers(ImmutableSet.of()).build();
persistResource(domain);
assertAboutImmutableObjects()
@@ -373,18 +358,9 @@ public class DomainSqlTest {
.isEqualExceptFields(domain, "updateTimestamp", "creationTime");
}
static Contact makeContact(String repoId) {
return new Contact.Builder()
.setRepoId(repoId)
.setCreationRegistrarId("registrar1")
.setTransferData(new ContactTransferData.Builder().build())
.setPersistedCurrentSponsorRegistrarId("registrar1")
.build();
}
private void persistDomain() {
createTld("com");
persistResources(contact, contact2, domain, host);
persistResources(domain, host);
}
private <T> VKey<T> createKey(Class<T> clazz, String key) {
@@ -421,7 +397,7 @@ public class DomainSqlTest {
.setPersistedCurrentSponsorRegistrarId("registrar2")
.build();
persistResource(host2);
domain = persisted.asBuilder().addNameserver(host2.createVKey()).build();
domain = persisted.asBuilder().addNameserver(host2.createVKey()).build();
persistResource(domain);
domain = loadByKey(domain.createVKey());
assertThat(domain.getUpdateTimestamp().getTimestamp())

View File

@@ -23,7 +23,6 @@ import static google.registry.model.domain.token.AllocationToken.TokenType.SINGL
import static google.registry.testing.DatabaseHelper.cloneAndSetAutoTimestamps;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.newHost;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -49,8 +48,6 @@ import google.registry.model.billing.BillingBase.Flag;
import google.registry.model.billing.BillingBase.Reason;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingRecurrence;
import google.registry.model.contact.Contact;
import google.registry.model.domain.DesignatedContact.Type;
import google.registry.model.domain.fee.FeeQueryCommandExtensionItem.CommandName;
import google.registry.model.domain.launch.LaunchNotice;
import google.registry.model.domain.rgp.GracePeriodStatus;
@@ -91,7 +88,6 @@ public class DomainTest {
private VKey<BillingEvent> oneTimeBillKey;
private VKey<BillingRecurrence> recurrenceBillKey;
private DomainHistory domainHistory;
private VKey<Contact> contact1Key, contact2Key;
@BeforeEach
void setUp() {
@@ -102,8 +98,6 @@ public class DomainTest {
createTld("com");
domain = persistActiveDomain("example.com");
VKey<Host> hostKey = persistActiveHost("ns1.example.com").createVKey();
contact1Key = persistActiveContact("contact_id1").createVKey();
contact2Key = persistActiveContact("contact_id1").createVKey();
domainHistory =
persistResource(
new DomainHistory.Builder()
@@ -185,7 +179,6 @@ public class DomainTest {
StatusValue.SERVER_UPDATE_PROHIBITED,
StatusValue.SERVER_RENEW_PROHIBITED,
StatusValue.SERVER_HOLD))
.setRegistrant(Optional.of(contact1Key))
.setNameservers(ImmutableSet.of(hostKey))
.setSubordinateHosts(ImmutableSet.of("ns1.example.com"))
.setPersistedCurrentSponsorRegistrarId("NewRegistrar")
@@ -243,17 +236,6 @@ public class DomainTest {
.hasValue(domain);
}
@Test
void testRegistrantNotRequired() {
persistResource(domain.asBuilder().setRegistrant(Optional.empty()).build());
String foreignKey = domain.getForeignKey();
assertThat(
ForeignKeyUtils.loadResource(Domain.class, foreignKey, fakeClock.nowUtc())
.get()
.getRegistrant())
.isEmpty();
}
@Test
void testEmptyStringsBecomeNull() {
assertThat(
@@ -1015,51 +997,6 @@ public class DomainTest {
}
}
@Test
void testContactFields() {
VKey<Contact> contact3Key = persistActiveContact("contact_id3").createVKey();
VKey<Contact> contact4Key = persistActiveContact("contact_id4").createVKey();
// Set all of the contacts.
domain.setContactFields(
ImmutableSet.of(
DesignatedContact.create(Type.REGISTRANT, contact1Key),
DesignatedContact.create(Type.ADMIN, contact2Key),
DesignatedContact.create(Type.BILLING, contact3Key),
DesignatedContact.create(Type.TECH, contact4Key)),
true);
assertThat(domain.getRegistrant()).hasValue(contact1Key);
assertThat(domain.getAdminContact()).hasValue(contact2Key);
assertThat(domain.getBillingContact()).hasValue(contact3Key);
assertThat(domain.getTechContact()).hasValue(contact4Key);
// Make sure everything gets nulled out.
domain.setContactFields(ImmutableSet.of(), true);
assertThat(domain.getRegistrant()).isEmpty();
assertThat(domain.getAdminContact()).isEmpty();
assertThat(domain.getBillingContact()).isEmpty();
assertThat(domain.getTechContact()).isEmpty();
// Make sure that changes don't affect the registrant unless requested.
domain.setContactFields(
ImmutableSet.of(
DesignatedContact.create(Type.REGISTRANT, contact1Key),
DesignatedContact.create(Type.ADMIN, contact2Key),
DesignatedContact.create(Type.BILLING, contact3Key),
DesignatedContact.create(Type.TECH, contact4Key)),
false);
assertThat(domain.getRegistrant()).isEmpty();
assertThat(domain.getAdminContact()).hasValue(contact2Key);
assertThat(domain.getBillingContact()).hasValue(contact3Key);
assertThat(domain.getTechContact()).hasValue(contact4Key);
domain = domain.asBuilder().setRegistrant(Optional.of(contact1Key)).build();
domain.setContactFields(ImmutableSet.of(), false);
assertThat(domain.getRegistrant()).hasValue(contact1Key);
assertThat(domain.getAdminContact()).isEmpty();
assertThat(domain.getBillingContact()).isEmpty();
assertThat(domain.getTechContact()).isEmpty();
}
@Test
void testFail_currentBulkTokenWrongTokenType() {
AllocationToken allocationToken =

View File

@@ -15,18 +15,48 @@
package google.registry.model.eppcommon;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.model.eppcommon.EppXmlTransformer.isFeeExtension;
import static google.registry.model.eppcommon.EppXmlTransformer.unmarshal;
import static google.registry.testing.TestDataHelper.loadBytes;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableSet;
import google.registry.model.domain.bulktoken.BulkTokenResponseExtension;
import google.registry.model.domain.launch.LaunchCheckResponseExtension;
import google.registry.model.domain.rgp.RgpInfoExtension;
import google.registry.model.domain.secdns.SecDnsInfoExtension;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppoutput.EppOutput;
import google.registry.model.eppoutput.EppResponse;
import google.registry.util.RegistryEnvironment;
import jakarta.xml.bind.annotation.XmlElementRef;
import jakarta.xml.bind.annotation.XmlElementRefs;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
/** Tests for {@link EppXmlTransformer}. */
class EppXmlTransformerTest {
// Non-fee extensions allowed in {@code Response.extensions}.
private static final ImmutableSet<Class<?>> NON_FEE_EXTENSIONS =
ImmutableSet.of(
BulkTokenResponseExtension.class,
LaunchCheckResponseExtension.class,
RgpInfoExtension.class,
SecDnsInfoExtension.class);
@Test
void isFeeExtension_eppResponse() throws Exception {
var xmlRefs =
EppResponse.class.getDeclaredField("extensions").getAnnotation(XmlElementRefs.class);
Arrays.stream(xmlRefs.value())
.map(XmlElementRef::type)
.filter(type -> !NON_FEE_EXTENSIONS.contains(type))
.forEach(
type -> assertWithMessage(type.getSimpleName()).that(isFeeExtension(type)).isTrue());
}
@Test
void testUnmarshalingEppInput() throws Exception {
EppInput input = unmarshal(EppInput.class, loadBytes(getClass(), "contact_info.xml").read());

View File

@@ -19,7 +19,6 @@ import static google.registry.model.eppcommon.EppXmlTransformer.unmarshal;
import static google.registry.testing.TestDataHelper.loadBytes;
import static org.junit.jupiter.api.Assertions.assertThrows;
import google.registry.model.contact.ContactTest;
import google.registry.model.domain.DomainTest;
import google.registry.model.eppinput.EppInput.InnerCommand;
import google.registry.model.eppinput.EppInput.Login;
@@ -29,17 +28,6 @@ import org.junit.jupiter.api.Test;
/** Unit tests for {@link EppInput}. */
class EppInputTest {
@Test
void testUnmarshalling_contactInfo() throws Exception {
EppInput input =
unmarshal(EppInput.class, loadBytes(ContactTest.class, "contact_info.xml").read());
assertThat(input.getCommandWrapper().getClTrid()).hasValue("ABC-12345");
assertThat(input.getCommandType()).isEqualTo("info");
assertThat(input.getResourceType()).hasValue("contact");
assertThat(input.getSingleTargetId()).hasValue("sh8013");
assertThat(input.getTargetIds()).containsExactly("sh8013");
}
@Test
void testUnmarshalling_domainCheck() throws Exception {
EppInput input =

View File

@@ -1,145 +0,0 @@
// 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.history;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.newContactWithRoid;
import static google.registry.testing.DatabaseHelper.persistResource;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableList;
import google.registry.model.EntityTestCase;
import google.registry.model.contact.Contact;
import google.registry.model.contact.ContactAddress;
import google.registry.model.contact.ContactBase;
import google.registry.model.contact.ContactHistory;
import google.registry.model.contact.ContactPhoneNumber;
import google.registry.model.contact.PostalInfo;
import google.registry.model.eppcommon.Trid;
import google.registry.model.reporting.HistoryEntry;
import google.registry.util.SerializeUtils;
import org.junit.jupiter.api.Test;
/** Tests for {@link ContactHistory}. */
public class ContactHistoryTest extends EntityTestCase {
ContactHistoryTest() {
super(JpaEntityCoverageCheck.ENABLED);
}
@Test
void testPersistence() {
Contact contact = newContactWithRoid("contactId", "contact1");
persistResource(contact);
Contact contactFromDb = loadByEntity(contact);
ContactHistory contactHistory = createContactHistory(contactFromDb);
persistResource(contactHistory);
tm().transact(
() -> {
ContactHistory fromDatabase = tm().loadByKey(contactHistory.createVKey());
assertContactHistoriesEqual(fromDatabase, contactHistory);
assertThat(fromDatabase.getRepoId()).isEqualTo(contactHistory.getRepoId());
});
}
@Test
void testSerializable() {
Contact contact = newContactWithRoid("contactId", "contact1");
persistResource(contact);
Contact contactFromDb = loadByEntity(contact);
ContactHistory contactHistory = createContactHistory(contactFromDb);
persistResource(contactHistory);
ContactHistory fromDatabase = tm().transact(() -> tm().loadByKey(contactHistory.createVKey()));
assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase);
}
@Test
void testWipeOutPii_assertsAllPiiFieldsAreNull() {
ContactHistory originalEntity =
createContactHistory(
new Contact.Builder()
.setRepoId("1-FOOBAR")
.setLocalizedPostalInfo(
new PostalInfo.Builder()
.setType(PostalInfo.Type.LOCALIZED)
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of("111 8th Ave", "4th Floor"))
.setCity("New York")
.setState("NY")
.setZip("10011")
.setCountryCode("US")
.build())
.build())
.setInternationalizedPostalInfo(
new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of("111 8th Ave", "4th Floor"))
.setCity("New York")
.setState("NY")
.setZip("10011")
.setCountryCode("US")
.build())
.build())
.setVoiceNumber(new ContactPhoneNumber.Builder().setPhoneNumber("867-5309").build())
.setFaxNumber(
new ContactPhoneNumber.Builder()
.setPhoneNumber("867-5309")
.setExtension("1000")
.build())
.setEmailAddress("test@example.com")
.build());
assertThat(originalEntity.getContactBase().get().getEmailAddress()).isNotNull();
assertThat(originalEntity.getContactBase().get().getLocalizedPostalInfo()).isNotNull();
assertThat(originalEntity.getContactBase().get().getInternationalizedPostalInfo()).isNotNull();
assertThat(originalEntity.getContactBase().get().getVoiceNumber()).isNotNull();
assertThat(originalEntity.getContactBase().get().getFaxNumber()).isNotNull();
ContactHistory wipedEntity = originalEntity.asBuilder().wipeOutPii().build();
assertThat(wipedEntity.getContactBase().get().getEmailAddress()).isNull();
assertThat(wipedEntity.getContactBase().get().getLocalizedPostalInfo()).isNull();
assertThat(wipedEntity.getContactBase().get().getInternationalizedPostalInfo()).isNull();
assertThat(wipedEntity.getContactBase().get().getVoiceNumber()).isNull();
assertThat(wipedEntity.getContactBase().get().getFaxNumber()).isNull();
}
private ContactHistory createContactHistory(ContactBase contact) {
return new ContactHistory.Builder()
.setType(HistoryEntry.Type.HOST_CREATE)
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
.setModificationTime(fakeClock.nowUtc())
.setRegistrarId("TheRegistrar")
.setTrid(Trid.create("ABC-123", "server-trid"))
.setBySuperuser(false)
.setReason("reason")
.setRequestedByRegistrar(true)
.setContact(contact)
.build();
}
static void assertContactHistoriesEqual(ContactHistory one, ContactHistory two) {
assertAboutImmutableObjects().that(one).isEqualExceptFields(two, "resource");
assertAboutImmutableObjects()
.that(one.getContactBase().get())
.isEqualExceptFields(two.getContactBase().get());
}
}

View File

@@ -18,7 +18,6 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.newContactWithRoid;
import static google.registry.testing.DatabaseHelper.newDomain;
import static google.registry.testing.DatabaseHelper.newHostWithRoid;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -27,7 +26,6 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableSet;
import google.registry.model.EntityTestCase;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainBase;
import google.registry.model.domain.DomainHistory;
@@ -58,7 +56,7 @@ public class DomainHistoryTest extends EntityTestCase {
@Test
void testPersistence() {
Domain domain = addGracePeriodForSql(createDomainWithContactsAndHosts());
Domain domain = addGracePeriodForSql(createDomainWithHosts());
DomainHistory domainHistory = createDomainHistory(domain);
persistResource(domainHistory);
@@ -72,26 +70,18 @@ public class DomainHistoryTest extends EntityTestCase {
@Test
void testSerializable() {
Domain domain = addGracePeriodForSql(createDomainWithContactsAndHosts());
Domain domain = addGracePeriodForSql(createDomainWithHosts());
DomainHistory domainHistory = createDomainHistory(domain);
persistResource(domainHistory);
DomainHistory fromDatabase = tm().transact(() -> tm().loadByKey(domainHistory.createVKey()));
assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase);
}
static Domain createDomainWithContactsAndHosts() {
static Domain createDomainWithHosts() {
createTld("tld");
Host host = newHostWithRoid("ns1.example.com", "host1");
Contact contact = newContactWithRoid("contactId", "contact1");
tm().transact(
() -> {
tm().insert(host);
tm().insert(contact);
});
Host host = persistResource(newHostWithRoid("ns1.example.com", "host1"));
Domain domain =
newDomain("example.tld", "domainRepoId", contact)
newDomain("example.tld", "domainRepoId")
.asBuilder()
.setNameservers(host.createVKey())
.setDsData(ImmutableSet.of(DomainDsData.create(1, 2, 3, new byte[] {0, 1, 2})))

View File

@@ -78,8 +78,8 @@ public class PollMessageExternalKeyConverterTest {
.setMsg("Test poll message")
.setHistoryEntry(historyEntry)
.build());
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("5-2007");
assertVKeysEqual(parsePollMessageExternalId("5-2007"), pollMessage.createVKey());
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("4-2007");
assertVKeysEqual(parsePollMessageExternalId("4-2007"), pollMessage.createVKey());
}
@Test
@@ -95,8 +95,8 @@ public class PollMessageExternalKeyConverterTest {
.setMsg("Test poll message")
.setHistoryEntry(historyEntry)
.build());
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("7-2007");
assertVKeysEqual(parsePollMessageExternalId("7-2007"), pollMessage.createVKey());
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("6-2007");
assertVKeysEqual(parsePollMessageExternalId("6-2007"), pollMessage.createVKey());
}
@Test

View File

@@ -18,13 +18,11 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadByKey;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistResource;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableList;
import google.registry.model.EntityTestCase;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainHistory;
import google.registry.model.domain.Period;
@@ -51,8 +49,7 @@ public class PollMessageTest extends EntityTestCase {
@BeforeEach
void setUp() {
createTld("foobar");
Contact contact = persistActiveContact("contact1234");
Domain domain = persistResource(DatabaseHelper.newDomain("foo.foobar", contact));
Domain domain = persistResource(DatabaseHelper.newDomain("foo.foobar"));
historyEntry =
persistResource(
new DomainHistory.Builder()

View File

@@ -18,13 +18,11 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ImmutableObjectSubject.immutableObjectCorrespondence;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTlds;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistResource;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import google.registry.model.EntityTestCase;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.reporting.Spec11ThreatMatch.ThreatType;
import google.registry.testing.DatabaseHelper;
@@ -46,11 +44,10 @@ class Spec11ThreatMatchDaoTest extends EntityTestCase {
@BeforeEach
void setUp() {
createTlds("com", "org");
Contact contact = persistActiveContact("jd1234");
todayComDomain = persistResource(DatabaseHelper.newDomain("today.com", contact));
todayOrgDomain = persistResource(DatabaseHelper.newDomain("today.org", contact));
yesterdayComDomain = persistResource(DatabaseHelper.newDomain("yesterday.com", contact));
yesterdayOrgDomain = persistResource(DatabaseHelper.newDomain("yesterday.org", contact));
todayComDomain = persistResource(DatabaseHelper.newDomain("today.com"));
todayOrgDomain = persistResource(DatabaseHelper.newDomain("today.org"));
yesterdayComDomain = persistResource(DatabaseHelper.newDomain("yesterday.com"));
yesterdayOrgDomain = persistResource(DatabaseHelper.newDomain("yesterday.org"));
tm().transact(
() -> {
tm().insertAll(getThreatMatchesToday());

View File

@@ -27,12 +27,9 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableSet;
import google.registry.model.EntityTestCase;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.host.Host;
import google.registry.model.transfer.ContactTransferData;
import google.registry.persistence.VKey;
import java.util.Optional;
import org.joda.time.LocalDate;
import org.joda.time.format.ISODateTimeFormat;
import org.junit.jupiter.api.BeforeEach;
@@ -48,7 +45,6 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
private Spec11ThreatMatch threat;
private Domain domain;
private Host host;
private Contact registrantContact;
Spec11ThreatMatchTest() {
super(JpaEntityCoverageCheck.ENABLED);
@@ -57,7 +53,6 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
@BeforeEach
void setUp() {
VKey<Host> hostVKey = VKey.create(Host.class, "host");
VKey<Contact> registrantContactVKey = VKey.create(Contact.class, "contact_id");
String domainRepoId = "4-TLD";
createTld("tld");
@@ -70,17 +65,6 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
.setDomainName("foo.tld")
.setRepoId(domainRepoId)
.setNameservers(hostVKey)
.setRegistrant(Optional.of(registrantContactVKey))
.setContacts(ImmutableSet.of())
.build();
// Create a contact for the purpose of testing a foreign key reference in the Domain table.
registrantContact =
new Contact.Builder()
.setRepoId("contact_id")
.setCreationRegistrarId(REGISTRAR_ID)
.setTransferData(new ContactTransferData.Builder().build())
.setPersistedCurrentSponsorRegistrarId(REGISTRAR_ID)
.build();
// Create a host for the purpose of testing a foreign key reference in the Domain table. */
@@ -106,7 +90,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
void testPersistence() {
createTld("tld");
saveRegistrar(REGISTRAR_ID);
tm().transact(() -> tm().insertAll(registrantContact, domain, host, threat));
tm().transact(() -> tm().insertAll(domain, host, threat));
assertAboutImmutableObjects().that(loadByEntity(threat)).isEqualExceptFields(threat, "id");
}
@@ -114,12 +98,12 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
@Disabled("We can't rely on foreign keys until we've migrated to SQL")
void testThreatForeignKeyConstraints() {
// Persist the threat without the associated registrar.
assertThrowForeignKeyViolation(() -> persistResources(host, registrantContact, domain, threat));
assertThrowForeignKeyViolation(() -> persistResources(host, domain, threat));
saveRegistrar(REGISTRAR_ID);
// Persist the threat without the associated domain.
assertThrowForeignKeyViolation(() -> persistResources(registrantContact, host, threat));
assertThrowForeignKeyViolation(() -> persistResources(host, threat));
}
@Test

View File

@@ -76,7 +76,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
makeAndPersistHost(
"ns2.cat.lol", "bad:f00d:cafe:0:0:0:15:beef", clock.nowUtc().minusYears(2));
persistResource(
makeDomain("cat.lol", null, null, null, host1, host2, registrarLol)
makeDomain("cat.lol", host1, host2, registrarLol)
.asBuilder()
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
.setCreationRegistrarId("TheRegistrar")
@@ -88,7 +88,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
"ns2.dodo.lol", "bad:f00d:cafe:0:0:0:15:beef", clock.nowUtc().minusYears(2));
Domain domainDeleted =
persistResource(
makeDomain("dodo.lol", null, null, null, host1, hostDodo2, registrarLol)
makeDomain("dodo.lol", host1, hostDodo2, registrarLol)
.asBuilder()
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
.setCreationRegistrarId("TheRegistrar")
@@ -100,7 +100,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
persistResource(makeRegistrar("idnregistrar", "IDN Registrar", Registrar.State.ACTIVE));
persistResources(makeRegistrarPocs(registrarIdn));
persistResource(
makeDomain("cat.みんな", null, null, null, host1, host2, registrarIdn)
makeDomain("cat.みんな", host1, host2, registrarIdn)
.asBuilder()
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
.setCreationRegistrarId("TheRegistrar")
@@ -113,7 +113,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
makeRegistrar("1tldregistrar", "Multilevel Registrar", Registrar.State.ACTIVE));
persistResources(makeRegistrarPocs(registrar1Tld));
persistResource(
makeDomain("cat.1.tld", null, null, null, host1, host2, registrar1Tld)
makeDomain("cat.1.tld", host1, host2, registrar1Tld)
.asBuilder()
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
.setCreationRegistrarId("TheRegistrar")
@@ -473,7 +473,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
String label, String tld, DateTime creationTime, DateTime expirationTime) {
return persistResource(
persistDomainWithDependentResources(
label, tld, null, clock.nowUtc(), creationTime, expirationTime)
label, tld, clock.nowUtc(), creationTime, expirationTime)
.asBuilder()
.addNameserver(host1.createVKey())
.build());

View File

@@ -137,7 +137,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
"ns2.cat.lol", "bad:f00d:cafe:0:0:0:15:beef", clock.nowUtc().minusYears(2)));
domainCatLol =
persistResource(
makeDomain("cat.lol", null, null, null, hostNs1CatLol, hostNs2CatLol, registrar)
makeDomain("cat.lol", hostNs1CatLol, hostNs2CatLol, registrar)
.asBuilder()
.setSubordinateHosts(ImmutableSet.of("ns1.cat.lol", "ns2.cat.lol"))
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
@@ -152,9 +152,6 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
persistResource(
makeDomain(
"cat2.lol",
null,
null,
null,
addHostToMap(
FullFieldsTestEntityHelper.makeAndPersistHost(
"ns1.cat.example", "10.20.30.40", clock.nowUtc().minusYears(1))),
@@ -178,9 +175,6 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
persistResource(
makeDomain(
"cat.example",
null,
null,
null,
hostNs1CatLol,
addHostToMap(
FullFieldsTestEntityHelper.makeAndPersistHost(
@@ -200,9 +194,6 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
persistResource(
makeDomain(
"cat.みんな",
null,
null,
null,
addHostToMap(
FullFieldsTestEntityHelper.makeAndPersistHost(
"ns1.cat.みんな", "1.2.3.5", clock.nowUtc().minusYears(1))),
@@ -224,9 +215,6 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
persistResource(
makeDomain(
"cat.1.test",
null,
null,
null,
addHostToMap(
FullFieldsTestEntityHelper.makeAndPersistHost(
"ns1.cat.1.test", "1.2.3.5", clock.nowUtc().minusYears(1))),
@@ -336,7 +324,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
for (int i = numActiveDomains * numTotalDomainsPerActiveDomain; i >= 1; i--) {
String domainName = String.format("domain%d.lol", i);
Domain.Builder builder =
makeDomain(domainName, null, null, null, null, null, registrar)
makeDomain(domainName, null, null, registrar)
.asBuilder()
.setNameservers(hostKeys)
.setCreationTimeForTest(clock.nowUtc().minusYears(3))

View File

@@ -54,7 +54,7 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
persistResources(makeRegistrarPocs(registrarLol));
Host host1 = persistResource(makeHost("ns1.cat.lol", "1.2.3.4"));
Host host2 = persistResource(makeHost("ns2.cat.lol", "bad:f00d:cafe:0:0:0:15:beef"));
persistResource(makeDomain("cat.lol", null, null, null, host1, host2, registrarLol));
persistResource(makeDomain("cat.lol", host1, host2, registrarLol));
// xn--q9jyb4c
createTld("xn--q9jyb4c");
Registrar registrarIdn = persistResource(

View File

@@ -114,9 +114,7 @@ class RdapJsonFormatterTest {
"ns5.cat.みんな", null, null, clock.nowUtc().minusYears(5), "unicoderegistrar");
// Create an unused domain that references hostBoth and hostNoAddresses so that
// they will have "associated" (ie, StatusValue.LINKED) status.
Domain dog =
persistResource(
makeDomain("dog.みんな", null, null, null, hostBoth, hostNoAddresses, registrar));
Domain dog = persistResource(makeDomain("dog.みんな", hostBoth, hostNoAddresses, registrar));
hostSuperordinatePendingTransfer =
persistResource(
makeAndPersistHost(
@@ -142,14 +140,14 @@ class RdapJsonFormatterTest {
.build());
domainFull =
persistResource(
makeDomain("cat.みんな", null, null, null, hostIpv4, hostIpv6, registrar)
makeDomain("cat.みんな", hostIpv4, hostIpv6, registrar)
.asBuilder()
.setCreationTimeForTest(clock.nowUtc().minusMonths(4))
.setLastEppUpdateTime(clock.nowUtc().minusMonths(3))
.build());
domainNoNameserversNoTransfers =
persistResource(
makeDomain("fish.みんな", null, null, null, null, null, registrar)
makeDomain("fish.みんな", null, null, registrar)
.asBuilder()
.setCreationTimeForTest(clock.nowUtc())
.setLastEppUpdateTime(null)

View File

@@ -131,7 +131,7 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
// create a domain so that we can use it as a test nameserver search string suffix
domainCatLol =
persistResource(
makeDomain("cat.lol", null, null, null, hostNs1CatLol, hostNs2CatLol, registrar)
makeDomain("cat.lol", hostNs1CatLol, hostNs2CatLol, registrar)
.asBuilder()
.setSubordinateHosts(ImmutableSet.of("ns1.cat.lol", "ns2.cat.lol"))
.build());

View File

@@ -1,337 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.rde;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatabaseHelper.createTld;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import google.registry.model.contact.Contact;
import google.registry.model.contact.ContactAddress;
import google.registry.model.contact.ContactAuthInfo;
import google.registry.model.contact.ContactPhoneNumber;
import google.registry.model.contact.Disclose;
import google.registry.model.contact.PostalInfo;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.PresenceMarker;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppcommon.Trid;
import google.registry.model.transfer.ContactTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.xjc.contact.XjcContactPostalInfoEnumType;
import google.registry.xjc.contact.XjcContactPostalInfoType;
import google.registry.xjc.contact.XjcContactStatusType;
import google.registry.xjc.contact.XjcContactStatusValueType;
import google.registry.xjc.eppcom.XjcEppcomTrStatusType;
import google.registry.xjc.rde.XjcRdeContentsType;
import google.registry.xjc.rde.XjcRdeDeposit;
import google.registry.xjc.rde.XjcRdeDepositTypeType;
import google.registry.xjc.rde.XjcRdeMenuType;
import google.registry.xjc.rdecontact.XjcRdeContact;
import google.registry.xjc.rdecontact.XjcRdeContactElement;
import java.io.ByteArrayOutputStream;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/**
* Unit tests for {@link ContactToXjcConverter}.
*
* <p>This tests the mapping between {@link Contact} and {@link XjcRdeContact} as well as some
* exceptional conditions.
*/
public class ContactToXjcConverterTest {
@RegisterExtension
final JpaIntegrationTestExtension jpa =
new JpaTestExtensions.Builder().buildIntegrationTestExtension();
@BeforeEach
void beforeEach() {
createTld("xn--q9jyb4c");
}
@Test
void testConvertContact() {
Contact contact = makeContact();
XjcRdeContact bean = ContactToXjcConverter.convertContact(contact);
// o A <id> element that contains the server-unique identifier of the
// contact object
assertThat(bean.getId()).isEqualTo("love-id");
// o A <roid> element that contains the Repository Object IDentifier
// assigned to the contact object when the object was created.
assertThat(bean.getRoid()).isEqualTo("2-ROID");
// o One or more <status> elements that describe the status of the
// contact object.
assertThat(bean.getStatuses().stream().map(XjcContactStatusType::getS))
.containsExactly(
XjcContactStatusValueType.CLIENT_DELETE_PROHIBITED,
XjcContactStatusValueType.SERVER_UPDATE_PROHIBITED);
// o One or two <postalInfo> elements that contain postal-address
// information. Two elements are provided so that address
// information can be provided in both internationalized and
// localized forms; a "type" attribute is used to identify the two
// forms. If an internationalized form (type="int") is provided,
// element content MUST be represented in a subset of UTF-8 that can
// be represented in the 7-bit US-ASCII character set. If a
// localized form (type="loc") is provided, element content MAY be
// represented in unrestricted UTF-8. The <postalInfo> element
// contains the following child elements:
//
// * A <name> element that contains the name of the individual or
// role represented by the contact.
//
// * An OPTIONAL <org> element that contains the name of the
// organization with which the contact is affiliated.
//
// * An <addr> element that contains address information associated
// with the contact. An <addr> element contains the following
// child elements:
//
// + One, two, or three OPTIONAL <street> elements that contain
// the contact's street address.
//
// + A <city> element that contains the contact's city.
//
// + An OPTIONAL <sp> element that contains the contact's state
// or province.
//
// + An OPTIONAL <pc> element that contains the contact's postal
// code.
//
// + A <cc> element that contains the contact's two-letter
// country code.
assertThat(bean.getPostalInfos()).hasSize(1);
XjcContactPostalInfoType postalInfo = bean.getPostalInfos().get(0);
assertThat(postalInfo.getName()).isEqualTo("Dipsy Doodle");
assertThat(postalInfo.getOrg()).isEqualTo("Charleston Road Registry Incorporated");
assertThat(postalInfo.getAddr().getStreets()).hasSize(2);
assertThat(postalInfo.getAddr().getStreets().get(0)).isEqualTo("123 Charleston Road");
assertThat(postalInfo.getAddr().getStreets().get(1)).isEqualTo("Suite 123");
assertThat(postalInfo.getAddr().getSp()).isEqualTo("CA");
assertThat(postalInfo.getAddr().getPc()).isEqualTo("31337");
assertThat(postalInfo.getAddr().getCc()).isEqualTo("US");
// o An OPTIONAL <voice> element that contains the contact's voice
// telephone number.
assertThat(bean.getVoice()).isNotNull();
assertThat(bean.getVoice().getValue()).isEqualTo("+1.2126660000");
assertThat(bean.getVoice().getX()).isEqualTo("123");
// o An OPTIONAL <fax> element that contains the contact's facsimile
// telephone number.
assertThat(bean.getFax()).isNotNull();
assertThat(bean.getFax().getValue()).isEqualTo("+1.2126660001");
assertThat(bean.getFax().getX()).isNull();
// o An <email> element that contains the contact's email address.
assertThat(bean.getEmail()).isEqualTo("justine@crr.com");
// o A <clID> element that contains the identifier of the sponsoring
// registrar.
assertThat(bean.getClID()).isEqualTo("TheRegistrar");
// o A <crRr> element that contains the identifier of the registrar
// that created the contact object. An OPTIONAL client attribute is
// used to specify the client that performed the operation.
assertThat(bean.getCrRr().getValue()).isEqualTo("NewRegistrar");
// o A <crDate> element that contains the date and time of contact-
// object creation.
assertThat(bean.getCrDate()).isEqualTo(DateTime.parse("1900-01-01TZ"));
// o An OPTIONAL <upRr> element that contains the identifier of the
// registrar that last updated the contact object. This element MUST
// NOT be present if the contact has never been modified. An
// OPTIONAL client attribute is used to specify the client that
// performed the operation.
assertThat(bean.getUpRr().getValue()).isEqualTo("TheRegistrar");
// o An OPTIONAL <upDate> element that contains the date and time of
// the most recent contact-object modification. This element MUST
// NOT be present if the contact object has never been modified.
assertThat(bean.getUpDate()).isEqualTo(DateTime.parse("1930-04-20TZ"));
// o An OPTIONAL <trDate> element that contains the date and time of
// the most recent contact object successful transfer. This element
// MUST NOT be present if the contact object has never been
// transferred.
assertThat(bean.getTrDate()).isEqualTo(DateTime.parse("1925-04-20TZ"));
// o An OPTIONAL <trnData> element that contains the following child
// elements related to the last transfer request of the contact
// object:
//
// * A <trStatus> element that contains the state of the most recent
// transfer request.
//
// * A <reRr> element that contains the identifier of the registrar
// that requested the domain name object transfer. An OPTIONAL
// client attribute is used to specify the client that performed
// the operation.
//
// * An <acRr> element that contains the identifier of the registrar
// that SHOULD act upon a PENDING transfer request. For all other
// status types, the value identifies the registrar that took the
// indicated action. An OPTIONAL client attribute is used to
// specify the client that performed the operation.
//
// * A <reDate> element that contains the date and time that the
// transfer was requested.
//
// * An <acDate> element that contains the date and time of a
// required or completed response. For a PENDING request, the
// value identifies the date and time by which a response is
// required before an automated response action will be taken by
// the registry. For all other status types, the value identifies
// the date and time when the request was completed.
assertThat(bean.getTrnData()).isNotNull();
assertThat(bean.getTrnData().getTrStatus()).isEqualTo(XjcEppcomTrStatusType.SERVER_APPROVED);
assertThat(bean.getTrnData().getReRr().getValue()).isEqualTo("TheRegistrar");
assertThat(bean.getTrnData().getReDate()).isEqualTo(DateTime.parse("1925-04-19TZ"));
assertThat(bean.getTrnData().getAcRr().getValue()).isEqualTo("NewRegistrar");
assertThat(bean.getTrnData().getAcDate()).isEqualTo(DateTime.parse("1925-04-21TZ"));
// o An OPTIONAL <disclose> element that identifies elements that
// requiring exceptional server-operator handling to allow or
// restrict disclosure to third parties. See Section 2.9 of
// [RFC5733] for a description of the child elements contained within
// the <disclose> element.
assertThat(bean.getDisclose()).isNotNull();
assertThat(bean.getDisclose().isFlag()).isTrue();
assertThat(bean.getDisclose().getAddrs()).hasSize(1);
assertThat(bean.getDisclose().getAddrs().get(0).getType())
.isEqualTo(XjcContactPostalInfoEnumType.INT);
assertThat(bean.getDisclose().getNames()).hasSize(1);
assertThat(bean.getDisclose().getNames().get(0).getType())
.isEqualTo(XjcContactPostalInfoEnumType.INT);
assertThat(bean.getDisclose().getOrgs()).isEmpty();
}
@Test
void testConvertContact_absentVoiceAndFaxNumbers() {
XjcRdeContact bean =
ContactToXjcConverter.convertContact(
makeContact().asBuilder().setVoiceNumber(null).setFaxNumber(null).build());
assertThat(bean.getVoice()).isNull();
assertThat(bean.getFax()).isNull();
}
@Test
void testConvertContact_absentDisclose() {
XjcRdeContact bean =
ContactToXjcConverter.convertContact(makeContact().asBuilder().setDisclose(null).build());
assertThat(bean.getDisclose()).isNull();
}
@Test
void testConvertContact_absentTransferData() {
XjcRdeContact bean =
ContactToXjcConverter.convertContact(
makeContact().asBuilder().setLastTransferTime(null).setTransferData(null).build());
assertThat(bean.getTrDate()).isNull();
assertThat(bean.getTrnData()).isNull();
}
@Test
void testMarshal() throws Exception {
XjcRdeContact bean = ContactToXjcConverter.convertContact(makeContact());
wrapDeposit(bean).marshal(new ByteArrayOutputStream(), UTF_8);
}
private static XjcRdeDeposit wrapDeposit(XjcRdeContact contact) {
XjcRdeDeposit deposit = new XjcRdeDeposit();
deposit.setId("984302");
deposit.setType(XjcRdeDepositTypeType.FULL);
deposit.setWatermark(new DateTime("2012-01-01T04:20:00Z"));
XjcRdeMenuType menu = new XjcRdeMenuType();
menu.setVersion("1.0");
menu.getObjURIs().add("lol");
deposit.setRdeMenu(menu);
XjcRdeContactElement element = new XjcRdeContactElement();
element.setValue(contact);
XjcRdeContentsType contents = new XjcRdeContentsType();
contents.getContents().add(element);
deposit.setContents(contents);
return deposit;
}
private static Contact makeContact() {
return new Contact.Builder()
.setContactId("love-id")
.setRepoId("2-ROID")
.setCreationRegistrarId("NewRegistrar")
.setPersistedCurrentSponsorRegistrarId("TheRegistrar")
.setLastEppUpdateRegistrarId("TheRegistrar")
.setAuthInfo(ContactAuthInfo.create(PasswordAuth.create("2fooBAR")))
.setCreationTimeForTest(DateTime.parse("1900-01-01TZ"))
.setLastTransferTime(DateTime.parse("1925-04-20TZ"))
.setLastEppUpdateTime(DateTime.parse("1930-04-20TZ"))
.setEmailAddress("justine@crr.com")
.setStatusValues(
ImmutableSet.of(
StatusValue.CLIENT_DELETE_PROHIBITED, StatusValue.SERVER_UPDATE_PROHIBITED))
.setInternationalizedPostalInfo(
new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName("Dipsy Doodle")
.setOrg("Charleston Road Registry Incorporated")
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of("123 Charleston Road", "Suite 123"))
.setCity("Mountain View")
.setState("CA")
.setZip("31337")
.setCountryCode("US")
.build())
.build())
.setVoiceNumber(
new ContactPhoneNumber.Builder()
.setPhoneNumber("+1.2126660000")
.setExtension("123")
.build())
.setFaxNumber(new ContactPhoneNumber.Builder().setPhoneNumber("+1.2126660001").build())
.setTransferData(
new ContactTransferData.Builder()
.setGainingRegistrarId("TheRegistrar")
.setLosingRegistrarId("NewRegistrar")
.setTransferRequestTime(DateTime.parse("1925-04-19TZ"))
.setPendingTransferExpirationTime(DateTime.parse("1925-04-21TZ"))
.setTransferStatus(TransferStatus.SERVER_APPROVED)
.setTransferRequestTrid(Trid.create("client-trid", "server-trid"))
.build())
.setDisclose(
new Disclose.Builder()
.setFlag(true)
.setEmail(new PresenceMarker())
.setAddrs(
ImmutableList.of(
Disclose.PostalInfoChoice.create(PostalInfo.Type.INTERNATIONALIZED)))
.setNames(
ImmutableList.of(
Disclose.PostalInfoChoice.create(PostalInfo.Type.INTERNATIONALIZED)))
.build())
.build();
}
}

View File

@@ -14,11 +14,9 @@
package google.registry.rde;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.io.BaseEncoding.base16;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistEppResource;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -34,7 +32,6 @@ import google.registry.model.billing.BillingBase.Flag;
import google.registry.model.billing.BillingBase.Reason;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingRecurrence;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainAuthInfo;
import google.registry.model.domain.DomainHistory;
@@ -103,7 +100,7 @@ public class DomainToXjcConverterTest {
assertThat(
bean.getContacts().stream()
.map(input -> String.format("%s %s", input.getType().toString(), input.getValue())))
.containsExactly("ADMIN contact1234", "TECH contact1234");
.isEmpty();
assertThat(bean.getCrDate()).isEqualTo(DateTime.parse("1900-01-01T00:00:00Z"));
@@ -132,7 +129,7 @@ public class DomainToXjcConverterTest {
// name used to generate the IDN variant.
// TODO(b/26125498): bean.getOriginalName()
assertThat(bean.getRegistrant()).isEqualTo("contact1234");
assertThat(bean.getRegistrant()).isNull();
// o Zero or more OPTIONAL <rgpStatus> element to represent
// "pendingDelete" sub-statuses, including "redemptionPeriod",
@@ -198,12 +195,6 @@ public class DomainToXjcConverterTest {
@Test
void testConvertAbsentContacts() throws XmlException {
Domain domain = makeDomain(clock);
tm().transact(
() ->
tm().delete(
domain.getAllContacts().stream()
.map(DesignatedContact::getContactKey)
.collect(toImmutableSet())));
XjcRdeDomain bean = DomainToXjcConverter.convertDomain(domain, RdeMode.FULL);
assertThat(bean.getRegistrant()).isNull();
assertThat(bean.getContacts()).isEmpty();

View File

@@ -1,273 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.rde;
import static com.google.common.io.BaseEncoding.base16;
import static google.registry.testing.DatabaseHelper.generateNewContactHostRoid;
import static google.registry.testing.DatabaseHelper.generateNewDomainRoid;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static org.joda.money.CurrencyUnit.USD;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InetAddresses;
import google.registry.model.billing.BillingBase.Flag;
import google.registry.model.billing.BillingBase.Reason;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingRecurrence;
import google.registry.model.contact.Contact;
import google.registry.model.contact.ContactAddress;
import google.registry.model.contact.ContactPhoneNumber;
import google.registry.model.contact.PostalInfo;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainAuthInfo;
import google.registry.model.domain.DomainHistory;
import google.registry.model.domain.GracePeriod;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.domain.secdns.DomainDsData;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppcommon.Trid;
import google.registry.model.host.Host;
import google.registry.model.poll.PollMessage;
import google.registry.model.poll.PollMessage.Autorenew;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.testing.FakeClock;
import google.registry.util.Idn;
import java.util.Optional;
import org.joda.money.Money;
import org.joda.time.DateTime;
/** Utility class for creating {@code EppResource} entities that'll successfully marshal. */
final class RdeFixtures {
static Domain makeDomain(FakeClock clock, String tld) {
Domain domain =
new Domain.Builder()
.setDomainName("example." + tld)
.setRepoId(generateNewDomainRoid(tld))
.setRegistrant(
Optional.of(
makeContact(clock, "5372808-ERL", "(◕‿◕) nevermore", "prophet@evil.みんな")
.createVKey()))
.build();
DomainHistory historyEntry =
persistResource(
new DomainHistory.Builder()
.setDomain(domain)
.setType(HistoryEntry.Type.DOMAIN_CREATE)
.setModificationTime(clock.nowUtc())
.setRegistrarId("TheRegistrar")
.build());
clock.advanceOneMilli();
BillingEvent billingEvent =
persistResource(
new BillingEvent.Builder()
.setReason(Reason.CREATE)
.setTargetId("example." + tld)
.setRegistrarId("TheRegistrar")
.setCost(Money.of(USD, 26))
.setPeriodYears(2)
.setEventTime(DateTime.parse("1990-01-01T00:00:00Z"))
.setBillingTime(DateTime.parse("1990-01-01T00:00:00Z"))
.setDomainHistory(historyEntry)
.build());
domain =
domain
.asBuilder()
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("secret")))
.setContacts(
ImmutableSet.of(
DesignatedContact.create(
DesignatedContact.Type.ADMIN,
makeContact(
clock,
"5372808-IRL",
"be that word our sign in parting",
"BOFH@cat.みんな")
.createVKey()),
DesignatedContact.create(
DesignatedContact.Type.TECH,
makeContact(
clock,
"5372808-TRL",
"bird or fiend!? i shrieked upstarting",
"bog@cat.みんな")
.createVKey())))
.setCreationRegistrarId("TheRegistrar")
.setPersistedCurrentSponsorRegistrarId("TheRegistrar")
.setCreationTimeForTest(clock.nowUtc())
.setDsData(
ImmutableSet.of(DomainDsData.create(123, 200, 230, base16().decode("1234567890"))))
.setDomainName(Idn.toASCII("love." + tld))
.setLastTransferTime(DateTime.parse("1990-01-01T00:00:00Z"))
.setLastEppUpdateRegistrarId("IntoTheTempest")
.setLastEppUpdateTime(clock.nowUtc())
.setIdnTableName("extended_latin")
.setNameservers(
ImmutableSet.of(
makeHost(clock, "bird.or.devil.みんな", "1.2.3.4").createVKey(),
makeHost(clock, "ns2.cat.みんな", "bad:f00d:cafe::15:beef").createVKey()))
.setRegistrationExpirationTime(DateTime.parse("1994-01-01T00:00:00Z"))
.setGracePeriods(
ImmutableSet.of(
GracePeriod.forBillingEvent(
GracePeriodStatus.RENEW,
domain.getRepoId(),
persistResource(
new BillingEvent.Builder()
.setReason(Reason.RENEW)
.setTargetId("love." + tld)
.setRegistrarId("TheRegistrar")
.setCost(Money.of(USD, 456))
.setPeriodYears(2)
.setEventTime(DateTime.parse("1992-01-01T00:00:00Z"))
.setBillingTime(DateTime.parse("1992-01-01T00:00:00Z"))
.setDomainHistory(historyEntry)
.build())),
GracePeriod.create(
GracePeriodStatus.TRANSFER,
domain.getRepoId(),
DateTime.parse("1992-01-01T00:00:00Z"),
"foo",
null)))
.setSubordinateHosts(ImmutableSet.of("home.by.horror.haunted"))
.setStatusValues(
ImmutableSet.of(
StatusValue.CLIENT_DELETE_PROHIBITED,
StatusValue.CLIENT_RENEW_PROHIBITED,
StatusValue.CLIENT_TRANSFER_PROHIBITED,
StatusValue.SERVER_UPDATE_PROHIBITED))
.setAutorenewBillingEvent(
persistResource(
new BillingRecurrence.Builder()
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(tld)
.setRegistrarId("TheRegistrar")
.setEventTime(END_OF_TIME)
.setRecurrenceEndTime(END_OF_TIME)
.setDomainHistory(historyEntry)
.build())
.createVKey())
.setAutorenewPollMessage(
persistResource(
new PollMessage.Autorenew.Builder()
.setTargetId(tld)
.setRegistrarId("TheRegistrar")
.setEventTime(END_OF_TIME)
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(historyEntry)
.build())
.createVKey())
.setTransferData(
new DomainTransferData.Builder()
.setGainingRegistrarId("gaining")
.setLosingRegistrarId("losing")
.setPendingTransferExpirationTime(DateTime.parse("1993-04-20T00:00:00Z"))
.setServerApproveBillingEvent(billingEvent.createVKey())
.setServerApproveAutorenewEvent(
persistResource(
new BillingRecurrence.Builder()
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId("example." + tld)
.setRegistrarId("TheRegistrar")
.setEventTime(END_OF_TIME)
.setRecurrenceEndTime(END_OF_TIME)
.setDomainHistory(historyEntry)
.build())
.createVKey())
.setServerApproveAutorenewPollMessage(
persistResource(
new Autorenew.Builder()
.setTargetId("example." + tld)
.setRegistrarId("TheRegistrar")
.setEventTime(END_OF_TIME)
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(historyEntry)
.build())
.createVKey())
.setServerApproveEntities(
historyEntry.getRepoId(),
historyEntry.getRevisionId(),
ImmutableSet.of(billingEvent.createVKey()))
.setTransferRequestTime(DateTime.parse("1991-01-01T00:00:00Z"))
.setTransferStatus(TransferStatus.PENDING)
.setTransferredRegistrationExpirationTime(
DateTime.parse("1995-01-01T00:00:00.000Z"))
.setTransferRequestTrid(Trid.create("client-trid", "server-trid"))
.build())
.build();
clock.advanceOneMilli();
return persistResource(domain);
}
static Contact makeContact(FakeClock clock, String id, String name, String email) {
clock.advanceOneMilli();
return persistResource(
new Contact.Builder()
.setContactId(id)
.setRepoId(generateNewContactHostRoid())
.setEmailAddress(email)
.setStatusValues(ImmutableSet.of(StatusValue.OK))
.setPersistedCurrentSponsorRegistrarId("GetTheeBack")
.setCreationRegistrarId("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")
.build())
.build())
.setVoiceNumber(
new ContactPhoneNumber.Builder().setPhoneNumber("+1.5558675309").build())
.setFaxNumber(new ContactPhoneNumber.Builder().setPhoneNumber("+1.5558675310").build())
.build());
}
static Host makeHost(FakeClock clock, String fqhn, String ip) {
clock.advanceOneMilli();
return persistResource(
new Host.Builder()
.setRepoId(generateNewContactHostRoid())
.setCreationRegistrarId("LawyerCat")
.setCreationTimeForTest(clock.nowUtc())
.setPersistedCurrentSponsorRegistrarId("BusinessCat")
.setHostName(Idn.toASCII(fqhn))
.setInetAddresses(ImmutableSet.of(InetAddresses.forString(ip)))
.setLastTransferTime(DateTime.parse("1990-01-01T00:00:00Z"))
.setLastEppUpdateRegistrarId("CeilingCat")
.setLastEppUpdateTime(clock.nowUtc())
.setStatusValues(ImmutableSet.of(StatusValue.OK))
.build());
}
private RdeFixtures() {}
}

View File

@@ -27,11 +27,9 @@ import google.registry.model.common.FeatureFlagTest;
import google.registry.model.console.ConsoleUpdateHistoryTest;
import google.registry.model.console.PasswordResetRequestTest;
import google.registry.model.console.UserTest;
import google.registry.model.contact.ContactTest;
import google.registry.model.domain.DomainSqlTest;
import google.registry.model.domain.token.AllocationTokenTest;
import google.registry.model.domain.token.BulkPricingPackageTest;
import google.registry.model.history.ContactHistoryTest;
import google.registry.model.history.DomainHistoryTest;
import google.registry.model.history.HostHistoryTest;
import google.registry.model.poll.PollMessageTest;
@@ -96,8 +94,6 @@ import org.junit.runner.RunWith;
BulkPricingPackageTest.class,
ClaimsListDaoTest.class,
ConsoleUpdateHistoryTest.class,
ContactHistoryTest.class,
ContactTest.class,
CursorTest.class,
DnsRefreshRequestTest.class,
DomainSqlTest.class,

View File

@@ -14,28 +14,19 @@
package google.registry.server;
import static google.registry.model.domain.DesignatedContact.Type.ADMIN;
import static google.registry.model.domain.DesignatedContact.Type.BILLING;
import static google.registry.model.domain.DesignatedContact.Type.TECH;
import static google.registry.testing.DatabaseHelper.createTlds;
import static google.registry.testing.DatabaseHelper.loadRegistrar;
import static google.registry.testing.DatabaseHelper.newContact;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.DatabaseHelper.persistPremiumList;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.joda.money.CurrencyUnit.USD;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import google.registry.model.OteStatsTestHelper;
import google.registry.model.console.RegistrarRole;
import google.registry.model.console.User;
import google.registry.model.console.UserRoles;
import google.registry.model.contact.Contact;
import google.registry.model.contact.ContactAddress;
import google.registry.model.contact.PostalInfo;
import google.registry.model.domain.DesignatedContact;
import google.registry.testing.DatabaseHelper;
import java.io.IOException;
@@ -63,78 +54,9 @@ public enum Fixture {
throw new RuntimeException(e);
}
Contact google =
persistResource(
newContact("google")
.asBuilder()
.setLocalizedPostalInfo(
new PostalInfo.Builder()
.setType(PostalInfo.Type.LOCALIZED)
.setName("Mr. Google")
.setOrg("Google Inc.")
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of("111 8th Ave", "4th Floor"))
.setCity("New York")
.setState("NY")
.setZip("10011")
.setCountryCode("US")
.build())
.build())
.build());
Contact justine =
persistResource(
newContact("justine")
.asBuilder()
.setLocalizedPostalInfo(
new PostalInfo.Builder()
.setType(PostalInfo.Type.LOCALIZED)
.setName("Justine Bean")
.setOrg("(✿◕ ‿◕ ) Incorporated")
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of("123 Fake St."))
.setCity("Stratford")
.setState("CT")
.setZip("06615")
.setCountryCode("US")
.build())
.build())
.build());
Contact robert =
persistResource(
newContact("robert")
.asBuilder()
.setLocalizedPostalInfo(
new PostalInfo.Builder()
.setType(PostalInfo.Type.LOCALIZED)
.setName("Captain Robert")
.setOrg("Ancient World")
.setAddress(
new ContactAddress.Builder()
.setStreet(
ImmutableList.of(
"A skeleton crew is what came back",
"And once in port he filled his sack",
"With bribes and cash and fame and coin"))
.setCity("Things to make a new crew join")
.setState("NY")
.setZip("10011")
.setCountryCode("US")
.build())
.build())
.build());
persistResource(
DatabaseHelper.newDomain("love.xn--q9jyb4c", justine)
DatabaseHelper.newDomain("love.xn--q9jyb4c")
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(ADMIN, robert.createVKey()),
DesignatedContact.create(BILLING, google.createVKey()),
DesignatedContact.create(TECH, justine.createVKey())))
.setNameservers(
ImmutableSet.of(
persistActiveHost("ns1.love.xn--q9jyb4c").createVKey(),
@@ -142,13 +64,8 @@ public enum Fixture {
.build());
persistResource(
DatabaseHelper.newDomain("moogle.example", justine)
DatabaseHelper.newDomain("moogle.example")
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(ADMIN, robert.createVKey()),
DesignatedContact.create(BILLING, google.createVKey()),
DesignatedContact.create(TECH, justine.createVKey())))
.setNameservers(
ImmutableSet.of(
persistActiveHost("ns1.linode.com").createVKey(),

View File

@@ -1,139 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.testing;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.truth.Fact.simpleFact;
import static com.google.common.truth.Truth.assertAbout;
import com.google.common.truth.FailureMetadata;
import com.google.common.truth.SimpleSubjectBuilder;
import google.registry.model.contact.Contact;
import google.registry.model.contact.PostalInfo;
import google.registry.model.eppcommon.AuthInfo;
import google.registry.testing.TruthChainer.And;
import org.joda.time.DateTime;
/** Truth subject for asserting things about {@link Contact} entities. */
public final class ContactSubject extends AbstractEppResourceSubject<Contact, ContactSubject> {
private final Contact actual;
public ContactSubject(FailureMetadata failureMetadata, Contact subject) {
super(failureMetadata, checkNotNull(subject));
this.actual = subject;
}
public And<ContactSubject> hasLocalizedPostalInfo(PostalInfo postalInfo) {
return hasValue(postalInfo, actual.getLocalizedPostalInfo(), "has localizedPostalInfo");
}
public And<ContactSubject> hasNullLocalizedPostalInfo() {
if (actual.getLocalizedPostalInfo() != null) {
failWithActual(simpleFact("expected to have null localized postal info"));
}
return andChainer();
}
public And<ContactSubject> hasNonNullLocalizedPostalInfo() {
if (actual.getLocalizedPostalInfo() == null) {
failWithActual(simpleFact("expected to have non-null localized postal info"));
}
return andChainer();
}
public And<ContactSubject> hasInternationalizedPostalInfo(PostalInfo postalInfo) {
return hasValue(
postalInfo, actual.getInternationalizedPostalInfo(), "has internationalizedPostalInfo");
}
public And<ContactSubject> hasNullInternationalizedPostalInfo() {
if (actual.getInternationalizedPostalInfo() != null) {
failWithActual(simpleFact("expected to have null internationalized postal info"));
}
return andChainer();
}
public And<ContactSubject> hasNonNullInternationalizedPostalInfo() {
if (actual.getInternationalizedPostalInfo() == null) {
failWithActual(simpleFact("expected to have non-null internationalized postal info"));
}
return andChainer();
}
public And<ContactSubject> hasNullEmailAddress() {
if (actual.getEmailAddress() != null) {
failWithActual(simpleFact("expected to have null email address"));
}
return andChainer();
}
public And<ContactSubject> hasNonNullEmailAddress() {
if (actual.getEmailAddress() == null) {
failWithActual(simpleFact("expected to have non-null email address"));
}
return andChainer();
}
public And<ContactSubject> hasNullVoiceNumber() {
if (actual.getVoiceNumber() != null) {
failWithActual(simpleFact("expected to have null voice number"));
}
return andChainer();
}
public And<ContactSubject> hasNonNullVoiceNumber() {
if (actual.getVoiceNumber() == null) {
failWithActual(simpleFact("expected to have non-null voice number"));
}
return andChainer();
}
public And<ContactSubject> hasNullFaxNumber() {
if (actual.getFaxNumber() != null) {
failWithActual(simpleFact("expected to have null fax number"));
}
return andChainer();
}
public And<ContactSubject> hasNonNullFaxNumber() {
if (actual.getFaxNumber() == null) {
failWithActual(simpleFact("expected to have non-null fax number"));
}
return andChainer();
}
public And<ContactSubject> hasAuthInfoPwd(String pw) {
AuthInfo authInfo = actual.getAuthInfo();
return hasValue(pw, authInfo == null ? null : authInfo.getPw().getValue(), "has auth info pw");
}
public And<ContactSubject> hasLastTransferTime(DateTime lastTransferTime) {
return hasValue(lastTransferTime, actual.getLastTransferTime(), "has lastTransferTime");
}
public And<ContactSubject> hasLastTransferTimeNotEqualTo(DateTime lastTransferTime) {
return doesNotHaveValue(lastTransferTime, actual.getLastTransferTime(), "lastTransferTime");
}
public And<ContactSubject> hasCurrentSponsorRegistrarId(String registrarId) {
return hasValue(
registrarId, actual.getCurrentSponsorRegistrarId(), "has currentSponsorRegistrarId");
}
public static SimpleSubjectBuilder<ContactSubject, Contact> assertAboutContacts() {
return assertAbout(ContactSubject::new);
}
}

View File

@@ -24,7 +24,7 @@ import static com.google.common.collect.Iterables.toArray;
import static com.google.common.collect.MoreCollectors.onlyElement;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.config.RegistryConfig.getContactAndHostRoidSuffix;
import static google.registry.config.RegistryConfig.getHostRoidSuffix;
import static google.registry.model.EppResourceUtils.createDomainRepoId;
import static google.registry.model.EppResourceUtils.createRepoId;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
@@ -73,10 +73,6 @@ import google.registry.model.common.DnsRefreshRequest;
import google.registry.model.console.GlobalRole;
import google.registry.model.console.User;
import google.registry.model.console.UserRoles;
import google.registry.model.contact.Contact;
import google.registry.model.contact.ContactAuthInfo;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.DesignatedContact.Type;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainAuthInfo;
import google.registry.model.domain.DomainBase;
@@ -103,9 +99,7 @@ import google.registry.model.tld.label.PremiumList.PremiumEntry;
import google.registry.model.tld.label.PremiumListDao;
import google.registry.model.tld.label.ReservedList;
import google.registry.model.tld.label.ReservedListDao;
import google.registry.model.transfer.ContactTransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import java.util.Arrays;
@@ -150,7 +144,7 @@ public final class DatabaseHelper {
}
public static Host newHost(String hostName) {
return newHostWithRoid(hostName, generateNewContactHostRoid());
return newHostWithRoid(hostName, generateNewHostRoid());
}
public static Host newHostWithRoid(String hostName, String repoId) {
@@ -165,11 +159,7 @@ public final class DatabaseHelper {
public static Domain newDomain(String domainName) {
String repoId = generateNewDomainRoid(getTldFromDomainName(domainName));
return newDomain(domainName, repoId, persistActiveContact("contact1234"));
}
public static Domain newDomain(String domainName, Contact contact) {
return newDomain(domainName, generateNewDomainRoid(getTldFromDomainName(domainName)), contact);
return newDomain(domainName, repoId);
}
public static Domain newDomain(String domainName, Host... hosts) {
@@ -178,8 +168,7 @@ public final class DatabaseHelper {
return newDomain(domainName).asBuilder().setNameservers(hostKeys).build();
}
public static Domain newDomain(String domainName, String repoId, Contact contact) {
VKey<Contact> contactKey = contact.createVKey();
public static Domain newDomain(String domainName, String repoId) {
return new Domain.Builder()
.setRepoId(repoId)
.setDomainName(domainName)
@@ -187,34 +176,10 @@ public final class DatabaseHelper {
.setPersistedCurrentSponsorRegistrarId("TheRegistrar")
.setCreationTimeForTest(START_OF_TIME)
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("2fooBAR")))
.setRegistrant(Optional.of(contactKey))
.setContacts(
ImmutableSet.of(
DesignatedContact.create(Type.ADMIN, contactKey),
DesignatedContact.create(Type.TECH, contactKey)))
.setRegistrationExpirationTime(END_OF_TIME)
.build();
}
/**
* Returns a newly created {@link Contact} for the given contactId (which is the foreign key) with
* an auto-generated repoId.
*/
public static Contact newContact(String contactId) {
return newContactWithRoid(contactId, generateNewContactHostRoid());
}
public static Contact newContactWithRoid(String contactId, String repoId) {
return new Contact.Builder()
.setRepoId(repoId)
.setContactId(contactId)
.setCreationRegistrarId("TheRegistrar")
.setPersistedCurrentSponsorRegistrarId("TheRegistrar")
.setAuthInfo(ContactAuthInfo.create(PasswordAuth.create("2fooBAR")))
.setCreationTimeForTest(START_OF_TIME)
.build();
}
public static Tld newTld(String tld, String roidSuffix) {
return newTld(tld, roidSuffix, ImmutableSortedMap.of(START_OF_TIME, GENERAL_AVAILABILITY));
}
@@ -254,15 +219,6 @@ public final class DatabaseHelper {
.build();
}
public static Contact persistActiveContact(String contactId) {
return persistResource(newContact(contactId));
}
/** Persists a contact resource with the given contact id deleted at the specified time. */
public static Contact persistDeletedContact(String contactId, DateTime deletionTime) {
return persistResource(newContact(contactId).asBuilder().setDeletionTime(deletionTime).build());
}
public static Host persistActiveHost(String hostName) {
return persistResource(newHost(hostName));
}
@@ -490,24 +446,14 @@ public final class DatabaseHelper {
.setPendingTransferExpirationTime(expirationTime);
}
private static ContactTransferData.Builder createContactTransferDataBuilder(
DateTime requestTime, DateTime expirationTime) {
return new ContactTransferData.Builder()
.setTransferStatus(TransferStatus.PENDING)
.setGainingRegistrarId("NewRegistrar")
.setTransferRequestTime(requestTime)
.setLosingRegistrarId("TheRegistrar")
.setPendingTransferExpirationTime(expirationTime);
}
public static PollMessage.OneTime createPollMessageForImplicitTransfer(
EppResource resource,
Domain domain,
HistoryEntry historyEntry,
String registrarId,
DateTime requestTime,
DateTime expirationTime,
@Nullable DateTime extendedRegistrationExpirationTime) {
TransferData transferData =
DomainTransferData transferData =
createDomainTransferDataBuilder(requestTime, expirationTime)
.setTransferredRegistrationExpirationTime(extendedRegistrationExpirationTime)
.build();
@@ -515,7 +461,7 @@ public final class DatabaseHelper {
.setRegistrarId(registrarId)
.setEventTime(expirationTime)
.setMsg("Transfer server approved.")
.setResponseData(ImmutableList.of(createTransferResponse(resource, transferData)))
.setResponseData(ImmutableList.of(createTransferResponse(domain, transferData)))
.setHistoryEntry(historyEntry)
.build();
}
@@ -537,7 +483,6 @@ public final class DatabaseHelper {
public static Domain persistDomainWithDependentResources(
String label,
String tld,
@Nullable Contact contact,
DateTime now,
DateTime creationTime,
DateTime expirationTime) {
@@ -553,14 +498,6 @@ public final class DatabaseHelper {
.setRegistrationExpirationTime(expirationTime)
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("fooBAR")));
Duration addGracePeriodLength = Tld.get(tld).getAddGracePeriodLength();
if (contact != null) {
domainBuilder
.setRegistrant(Optional.of(contact.createVKey()))
.setContacts(
ImmutableSet.of(
DesignatedContact.create(Type.ADMIN, contact.createVKey()),
DesignatedContact.create(Type.TECH, contact.createVKey())));
}
if (creationTime.plus(addGracePeriodLength).isAfter(now)) {
domainBuilder.addGracePeriod(
GracePeriod.create(
@@ -923,9 +860,9 @@ public final class DatabaseHelper {
return createDomainRepoId(tm().reTransact(tm()::allocateId), tld);
}
/** Returns a newly allocated, globally unique contact/host repoId of the format HEX_TLD-ROID. */
public static String generateNewContactHostRoid() {
return createRepoId(tm().reTransact(tm()::allocateId), getContactAndHostRoidSuffix());
/** Returns a newly allocated, globally unique host repoId of the format HEX_TLD-ROID. */
public static String generateNewHostRoid() {
return createRepoId(tm().reTransact(tm()::allocateId), getHostRoidSuffix());
}
/** Persists an object in the DB for tests. */
@@ -1065,11 +1002,7 @@ public final class DatabaseHelper {
}
private static HistoryEntry.Type getHistoryEntryType(EppResource resource) {
if (resource instanceof Contact) {
return resource.getRepoId() != null
? HistoryEntry.Type.CONTACT_CREATE
: HistoryEntry.Type.CONTACT_UPDATE;
} else if (resource instanceof Host) {
if (resource instanceof Host) {
return resource.getRepoId() != null
? HistoryEntry.Type.HOST_CREATE
: HistoryEntry.Type.HOST_UPDATE;

View File

@@ -14,8 +14,8 @@
package google.registry.testing;
import static google.registry.testing.DatabaseHelper.generateNewContactHostRoid;
import static google.registry.testing.DatabaseHelper.generateNewDomainRoid;
import static google.registry.testing.DatabaseHelper.generateNewHostRoid;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DomainNameUtils.getTldFromDomainName;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -24,11 +24,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InetAddresses;
import google.registry.model.EppResource;
import google.registry.model.contact.Contact;
import google.registry.model.contact.ContactAddress;
import google.registry.model.contact.ContactPhoneNumber;
import google.registry.model.contact.PostalInfo;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainHistory;
import google.registry.model.domain.Period;
@@ -43,8 +38,6 @@ import google.registry.model.reporting.HistoryEntry;
import google.registry.persistence.VKey;
import google.registry.util.Idn;
import java.net.InetAddress;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
@@ -142,7 +135,7 @@ public final class FullFieldsTestEntityHelper {
String fqhn, @Nullable String ip1, @Nullable String ip2, String registrarClientId) {
Host.Builder builder =
new Host.Builder()
.setRepoId(generateNewContactHostRoid())
.setRepoId(generateNewHostRoid())
.setHostName(fqhn)
.setCreationTimeForTest(DateTime.parse("2000-10-08T00:45:00Z"))
.setPersistedCurrentSponsorRegistrarId(registrarClientId);
@@ -183,156 +176,8 @@ public final class FullFieldsTestEntityHelper {
return host;
}
public static Contact makeContact(String id, String name, @Nullable String email) {
return makeContact(id, name, email, ImmutableList.of("123 Example Boulevard <script>"), null);
}
public static Contact makeContact(
String id, String name, @Nullable String email, @Nullable Registrar registrar) {
return makeContact(
id, name, email, ImmutableList.of("123 Example Boulevard <script>"), registrar);
}
public static Contact makeContact(
String id,
String name,
@Nullable String email,
@Nullable List<String> street,
@Nullable Registrar registrar) {
return makeContact(id, name, email, street, registrar, null);
}
public static Contact makeContact(
String id,
String name,
@Nullable String email,
@Nullable List<String> street,
@Nullable Registrar registrar,
@Nullable DateTime deletionTime) {
PostalInfo.Builder postalBuilder = new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName(name)
.setOrg("GOOGLE INCORPORATED <script>");
if (street != null) {
postalBuilder.setAddress(new ContactAddress.Builder()
.setStreet(ImmutableList.copyOf(street))
.setCity("KOKOMO")
.setState("BM")
.setZip("31337")
.setCountryCode("US")
.build());
}
Contact.Builder builder =
new Contact.Builder()
.setContactId(id)
.setRepoId(generateNewContactHostRoid())
.setCreationTimeForTest(DateTime.parse("2000-10-08T00:45:00Z"))
.setInternationalizedPostalInfo(postalBuilder.build())
.setVoiceNumber(
new ContactPhoneNumber.Builder().setPhoneNumber("+1.2126660420").build())
.setFaxNumber(new ContactPhoneNumber.Builder().setPhoneNumber("+1.2126660420").build());
if (email != null) {
builder.setEmailAddress(email);
}
String registrarId = registrar == null ? "TheRegistrar" : registrar.getRegistrarId();
builder.setCreationRegistrarId(registrarId).setPersistedCurrentSponsorRegistrarId(registrarId);
if (deletionTime != null) {
builder.setDeletionTime(deletionTime);
}
return builder.build();
}
public static Contact makeWipedOutContact(
String id, @Nullable Registrar registrar, @Nullable DateTime deletionTime) {
Contact.Builder builder =
new Contact.Builder()
.setContactId(id)
.setRepoId(generateNewContactHostRoid())
.setCreationTimeForTest(DateTime.parse("2000-10-08T00:45:00Z"));
if (registrar != null) {
builder
.setCreationRegistrarId(registrar.getRegistrarId())
.setPersistedCurrentSponsorRegistrarId(registrar.getRegistrarId());
}
if (deletionTime != null) {
builder.setDeletionTime(deletionTime);
}
return builder.build();
}
public static Contact makeAndPersistContact(
String id,
String name,
@Nullable String email,
@Nullable DateTime creationTime,
@Nullable Registrar registrar) {
return makeAndPersistContact(
id,
name,
email,
ImmutableList.of("123 Example Boulevard <script>"),
creationTime,
registrar,
null);
}
public static Contact makeAndPersistContact(
String id,
String name,
@Nullable String email,
@Nullable List<String> street,
@Nullable DateTime creationTime) {
return makeAndPersistContact(id, name, email, street, creationTime, null, null);
}
public static Contact makeAndPersistContact(
String id,
String name,
@Nullable String email,
@Nullable List<String> street,
@Nullable DateTime creationTime,
@Nullable Registrar registrar) {
return makeAndPersistContact(id, name, email, street, creationTime, registrar, null);
}
public static Contact makeAndPersistContact(
String id,
String name,
@Nullable String email,
@Nullable List<String> street,
@Nullable DateTime creationTime,
@Nullable Registrar registrar,
@Nullable DateTime deletionTime) {
Contact contact =
persistResource(makeContact(id, name, email, street, registrar, deletionTime));
if (creationTime != null) {
persistResource(
makeHistoryEntry(
contact, HistoryEntry.Type.CONTACT_CREATE, null, "created", creationTime));
}
if (deletionTime != null) {
persistResource(
makeHistoryEntry(
contact, HistoryEntry.Type.CONTACT_DELETE, null, "deleted", deletionTime));
}
return contact;
}
public static Contact makeAndPersistDeletedContact(
String id, DateTime creationTime, Registrar registrar, DateTime deletionTime) {
Contact contact = persistResource(makeWipedOutContact(id, registrar, deletionTime));
persistResource(
makeHistoryEntry(contact, HistoryEntry.Type.CONTACT_CREATE, null, "created", creationTime));
persistResource(
makeHistoryEntry(contact, HistoryEntry.Type.CONTACT_DELETE, null, "deleted", deletionTime));
return contact;
}
public static Domain makeDomain(
String domain,
@Nullable Contact registrant,
@Nullable Contact admin,
@Nullable Contact tech,
@Nullable Host ns1,
@Nullable Host ns2,
Registrar registrar) {
@@ -352,21 +197,6 @@ public final class FullFieldsTestEntityHelper {
StatusValue.CLIENT_TRANSFER_PROHIBITED,
StatusValue.SERVER_UPDATE_PROHIBITED))
.setDsData(ImmutableSet.of(DomainDsData.create(1, 2, 3, "deadface")));
if (registrant != null) {
builder.setRegistrant(Optional.of(registrant.createVKey()));
}
if ((admin != null) || (tech != null)) {
ImmutableSet.Builder<DesignatedContact> contactsBuilder = new ImmutableSet.Builder<>();
if (admin != null) {
contactsBuilder.add(
DesignatedContact.create(DesignatedContact.Type.ADMIN, admin.createVKey()));
}
if (tech != null) {
contactsBuilder.add(
DesignatedContact.create(DesignatedContact.Type.TECH, tech.createVKey()));
}
builder.setContacts(contactsBuilder.build());
}
if ((ns1 != null) || (ns2 != null)) {
ImmutableSet.Builder<VKey<Host>> nsBuilder = new ImmutableSet.Builder<>();
if (ns1 != null) {

View File

@@ -72,8 +72,8 @@ class NordnUploadActionTest {
"""
1,2010-05-04T10:11:12.000Z,2
roid,domain-name,notice-id,registrar-id,registration-datetime,ack-datetime,application-datetime
6-TLD,claims-landrush2.tld,landrush2tcn,88888,2010-05-03T10:11:12.000Z,2010-05-03T08:11:12.000Z
8-TLD,claims-landrush1.tld,landrush1tcn,99999,2010-05-04T10:11:12.000Z,2010-05-04T09:11:12.000Z
4-TLD,claims-landrush2.tld,landrush2tcn,88888,2010-05-03T10:11:12.000Z,2010-05-03T08:11:12.000Z
5-TLD,claims-landrush1.tld,landrush1tcn,99999,2010-05-04T10:11:12.000Z,2010-05-04T09:11:12.000Z
""";
private static final String SUNRISE_CSV =
@@ -81,7 +81,7 @@ class NordnUploadActionTest {
1,2010-05-04T10:11:12.000Z,2
roid,domain-name,SMD-id,registrar-id,registration-datetime,application-datetime
2-TLD,sunrise2.tld,new-smdid,88888,2010-05-01T10:11:12.000Z
4-TLD,sunrise1.tld,my-smdid,99999,2010-05-02T10:11:12.000Z
3-TLD,sunrise1.tld,my-smdid,99999,2010-05-02T10:11:12.000Z
""";
private static final String LOCATION_URL = "http://trololol";

View File

@@ -1,90 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.beust.jcommander.ParameterException;
import google.registry.testing.DeterministicStringGenerator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link CreateContactCommand}. */
class CreateContactCommandTest extends EppToolCommandTestCase<CreateContactCommand> {
@BeforeEach
void beforeEach() {
command.passwordGenerator = new DeterministicStringGenerator("abcdefghijklmnopqrstuvwxyz");
}
@Test
void testSuccess_complete() throws Exception {
runCommandForced(
"--client=NewRegistrar",
"--id=sh8013",
"--name=John Doe",
"--org=Example Inc.",
"--street=123 Example Dr.",
"--street=Floor 3",
"--street=Suite 100",
"--city=Dulles",
"--state=VA",
"--zip=20166-6503",
"--cc=US",
"--phone=+1.7035555555",
"--fax=+1.7035555556",
"--email=jdoe@example.com",
"--password=2fooBAR");
eppVerifier.verifySent("contact_create_complete.xml");
}
@Test
void testSuccess_minimal() throws Exception {
// Will never be the case, but tests that each field can be omitted.
// Also tests the auto-gen password.
runCommandForced("--client=NewRegistrar");
eppVerifier.verifySent("contact_create_minimal.xml");
}
@Test
void testFailure_missingClientId() {
assertThrows(ParameterException.class, this::runCommandForced);
}
@Test
void testFailure_tooManyStreetLines() {
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--client=NewRegistrar",
"--street=\"123 Example Dr.\"",
"--street=\"Floor 3\"",
"--street=\"Suite 100\"",
"--street=\"Office 1\""));
}
@Test
void testFailure_badPhone() {
assertThrows(
ParameterException.class, () -> runCommandForced("--client=NewRegistrar", "--phone=3"));
}
@Test
void testFailure_badFax() {
assertThrows(
ParameterException.class, () -> runCommandForced("--client=NewRegistrar", "--fax=3"));
}
}

View File

@@ -47,9 +47,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
"--client=NewRegistrar",
"--period=1",
"--nameservers=ns1.zdns.google,ns2.zdns.google,ns3.zdns.google,ns4.zdns.google",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--password=2fooBAR",
"--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 1"
+ " A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
@@ -64,9 +61,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
"--client=NewRegistrar",
"--period=1",
"--nameservers=NS1.zdns.google,ns2.ZDNS.google,ns3.zdns.gOOglE,ns4.zdns.google",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--password=2fooBAR",
"--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 1"
+ " A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
@@ -81,9 +75,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
"--client=NewRegistrar",
"--period=1",
"--nameservers=ns[1-4].zdns.google",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--password=2fooBAR",
"--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 1"
+ " A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
@@ -98,9 +89,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
"--client=NewRegistrar",
"--period=1",
"--nameservers=NS[1-4].zdns.google",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--password=2fooBAR",
"--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 1"
+ " A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
@@ -123,14 +111,9 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
createTld("abc");
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"example.tld",
"example.abc");
eppVerifier
.verifySent("domain_create_contacts.xml")
.verifySent("domain_create_contacts_abc.xml");
eppVerifier.verifySent("domain_create_minimal.xml").verifySent("domain_create_minimal_abc.xml");
}
@Test
@@ -145,14 +128,9 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
tm().transact(() -> tm().put(registry));
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"example.tld",
"example.abc");
eppVerifier
.verifySent("domain_create_contacts.xml")
.verifySent("domain_create_contacts_abc.xml");
eppVerifier.verifySent("domain_create_minimal.xml").verifySent("domain_create_minimal_abc.xml");
}
@Test
@@ -166,9 +144,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
.build());
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--period=3",
"--force_premiums",
"parajiumu.baar");
@@ -183,17 +158,14 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
createTld("abc");
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--force_premiums",
"example.tld",
"palladium.tld",
"example.abc");
eppVerifier
.verifySent("domain_create_contacts.xml")
.verifySent("domain_create_minimal.xml")
.verifySent("domain_create_palladium.xml")
.verifySent("domain_create_contacts_abc.xml");
.verifySent("domain_create_minimal_abc.xml");
assertInStdout(
"palladium.tld is premium at USD 877.00 per year; "
+ "sending total cost for 1 year(s) of USD 877.00.");
@@ -204,9 +176,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
createTld("tld");
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--reason=Creating test domain",
"--registrar_request=false",
"example.tld");
@@ -218,27 +187,11 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
createTld("tld");
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--allocation_token=abc123",
"example.tld");
eppVerifier.verifySent("domain_create_token.xml");
}
@Test
void testSuccess_contactsStillRequired() throws Exception {
// Verify that if contacts are still required, the minimum+contacts request is sent
createTld("tld");
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"example.tld");
eppVerifier.verifySent("domain_create_contacts.xml");
}
@Test
void testFailure_duplicateDomains() {
IllegalArgumentException thrown =
@@ -247,9 +200,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"example.tld",
"example.tld"));
assertThat(thrown).hasMessageThat().contains("Duplicate arguments found: 'example.tld'");
@@ -258,14 +208,7 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
@Test
void testFailure_missingDomain() {
ParameterException thrown =
assertThrows(
ParameterException.class,
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech"));
assertThrows(ParameterException.class, () -> runCommandForced("--client=NewRegistrar"));
assertThat(thrown).hasMessageThat().contains("Main parameters are required");
}
@@ -276,9 +219,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
ParameterException.class,
() ->
runCommandForced(
"--admins=crr-admin",
"--techs=crr-tech",
"--registrant=crr-admin",
"example.tld"));
assertThat(thrown).hasMessageThat().contains("--client");
}
@@ -291,9 +231,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--nameservers=ns1.zdns.google,ns2.zdns.google,ns3.zdns.google,ns4.zdns.google,"
+ "ns5.zdns.google,ns6.zdns.google,ns7.zdns.google,ns8.zdns.google,"
+ "ns9.zdns.google,ns10.zdns.google,ns11.zdns.google,ns12.zdns.google,"
@@ -310,9 +247,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--nameservers=ns[1-14].zdns.google",
"example.tld"));
assertThat(thrown).hasMessageThat().contains("There can be at most 13 nameservers");
@@ -326,9 +260,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--period=x",
"--domain=example.tld"));
assertThat(thrown).hasMessageThat().contains("--period");
@@ -342,9 +273,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--ds_records=1 2 3 abcd",
"example.tld"));
assertThat(thrown).hasMessageThat().isEqualTo("DS record uses an unrecognized digest type: 3");
@@ -358,9 +286,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--ds_records=1 2 1 abcd",
"example.tld"));
assertThat(thrown).hasMessageThat().isEqualTo("DS record has an invalid digest length: ABCD");
@@ -374,9 +299,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--ds_records=1 999 4"
+ " 768412320F7B0AA5812FCE428DC4706B3CAE50E02A64CAA16A782249BFE8EFC4B7EF1C"
+ "CB126255D196047DFEDF17A0A9",
@@ -392,9 +314,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--ds_records=1 2 3 ab cd",
"example.tld"));
assertThat(thrown).hasMessageThat().contains("should have 4 parts, but has 5");
@@ -408,9 +327,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--ds_records=x 2 3 abcd",
"example.tld"));
assertThat(thrown).hasMessageThat().contains("\"x\"");
@@ -424,9 +340,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--ds_records=1 x 3 abcd",
"example.tld"));
assertThat(thrown).hasMessageThat().contains("\"x\"");
@@ -440,9 +353,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--ds_records=1 2 x abcd",
"example.tld"));
assertThat(thrown).hasMessageThat().contains("\"x\"");
@@ -456,9 +366,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--ds_records=1 2 3 xbcd",
"example.tld"));
assertThat(thrown).hasMessageThat().contains("XBCD");
@@ -472,9 +379,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--ds_records=1 2 3 abcde",
"example.tld"));
assertThat(thrown).hasMessageThat().contains("length 5");
@@ -488,9 +392,6 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"gold.tld"));
assertThat(thrown)
.hasMessageThat()

View File

@@ -56,19 +56,19 @@ class GenerateLordnCommandTest extends CommandTestCase<GenerateLordnCommand> {
assertThat(Files.readAllBytes(claimsCsv))
.isEqualTo(
"""
1,2021-04-16T10:04:00.000Z,1
roid,domain-name,notice-id,registrar-id,registration-datetime,ack-datetime,application-datetime
6-TLD,fleecey.tld,smd3,1,1970-01-01T00:00:00.000Z,1970-01-01T00:00:00.000Z
"""
1,2021-04-16T10:04:00.000Z,1
roid,domain-name,notice-id,registrar-id,registration-datetime,ack-datetime,application-datetime
4-TLD,fleecey.tld,smd3,1,1970-01-01T00:00:00.000Z,1970-01-01T00:00:00.000Z
"""
.getBytes(UTF_8));
assertThat(Files.readAllBytes(sunriseCsv))
.isEqualTo(
"""
1,2021-04-16T10:04:00.001Z,2
roid,domain-name,SMD-id,registrar-id,registration-datetime,application-datetime
2-TLD,sneezy.tld,smd1,1,1970-01-01T00:00:00.000Z
4-TLD,wheezy.tld,smd2,1,1970-01-01T00:00:00.000Z
"""
1,2021-04-16T10:04:00.001Z,2
roid,domain-name,SMD-id,registrar-id,registration-datetime,application-datetime
2-TLD,sneezy.tld,smd1,1,1970-01-01T00:00:00.000Z
3-TLD,wheezy.tld,smd2,1,1970-01-01T00:00:00.000Z
"""
.getBytes(UTF_8));
}
}

View File

@@ -1,90 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.newContact;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistDeletedContact;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.beust.jcommander.ParameterException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link GetContactCommand}. */
class GetContactCommandTest extends CommandTestCase<GetContactCommand> {
@BeforeEach
void beforeEach() {
createTld("tld");
command.clock = fakeClock;
}
@Test
void testSuccess() throws Exception {
persistActiveContact("sh8013");
runCommand("sh8013");
assertInStdout("contactId=sh8013");
assertInStdout("Websafe key: " + "kind:Contact" + "@sql:rO0ABXQABjItUk9JRA");
}
@Test
void testSuccess_expand() throws Exception {
persistActiveContact("sh8013");
runCommand("sh8013", "--expand");
assertInStdout("contactId=sh8013");
assertInStdout("Websafe key: " + "kind:Contact" + "@sql:rO0ABXQABjItUk9JRA");
assertNotInStdout("LiveRef");
}
@Test
void testSuccess_multipleArguments() throws Exception {
persistActiveContact("sh8013");
persistActiveContact("jd1234");
runCommand("sh8013", "jd1234");
assertInStdout("contactId=sh8013");
assertInStdout("contactId=jd1234");
assertInStdout("Websafe key: " + "kind:Contact" + "@sql:rO0ABXQABjItUk9JRA");
assertInStdout("Websafe key: " + "kind:Contact" + "@sql:rO0ABXQABjMtUk9JRA");
}
@Test
void testSuccess_deletedContact() throws Exception {
persistDeletedContact("sh8013", fakeClock.nowUtc().minusDays(1));
runCommand("sh8013");
assertInStdout("Contact 'sh8013' does not exist or is deleted");
}
@Test
void testSuccess_contactDoesNotExist() throws Exception {
runCommand("nope");
assertInStdout("Contact 'nope' does not exist or is deleted");
}
@Test
void testFailure_noContact() {
assertThrows(ParameterException.class, this::runCommand);
}
@Test
void testSuccess_contactDeletedInFuture() throws Exception {
persistResource(
newContact("sh8013").asBuilder().setDeletionTime(fakeClock.nowUtc().plusDays(1)).build());
runCommand("sh8013", "--read_timestamp=" + fakeClock.nowUtc().plusMonths(1));
assertInStdout("Contact 'sh8013' does not exist or is deleted");
}
}

View File

@@ -39,7 +39,6 @@ class GetDomainCommandTest extends CommandTestCase<GetDomainCommand> {
persistActiveDomain("example.tld");
runCommand("example.tld");
assertInStdout("domainName=example.tld");
assertInStdout("Contact=VKey<Contact>(sql:3-ROID");
assertInStdout("Websafe key: " + "kind:Domain" + "@sql:rO0ABXQABTItVExE");
}
@@ -48,7 +47,6 @@ class GetDomainCommandTest extends CommandTestCase<GetDomainCommand> {
persistActiveDomain("example.tld");
runCommand("example.tld", "--expand");
assertInStdout("domainName=example.tld");
assertInStdout("key=3-ROID");
assertInStdout("Websafe key: " + "kind:Domain" + "@sql:rO0ABXQABTItVExE");
assertNotInStdout("LiveRef");
}
@@ -59,7 +57,6 @@ class GetDomainCommandTest extends CommandTestCase<GetDomainCommand> {
persistActiveDomain("xn--aualito-txac.xn--q9jyb4c");
runCommand("çauçalito.みんな", "--expand");
assertInStdout("domainName=xn--aualito-txac.xn--q9jyb4c");
assertInStdout("key=4-ROID");
}
@Test
@@ -70,7 +67,7 @@ class GetDomainCommandTest extends CommandTestCase<GetDomainCommand> {
assertInStdout("domainName=example.tld");
assertInStdout("domainName=example2.tld");
assertInStdout("Websafe key: kind:Domain@sql:rO0ABXQABTItVExE");
assertInStdout("Websafe key: kind:Domain@sql:rO0ABXQABTQtVExE");
assertInStdout("Websafe key: kind:Domain@sql:rO0ABXQABTMtVExE");
}
@Test
@@ -134,7 +131,7 @@ class GetDomainCommandTest extends CommandTestCase<GetDomainCommand> {
// Active
assertInStdout("Websafe key: kind:Domain@sql:rO0ABXQABTItVExE");
// Deleted
assertInStdout("Websafe key: kind:Domain@sql:rO0ABXQABTQtVExE");
assertInStdout("Websafe key: kind:Domain@sql:rO0ABXQABTMtVExE");
}
}

View File

@@ -24,7 +24,6 @@ import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType;
import static google.registry.testing.DatabaseHelper.getPollMessages;
import static google.registry.testing.DatabaseHelper.loadByKey;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistDeletedDomain;
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
@@ -37,7 +36,6 @@ import google.registry.model.ForeignKeyUtils;
import google.registry.model.billing.BillingBase.Flag;
import google.registry.model.billing.BillingBase.Reason;
import google.registry.model.billing.BillingRecurrence;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainHistory;
import google.registry.model.eppcommon.StatusValue;
@@ -60,12 +58,10 @@ public class UnrenewDomainCommandTest extends CommandTestCase<UnrenewDomainComma
@Test
void test_unrenewTwoDomains_worksSuccessfully() throws Exception {
Contact contact = persistActiveContact("jd1234");
fakeClock.advanceOneMilli();
persistDomainWithDependentResources(
"foo",
"tld",
contact,
fakeClock.nowUtc(),
fakeClock.nowUtc(),
fakeClock.nowUtc().plusYears(5));
@@ -73,7 +69,6 @@ public class UnrenewDomainCommandTest extends CommandTestCase<UnrenewDomainComma
persistDomainWithDependentResources(
"bar",
"tld",
contact,
fakeClock.nowUtc(),
fakeClock.nowUtc(),
fakeClock.nowUtc().plusYears(4));
@@ -95,12 +90,10 @@ public class UnrenewDomainCommandTest extends CommandTestCase<UnrenewDomainComma
@Test
void test_unrenewDomain_savesDependentEntitiesCorrectly() throws Exception {
Contact contact = persistActiveContact("jd1234");
fakeClock.advanceOneMilli();
persistDomainWithDependentResources(
"foo",
"tld",
contact,
fakeClock.nowUtc(),
fakeClock.nowUtc(),
fakeClock.nowUtc().plusYears(5));

View File

@@ -20,7 +20,6 @@ import static google.registry.model.eppcommon.StatusValue.PENDING_DELETE;
import static google.registry.model.eppcommon.StatusValue.SERVER_UPDATE_PROHIBITED;
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_CREATE;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.newContact;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -35,8 +34,6 @@ import com.google.common.collect.ImmutableSet;
import google.registry.model.billing.BillingBase.Flag;
import google.registry.model.billing.BillingBase.Reason;
import google.registry.model.billing.BillingRecurrence;
import google.registry.model.contact.Contact;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainHistory;
import google.registry.model.domain.GracePeriod;
@@ -75,18 +72,13 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
runCommandForced(
"--client=NewRegistrar",
"--add_nameservers=ns1.zdns.google,ns2.zdns.google",
"--add_admins=crr-admin2",
"--add_techs=crr-tech2",
"--add_statuses=serverDeleteProhibited",
"--add_ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4"
+ " 5 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--remove_nameservers=ns3.zdns.google,ns4.zdns.google",
"--remove_admins=crr-admin1",
"--remove_techs=crr-tech1",
"--remove_statuses=serverHold",
"--remove_ds_records=7 8 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3,6 5 4"
+ " 768412320F7B0AA5812FCE428DC4706B3CAE50E02A64CAA16A782249BFE8EFC4B7EF1CCB126255D196047DFEDF17A0A9",
"--registrant=crr-admin",
"--password=2fooBAR",
"example.tld");
eppVerifier.verifySent("domain_update_complete.xml");
@@ -97,18 +89,13 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
runCommandForced(
"--client=NewRegistrar",
"--add_nameservers=NS[1-2].zdns.google",
"--add_admins=crr-admin2",
"--add_techs=crr-tech2",
"--add_statuses=serverDeleteProhibited",
"--add_ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4"
+ " 5 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--remove_nameservers=ns[3-4].zdns.google",
"--remove_admins=crr-admin1",
"--remove_techs=crr-tech1",
"--remove_statuses=serverHold",
"--remove_ds_records=7 8 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3,6 5 4"
+ " 768412320F7B0AA5812FCE428DC4706B3CAE50E02A64CAA16A782249BFE8EFC4B7EF1CCB126255D196047DFEDF17A0A9",
"--registrant=crr-admin",
"--password=2fooBAR",
"example.tld");
eppVerifier.verifySent("domain_update_complete.xml");
@@ -121,18 +108,13 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
runCommandForced(
"--client=NewRegistrar",
"--add_nameservers=ns1.zdns.google,ns2.zdns.google",
"--add_admins=crr-admin2",
"--add_techs=crr-tech2",
"--add_statuses=serverDeleteProhibited",
"--add_ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4"
+ " 5 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
"--remove_nameservers=ns[3-4].zdns.google",
"--remove_admins=crr-admin1",
"--remove_techs=crr-tech1",
"--remove_statuses=serverHold",
"--remove_ds_records=7 8 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3,6 5 4"
+ " 768412320F7B0AA5812FCE428DC4706B3CAE50E02A64CAA16A782249BFE8EFC4B7EF1CCB126255D196047DFEDF17A0A9",
"--registrant=crr-admin",
"--password=2fooBAR",
"example.tld",
"example.abc");
@@ -177,8 +159,6 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
runCommandForced(
"--client=NewRegistrar",
"--add_nameservers=ns2.zdns.google,ns3.zdns.google",
"--add_admins=crr-admin2",
"--add_techs=crr-tech2",
"--add_statuses=serverDeleteProhibited",
"--add_ds_records=1 2 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A,4"
+ " 5 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3",
@@ -191,8 +171,6 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
runCommandForced(
"--client=NewRegistrar",
"--remove_nameservers=ns4.zdns.google",
"--remove_admins=crr-admin1",
"--remove_techs=crr-tech1",
"--remove_statuses=serverHold",
"--remove_ds_records=7 8 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3,6 5 4"
+ " 768412320F7B0AA5812FCE428DC4706B3CAE50E02A64CAA16A782249BFE8EFC4B7EF1CCB126255D196047DFEDF17A0A9",
@@ -202,8 +180,7 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
@Test
void testSuccess_change() throws Exception {
runCommandForced(
"--client=NewRegistrar", "--registrant=crr-admin", "--password=2fooBAR", "example.tld");
runCommandForced("--client=NewRegistrar", "--password=2fooBAR", "example.tld");
eppVerifier.verifySent("domain_update_change.xml");
}
@@ -211,7 +188,6 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
void testSuccess_change_reasonAndRegistrarRequest() throws Exception {
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--password=2fooBAR",
"--reason=Testing domain update",
"--registrar_request=false",
@@ -230,27 +206,6 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
eppVerifier.verifySent("domain_update_set_nameservers.xml");
}
@Test
void testSuccess_setContacts() throws Exception {
Contact adminContact = persistResource(newContact("crr-admin1"));
Contact techContact = persistResource(newContact("crr-tech1"));
VKey<Contact> adminContactKey = adminContact.createVKey();
VKey<Contact> techContactKey = techContact.createVKey();
persistResource(
domain
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(DesignatedContact.Type.ADMIN, adminContactKey),
DesignatedContact.create(DesignatedContact.Type.TECH, techContactKey)))
.build());
runCommandForced(
"--client=NewRegistrar", "--admins=crr-admin3", "--techs=crr-tech3", "example.tld");
eppVerifier.verifySent("domain_update_set_contacts.xml");
}
@Test
void testSuccess_setStatuses() throws Exception {
Host host = persistActiveHost("ns1.zdns.google");
@@ -359,29 +314,23 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
@Test
void testSuccess_canUpdatePendingDeleteDomain_whenSuperuserPassesOverrideFlag() throws Exception {
Contact adminContact = persistResource(newContact("crr-admin1"));
Contact techContact = persistResource(newContact("crr-tech1"));
VKey<Contact> adminContactKey = adminContact.createVKey();
VKey<Contact> techContactKey = techContact.createVKey();
Host host1 = persistActiveHost("ns1.zdns.google");
persistActiveHost("ns2.zdns.google");
persistResource(
domain
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(DesignatedContact.Type.ADMIN, adminContactKey),
DesignatedContact.create(DesignatedContact.Type.TECH, techContactKey)))
.setNameservers(host1.createVKey())
.setStatusValues(ImmutableSet.of(PENDING_DELETE))
.build());
runCommandForced(
"--client=NewRegistrar",
"--admins=crr-admin3",
"--techs=crr-tech3",
"--add_nameservers=ns2.zdns.google",
"--superuser",
"--force_in_pending_delete",
"example.tld");
eppVerifier.expectSuperuser().verifySent("domain_update_set_contacts.xml");
eppVerifier.expectSuperuser().verifySent("domain_update_add_nameserver.xml");
}
@Test
@@ -440,7 +389,6 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--password=2fooBAR",
"example.tld",
"example.tld"));
@@ -452,9 +400,7 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
ParameterException thrown =
assertThrows(
ParameterException.class,
() ->
runCommandForced(
"--client=NewRegistrar", "--registrant=crr-admin", "--password=2fooBAR"));
() -> runCommandForced("--client=NewRegistrar", "--password=2fooBAR"));
assertThat(thrown).hasMessageThat().contains("Main parameters are required");
}
@@ -462,8 +408,7 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
void testFailure_missingClientId() {
ParameterException thrown =
assertThrows(
ParameterException.class,
() -> runCommandForced("--registrant=crr-admin", "--password=2fooBAR", "example.tld"));
ParameterException.class, () -> runCommandForced("--password=2fooBAR", "example.tld"));
assertThat(thrown).hasMessageThat().contains("--client");
}
@@ -479,8 +424,6 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
+ "ns5.zdns.google,ns6.zdns.google,ns7.zdns.google,ns8.zdns.google,"
+ "ns9.zdns.google,ns10.zdns.google,ns11.zdns.google,ns12.zdns.google,"
+ "ns13.zdns.google,ns14.zdns.google",
"--add_admins=crr-admin2",
"--add_techs=crr-tech2",
"--add_statuses=serverDeleteProhibited",
"example.tld"));
assertThat(thrown).hasMessageThat().contains("You can add at most 13 nameservers");
@@ -522,76 +465,6 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
+ "you cannot use the add_nameservers and remove_nameservers flags.");
}
@Test
void testFailure_providedAdminsAndAddAdmins() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--client=NewRegistrar",
"--add_admins=crr-admin2",
"--admins=crr-admin2",
"example.tld"));
assertThat(thrown)
.hasMessageThat()
.isEqualTo(
"If you provide the admins flag, "
+ "you cannot use the add_admins and remove_admins flags.");
}
@Test
void testFailure_providedAdminsAndRemoveAdmins() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--client=NewRegistrar",
"--remove_admins=crr-admin2",
"--admins=crr-admin2",
"example.tld"));
assertThat(thrown)
.hasMessageThat()
.isEqualTo(
"If you provide the admins flag, "
+ "you cannot use the add_admins and remove_admins flags.");
}
@Test
void testFailure_providedTechsAndAddTechs() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--client=NewRegistrar",
"--add_techs=crr-tech2",
"--techs=crr-tech2",
"example.tld"));
assertThat(thrown)
.hasMessageThat()
.contains(
"If you provide the techs flag, you cannot use the add_techs and remove_techs flags.");
}
@Test
void testFailure_providedTechsAndRemoveTechs() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--client=NewRegistrar",
"--remove_techs=crr-tech2",
"--techs=crr-tech2",
"example.tld"));
assertThat(thrown)
.hasMessageThat()
.contains(
"If you provide the techs flag, you cannot use the add_techs and remove_techs flags.");
}
@Test
void testFailure_providedStatusesAndAddStatuses() {
IllegalArgumentException thrown =
@@ -664,9 +537,6 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
() ->
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"--ds_records=1 2 1 abcd",
"example.tld"));
assertThat(thrown).hasMessageThat().isEqualTo("DS record has an invalid digest length: ABCD");

View File

@@ -19,7 +19,6 @@ import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadAllOf;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.loadByKey;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
import static google.registry.testing.DatabaseHelper.persistDomainWithPendingTransfer;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -244,7 +243,6 @@ public class UpdateRecurrenceCommandTest extends CommandTestCase<UpdateRecurrenc
persistDomainWithDependentResources(
"domain",
"tld",
persistActiveContact("contact1234"),
fakeClock.nowUtc(),
fakeClock.nowUtc(),
END_OF_TIME);

View File

@@ -16,7 +16,6 @@ package google.registry.tools.javascrap;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -27,7 +26,6 @@ import com.google.common.collect.Iterables;
import google.registry.model.billing.BillingBase.Reason;
import google.registry.model.billing.BillingCancellation;
import google.registry.model.billing.BillingEvent;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainHistory;
import google.registry.model.reporting.HistoryEntryDao;
@@ -50,12 +48,10 @@ public class CreateCancellationsForBillingEventsCommandTest
@BeforeEach
void beforeEach() {
createTld("tld");
Contact contact = persistActiveContact("contact1234");
domain =
persistDomainWithDependentResources(
"example",
"tld",
contact,
fakeClock.nowUtc(),
fakeClock.nowUtc(),
fakeClock.nowUtc().plusYears(2));
@@ -68,7 +64,7 @@ public class CreateCancellationsForBillingEventsCommandTest
assertThat(DatabaseHelper.loadAllOf(BillingCancellation.class)).isEmpty();
runCommandForced(String.valueOf(billingEventToCancel.getId()));
assertBillingEventCancelled();
assertInStdout("Added BillingCancellation for BillingEvent with ID 9");
assertInStdout("Added BillingCancellation for BillingEvent with ID 8");
assertInStdout("Created 1 BillingCancellation event(s)");
}
@@ -78,7 +74,7 @@ public class CreateCancellationsForBillingEventsCommandTest
assertBillingEventCancelled();
assertInStdout("Found 1 BillingEvent(s) to cancel");
assertInStdout("Missing BillingEvent(s) for IDs [9001]");
assertInStdout("Added BillingCancellation for BillingEvent with ID 9");
assertInStdout("Added BillingCancellation for BillingEvent with ID 8");
assertInStdout("Created 1 BillingCancellation event(s)");
}
@@ -91,8 +87,8 @@ public class CreateCancellationsForBillingEventsCommandTest
assertBillingEventCancelled(billingEventToCancel.getId());
assertBillingEventCancelled(secondToCancel.getId());
assertInStdout("Create cancellations for 2 BillingEvent(s)?");
assertInStdout("Added BillingCancellation for BillingEvent with ID 8");
assertInStdout("Added BillingCancellation for BillingEvent with ID 9");
assertInStdout("Added BillingCancellation for BillingEvent with ID 10");
assertInStdout("Created 2 BillingCancellation event(s)");
}
@@ -107,7 +103,7 @@ public class CreateCancellationsForBillingEventsCommandTest
assertBillingEventCancelled();
assertThat(DatabaseHelper.loadAllOf(BillingCancellation.class)).hasSize(1);
assertInStdout("Found 0 BillingEvent(s) to cancel");
assertInStdout("The following BillingEvent IDs were already cancelled: [9]");
assertInStdout("The following BillingEvent IDs were already cancelled: [8]");
}
@Test

View File

@@ -19,7 +19,6 @@ import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadAllOf;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.loadByKey;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
@@ -27,7 +26,6 @@ import static org.junit.Assert.assertThrows;
import google.registry.model.ImmutableObjectSubject;
import google.registry.model.billing.BillingRecurrence;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.tools.CommandTestCase;
import org.joda.time.DateTime;
@@ -38,7 +36,6 @@ import org.junit.jupiter.api.Test;
public class RecreateBillingRecurrencesCommandTest
extends CommandTestCase<RecreateBillingRecurrencesCommand> {
private Contact contact;
private Domain domain;
private BillingRecurrence oldRecurrence;
@@ -46,12 +43,10 @@ public class RecreateBillingRecurrencesCommandTest
void beforeEach() {
fakeClock.setTo(DateTime.parse("2022-09-05TZ"));
createTld("tld");
contact = persistActiveContact("contact1234");
domain =
persistDomainWithDependentResources(
"example",
"tld",
contact,
fakeClock.nowUtc(),
fakeClock.nowUtc(),
fakeClock.nowUtc().plusYears(1));
@@ -82,7 +77,6 @@ public class RecreateBillingRecurrencesCommandTest
persistDomainWithDependentResources(
"other",
"tld",
contact,
DateTime.parse("2022-09-07TZ"),
DateTime.parse("2022-09-07TZ"),
DateTime.parse("2023-09-07TZ"));
@@ -137,7 +131,7 @@ public class RecreateBillingRecurrencesCommandTest
assertThat(assertThrows(IllegalArgumentException.class, () -> runCommandForced("example.tld")))
.hasMessageThat()
.isEqualTo(
"There exists a recurrence with id 9 for domain example.tld with an end date of"
"There exists a recurrence with id 8 for domain example.tld with an end date of"
+ " END_OF_TIME");
}
}

View File

@@ -17,7 +17,6 @@ package google.registry.tools.server;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatabaseHelper.createTlds;
import static google.registry.testing.DatabaseHelper.newHost;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -132,7 +131,6 @@ class GenerateZoneFilesActionTest {
.asBuilder()
.setDsData(ImmutableSet.of(DomainDsData.create(1, 2, 3, new byte[] {0, 1, 2})))
.build());
persistActiveContact("ignored_contact");
persistActiveHost("ignored.host.tld"); // No ips.
persistActiveDomain("ignored_domain.tld"); // No hosts or DS data.
persistResource(newHost("ignored.foo.com").asBuilder().addInetAddresses(ips).build());

View File

@@ -145,7 +145,7 @@ class ListDomainsActionTest extends ListActionTestCase {
"^domainName\\s+repoId\\s*$",
"^-+\\s+-+\\s*$",
"^example1.foo\\s+2-FOO\\s*$",
"^example3.foo\\s+4-FOO\\s*$");
"^example3.foo\\s+3-FOO\\s*$");
}
@Test
@@ -159,7 +159,7 @@ class ListDomainsActionTest extends ListActionTestCase {
Optional.of(false),
Optional.empty(),
"^example1.foo 2-FOO$",
"^example3.foo 4-FOO$");
"^example3.foo 3-FOO$");
}
@Test
@@ -175,7 +175,7 @@ class ListDomainsActionTest extends ListActionTestCase {
"^domainName\\s+repoId\\s*$",
"^-+\\s+-+\\s*$",
"^example1.foo\\s+2-FOO\\s*$",
"^example3.foo\\s+4-FOO\\s*$");
"^example3.foo\\s+3-FOO\\s*$");
}
@Test
@@ -191,7 +191,7 @@ class ListDomainsActionTest extends ListActionTestCase {
"^domainName\\s+.*repoId",
"^-+\\s+-+",
"^example1.foo\\s+.*2-FOO",
"^example3.foo\\s+.*4-FOO");
"^example3.foo\\s+.*3-FOO");
}
@Test
@@ -207,7 +207,7 @@ class ListDomainsActionTest extends ListActionTestCase {
"^domainName\\s+.*repoId",
"^-+\\s+-+",
"^example1.foo\\s+.*2-FOO",
"^example3.foo\\s+.*4-FOO");
"^example3.foo\\s+.*3-FOO");
}
@Test

Some files were not shown because too many files have changed in this diff Show More