1
0
mirror of https://github.com/google/nomulus synced 2026-02-23 05:19:13 +00:00

Compare commits

...

4 Commits

Author SHA1 Message Date
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
88 changed files with 727 additions and 2461 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

@@ -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

@@ -1252,7 +1252,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

@@ -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

@@ -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

@@ -24,7 +24,6 @@ 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.
@@ -58,11 +57,6 @@ public class Contact extends ContactBase implements ForeignKeyedEppResource {
return super.getRepoId();
}
@Override
public Contact cloneProjectedAtTime(DateTime now) {
return ContactBase.cloneContactProjectedAtTime(this, now);
}
@Override
public Builder asBuilder() {
return new Builder(clone(this));

View File

@@ -16,7 +16,6 @@ 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;
@@ -254,17 +253,8 @@ public class ContactBase extends EppResource
@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();
// Contacts no longer exist and thus do not need to be projected
return this;
}
@Override

View File

@@ -16,20 +16,18 @@ 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;
@@ -67,7 +65,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>. */
@@ -171,26 +170,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;
}
@@ -369,10 +357,13 @@ public class DomainCommand {
}
/** 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 +371,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 +387,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 +402,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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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,7 +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())
@@ -212,6 +203,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

@@ -348,7 +348,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

@@ -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

@@ -92,9 +92,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 +126,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 +136,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 +144,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(
@@ -311,6 +272,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
@Test
void testFailure_minimumDataset_whenAddingNewContacts() throws Exception {
persistActiveContact("mak21");
// This EPP adds a new technical contact mak21 that wasn't already present.
setEppInput("domain_update_empty_registrant.xml");
persistReferencedEntities();
@@ -349,7 +311,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 +394,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 +1055,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);
@@ -1429,14 +1375,11 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
@Test
void testFailure_minimumDataset_addingNewRegistrantFails() throws Exception {
persistActiveContact("sh8013");
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());
// This EPP sets the registrant to sh8013, whereas in our test setup it is absent.

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

@@ -16,7 +16,6 @@ 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;
@@ -212,47 +211,6 @@ public class ContactTest extends EntityTestCase {
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 =

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,7 +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.fee.FeeQueryCommandExtensionItem.CommandName;
import google.registry.model.domain.launch.LaunchNotice;
import google.registry.model.domain.rgp.GracePeriodStatus;
@@ -45,7 +44,6 @@ 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;
@@ -360,15 +358,6 @@ 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(domain, host);
@@ -408,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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -103,7 +103,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 +132,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",

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.generateNewDomainRoid;
import static google.registry.testing.DatabaseHelper.generateNewHostRoid;
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(generateNewHostRoid())
.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(generateNewHostRoid())
.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

@@ -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

@@ -75,8 +75,6 @@ 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 +101,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;
@@ -165,11 +161,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 +170,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,23 +178,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, generateNewHostRoid());
}
public static Contact newContactWithRoid(String contactId, String repoId) {
return new Contact.Builder()
.setRepoId(repoId)
@@ -255,12 +233,7 @@ public final class DatabaseHelper {
}
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());
return persistResource(newContactWithRoid(contactId, generateNewHostRoid()));
}
public static Host persistActiveHost(String hostName) {
@@ -490,24 +463,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 +478,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 +500,6 @@ public final class DatabaseHelper {
public static Domain persistDomainWithDependentResources(
String label,
String tld,
@Nullable Contact contact,
DateTime now,
DateTime creationTime,
DateTime expirationTime) {
@@ -553,14 +515,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,7 +877,7 @@ 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. */
/** 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());
}

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

@@ -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

@@ -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

View File

@@ -55,16 +55,12 @@ public class ConsoleDomainGetActionTest extends ConsoleActionBaseTestCase {
assertThat(response.getStatus()).isEqualTo(SC_OK);
assertThat(response.getPayload())
.isEqualTo(
"{\"domainName\":\"exists.tld\",\"adminContact\":{\"key\":\"3-ROID\",\"kind\":"
+ "\"google.registry.model.contact.Contact\"},\"techContact\":{\"key\":\"3-ROID\","
+ "\"kind\":\"google.registry.model.contact.Contact\"},\"registrantContact\":"
+ "{\"key\":\"3-ROID\",\"kind\":\"google.registry.model.contact.Contact\"},"
+ "\"registrationExpirationTime\":\"294247-01-10T04:00:54.775Z\","
+ "\"lastTransferTime\":\"null\",\"repoId\":\"2-TLD\","
+ "\"currentSponsorRegistrarId\":\"TheRegistrar\",\"creationRegistrarId\":"
+ "\"TheRegistrar\",\"creationTime\":{\"creationTime\":"
+ "\"1970-01-01T00:00:00.000Z\"},\"lastEppUpdateTime\":\"null\",\"statuses\":"
+ "[\"INACTIVE\"]}");
"""
{"domainName":"exists.tld","registrationExpirationTime":"294247-01-10T04:00:54.775Z",\
"lastTransferTime":"null","repoId":"2-TLD","currentSponsorRegistrarId":"TheRegistrar",\
"creationRegistrarId":"TheRegistrar","creationTime":{"creationTime":"1970-01-01T00:00:00.000Z"},\
"lastEppUpdateTime":"null","statuses":["INACTIVE"]}\
""");
}
@Test

View File

@@ -72,7 +72,6 @@ public class ConsoleBulkDomainActionTest extends ConsoleActionBaseTestCase {
persistDomainWithDependentResources(
"example",
"tld",
null,
clock.nowUtc(),
clock.nowUtc().minusMonths(1),
clock.nowUtc().plusMonths(11));

View File

@@ -28,7 +28,7 @@
<fee:command name="create">
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-03T10:00:00.002Z">50.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-03T10:00:00.001Z">50.00</fee:fee>
<fee:date>2010-01-02T13:22:21Z</fee:date>
<fee:notAfter>2010-01-03T10:00:00.000Z</fee:notAfter>
</fee:command>
@@ -40,7 +40,7 @@
<fee:command name="create">
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-03T10:00:00.002Z">50.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-03T10:00:00.001Z">50.00</fee:fee>
<fee:date>2010-01-02T13:22:21Z</fee:date>
<fee:notAfter>2010-01-03T10:00:00.000Z</fee:notAfter>
</fee:command>
@@ -52,7 +52,7 @@
<fee:command name="create">
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-03T10:00:00.002Z">50.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-03T10:00:00.001Z">50.00</fee:fee>
<fee:date>2010-01-02T13:22:21Z</fee:date>
<fee:notAfter>2010-01-03T10:00:00.000Z</fee:notAfter>
</fee:command>

View File

@@ -25,7 +25,7 @@
<fee:command name="create">
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.002Z">100.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.001Z">100.00</fee:fee>
</fee:command>
</fee:cd>
<fee:cd>
@@ -33,7 +33,7 @@
<fee:command name="create">
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.002Z">100.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.001Z">100.00</fee:fee>
</fee:command>
</fee:cd>
<fee:cd>
@@ -41,7 +41,7 @@
<fee:command name="create">
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.002Z">100.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.001Z">100.00</fee:fee>
</fee:command>
</fee:cd>
</fee:chkData>

View File

@@ -25,7 +25,7 @@
<fee:command>create</fee:command>
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.002Z">100.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.001Z">100.00</fee:fee>
</fee:cd>
<fee:cd xmlns:fee="urn:ietf:params:xml:ns:fee-0.6">
<fee:name>example3.tld</fee:name>
@@ -33,7 +33,7 @@
<fee:command>create</fee:command>
<fee:period unit="y">2</fee:period>
<fee:fee description="create">24.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.002Z">100.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.001Z">100.00</fee:fee>
</fee:cd>
</fee:chkData>
</extension>

View File

@@ -28,7 +28,7 @@
<fee:currency>USD</fee:currency>
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.002Z">100.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.001Z">100.00</fee:fee>
</fee:cd>
<fee:cd avail="1">
<fee:object>
@@ -38,7 +38,7 @@
<fee:currency>USD</fee:currency>
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.002Z">100.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.001Z">100.00</fee:fee>
</fee:cd>
<fee:cd avail="1">
<fee:object>
@@ -48,7 +48,7 @@
<fee:currency>USD</fee:currency>
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.002Z">100.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.001Z">100.00</fee:fee>
</fee:cd>
</fee:chkData>
</extension>

View File

@@ -28,7 +28,7 @@
<fee:command name="create">
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.002Z">100.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.001Z">100.00</fee:fee>
<fee:notAfter>2010-01-02T10:00:00.000Z</fee:notAfter>
</fee:command>
</fee:cd>
@@ -39,7 +39,7 @@
<fee:command name="create">
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.002Z">100.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.001Z">100.00</fee:fee>
<fee:notAfter>2010-01-02T10:00:00.000Z</fee:notAfter>
</fee:command>
</fee:cd>
@@ -50,7 +50,7 @@
<fee:command name="create">
<fee:period unit="y">1</fee:period>
<fee:fee description="create">13.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.002Z">100.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 2010-01-02T10:00:00.001Z">100.00</fee:fee>
<fee:notAfter>2010-01-02T10:00:00.000Z</fee:notAfter>
</fee:command>
</fee:cd>

View File

@@ -15,7 +15,7 @@
<fee:creData xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
<fee:currency>USD</fee:currency>
<fee:fee description="create">24.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 1999-04-04T22:00:00.023Z">100.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 1999-04-04T22:00:00.021Z">100.00</fee:fee>
</fee:creData>
</extension>
<trID>

View File

@@ -15,7 +15,7 @@
<fee:creData xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
<fee:currency>USD</fee:currency>
<fee:fee description="create">200.00</fee:fee>
<fee:fee description="Early Access Period, fee expires: 1999-04-04T22:00:00.027Z">100.00
<fee:fee description="Early Access Period, fee expires: 1999-04-04T22:00:00.025Z">100.00
</fee:fee>
</fee:creData>
</extension>

View File

@@ -12,12 +12,6 @@
<domain:status s="clientHold"
lang="en">Payment overdue.</domain:status>
</domain:add>
<domain:rem>
<domain:ns>
<domain:hostObj>ns1.example.foo</domain:hostObj>
</domain:ns>
<domain:contact type="tech">sh8013</domain:contact>
</domain:rem>
<domain:chg>
<domain:registrant/>
<domain:authInfo>

View File

@@ -1,17 +0,0 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<update>
<domain:update
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
<domain:add>
</domain:add>
<domain:rem>
</domain:rem>
<domain:chg>
</domain:chg>
</domain:update>
</update>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View File

@@ -3,9 +3,9 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="6-2011">
<msgQ count="1" id="5-2011">
<qDate>2011-01-02T01:01:01Z</qDate>
<msg>Domain test.example was deleted by registry administrator with final deletion effective: 2011-01-02T00:56:01.008Z</msg>
<msg>Domain test.example was deleted by registry administrator with final deletion effective: 2011-01-02T00:56:01.007Z</msg>
</msgQ>
<resData>
<domain:panData>

View File

@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="6-2011">
<msgQ count="1" id="5-2011">
<qDate>2011-01-01T01:01:01Z</qDate>
<msg>Domain was auto-renewed.</msg>
</msgQ>

View File

@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="6-2011">
<msgQ count="1" id="5-2011">
<qDate>2011-01-01T01:01:01Z</qDate>
<msg>Domain deleted.</msg>
</msgQ>

View File

@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="6-2011">
<msgQ count="1" id="5-2011">
<qDate>2011-01-01T01:01:01Z</qDate>
<msg>Transfer approved.</msg>
</msgQ>

View File

@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="6-2011">
<msgQ count="1" id="5-2011">
<qDate>2011-01-01T01:01:01Z</qDate>
<msg>Transfer approved.</msg>
</msgQ>

View File

@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="6-2011">
<msgQ count="1" id="5-2011">
<qDate>2011-01-01T01:01:01Z</qDate>
<msg>Deleted host ns1.test.example</msg>
</msgQ>

View File

@@ -9,9 +9,6 @@
<domain:hostObj>ns1.example.net</domain:hostObj>
<domain:hostObj>ns2.example.net</domain:hostObj>
</domain:ns>
<domain:registrant>jd1234</domain:registrant>
<domain:contact type="admin">sh8013</domain:contact>
<domain:contact type="tech">sh8013</domain:contact>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>
</domain:authInfo>

View File

@@ -0,0 +1,22 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<create>
<domain:create
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.com</domain:name>
<domain:period unit="y">2</domain:period>
<domain:ns>
<domain:hostObj>ns1.example.net</domain:hostObj>
<domain:hostObj>ns2.example.net</domain:hostObj>
</domain:ns>
<domain:registrant>jd1234</domain:registrant>
<domain:contact type="admin">sh8013</domain:contact>
<domain:contact type="tech">sh8013</domain:contact>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>
</domain:authInfo>
</domain:create>
</create>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View File

@@ -8,18 +8,15 @@
<domain:ns>
<domain:hostObj>ns2.example.com</domain:hostObj>
</domain:ns>
<domain:contact type="tech">mak21</domain:contact>
<domain:status s="clientHold"/>
</domain:add>
<domain:rem>
<domain:ns>
<domain:hostObj>ns1.example.com</domain:hostObj>
</domain:ns>
<domain:contact type="tech">sh8013</domain:contact>
<domain:status s="clientUpdateProhibited"/>
</domain:rem>
<domain:chg>
<domain:registrant>sh8013</domain:registrant>
<domain:authInfo>
<domain:pw>2BARfoo</domain:pw>
</domain:authInfo>

View File

@@ -0,0 +1,31 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<update>
<domain:update
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.com</domain:name>
<domain:add>
<domain:ns>
<domain:hostObj>ns2.example.com</domain:hostObj>
</domain:ns>
<domain:contact type="tech">mak21</domain:contact>
<domain:status s="clientHold"/>
</domain:add>
<domain:rem>
<domain:ns>
<domain:hostObj>ns1.example.com</domain:hostObj>
</domain:ns>
<domain:contact type="tech">sh8013</domain:contact>
<domain:status s="clientUpdateProhibited"/>
</domain:rem>
<domain:chg>
<domain:registrant>sh8013</domain:registrant>
<domain:authInfo>
<domain:pw>2BARfoo</domain:pw>
</domain:authInfo>
</domain:chg>
</domain:update>
</update>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View File

@@ -14,4 +14,6 @@ RUN mkdir -p /opt/cprof && \
USER jetty
EXPOSE 8080
ENTRYPOINT ["/bin/sh", "/start.sh"]
# jetty:12-jdk21 has bash. We can afford the extra 200M in image size over
# the -alpine flavor.
ENTRYPOINT ["/bin/bash", "/start.sh"]

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
# Copyright 2024 The Nomulus Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");