Compare commits

..
Author SHA1 Message Date
Ben McIlwainandGitHub d91ca0eb8a Clean up tx manager insert() signature and add convenience helper method (#1325)
* Clean up tx manager insert() signature and add convenience helper method

This is the first of a series of PRs to clean up the type signatures on the
TransactionManager methods (which are way too generic), along with creating some
helper methods for use in tests only that don't require creating transactions
all over the place, thus reducing visual noise at callsites. This first method
is DatabaseHelper.insertInDb(), but there will be plenty of others. Note that
this is only for the Cloud SQL transaction manager -- I'm not bothering to
migrate any Datastore-only code, as that will be going away soon enough.
2021-09-17 14:45:07 -04:00
gbrodmanandGitHub 12dac76dc8 Skip synthetic history entries for resources that don't need them (#1320)
* Skip synthetic history entries for resources that don't need them

The reason for creating synthetic history entries is so that we can
guarantee that each EppResource's most recent *History object contains
that resource at that point in time. If the most recent *History object
in SQL contains that resource already, there is no need to create a
synthetic *History object for that resource.
2021-09-17 12:10:15 -04:00
Michael MullerandGitHub ad6471b3fd Clean up a few lint warnings (#1324)
The build is generating the following lint warnings:

core/src/main/java/google/registry/flows/certs/CertificateChecker.java:246:
warning: [ReferenceEquality] Compariso
n using reference equality instead of value equality
        && (lastExpiringNotificationSentDate == START_OF_TIME
                                             ^
    (see https://errorprone.info/bugpattern/ReferenceEquality)
core/src/test/java/google/registry/backup/ReplayCommitLogsToSqlActionTest.java:350:
warning: [UnnecessaryParenthes
es] These grouping parentheses are unnecessary; it is unlikely the code will
be misinterpreted without them
        .that(jpaTm().transact((() -> jpaTm().loadByEntity(contactResource))))
2021-09-17 09:15:48 -04:00
Rachel GuanandGitHub 942584b880 Update the initial value for lastExpiringCertNotificationSentDate to START_OF_TIME (#1321)
* Update the initial value for lastExpiringCertNotificationSentDate to START_OF_TIME
2021-09-16 13:06:47 -04:00
Ben McIlwainandGitHub 8d421e995e Rename client ID to registrar ID in most places (#1317)
* Rename client ID to registrar ID in most places

This is a code-only change, that shouldn't require any sort of data
migration. Correspondingly, there are some existing uses of clientId that are
not migrated (e.g. Datastore fields, task queue payloads, URL parameters for
actions that might be hit from task queues, etc.). And it of course doesn't
modify any fields in EPP XML. Note that the Cloud SQL schema fields are
already named using the registar_id pattern.

This also doesn't yet touch on the -c parameters in nomulus tools; that will be
coming later (since that is an external manual touch-point, it will require a
lot more in the way of changes to various meta scripts and documentation).

* Change more client IDs

* Merge branch 'master' into clientid-to-registrarid
2021-09-16 12:57:43 -04:00
gbrodmanandGitHub adc10131a0 Don't change UpdateAutoTimestamp on DS->SQL replay (#1322)
* Don't change UpdateAutoTimestamp on DS->SQL replay
2021-09-16 10:44:53 -04:00
Weimin YuandGitHub a8ddb5c053 Add indexes to DomainHistory sub tables (#1319)
* Add indexes to DomainHistory sub tables

Add indexes to DomainTransactionRecord and DomainDsDataHistory to speed
up query for DomainHistory. Without these indexes, DomainHistory loading
is extremely slow: 2 QPS with current production data.
2021-09-14 14:54:21 -04:00
Ben McIlwainandGitHub 88be34808d Rename Spec11Pipeline's Subdomain -> DomainNameInfo (#1318)
* Rename Spec11Pipeline's Subdomain -> DomainNameInfo

"Subdomain" never made any sense as a class name because these are all
second-level domain names, along with a little bit of metadata such as some
registrar info. "DomainNameInfo" is a better fit.
2021-09-14 14:07:26 -04:00
sarahcaseybotandGitHub 099555c789 Remove "Datastore" from comments when using both DBs (#1310)
* Change datastore references in comments to be more generic

* Update flows doc
2021-09-13 18:02:41 -04:00
Weimin YuandGitHub 652d099e0e Preserve update_time when replicating to SQL (#1316)
* Preserve update_time when replicating to SQL

Prevent InitSqlPipeline from changing the UpdateAutoTimestamp fields in
entities.
2021-09-13 16:55:20 -04:00
gbrodmanandGitHub f31d77c570 Update references to RDAP RFCs (#1313)
* Update references to RDAP RFCs

There were minor changes to the RDAP RFCs used -- we don't need to
change anything since we already comply with all of the changes, but we
should refer to the newer RFCs in the code.
2021-09-13 15:12:52 -04:00
gbrodmanandGitHub 1ced2b0a5d Fix URS check in BackfillRegistryLocksCommand (#1315)
* Fix URS check in BackfillRegistryLocksCommand

"reason" can be null
2021-09-13 14:15:25 -04:00
Rachel GuanandGitHub 0e6b5e949d Set up sendExpiringCertificateNotificationEmail cron job in prod (#1272)
* Set up sendExpiringCertificateNotificationEmail cron job in prod
2021-09-13 13:36:11 -04:00
Weimin YuandGitHub fe714329c9 Add a temporary fix to Hibernate detach in BEAM queries (#1314)
* Add a temporary fix to Hibernate detach in query

Make all queries in RegistryQuery (exclusively used by BEAM) use
EntityManager.clear() to detach entities. This is a temporary measure
that unblocks work in BEAM. We will revert the work once
JpaTransactionManager can detach entities properly for all types of
queries.

Also fixed regression bugs that broke query result streaming:
- The code that sets query fetch size was not carried over from
QueryComposer.
- The new ReadOnlyCheckingTypedQuery class did not override parent's
getResultStream() method, which calls getList().
2021-09-10 21:23:07 -04:00
Ben McIlwainandGitHub 9297b11a57 Add the DNS refresh request time field to the Domain tables (#1279)
* Add the DNS refresh request time field to the Domain tables

This isn't used yet, but it will eventually be the replacement for the dns-pull
task queue once we get further in the migration.

* Merge branch 'master' into domain-dns-dirty
2021-09-10 14:18:32 -04:00
Michael MullerandGitHub 031f4ea063 Remove VKeyTranslatorFactory.createVKey(String) (#1312)
* Remove VKeyTranslatorFactory.createVKey(String)

This method serves the same function as VKey.fromWebsafeKey(), and isn't used
anywhere.  Move the test for it into VKeyTest and use it to instead test
fromWebsafeKey() (which didn't previously have a test).
2021-09-09 12:24:02 -04:00
Rachel GuanandGitHub 0a25182fea Keep new lines/spaces as the way it shows in config yaml (#1311)
* Paste the email content as the way it is in doc.
2021-09-08 22:00:32 -04:00
Lai JiangandGitHub f1dcb1299f Reformat a file (#1305)
* Reformat a file

Constants should be SNAKE_CASE named and static fields usually go before
instance fields.
2021-09-03 16:56:57 -04:00
gbrodmanandGitHub d46594c610 Select correct history entries when creating canceling records (#1309) 2021-09-03 11:25:53 -04:00
gbrodmanandGitHub 0a9fa8cf23 Add RetryingTest annotation to flaky RDE test (#1306)
I'm not sure why this test is failing. It's failing saying that the
listObjects call is failing to include
"soy_2000-01-01_thin_S1_R1.xml.ghostryde" in the results, however the
verifyFiles method that we call right beforehand verifies that file and
its contents
2021-09-03 09:39:55 -04:00
sarahcaseybotandGitHub db4bf90538 Remove Datastore references from DomainLabelEntry (#1307) 2021-09-02 17:55:55 -04:00
Rachel GuanandGitHub d6127e4c0c Log registrar and certificate info before sending an email (#1308)
* Log registrar and certificate info before sending an email
2021-09-02 16:58:58 -04:00
sarahcaseybotandGitHub 447bfa162b Remove Datastore references in BaseDomainLabelList (#1304) 2021-09-02 13:21:45 -04:00
347 changed files with 2791 additions and 2333 deletions
-3
View File
@@ -206,15 +206,12 @@ PRESUBMITS = {
"RegistryJpaIO.java",
# TODO(b/179158393): Remove everything below, which should be done
# using Criteria
"ForeignKeyIndex.java",
"HistoryEntryDao.java",
"JpaTransactionManager.java",
"JpaTransactionManagerImpl.java",
# CriteriaQueryBuilder is a false positive
"CriteriaQueryBuilder.java",
"RdapDomainSearchAction.java",
"RdapNameserverSearchAction.java",
"RdapSearchActionBase.java",
"ReadOnlyCheckingEntityManager.java",
"RegistryQuery",
},
@@ -33,6 +33,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import google.registry.config.RegistryConfig.Config;
import google.registry.gcs.GcsUtils;
import google.registry.model.UpdateAutoTimestamp;
import google.registry.model.common.DatabaseMigrationStateSchedule;
import google.registry.model.common.DatabaseMigrationStateSchedule.MigrationState;
import google.registry.model.common.DatabaseMigrationStateSchedule.ReplayDirection;
@@ -222,8 +223,11 @@ public class ReplayCommitLogsToSqlAction implements Runnable {
// Load and process the Datastore transactions one at a time
ImmutableList<ImmutableList<VersionedEntity>> allTransactions =
CommitLogImports.loadEntitiesByTransaction(input);
allTransactions.forEach(
transaction -> jpaTm().transact(() -> replayTransaction(transaction)));
try (UpdateAutoTimestamp.DisableAutoUpdateResource disabler =
UpdateAutoTimestamp.disableAutoUpdate()) {
allTransactions.forEach(
transaction -> jpaTm().transact(() -> replayTransaction(transaction)));
}
// if we succeeded, set the last-seen time
DateTime checkpoint = DateTime.parse(metadata.getName().substring(DIFF_FILE_PREFIX.length()));
jpaTm().transact(() -> SqlReplayCheckpoint.set(checkpoint));
@@ -126,18 +126,18 @@ public final class AsyncTaskEnqueuer {
public void enqueueAsyncDelete(
EppResource resourceToDelete,
DateTime now,
String requestingClientId,
String requestingRegistrarId,
Trid trid,
boolean isSuperuser) {
Key<EppResource> resourceKey = Key.create(resourceToDelete);
logger.atInfo().log(
"Enqueuing async deletion of %s on behalf of registrar %s.",
resourceKey, requestingClientId);
resourceKey, requestingRegistrarId);
TaskOptions task =
TaskOptions.Builder.withMethod(Method.PULL)
.countdownMillis(asyncDeleteDelay.getMillis())
.param(PARAM_RESOURCE_KEY, resourceKey.getString())
.param(PARAM_REQUESTING_CLIENT_ID, requestingClientId)
.param(PARAM_REQUESTING_CLIENT_ID, requestingRegistrarId)
.param(PARAM_SERVER_TRANSACTION_ID, trid.getServerTransactionId())
.param(PARAM_IS_SUPERUSER, Boolean.toString(isSuperuser))
.param(PARAM_REQUESTED_TIME, now.toString());
@@ -343,15 +343,15 @@ public class DeleteContactsAndHostsAction implements Runnable {
}
// Contacts and external hosts have a direct client id. For subordinate hosts it needs to be
// read off of the superordinate domain.
String resourceClientId = resource.getPersistedCurrentSponsorClientId();
String resourceRegistrarId = resource.getPersistedCurrentSponsorRegistrarId();
if (resource instanceof HostResource && ((HostResource) resource).isSubordinate()) {
resourceClientId =
resourceRegistrarId =
tm().loadByKey(((HostResource) resource).getSuperordinateDomain())
.cloneProjectedAtTime(now)
.getCurrentSponsorClientId();
.getCurrentSponsorRegistrarId();
}
boolean requestedByCurrentOwner =
resourceClientId.equals(deletionRequest.requestingClientId());
resourceRegistrarId.equals(deletionRequest.requestingClientId());
boolean deleteAllowed =
hasNoActiveReferences && (requestedByCurrentOwner || deletionRequest.isSuperuser());
@@ -371,14 +371,14 @@ public class DeleteContactsAndHostsAction implements Runnable {
HistoryEntry historyEntry =
HistoryEntry.createBuilderForResource(resource)
.setClientId(deletionRequest.requestingClientId())
.setRegistrarId(deletionRequest.requestingClientId())
.setModificationTime(now)
.setType(getHistoryEntryType(resource, deleteAllowed))
.build();
PollMessage.OneTime pollMessage =
new PollMessage.OneTime.Builder()
.setClientId(deletionRequest.requestingClientId())
.setRegistrarId(deletionRequest.requestingClientId())
.setMsg(pollMessageText)
.setParent(historyEntry)
.setEventTime(now)
@@ -135,7 +135,7 @@ public class DeleteLoadTestDataAction implements Runnable {
}
private void deleteContact(ContactResource contact) {
if (!LOAD_TEST_REGISTRARS.contains(contact.getPersistedCurrentSponsorClientId())) {
if (!LOAD_TEST_REGISTRARS.contains(contact.getPersistedCurrentSponsorRegistrarId())) {
return;
}
// We cannot remove contacts from domains in the general case, so we cannot delete contacts
@@ -150,7 +150,7 @@ public class DeleteLoadTestDataAction implements Runnable {
}
private void deleteHost(HostResource host) {
if (!LOAD_TEST_REGISTRARS.contains(host.getPersistedCurrentSponsorClientId())) {
if (!LOAD_TEST_REGISTRARS.contains(host.getPersistedCurrentSponsorRegistrarId())) {
return;
}
VKey<HostResource> hostVKey = host.createVKey();
@@ -198,7 +198,7 @@ public class DeleteLoadTestDataAction implements Runnable {
@Override
public final void map(EppResource resource) {
if (LOAD_TEST_REGISTRARS.contains(resource.getPersistedCurrentSponsorClientId())) {
if (LOAD_TEST_REGISTRARS.contains(resource.getPersistedCurrentSponsorRegistrarId())) {
deleteResource(resource);
getContext()
.incrementCounter(
@@ -291,7 +291,7 @@ public class DeleteProberDataAction implements Runnable {
.setModificationTime(tm().getTransactionTime())
.setBySuperuser(true)
.setReason("Deletion of prober data")
.setClientId(registryAdminRegistrarId)
.setRegistrarId(registryAdminRegistrarId)
.build();
// Note that we don't bother handling grace periods, billing events, pending transfers, poll
// messages, or auto-renews because those will all be hard-deleted the next time the job runs
@@ -324,7 +324,7 @@ public class ExpandRecurringBillingEventsAction implements Runnable {
DomainHistory historyEntry =
new DomainHistory.Builder()
.setBySuperuser(false)
.setClientId(recurring.getClientId())
.setRegistrarId(recurring.getRegistrarId())
.setModificationTime(tm().getTransactionTime())
.setDomain(tm().loadByKey(domainKey))
.setPeriod(Period.create(1, YEARS))
@@ -354,7 +354,7 @@ public class ExpandRecurringBillingEventsAction implements Runnable {
syntheticOneTimesBuilder.add(
new OneTime.Builder()
.setBillingTime(billingTime)
.setClientId(recurring.getClientId())
.setRegistrarId(recurring.getRegistrarId())
.setCost(renewCost)
.setEventTime(eventTime)
.setFlags(union(recurring.getFlags(), Flag.SYNTHETIC))
@@ -203,11 +203,11 @@ public class RelockDomainAction implements Runnable {
"Domain %s has a pending transfer.",
domainName);
checkArgument(
domain.getCurrentSponsorClientId().equals(oldLock.getRegistrarId()),
domain.getCurrentSponsorRegistrarId().equals(oldLock.getRegistrarId()),
"Domain %s has been transferred from registrar %s to registrar %s since the unlock.",
domainName,
oldLock.getRegistrarId(),
domain.getCurrentSponsorClientId());
domain.getCurrentSponsorRegistrarId());
}
private void handleNonRetryableFailure(RegistryLock oldLock, Throwable t) {
@@ -293,7 +293,7 @@ public class RelockDomainAction implements Runnable {
private ImmutableSet<InternetAddress> getEmailRecipients(String registrarId) {
Registrar registrar =
Registrar.loadByClientIdCached(registrarId)
Registrar.loadByRegistrarIdCached(registrarId)
.orElseThrow(
() ->
new IllegalStateException(String.format("Unknown registrar %s", registrarId)));
@@ -151,6 +151,12 @@ public class SendExpiringCertificateNotificationEmailAction implements Runnable
}
try {
ImmutableSet<InternetAddress> recipients = getEmailAddresses(registrar, Type.TECH);
Date expirationDate = certificateChecker.getCertificate(certificate.get()).getNotAfter();
logger.atInfo().log(
"Registrar %s should receive an email that its %s SSL certificate will expire on %s.",
registrar.getRegistrarName(),
certificateType.getDisplayName(),
expirationDate.toString());
if (recipients.isEmpty()) {
logger.atWarning().log(
"Registrar %s contains no email addresses to receive notification email.",
@@ -165,16 +171,11 @@ public class SendExpiringCertificateNotificationEmailAction implements Runnable
getEmailBody(
registrar.getRegistrarName(),
certificateType,
certificateChecker.getCertificate(certificate.get()).getNotAfter(),
registrar.getClientId()))
expirationDate,
registrar.getRegistrarId()))
.setRecipients(recipients)
.setCcs(getEmailAddresses(registrar, Type.ADMIN))
.build());
logger.atInfo().log(
"Sent an email to inform registrar %s that its %s SSL certificate will expire on %s.",
registrar.getRegistrarName(),
certificateType.getDisplayName(),
DATE_FORMATTER.print(lastExpiringCertNotificationSentDate));
/*
* A duration time offset is used here to ensure that date comparison between two
* successive dates is always greater than 1 day. This date is set as last updated date,
@@ -22,6 +22,8 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Streams;
import google.registry.backup.AppEngineEnvironment;
import google.registry.beam.common.RegistryQuery.CriteriaQuerySupplier;
import google.registry.model.UpdateAutoTimestamp;
import google.registry.model.UpdateAutoTimestamp.DisableAutoUpdateResource;
import google.registry.model.ofy.ObjectifyService;
import google.registry.model.replay.SqlEntity;
import google.registry.persistence.transaction.JpaTransactionManager;
@@ -274,6 +276,12 @@ public final class RegistryJpaIO {
public abstract SerializableFunction<T, Object> jpaConverter();
/**
* Signal to the writer that the {@link UpdateAutoTimestamp} property should be allowed to
* manipulate its value before persistence. The default value is {@code true}.
*/
abstract boolean withUpdateAutoTimestamp();
public Write<T> withName(String name) {
return toBuilder().name(name).build();
}
@@ -294,6 +302,10 @@ public final class RegistryJpaIO {
return toBuilder().jpaConverter(jpaConverter).build();
}
public Write<T> disableUpdateAutoTimestamp() {
return toBuilder().withUpdateAutoTimestamp(false).build();
}
abstract Builder<T> toBuilder();
@Override
@@ -310,7 +322,7 @@ public final class RegistryJpaIO {
GroupIntoBatches.<Integer, T>ofSize(batchSize()).withShardedKey())
.apply(
"Write in batch for " + name(),
ParDo.of(new SqlBatchWriter<>(name(), jpaConverter())));
ParDo.of(new SqlBatchWriter<>(name(), jpaConverter(), withUpdateAutoTimestamp())));
}
static <T> Builder<T> builder() {
@@ -318,7 +330,8 @@ public final class RegistryJpaIO {
.name(DEFAULT_NAME)
.batchSize(DEFAULT_BATCH_SIZE)
.shards(DEFAULT_SHARDS)
.jpaConverter(x -> x);
.jpaConverter(x -> x)
.withUpdateAutoTimestamp(true);
}
@AutoValue.Builder
@@ -332,6 +345,8 @@ public final class RegistryJpaIO {
abstract Builder<T> jpaConverter(SerializableFunction<T, Object> jpaConverter);
abstract Builder<T> withUpdateAutoTimestamp(boolean withUpdateAutoTimestamp);
abstract Write<T> build();
}
}
@@ -340,10 +355,13 @@ public final class RegistryJpaIO {
private static class SqlBatchWriter<T> extends DoFn<KV<ShardedKey<Integer>, Iterable<T>>, Void> {
private final Counter counter;
private final SerializableFunction<T, Object> jpaConverter;
private final boolean withAutoTimestamp;
SqlBatchWriter(String type, SerializableFunction<T, Object> jpaConverter) {
SqlBatchWriter(
String type, SerializableFunction<T, Object> jpaConverter, boolean withAutoTimestamp) {
counter = Metrics.counter("SQL_WRITE", type);
this.jpaConverter = jpaConverter;
this.withAutoTimestamp = withAutoTimestamp;
}
@Setup
@@ -358,6 +376,16 @@ public final class RegistryJpaIO {
@ProcessElement
public void processElement(@Element KV<ShardedKey<Integer>, Iterable<T>> kv) {
if (withAutoTimestamp) {
actuallyProcessElement(kv);
return;
}
try (DisableAutoUpdateResource disable = UpdateAutoTimestamp.disableAutoUpdate()) {
actuallyProcessElement(kv);
}
}
private void actuallyProcessElement(@Element KV<ShardedKey<Integer>, Iterable<T>> kv) {
try (AppEngineEnvironment env = new AppEngineEnvironment()) {
ImmutableList<Object> entities =
Streams.stream(kv.getValue())
@@ -16,6 +16,7 @@ package google.registry.beam.common;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import google.registry.persistence.transaction.JpaTransactionManager;
import java.io.Serializable;
import java.util.Map;
import java.util.function.Supplier;
@@ -28,6 +29,15 @@ import javax.persistence.criteria.CriteriaQuery;
/** Interface for query instances used by {@link RegistryJpaIO.Read}. */
public interface RegistryQuery<T> extends Serializable {
/**
* Number of JPA entities to fetch in each batch during a query.
*
* <p>With Hibernate, for result streaming to work, a query's fetchSize property must be set to a
* non-zero value.
*/
int QUERY_FETCH_SIZE = 1000;
Stream<T> stream();
interface CriteriaQuerySupplier<T> extends Supplier<CriteriaQuery<T>>, Serializable {}
@@ -49,6 +59,7 @@ public interface RegistryQuery<T> extends Serializable {
if (parameters != null) {
parameters.forEach(query::setParameter);
}
JpaTransactionManager.setQueryFetchSize(query, QUERY_FETCH_SIZE);
@SuppressWarnings("unchecked")
Stream<T> resultStream = query.getResultStream();
return nativeQuery ? resultStream : resultStream.map(e -> detach(entityManager, e));
@@ -64,11 +75,14 @@ public interface RegistryQuery<T> extends Serializable {
static <T> RegistryQuery<T> createQuery(
String jpql, @Nullable Map<String, Object> parameters, Class<T> clazz) {
return () -> {
TypedQuery<T> query = jpaTm().query(jpql, clazz);
// TODO(b/193662898): switch to jpaTm().query() when it can properly detach loaded entities.
EntityManager entityManager = jpaTm().getEntityManager();
TypedQuery<T> query = entityManager.createQuery(jpql, clazz);
if (parameters != null) {
parameters.forEach(query::setParameter);
}
return query.getResultStream();
JpaTransactionManager.setQueryFetchSize(query, QUERY_FETCH_SIZE);
return query.getResultStream().map(e -> detach(entityManager, e));
};
}
@@ -82,7 +96,13 @@ public interface RegistryQuery<T> extends Serializable {
* @param <T> Type of each row in the result set.
*/
static <T> RegistryQuery<T> createQuery(CriteriaQuerySupplier<T> criteriaQuery) {
return () -> jpaTm().query(criteriaQuery.get()).getResultStream();
return () -> {
// TODO(b/193662898): switch to jpaTm().query() when it can properly detach loaded entities.
EntityManager entityManager = jpaTm().getEntityManager();
TypedQuery<T> query = entityManager.createQuery(criteriaQuery.get());
JpaTransactionManager.setQueryFetchSize(query, QUERY_FETCH_SIZE);
return query.getResultStream().map(e -> detach(entityManager, e));
};
}
/**
@@ -108,7 +128,10 @@ public interface RegistryQuery<T> extends Serializable {
return;
}
try {
entityManager.detach(object);
// TODO(b/193662898): choose detach() or clear() based on the type of transaction.
// For context, EntityManager.detach() does not remove all metadata about loaded entities.
// See b/193925312 or https://hibernate.atlassian.net/browse/HHH-14735 for details.
entityManager.clear();
} catch (IllegalArgumentException e) {
// Not an entity. Do nothing.
}
@@ -219,7 +219,8 @@ public class InitSqlPipeline implements Serializable {
.withName(transformId)
.withBatchSize(options.getSqlWriteBatchSize())
.withShards(options.getSqlWriteShards())
.withJpaConverter(Transforms::convertVersionedEntityToSqlEntity));
.withJpaConverter(Transforms::convertVersionedEntityToSqlEntity)
.disableUpdateAutoTimestamp());
}
private static ImmutableList<String> toKindStrings(Collection<Class<?>> entityClasses) {
@@ -125,7 +125,7 @@ public class InvoicingPipeline implements Serializable {
oneTime.getId(),
DateTimeUtils.toZonedDateTime(oneTime.getBillingTime(), ZoneId.of("UTC")),
DateTimeUtils.toZonedDateTime(oneTime.getEventTime(), ZoneId.of("UTC")),
registrar.getClientId(),
registrar.getRegistrarId(),
registrar.getBillingIdentifier().toString(),
registrar.getPoNumber().orElse(""),
DomainNameUtils.getTldFromDomainName(oneTime.getTargetId()),
@@ -25,7 +25,7 @@ import org.apache.avro.generic.GenericRecord;
import org.apache.beam.sdk.io.gcp.bigquery.SchemaAndRecord;
/**
* A POJO representing a single subdomain, parsed from a {@code SchemaAndRecord}.
* A POJO representing a domain name and associated info, parsed from a {@code SchemaAndRecord}.
*
* <p>This is a trivially serializable class that allows Beam to transform the results of a Bigquery
* query into a standard Java representation, giving us the type guarantees and ease of manipulation
@@ -33,28 +33,31 @@ import org.apache.beam.sdk.io.gcp.bigquery.SchemaAndRecord;
* function.
*/
@AutoValue
public abstract class Subdomain implements Serializable {
public abstract class DomainNameInfo implements Serializable {
private static final ImmutableList<String> FIELD_NAMES =
ImmutableList.of("domainName", "domainRepoId", "registrarId", "registrarEmailAddress");
/** Returns the fully qualified domain name. */
abstract String domainName();
/** Returns the domain repo ID (the primary key of the domain table). */
abstract String domainRepoId();
/** Returns the registrar ID of the associated registrar for this domain. */
abstract String registrarId();
/** Returns the email address of the registrar associated with this domain. */
abstract String registrarEmailAddress();
/**
* Constructs a {@link Subdomain} from an Apache Avro {@code SchemaAndRecord}.
* Constructs a {@link DomainNameInfo} from an Apache Avro {@code SchemaAndRecord}.
*
* @see <a
* href=http://avro.apache.org/docs/1.7.7/api/java/org/apache/avro/generic/GenericData.Record.html>
* Apache AVRO GenericRecord</a>
*/
static Subdomain parseFromRecord(SchemaAndRecord schemaAndRecord) {
static DomainNameInfo parseFromRecord(SchemaAndRecord schemaAndRecord) {
checkFieldsNotNull(FIELD_NAMES, schemaAndRecord);
GenericRecord record = schemaAndRecord.getRecord();
return create(
@@ -65,18 +68,15 @@ public abstract class Subdomain implements Serializable {
}
/**
* Creates a concrete {@link Subdomain}.
* Creates a concrete {@link DomainNameInfo}.
*
* <p>This should only be used outside this class for testing- instances of {@link Subdomain}
* <p>This should only be used outside this class for testing- instances of {@link DomainNameInfo}
* should otherwise come from {@link #parseFromRecord}.
*/
@VisibleForTesting
static Subdomain create(
String domainName,
String domainRepoId,
String registrarId,
String registrarEmailAddress) {
return new AutoValue_Subdomain(
static DomainNameInfo create(
String domainName, String domainRepoId, String registrarId, String registrarEmailAddress) {
return new AutoValue_DomainNameInfo(
domainName, domainRepoId, registrarId, registrarEmailAddress);
}
}
@@ -55,13 +55,14 @@ public class SafeBrowsingTransforms {
"https://safebrowsing.googleapis.com/v4/threatMatches:find";
/**
* {@link DoFn} mapping a {@link Subdomain} to its evaluation report from SafeBrowsing.
* {@link DoFn} mapping a {@link DomainNameInfo} to its evaluation report from SafeBrowsing.
*
* <p>Refer to the Lookup API documentation for the request/response format and other details.
*
* @see <a href=https://developers.google.com/safe-browsing/v4/lookup-api>Lookup API</a>
*/
static class EvaluateSafeBrowsingFn extends DoFn<Subdomain, KV<Subdomain, ThreatMatch>> {
static class EvaluateSafeBrowsingFn
extends DoFn<DomainNameInfo, KV<DomainNameInfo, ThreatMatch>> {
/**
* Max number of urls we can check in a single query.
@@ -74,10 +75,11 @@ public class SafeBrowsingTransforms {
private final String apiKey;
/**
* Maps a subdomain's {@code fullyQualifiedDomainName} to its corresponding {@link Subdomain} to
* facilitate batching SafeBrowsing API requests.
* Maps a domain name's {@code fullyQualifiedDomainName} to its corresponding {@link
* DomainNameInfo} to facilitate batching SafeBrowsing API requests.
*/
private final Map<String, Subdomain> subdomainBuffer = new LinkedHashMap<>(BATCH_SIZE);
private final Map<String, DomainNameInfo> domainNameInfoBuffer =
new LinkedHashMap<>(BATCH_SIZE);
/**
* Provides the HTTP client we use to interact with the SafeBrowsing API.
@@ -119,37 +121,38 @@ public class SafeBrowsingTransforms {
closeableHttpClientSupplier = clientSupplier;
}
/** Evaluates any buffered {@link Subdomain} objects upon completing the bundle. */
/** Evaluates any buffered {@link DomainNameInfo} objects upon completing the bundle. */
@FinishBundle
public void finishBundle(FinishBundleContext context) {
if (!subdomainBuffer.isEmpty()) {
ImmutableSet<KV<Subdomain, ThreatMatch>> results = evaluateAndFlush();
if (!domainNameInfoBuffer.isEmpty()) {
ImmutableSet<KV<DomainNameInfo, ThreatMatch>> results = evaluateAndFlush();
results.forEach((kv) -> context.output(kv, Instant.now(), GlobalWindow.INSTANCE));
}
}
/**
* Buffers {@link Subdomain} objects until we reach the batch size, then bulk-evaluate the URLs
* with the SafeBrowsing API.
* Buffers {@link DomainNameInfo} objects until we reach the batch size, then bulk-evaluate the
* URLs with the SafeBrowsing API.
*/
@ProcessElement
public void processElement(ProcessContext context) {
Subdomain subdomain = context.element();
subdomainBuffer.put(subdomain.domainName(), subdomain);
if (subdomainBuffer.size() >= BATCH_SIZE) {
ImmutableSet<KV<Subdomain, ThreatMatch>> results = evaluateAndFlush();
DomainNameInfo domainNameInfo = context.element();
domainNameInfoBuffer.put(domainNameInfo.domainName(), domainNameInfo);
if (domainNameInfoBuffer.size() >= BATCH_SIZE) {
ImmutableSet<KV<DomainNameInfo, ThreatMatch>> results = evaluateAndFlush();
results.forEach(context::output);
}
}
/**
* Evaluates all {@link Subdomain} objects in the buffer and returns a list of key-value pairs
* from {@link Subdomain} to its SafeBrowsing report.
* Evaluates all {@link DomainNameInfo} objects in the buffer and returns a list of key-value
* pairs from {@link DomainNameInfo} to its SafeBrowsing report.
*
* <p>If a {@link Subdomain} is safe according to the API, it will not emit a report.
* <p>If a {@link DomainNameInfo} is safe according to the API, it will not emit a report.
*/
private ImmutableSet<KV<Subdomain, ThreatMatch>> evaluateAndFlush() {
ImmutableSet.Builder<KV<Subdomain, ThreatMatch>> resultBuilder = new ImmutableSet.Builder<>();
private ImmutableSet<KV<DomainNameInfo, ThreatMatch>> evaluateAndFlush() {
ImmutableSet.Builder<KV<DomainNameInfo, ThreatMatch>> resultBuilder =
new ImmutableSet.Builder<>();
try {
URIBuilder uriBuilder = new URIBuilder(SAFE_BROWSING_URL);
// Add the API key param
@@ -174,7 +177,7 @@ public class SafeBrowsingTransforms {
throw new RuntimeException("Caught parsing exception, failing pipeline.", e);
} finally {
// Flush the buffer
subdomainBuffer.clear();
domainNameInfoBuffer.clear();
}
return resultBuilder.build();
}
@@ -183,7 +186,7 @@ public class SafeBrowsingTransforms {
private JSONObject createRequestBody() throws JSONException {
// Accumulate all domain names to evaluate.
JSONArray threatArray = new JSONArray();
for (String fullyQualifiedDomainName : subdomainBuffer.keySet()) {
for (String fullyQualifiedDomainName : domainNameInfoBuffer.keySet()) {
threatArray.put(new JSONObject().put("url", fullyQualifiedDomainName));
}
// Construct the JSON request body
@@ -211,7 +214,7 @@ public class SafeBrowsingTransforms {
*/
private void processResponse(
CloseableHttpResponse response,
ImmutableSet.Builder<KV<Subdomain, ThreatMatch>> resultBuilder)
ImmutableSet.Builder<KV<DomainNameInfo, ThreatMatch>> resultBuilder)
throws JSONException, IOException {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != SC_OK) {
@@ -226,16 +229,17 @@ public class SafeBrowsingTransforms {
if (responseBody.length() == 0) {
logger.atInfo().log("Response was empty, no threats detected");
} else {
// Emit all Subdomains with their API results.
// Emit all DomainNameInfos with their API results.
JSONArray threatMatches = responseBody.getJSONArray("matches");
for (int i = 0; i < threatMatches.length(); i++) {
JSONObject match = threatMatches.getJSONObject(i);
String url = match.getJSONObject("threat").getString("url");
Subdomain subdomain = subdomainBuffer.get(url);
DomainNameInfo domainNameInfo = domainNameInfoBuffer.get(url);
resultBuilder.add(
KV.of(
subdomain,
ThreatMatch.create(match.getString("threatType"), subdomain.domainName())));
domainNameInfo,
ThreatMatch.create(
match.getString("threatType"), domainNameInfo.domainName())));
}
}
}
@@ -100,20 +100,20 @@ public class Spec11Pipeline implements Serializable {
void setupPipeline(Pipeline pipeline) {
options.setIsolationOverride(TransactionIsolationLevel.TRANSACTION_READ_COMMITTED);
PCollection<Subdomain> domains =
PCollection<DomainNameInfo> domains =
options.getDatabase().equals("DATASTORE")
? readFromBigQuery(options, pipeline)
: readFromCloudSql(pipeline);
PCollection<KV<Subdomain, ThreatMatch>> threatMatches =
PCollection<KV<DomainNameInfo, ThreatMatch>> threatMatches =
domains.apply("Run through SafeBrowsing API", ParDo.of(safeBrowsingFn));
saveToSql(threatMatches, options);
saveToGcs(threatMatches, options);
}
static PCollection<Subdomain> readFromCloudSql(Pipeline pipeline) {
Read<Object[], Subdomain> read =
static PCollection<DomainNameInfo> readFromCloudSql(Pipeline pipeline) {
Read<Object[], DomainNameInfo> read =
RegistryJpaIO.read(
"select d, r.emailAddress from Domain d join Registrar r on"
+ " d.currentSponsorClientId = r.clientIdentifier where r.type = 'REAL'"
@@ -124,62 +124,63 @@ public class Spec11Pipeline implements Serializable {
return pipeline.apply("Read active domains from Cloud SQL", read);
}
static PCollection<Subdomain> readFromBigQuery(Spec11PipelineOptions options, Pipeline pipeline) {
static PCollection<DomainNameInfo> readFromBigQuery(
Spec11PipelineOptions options, Pipeline pipeline) {
return pipeline.apply(
"Read active domains from BigQuery",
BigQueryIO.read(Subdomain::parseFromRecord)
BigQueryIO.read(DomainNameInfo::parseFromRecord)
.fromQuery(
SqlTemplate.create(getQueryFromFile(Spec11Pipeline.class, "subdomains.sql"))
SqlTemplate.create(getQueryFromFile(Spec11Pipeline.class, "domain_name_infos.sql"))
.put("PROJECT_ID", options.getProject())
.put("DATASTORE_EXPORT_DATASET", "latest_datastore_export")
.put("REGISTRAR_TABLE", "Registrar")
.put("DOMAIN_BASE_TABLE", "DomainBase")
.build())
.withCoder(SerializableCoder.of(Subdomain.class))
.withCoder(SerializableCoder.of(DomainNameInfo.class))
.usingStandardSql()
.withoutValidation()
.withTemplateCompatibility());
}
private static Subdomain parseRow(Object[] row) {
private static DomainNameInfo parseRow(Object[] row) {
DomainBase domainBase = (DomainBase) row[0];
String emailAddress = (String) row[1];
if (emailAddress == null) {
emailAddress = "";
}
return Subdomain.create(
return DomainNameInfo.create(
domainBase.getDomainName(),
domainBase.getRepoId(),
domainBase.getCurrentSponsorClientId(),
domainBase.getCurrentSponsorRegistrarId(),
emailAddress);
}
static void saveToSql(
PCollection<KV<Subdomain, ThreatMatch>> threatMatches, Spec11PipelineOptions options) {
PCollection<KV<DomainNameInfo, ThreatMatch>> threatMatches, Spec11PipelineOptions options) {
String transformId = "Spec11 Threat Matches";
LocalDate date = LocalDate.parse(options.getDate(), ISODateTimeFormat.date());
threatMatches.apply(
"Write to Sql: " + transformId,
RegistryJpaIO.<KV<Subdomain, ThreatMatch>>write()
RegistryJpaIO.<KV<DomainNameInfo, ThreatMatch>>write()
.withName(transformId)
.withBatchSize(options.getSqlWriteBatchSize())
.withShards(options.getSqlWriteShards())
.withJpaConverter(
(kv) -> {
Subdomain subdomain = kv.getKey();
DomainNameInfo domainNameInfo = kv.getKey();
return new Spec11ThreatMatch.Builder()
.setThreatTypes(
ImmutableSet.of(ThreatType.valueOf(kv.getValue().threatType())))
.setCheckDate(date)
.setDomainName(subdomain.domainName())
.setDomainRepoId(subdomain.domainRepoId())
.setRegistrarId(subdomain.registrarId())
.setDomainName(domainNameInfo.domainName())
.setDomainRepoId(domainNameInfo.domainRepoId())
.setRegistrarId(domainNameInfo.registrarId())
.build();
}));
}
static void saveToGcs(
PCollection<KV<Subdomain, ThreatMatch>> threatMatches, Spec11PipelineOptions options) {
PCollection<KV<DomainNameInfo, ThreatMatch>> threatMatches, Spec11PipelineOptions options) {
threatMatches
.apply(
"Map registrar ID to email/ThreatMatch pair",
@@ -187,7 +188,7 @@ public class Spec11Pipeline implements Serializable {
TypeDescriptors.kvs(
TypeDescriptors.strings(), TypeDescriptor.of(EmailAndThreatMatch.class)))
.via(
(KV<Subdomain, ThreatMatch> kv) ->
(KV<DomainNameInfo, ThreatMatch> kv) ->
KV.of(
kv.getKey().registrarId(),
EmailAndThreatMatch.create(
@@ -198,15 +199,15 @@ public class Spec11Pipeline implements Serializable {
MapElements.into(TypeDescriptors.strings())
.via(
(KV<String, Iterable<EmailAndThreatMatch>> kv) -> {
String clientId = kv.getKey();
String registrarId = kv.getKey();
checkArgument(
kv.getValue().iterator().hasNext(),
String.format(
"Registrar with ID %s had no corresponding threats", clientId));
"Registrar with ID %s had no corresponding threats", registrarId));
String email = kv.getValue().iterator().next().email();
JSONObject output = new JSONObject();
try {
output.put(REGISTRAR_CLIENT_ID_FIELD, clientId);
output.put(REGISTRAR_CLIENT_ID_FIELD, registrarId);
output.put(REGISTRAR_EMAIL_FIELD, email);
JSONArray threatMatchArray = new JSONArray();
for (EmailAndThreatMatch emailAndThreatMatch : kv.getValue()) {
@@ -230,7 +231,7 @@ public class Spec11Pipeline implements Serializable {
options.getReportingBucketUrl(),
getSpec11ReportFilePath(LocalDate.parse(options.getDate()))))
.withoutSharding()
.withHeader("Map from registrar email / name to detected subdomain threats:"));
.withHeader("Map from registrar email / name to detected domain name threats:"));
}
public static void main(String[] args) {
@@ -1138,8 +1138,8 @@ public final class RegistryConfig {
}
/**
* Returns the clientId of the registrar that admins are automatically logged in as if they
* aren't otherwise associated with one.
* Returns the ID of the registrar that admins are automatically logged in as if they aren't
* otherwise associated with one.
*/
@Provides
@Config("registryAdminClientId")
@@ -459,46 +459,29 @@ sslCertificateValidation:
expirationWarningEmailSubjectText: "[Important] Expiring SSL certificate for Google Registry EPP connection"
# Text for expiring certificate notification email body that accepts 3 parameters:
# registrar name, certificate type, and expiration date, respectively.
expirationWarningEmailBodyText: >
expirationWarningEmailBodyText: |
Dear %1$s,
We would like to inform you that your %2$s SSL certificate will expire at
%3$s. Please take note that using expired certificates will prevent
successful Registry login.
We would like to inform you that your %2$s SSL certificate will expire at %3$s. Please take note that using expired certificates will prevent successful Registry login.
Kindly update your production account certificate within the support
console using the following steps:
Kindly update your production account certificate within the support console using the following steps:
1. Navigate to support.registry.google and login using your
%4$s@registry.google credentials.
* If this is your first time logging in, you will be prompted to
reset your password, so please keep your new password safe.
* If you are already logged in with some other Google account(s) but
not your %4$s@registry.google account, you need to click on
1. Navigate to support.registry.google and login using your %4$s@registry.google credentials.
* If this is your first time logging in, you will be prompted to reset your password, so please keep your new password safe.
* If you are already logged in with some other Google account(s) but not your %4$s@registry.google account, you need to click on
“Add Account” and login using your %4$s@registry.google credentials.
2. Select “Settings > Security” from the left navigation bar.
3. Click “Edit” on the top left corner.
4. Enter your full certificate string
(including lines -----BEGIN CERTIFICATE----- and
-----END CERTIFICATE-----) in the box.
5. Click “Save”. If there are validation issues with the form, you will
be prompted to fix them and click “Save” again.
4. Enter your full certificate string (including lines -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----) in the box.
5. Click “Save”. If there are validation issues with the form, you will be prompted to fix them and click “Save” again.
A failover SSL certificate can also be added in order to prevent connection
issues once your main certificate expires. Connecting with either of the
certificates will work with our production EPP server.
A failover SSL certificate can also be added in order to prevent connection issues once your main certificate expires. Connecting with either of the certificates will work with our production EPP server.
Further information about our EPP connection requirements can be found in
section 9.2 in the updated Technical Guide in your Google Drive folder.
Further information about our EPP connection requirements can be found in section 9.2 in the updated Technical Guide in your Google Drive folder.
Note that account certificate changes take a few minutes to become
effective and that the existing connections will remain unaffected by
the change.
Note that account certificate changes take a few minutes to become effective and that the existing connections will remain unaffected by the change.
If you also would like to update your OT&E account certificate, please send
an email from your primary or technical contact to
registry-support@google.com and include the full certificate string
(including lines -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----).
If you also would like to update your OT&E account certificate, please send an email from your primary or technical contact to registry-support@google.com and include the full certificate string (including lines -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----).
Regards,
Google Registry
@@ -31,12 +31,12 @@ package google.registry.dns.writer;
public interface DnsWriter {
/**
* Loads {@code domainName} from Datastore and publishes its NS/DS records to the DNS server.
* Loads {@code domainName} from the database and publishes its NS/DS records to the DNS server.
* Replaces existing records for the exact name supplied with an NS record for each name server
* and a DS record for each delegation signer stored in the registry for the supplied domain name.
* If the domain is deleted or is in a "non-publish" state then any existing records are deleted.
*
* This must NOT actually perform any action, instead it should stage the action so that it's
* <p>This must NOT actually perform any action, instead it should stage the action so that it's
* performed when {@link #commit()} is called.
*
* @param domainName the fully qualified domain name, with no trailing dot
@@ -44,14 +44,14 @@ public interface DnsWriter {
void publishDomain(String domainName);
/**
* Loads {@code hostName} from Datastore and publishes its A/AAAA glue records to the DNS server,
* if it is used as an in-bailiwick nameserver. Orphaned glue records are prohibited. Replaces
* existing records for the exact name supplied, with an A or AAAA record (as appropriate) for
* each address stored in the registry, for the supplied host name. If the host is deleted then
* the existing records are deleted. Assumes that this method will only be called for in-bailiwick
* hosts. The registry does not have addresses for other hosts.
* Loads {@code hostName} from the database and publishes its A/AAAA glue records to the DNS
* server, if it is used as an in-bailiwick nameserver. Orphaned glue records are prohibited.
* Replaces existing records for the exact name supplied, with an A or AAAA record (as
* appropriate) for each address stored in the registry, for the supplied host name. If the host
* is deleted then the existing records are deleted. Assumes that this method will only be called
* for in-bailiwick hosts. The registry does not have addresses for other hosts.
*
* This must NOT actually perform any action, instead it should stage the action so that it's
* <p>This must NOT actually perform any action, instead it should stage the action so that it's
* performed when {@link #commit()} is called.
*
* @param hostName the fully qualified host name, with no trailing dot
@@ -193,6 +193,15 @@
<target>backend</target>
</cron>
<cron>
<url><![CDATA[/_dr/task/sendExpiringCertificateNotificationEmail]]></url>
<description>
This job runs an action that sends emails to partners if their certificates are expiring soon.
</description>
<schedule>every day 04:30</schedule>
<target>backend</target>
</cron>
<cron>
<url><![CDATA[/_dr/cron/fanout?queue=export-snapshot&endpoint=/_dr/task/backupDatastore&runInEmpty]]></url>
<description>
@@ -19,7 +19,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.request.Action.Method.POST;
import static google.registry.util.CollectionUtils.nullToEmpty;
import static google.registry.util.RegistrarUtils.normalizeClientId;
import static google.registry.util.RegistrarUtils.normalizeRegistrarId;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_OK;
@@ -96,16 +96,15 @@ public final class SyncGroupMembersAction implements Runnable {
}
/**
* Returns the Google Groups email address for the given registrar clientId and
* RegistrarContact.Type
* Returns the Google Groups email address for the given registrar ID and RegistrarContact.Type.
*/
public static String getGroupEmailAddressForContactType(
String clientId, RegistrarContact.Type type, String gSuiteDomainName) {
// Take the registrar's clientId, make it lowercase, and remove all characters that aren't
String registrarId, RegistrarContact.Type type, String gSuiteDomainName) {
// Take the registrar's ID, make it lowercase, and remove all characters that aren't
// alphanumeric, hyphens, or underscores.
return String.format(
"%s-%s-contacts@%s",
normalizeClientId(clientId), type.getDisplayName(), gSuiteDomainName);
normalizeRegistrarId(registrarId), type.getDisplayName(), gSuiteDomainName);
}
/**
@@ -150,7 +149,8 @@ public final class SyncGroupMembersAction implements Runnable {
/**
* Parses the results from Google Groups for each registrar, setting the dirty flag to false in
* Datastore for the calls that succeeded and accumulating the errors for the calls that failed.
* the database for the calls that succeeded and accumulating the errors for the calls that
* failed.
*/
private static List<Throwable> getErrorsAndUpdateFlagsForSuccesses(
ImmutableMap<Registrar, Optional<Throwable>> results) {
@@ -175,8 +175,8 @@ public final class SyncGroupMembersAction implements Runnable {
long totalAdded = 0;
long totalRemoved = 0;
for (final RegistrarContact.Type type : RegistrarContact.Type.values()) {
groupKey = getGroupEmailAddressForContactType(
registrar.getClientId(), type, gSuiteDomainName);
groupKey =
getGroupEmailAddressForContactType(registrar.getRegistrarId(), type, gSuiteDomainName);
Set<String> currentMembers = groupsConnection.getMembersOfGroup(groupKey);
Set<String> desiredMembers =
registrarContacts
@@ -195,11 +195,13 @@ public final class SyncGroupMembersAction implements Runnable {
}
logger.atInfo().log(
"Successfully synced contacts for registrar %s: added %d and removed %d",
registrar.getClientId(), totalAdded, totalRemoved);
registrar.getRegistrarId(), totalAdded, totalRemoved);
} catch (IOException e) {
// Package up exception and re-throw with attached additional relevant info.
String msg = String.format("Couldn't sync contacts for registrar %s to group %s",
registrar.getClientId(), groupKey);
String msg =
String.format(
"Couldn't sync contacts for registrar %s to group %s",
registrar.getRegistrarId(), groupKey);
throw new RuntimeException(msg, e);
}
}
@@ -47,7 +47,7 @@ import javax.inject.Inject;
import org.joda.time.DateTime;
/**
* Class for synchronizing all {@link Registrar} Datastore objects to a Google Spreadsheet.
* Class for synchronizing all {@link Registrar} objects to a Google Spreadsheet.
*
* @see SyncRegistrarsSheetAction
*/
@@ -82,7 +82,7 @@ class SyncRegistrarsSheet {
new Ordering<Registrar>() {
@Override
public int compare(Registrar left, Registrar right) {
return left.getClientId().compareTo(right.getClientId());
return left.getRegistrarId().compareTo(right.getRegistrarId());
}
}.immutableSortedCopy(Registrar.loadAllCached()).stream()
.filter(
@@ -116,7 +116,7 @@ class SyncRegistrarsSheet {
// and you'll need to remove deleted columns probably like a week after
// deployment.
//
builder.put("clientIdentifier", convert(registrar.getClientId()));
builder.put("clientIdentifier", convert(registrar.getRegistrarId()));
builder.put("registrarName", convert(registrar.getRegistrarName()));
builder.put("state", convert(registrar.getState()));
builder.put("ianaIdentifier", convert(registrar.getIanaIdentifier()));
@@ -61,7 +61,7 @@ public final class EppController {
boolean isDryRun,
boolean isSuperuser,
byte[] inputXmlBytes) {
eppMetricBuilder.setClientId(Optional.ofNullable(sessionMetadata.getClientId()));
eppMetricBuilder.setRegistrarId(Optional.ofNullable(sessionMetadata.getRegistrarId()));
try {
EppInput eppInput;
try {
@@ -76,7 +76,7 @@ public final class EppController {
JSONValue.toJSONString(
ImmutableMap.<String, Object>of(
"clientId",
nullToEmpty(sessionMetadata.getClientId()),
nullToEmpty(sessionMetadata.getRegistrarId()),
"resultCode",
e.getResult().getCode().code,
"resultMessage",
@@ -88,7 +88,7 @@ public class EppMetrics {
String eppStatusCode =
metric.getStatus().isPresent() ? String.valueOf(metric.getStatus().get().code) : "";
eppRequestsByRegistrar.increment(
metric.getCommandName().orElse(""), metric.getClientId().orElse(""), eppStatusCode);
metric.getCommandName().orElse(""), metric.getRegistrarId().orElse(""), eppStatusCode);
eppRequestsByTld.increment(
metric.getCommandName().orElse(""), metric.getTld().orElse(""), eppStatusCode);
}
@@ -38,7 +38,10 @@ public class EppToolAction implements Runnable {
public static final String PATH = "/_dr/epptool";
@Inject @Parameter("clientId") String clientId;
@Inject
@Parameter("clientId")
String registrarId;
@Inject @Parameter("superuser") boolean isSuperuser;
@Inject @Parameter("dryRun") boolean isDryRun;
@Inject @Parameter("xml") String xml;
@@ -49,8 +52,7 @@ public class EppToolAction implements Runnable {
public void run() {
eppRequestHandler.executeEpp(
new StatelessRequestSessionMetadata(
clientId,
ProtocolDefinition.getVisibleServiceExtensionUris()),
registrarId, ProtocolDefinition.getVisibleServiceExtensionUris()),
new PasswordOnlyTransportCredentials(),
EppRequestSource.TOOL,
isDryRun,
@@ -26,7 +26,7 @@ import com.google.common.flogger.FluentLogger;
import google.registry.flows.EppException.CommandUseErrorException;
import google.registry.flows.EppException.SyntaxErrorException;
import google.registry.flows.EppException.UnimplementedExtensionException;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.exceptions.OnlyToolCanPassMetadataException;
import google.registry.flows.exceptions.UnauthorizedForSuperuserExtensionException;
@@ -55,7 +55,7 @@ public final class ExtensionManager {
@Inject EppInput eppInput;
@Inject SessionMetadata sessionMetadata;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @Superuser boolean isSuperuser;
@Inject Class<? extends Flow> flowClass;
@Inject EppRequestSource eppRequestSource;
@@ -101,7 +101,7 @@ public final class ExtensionManager {
}
logger.atInfo().log(
"Client %s is attempting to run %s without declaring URIs %s on login",
clientId, flowClass.getSimpleName(), undeclaredUris);
registrarId, flowClass.getSimpleName(), undeclaredUris);
}
private static final ImmutableSet<EppRequestSource> ALLOWED_METADATA_EPP_REQUEST_SOURCES =
@@ -164,11 +164,11 @@ public class FlowModule {
@Provides
@FlowScope
@ClientId
static String provideClientId(SessionMetadata sessionMetadata) {
// Treat a missing clientId as null so we can always inject a non-null value. All we do with the
// clientId is log it (as "") or detect its absence, both of which work fine with empty.
return Strings.nullToEmpty(sessionMetadata.getClientId());
@RegistrarId
static String provideRegistrarId(SessionMetadata sessionMetadata) {
// Treat a missing registrarId as null so we can always inject a non-null value. All we do with
// the registrarId is log it (as "") or detect its absence, both of which work fine with empty.
return Strings.nullToEmpty(sessionMetadata.getRegistrarId());
}
@Provides
@@ -220,14 +220,14 @@ public class FlowModule {
Trid trid,
byte[] inputXmlBytes,
boolean isSuperuser,
String clientId,
String registrarId,
EppInput eppInput) {
builder
.setModificationTime(tm().getTransactionTime())
.setTrid(trid)
.setXmlBytes(inputXmlBytes)
.setBySuperuser(isSuperuser)
.setClientId(clientId);
.setRegistrarId(registrarId);
Optional<MetadataExtension> metadataExtension =
eppInput.getSingleExtension(MetadataExtension.class);
metadataExtension.ifPresent(
@@ -249,10 +249,10 @@ public class FlowModule {
Trid trid,
@InputXml byte[] inputXmlBytes,
@Superuser boolean isSuperuser,
@ClientId String clientId,
@RegistrarId String registrarId,
EppInput eppInput) {
return makeHistoryEntryBuilder(
new ContactHistory.Builder(), trid, inputXmlBytes, isSuperuser, clientId, eppInput);
new ContactHistory.Builder(), trid, inputXmlBytes, isSuperuser, registrarId, eppInput);
}
/**
@@ -266,10 +266,10 @@ public class FlowModule {
Trid trid,
@InputXml byte[] inputXmlBytes,
@Superuser boolean isSuperuser,
@ClientId String clientId,
@RegistrarId String registrarId,
EppInput eppInput) {
return makeHistoryEntryBuilder(
new HostHistory.Builder(), trid, inputXmlBytes, isSuperuser, clientId, eppInput);
new HostHistory.Builder(), trid, inputXmlBytes, isSuperuser, registrarId, eppInput);
}
/**
@@ -283,10 +283,10 @@ public class FlowModule {
Trid trid,
@InputXml byte[] inputXmlBytes,
@Superuser boolean isSuperuser,
@ClientId String clientId,
@RegistrarId String registrarId,
EppInput eppInput) {
return makeHistoryEntryBuilder(
new DomainHistory.Builder(), trid, inputXmlBytes, isSuperuser, clientId, eppInput);
new DomainHistory.Builder(), trid, inputXmlBytes, isSuperuser, registrarId, eppInput);
}
/**
@@ -322,7 +322,7 @@ public class FlowModule {
/** Dagger qualifier for registrar client id. */
@Qualifier
@Documented
public @interface ClientId {}
public @interface RegistrarId {}
/** Dagger qualifier for the target id (foreign key) for single resource flows. */
@Qualifier
@@ -23,8 +23,8 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.InputXml;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.model.eppcommon.Trid;
import google.registry.model.eppinput.EppInput;
@@ -45,7 +45,7 @@ public class FlowReporter {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@Inject Trid trid;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @InputXml byte[] inputXmlBytes;
@Inject EppInput eppInput;
@Inject Class<? extends Flow> flowClass;
@@ -64,7 +64,7 @@ public class FlowReporter {
JSONValue.toJSONString(
new ImmutableMap.Builder<String, Object>()
.put("serverTrid", trid.getServerTransactionId())
.put("clientId", clientId)
.put("clientId", registrarId)
.put("commandType", eppInput.getCommandType())
.put("resourceType", eppInput.getResourceType().orElse(""))
.put("flowClassName", flowClass.getSimpleName())
@@ -19,9 +19,9 @@ import static google.registry.xml.XmlTransformer.prettyPrint;
import com.google.common.base.Strings;
import com.google.common.flogger.FluentLogger;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.DryRun;
import google.registry.flows.FlowModule.InputXml;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.Transactional;
import google.registry.flows.session.LoginFlow;
@@ -38,7 +38,7 @@ public class FlowRunner {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject TransportCredentials credentials;
@Inject EppRequestSource eppRequestSource;
@Inject Provider<Flow> flowProvider;
@@ -59,7 +59,7 @@ public class FlowRunner {
logger.atInfo().log(
COMMAND_LOG_FORMAT,
trid.getServerTransactionId(),
clientId,
registrarId,
sessionMetadata,
prettyXml.replace("\n", "\n\t"),
credentials,
@@ -74,8 +74,8 @@ public class FlowRunner {
if (!isTransactional) {
EppOutput eppOutput = EppOutput.create(flowProvider.get().run());
if (flowClass.equals(LoginFlow.class)) {
// In LoginFlow, clientId isn't known until after the flow executes, so save it then.
eppMetricBuilder.setClientId(sessionMetadata.getClientId());
// In LoginFlow, registrarId isn't known until after the flow executes, so save it then.
eppMetricBuilder.setRegistrarId(sessionMetadata.getRegistrarId());
}
return eppOutput;
}
@@ -47,8 +47,8 @@ public final class FlowUtils {
private FlowUtils() {}
/** Validate that there is a logged in client. */
public static void validateClientIsLoggedIn(String clientId) throws EppException {
if (clientId.isEmpty()) {
public static void validateRegistrarIsLoggedIn(String registrarId) throws EppException {
if (registrarId.isEmpty()) {
throw new NotLoggedInException();
}
}
@@ -25,7 +25,7 @@ import javax.servlet.http.HttpSession;
/** A metadata class that is a wrapper around {@link HttpSession}. */
public class HttpSessionMetadata implements SessionMetadata {
private static final String CLIENT_ID = "CLIENT_ID";
private static final String REGISTRAR_ID = "REGISTRAR_ID";
private static final String SERVICE_EXTENSIONS = "SERVICE_EXTENSIONS";
private static final String FAILED_LOGIN_ATTEMPTS = "FAILED_LOGIN_ATTEMPTS";
@@ -41,8 +41,8 @@ public class HttpSessionMetadata implements SessionMetadata {
}
@Override
public String getClientId() {
return (String) session.getAttribute(CLIENT_ID);
public String getRegistrarId() {
return (String) session.getAttribute(REGISTRAR_ID);
}
@Override
@@ -57,8 +57,8 @@ public class HttpSessionMetadata implements SessionMetadata {
}
@Override
public void setClientId(String clientId) {
session.setAttribute(CLIENT_ID, clientId);
public void setRegistrarId(String registrarId) {
session.setAttribute(REGISTRAR_ID, registrarId);
}
@Override
@@ -79,7 +79,7 @@ public class HttpSessionMetadata implements SessionMetadata {
@Override
public String toString() {
return toStringHelper(getClass())
.add("clientId", getClientId())
.add("clientId", getRegistrarId())
.add("failedLoginAttempts", getFailedLoginAttempts())
.add("serviceExtensionUris", Joiner.on('.').join(nullToEmpty(getServiceExtensionUris())))
.toString();
@@ -69,10 +69,10 @@ public final class ResourceFlowUtils {
*/
private static final int FAILFAST_CHECK_COUNT = 5;
/** Check that the given clientId corresponds to the owner of given resource. */
public static void verifyResourceOwnership(String myClientId, EppResource resource)
/** Check that the given registrarId corresponds to the owner of given resource. */
public static void verifyResourceOwnership(String myRegistrarId, EppResource resource)
throws EppException {
if (!myClientId.equals(resource.getPersistedCurrentSponsorClientId())) {
if (!myRegistrarId.equals(resource.getPersistedCurrentSponsorRegistrarId())) {
throw new ResourceNotOwnedException();
}
}
@@ -138,8 +138,8 @@ public final class ResourceFlowUtils {
}
public static <R extends EppResource & ResourceWithTransferData> void verifyTransferInitiator(
String clientId, R resource) throws NotTransferInitiatorException {
if (!resource.getTransferData().getGainingClientId().equals(clientId)) {
String registrarId, R resource) throws NotTransferInitiatorException {
if (!resource.getTransferData().getGainingRegistrarId().equals(registrarId)) {
throw new NotTransferInitiatorException();
}
}
@@ -155,12 +155,12 @@ public final class ResourceFlowUtils {
}
public static <R extends EppResource> void verifyResourceDoesNotExist(
Class<R> clazz, String targetId, DateTime now, String clientId) throws EppException {
Class<R> clazz, String targetId, DateTime now, String registrarId) throws EppException {
VKey<R> key = loadAndGetKey(clazz, targetId, now);
if (key != null) {
R resource = tm().loadByKey(key);
// These are similar exceptions, but we can track them internally as log-based metrics.
if (Objects.equals(clientId, resource.getPersistedCurrentSponsorClientId())) {
if (Objects.equals(registrarId, resource.getPersistedCurrentSponsorRegistrarId())) {
throw new ResourceAlreadyExistsForThisClientException(targetId);
} else {
throw new ResourceCreateContentionException(targetId);
@@ -26,13 +26,13 @@ public interface SessionMetadata {
*/
void invalidate();
String getClientId();
String getRegistrarId();
Set<String> getServiceExtensionUris();
int getFailedLoginAttempts();
void setClientId(String clientId);
void setRegistrarId(String registrarId);
void setServiceExtensionUris(Set<String> serviceExtensionUris);
@@ -25,12 +25,12 @@ import java.util.Set;
/** A read-only {@link SessionMetadata} that doesn't support login/logout. */
public class StatelessRequestSessionMetadata implements SessionMetadata {
private final String clientId;
private final String registrarId;
private final ImmutableSet<String> serviceExtensionUris;
public StatelessRequestSessionMetadata(
String clientId, ImmutableSet<String> serviceExtensionUris) {
this.clientId = checkNotNull(clientId);
String registrarId, ImmutableSet<String> serviceExtensionUris) {
this.registrarId = checkNotNull(registrarId);
this.serviceExtensionUris = checkNotNull(serviceExtensionUris);
}
@@ -40,8 +40,8 @@ public class StatelessRequestSessionMetadata implements SessionMetadata {
}
@Override
public String getClientId() {
return clientId;
public String getRegistrarId() {
return registrarId;
}
@Override
@@ -55,7 +55,7 @@ public class StatelessRequestSessionMetadata implements SessionMetadata {
}
@Override
public void setClientId(String clientId) {
public void setRegistrarId(String registrarId) {
throw new UnsupportedOperationException();
}
@@ -77,7 +77,7 @@ public class StatelessRequestSessionMetadata implements SessionMetadata {
@Override
public String toString() {
return toStringHelper(getClass())
.add("clientId", getClientId())
.add("clientId", getRegistrarId())
.add("failedLoginAttempts", getFailedLoginAttempts())
.add("serviceExtensionUris", Joiner.on('.').join(nullToEmpty(getServiceExtensionUris())))
.toString();
@@ -97,7 +97,7 @@ public class TlsCredentials implements TransportCredentials {
if (ipAddressAllowList.isEmpty()) {
logger.atInfo().log(
"Skipping IP allow list check because %s doesn't have an IP allow list.",
registrar.getClientId());
registrar.getRegistrarId());
return;
}
// In the rare unexpected case that the client inet address wasn't passed along at all, then
@@ -113,7 +113,7 @@ public class TlsCredentials implements TransportCredentials {
logger.atInfo().log(
"Authentication error: IP address %s is not allow-listed for registrar %s; allow list is:"
+ " %s",
clientInetAddr, registrar.getClientId(), ipAddressAllowList);
clientInetAddr, registrar.getRegistrarId(), ipAddressAllowList);
throw new BadRegistrarIpAddressException();
}
@@ -132,7 +132,8 @@ public class TlsCredentials implements TransportCredentials {
// Check that the request included the certificate hash
if (!clientCertificateHash.isPresent()) {
logger.atInfo().log(
"Request from registrar %s did not include X-SSL-Certificate.", registrar.getClientId());
"Request from registrar %s did not include X-SSL-Certificate.",
registrar.getRegistrarId());
throw new MissingRegistrarCertificateException();
}
// Check if the certificate hash is equal to the one on file for the registrar.
@@ -141,7 +142,7 @@ public class TlsCredentials implements TransportCredentials {
logger.atWarning().log(
"Non-matching certificate hash (%s) for %s, wanted either %s or %s.",
clientCertificateHash,
registrar.getClientId(),
registrar.getRegistrarId(),
registrar.getClientCertificateHash(),
registrar.getFailoverClientCertificateHash());
throw new BadRegistrarCertificateException();
@@ -156,7 +157,7 @@ public class TlsCredentials implements TransportCredentials {
} catch (InsecureCertificateException e) {
logger.atWarning().log(
"Registrar certificate used for %s does not meet certificate requirements: %s",
registrar.getClientId(), e.getMessage());
registrar.getRegistrarId(), e.getMessage());
throw new CertificateContainsSecurityViolationsException(e);
}
}
@@ -33,7 +33,6 @@ import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Date;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import org.bouncycastle.jce.ECNamedCurveTable;
@@ -228,7 +227,7 @@ public class CertificateChecker {
/** Returns whether the client should receive a notification email. */
public boolean shouldReceiveExpiringNotification(
@Nullable DateTime lastExpiringNotificationSentDate, String certificateStr) {
DateTime lastExpiringNotificationSentDate, String certificateStr) {
X509Certificate certificate = getCertificate(certificateStr);
DateTime now = clock.nowUtc();
// expiration date is one day after lastValidDate
@@ -238,13 +237,13 @@ public class CertificateChecker {
}
/*
* Client should receive a notification if :
* 1) client has never received notification and the certificate has entered
* the expiring period, OR
* 1) client has never received notification (lastExpiringNotificationSentDate is initially
* set to START_OF_TIME) and the certificate has entered the expiring period, OR
* 2) client has received notification but the interval between now and
* lastExpiringNotificationSentDate is greater than expirationWarningIntervalDays.
*/
return !lastValidDate.after(now.plusDays(expirationWarningDays).toDate())
&& (lastExpiringNotificationSentDate == null
&& (lastExpiringNotificationSentDate.equals(START_OF_TIME)
|| !lastExpiringNotificationSentDate
.plusDays(expirationWarningIntervalDays)
.toDate()
@@ -14,7 +14,7 @@
package google.registry.flows.contact;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount;
import static google.registry.model.EppResourceUtils.checkResourcesExist;
@@ -24,7 +24,7 @@ import google.registry.config.RegistryConfig.Config;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.model.contact.ContactCommand.Check;
import google.registry.model.contact.ContactResource;
@@ -47,7 +47,7 @@ import javax.inject.Inject;
public final class ContactCheckFlow implements Flow {
@Inject ResourceCommand resourceCommand;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject ExtensionManager extensionManager;
@Inject Clock clock;
@Inject @Config("maxChecks") int maxChecks;
@@ -57,7 +57,7 @@ public final class ContactCheckFlow implements Flow {
@Override
public final EppResponse run() throws EppException {
extensionManager.validate(); // There are no legal extensions for this flow.
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
ImmutableList<String> targetIds = ((Check) resourceCommand).getTargetIds();
verifyTargetIdCount(targetIds, maxChecks);
ImmutableSet<String> existingIds =
@@ -14,7 +14,7 @@
package google.registry.flows.contact;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyResourceDoesNotExist;
import static google.registry.flows.contact.ContactFlowUtils.validateAsciiPostalInfo;
import static google.registry.flows.contact.ContactFlowUtils.validateContactAgainstPolicy;
@@ -27,7 +27,7 @@ import com.googlecode.objectify.Key;
import google.registry.config.RegistryConfig.Config;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
import google.registry.flows.annotations.ReportingSpec;
@@ -60,7 +60,7 @@ public final class ContactCreateFlow implements TransactionalFlow {
@Inject ResourceCommand resourceCommand;
@Inject ExtensionManager extensionManager;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject ContactHistory.Builder historyBuilder;
@Inject EppResponse.Builder responseBuilder;
@@ -71,16 +71,16 @@ public final class ContactCreateFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
Create command = (Create) resourceCommand;
DateTime now = tm().getTransactionTime();
verifyResourceDoesNotExist(ContactResource.class, targetId, now, clientId);
verifyResourceDoesNotExist(ContactResource.class, targetId, now, registrarId);
ContactResource newContact =
new ContactResource.Builder()
.setContactId(targetId)
.setAuthInfo(command.getAuthInfo())
.setCreationClientId(clientId)
.setPersistedCurrentSponsorClientId(clientId)
.setCreationRegistrarId(registrarId)
.setPersistedCurrentSponsorRegistrarId(registrarId)
.setRepoId(createRepoId(allocateId(), roidSuffix))
.setFaxNumber(command.getFax())
.setVoiceNumber(command.getVoice())
@@ -14,7 +14,7 @@
package google.registry.flows.contact;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.checkLinkedDomains;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyNoDisallowedStatuses;
@@ -31,7 +31,7 @@ import com.google.common.collect.ImmutableSet;
import google.registry.batch.AsyncTaskEnqueuer;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
@@ -75,7 +75,7 @@ public final class ContactDeleteFlow implements TransactionalFlow {
StatusValue.SERVER_DELETE_PROHIBITED);
@Inject ExtensionManager extensionManager;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject Trid trid;
@Inject @Superuser boolean isSuperuser;
@@ -91,21 +91,21 @@ public final class ContactDeleteFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
DateTime now = tm().getTransactionTime();
checkLinkedDomains(targetId, now, ContactResource.class, DomainBase::getReferencedContacts);
ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now);
verifyNoDisallowedStatuses(existingContact, DISALLOWED_STATUSES);
verifyOptionalAuthInfo(authInfo, existingContact);
if (!isSuperuser) {
verifyResourceOwnership(clientId, existingContact);
verifyResourceOwnership(registrarId, existingContact);
}
Type historyEntryType;
Code resultCode;
ContactResource newContact;
if (tm().isOfy()) {
asyncTaskEnqueuer.enqueueAsyncDelete(
existingContact, tm().getTransactionTime(), clientId, trid, isSuperuser);
existingContact, tm().getTransactionTime(), registrarId, trid, isSuperuser);
newContact = existingContact.asBuilder().addStatusValue(StatusValue.PENDING_DELETE).build();
historyEntryType = Type.CONTACT_PENDING_DELETE;
resultCode = SUCCESS_WITH_ACTION_PENDING;
@@ -113,7 +113,7 @@ public final class ContactDeleteFlow implements TransactionalFlow {
// Handle pending transfers on contact deletion.
newContact =
existingContact.getStatusValues().contains(StatusValue.PENDING_TRANSFER)
? denyPendingTransfer(existingContact, SERVER_CANCELLED, now, clientId)
? denyPendingTransfer(existingContact, SERVER_CANCELLED, now, registrarId)
: existingContact;
// Wipe out PII on contact deletion.
newContact =
@@ -73,7 +73,7 @@ public class ContactFlowUtils {
DateTime now,
Key<ContactHistory> contactHistoryKey) {
return new PollMessage.OneTime.Builder()
.setClientId(transferData.getGainingClientId())
.setRegistrarId(transferData.getGainingRegistrarId())
.setEventTime(transferData.getPendingTransferExpirationTime())
.setMsg(transferData.getTransferStatus().getMessage())
.setResponseData(
@@ -92,7 +92,7 @@ public class ContactFlowUtils {
static PollMessage createLosingTransferPollMessage(
String targetId, TransferData transferData, Key<ContactHistory> contactHistoryKey) {
return new PollMessage.OneTime.Builder()
.setClientId(transferData.getLosingClientId())
.setRegistrarId(transferData.getLosingRegistrarId())
.setEventTime(transferData.getPendingTransferExpirationTime())
.setMsg(transferData.getTransferStatus().getMessage())
.setResponseData(ImmutableList.of(createTransferResponse(targetId, transferData)))
@@ -105,8 +105,8 @@ public class ContactFlowUtils {
String targetId, TransferData transferData) {
return new ContactTransferResponse.Builder()
.setContactId(targetId)
.setGainingClientId(transferData.getGainingClientId())
.setLosingClientId(transferData.getLosingClientId())
.setGainingRegistrarId(transferData.getGainingRegistrarId())
.setLosingRegistrarId(transferData.getLosingRegistrarId())
.setPendingTransferExpirationTime(transferData.getPendingTransferExpirationTime())
.setTransferRequestTime(transferData.getTransferRequestTime())
.setTransferStatus(transferData.getTransferStatus())
@@ -14,7 +14,7 @@
package google.registry.flows.contact;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
import static google.registry.model.EppResourceUtils.isLinked;
@@ -23,7 +23,7 @@ import com.google.common.collect.ImmutableSet;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.annotations.ReportingSpec;
@@ -54,7 +54,7 @@ public final class ContactInfoFlow implements Flow {
@Inject ExtensionManager extensionManager;
@Inject Clock clock;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject Optional<AuthInfo> authInfo;
@Inject @Superuser boolean isSuperuser;
@@ -67,13 +67,13 @@ public final class ContactInfoFlow implements Flow {
public final EppResponse run() throws EppException {
DateTime now = clock.nowUtc();
extensionManager.validate(); // There are no legal extensions for this flow.
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
ContactResource contact = loadAndVerifyExistence(ContactResource.class, targetId, now);
if (!isSuperuser) {
verifyResourceOwnership(clientId, contact);
verifyResourceOwnership(registrarId, contact);
}
boolean includeAuthInfo =
clientId.equals(contact.getCurrentSponsorClientId()) || authInfo.isPresent();
registrarId.equals(contact.getCurrentSponsorRegistrarId()) || authInfo.isPresent();
ImmutableSet.Builder<StatusValue> statusValues = new ImmutableSet.Builder<>();
statusValues.addAll(contact.getStatusValues());
if (isLinked(contact.createVKey(), now)) {
@@ -89,10 +89,10 @@ public final class ContactInfoFlow implements Flow {
.setVoiceNumber(contact.getVoiceNumber())
.setFaxNumber(contact.getFaxNumber())
.setEmailAddress(contact.getEmailAddress())
.setCurrentSponsorClientId(contact.getCurrentSponsorClientId())
.setCreationClientId(contact.getCreationClientId())
.setCurrentSponsorClientId(contact.getCurrentSponsorRegistrarId())
.setCreationClientId(contact.getCreationRegistrarId())
.setCreationTime(contact.getCreationTime())
.setLastEppUpdateClientId(contact.getLastEppUpdateClientId())
.setLastEppUpdateClientId(contact.getLastEppUpdateRegistrarId())
.setLastEppUpdateTime(contact.getLastEppUpdateTime())
.setLastTransferTime(contact.getLastTransferTime())
.setAuthInfo(includeAuthInfo ? contact.getAuthInfo() : null)
@@ -14,7 +14,7 @@
package google.registry.flows.contact;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyHasPendingTransfer;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
@@ -29,7 +29,7 @@ import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
import google.registry.flows.annotations.ReportingSpec;
@@ -64,7 +64,7 @@ public final class ContactTransferApproveFlow implements TransactionalFlow {
@Inject ResourceCommand resourceCommand;
@Inject ExtensionManager extensionManager;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject Optional<AuthInfo> authInfo;
@Inject ContactHistory.Builder historyBuilder;
@@ -79,12 +79,12 @@ public final class ContactTransferApproveFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
DateTime now = tm().getTransactionTime();
ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now);
verifyOptionalAuthInfo(authInfo, existingContact);
verifyHasPendingTransfer(existingContact);
verifyResourceOwnership(clientId, existingContact);
verifyResourceOwnership(registrarId, existingContact);
ContactResource newContact =
approvePendingTransfer(existingContact, TransferStatus.CLIENT_APPROVED, now);
ContactHistory contactHistory =
@@ -14,7 +14,7 @@
package google.registry.flows.contact;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyHasPendingTransfer;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
@@ -29,7 +29,7 @@ import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
import google.registry.flows.annotations.ReportingSpec;
@@ -65,7 +65,7 @@ public final class ContactTransferCancelFlow implements TransactionalFlow {
@Inject ResourceCommand resourceCommand;
@Inject ExtensionManager extensionManager;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject ContactHistory.Builder historyBuilder;
@Inject EppResponse.Builder responseBuilder;
@@ -75,14 +75,14 @@ public final class ContactTransferCancelFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
DateTime now = tm().getTransactionTime();
ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now);
verifyOptionalAuthInfo(authInfo, existingContact);
verifyHasPendingTransfer(existingContact);
verifyTransferInitiator(clientId, existingContact);
verifyTransferInitiator(registrarId, existingContact);
ContactResource newContact =
denyPendingTransfer(existingContact, TransferStatus.CLIENT_CANCELLED, now, clientId);
denyPendingTransfer(existingContact, TransferStatus.CLIENT_CANCELLED, now, registrarId);
ContactHistory contactHistory =
historyBuilder.setType(CONTACT_TRANSFER_CANCEL).setContact(newContact).build();
// Create a poll message for the losing client.
@@ -14,7 +14,7 @@
package google.registry.flows.contact;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
import static google.registry.flows.contact.ContactFlowUtils.createTransferResponse;
@@ -22,7 +22,7 @@ import static google.registry.flows.contact.ContactFlowUtils.createTransferRespo
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.exceptions.NoTransferHistoryToQueryException;
@@ -55,7 +55,7 @@ public final class ContactTransferQueryFlow implements Flow {
@Inject ExtensionManager extensionManager;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject Clock clock;
@Inject EppResponse.Builder responseBuilder;
@@ -64,7 +64,7 @@ public final class ContactTransferQueryFlow implements Flow {
@Override
public final EppResponse run() throws EppException {
extensionManager.validate(); // There are no legal extensions for this flow.
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
ContactResource contact =
loadAndVerifyExistence(ContactResource.class, targetId, clock.nowUtc());
verifyOptionalAuthInfo(authInfo, contact);
@@ -76,8 +76,8 @@ public final class ContactTransferQueryFlow implements Flow {
// Note that the authorization info on the command (if present) has already been verified. If
// it's present, then the other checks are unnecessary.
if (!authInfo.isPresent()
&& !clientId.equals(contact.getTransferData().getGainingClientId())
&& !clientId.equals(contact.getTransferData().getLosingClientId())) {
&& !registrarId.equals(contact.getTransferData().getGainingRegistrarId())
&& !registrarId.equals(contact.getTransferData().getLosingRegistrarId())) {
throw new NotAuthorizedToViewTransferException();
}
return responseBuilder
@@ -14,7 +14,7 @@
package google.registry.flows.contact;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyHasPendingTransfer;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
@@ -29,7 +29,7 @@ import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
import google.registry.flows.annotations.ReportingSpec;
@@ -63,7 +63,7 @@ public final class ContactTransferRejectFlow implements TransactionalFlow {
@Inject ExtensionManager extensionManager;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject ContactHistory.Builder historyBuilder;
@Inject EppResponse.Builder responseBuilder;
@@ -73,14 +73,14 @@ public final class ContactTransferRejectFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
DateTime now = tm().getTransactionTime();
ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now);
verifyOptionalAuthInfo(authInfo, existingContact);
verifyHasPendingTransfer(existingContact);
verifyResourceOwnership(clientId, existingContact);
verifyResourceOwnership(registrarId, existingContact);
ContactResource newContact =
denyPendingTransfer(existingContact, TransferStatus.CLIENT_REJECTED, now, clientId);
denyPendingTransfer(existingContact, TransferStatus.CLIENT_REJECTED, now, registrarId);
ContactHistory contactHistory =
historyBuilder.setType(CONTACT_TRANSFER_REJECT).setContact(newContact).build();
PollMessage gainingPollMessage =
@@ -15,7 +15,7 @@
package google.registry.flows.contact;
import static google.registry.flows.FlowUtils.createHistoryKey;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyAuthInfo;
import static google.registry.flows.ResourceFlowUtils.verifyAuthInfoPresentForResourceTransfer;
@@ -32,7 +32,7 @@ import com.googlecode.objectify.Key;
import google.registry.config.RegistryConfig.Config;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
import google.registry.flows.annotations.ReportingSpec;
@@ -80,7 +80,7 @@ public final class ContactTransferRequestFlow implements TransactionalFlow {
@Inject ExtensionManager extensionManager;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String gainingClientId;
@Inject @RegistrarId String gainingClientId;
@Inject @TargetId String targetId;
@Inject @Config("contactAutomaticTransferLength") Duration automaticTransferLength;
@@ -93,7 +93,7 @@ public final class ContactTransferRequestFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(gainingClientId);
validateRegistrarIsLoggedIn(gainingClientId);
DateTime now = tm().getTransactionTime();
ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now);
verifyAuthInfoPresentForResourceTransfer(authInfo);
@@ -102,7 +102,7 @@ public final class ContactTransferRequestFlow implements TransactionalFlow {
if (TransferStatus.PENDING.equals(existingContact.getTransferData().getTransferStatus())) {
throw new AlreadyPendingTransferException(targetId);
}
String losingClientId = existingContact.getCurrentSponsorClientId();
String losingClientId = existingContact.getCurrentSponsorRegistrarId();
// Verify that this client doesn't already sponsor this resource.
if (gainingClientId.equals(losingClientId)) {
throw new ObjectAlreadySponsoredException();
@@ -114,8 +114,8 @@ public final class ContactTransferRequestFlow implements TransactionalFlow {
new ContactTransferData.Builder()
.setTransferRequestTime(now)
.setTransferRequestTrid(trid)
.setGainingClientId(gainingClientId)
.setLosingClientId(losingClientId)
.setGainingRegistrarId(gainingClientId)
.setLosingRegistrarId(losingClientId)
.setPendingTransferExpirationTime(transferExpirationTime)
.setTransferStatus(TransferStatus.SERVER_APPROVED)
.build();
@@ -15,7 +15,7 @@
package google.registry.flows.contact;
import static com.google.common.collect.Sets.union;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.checkSameValuesNotAddedAndRemoved;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyAllStatusesAreClientSettable;
@@ -30,7 +30,7 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import com.google.common.collect.ImmutableSet;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
@@ -79,7 +79,7 @@ public final class ContactUpdateFlow implements TransactionalFlow {
@Inject ResourceCommand resourceCommand;
@Inject ExtensionManager extensionManager;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject @Superuser boolean isSuperuser;
@Inject ContactHistory.Builder historyBuilder;
@@ -90,7 +90,7 @@ public final class ContactUpdateFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
Update command = (Update) resourceCommand;
DateTime now = tm().getTransactionTime();
ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now);
@@ -98,7 +98,7 @@ public final class ContactUpdateFlow implements TransactionalFlow {
ImmutableSet<StatusValue> statusToRemove = command.getInnerRemove().getStatusValues();
ImmutableSet<StatusValue> statusesToAdd = command.getInnerAdd().getStatusValues();
if (!isSuperuser) { // The superuser can update any contact and set any status.
verifyResourceOwnership(clientId, existingContact);
verifyResourceOwnership(registrarId, existingContact);
verifyAllStatusesAreClientSettable(union(statusesToAdd, statusToRemove));
}
verifyNoDisallowedStatuses(existingContact, DISALLOWED_STATUSES);
@@ -125,17 +125,18 @@ public final class ContactUpdateFlow implements TransactionalFlow {
builder.setInternationalizedPostalInfo(null);
}
}
ContactResource newContact = builder
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(clientId)
.setAuthInfo(preferFirst(change.getAuthInfo(), existingContact.getAuthInfo()))
.setDisclose(preferFirst(change.getDisclose(), existingContact.getDisclose()))
.setEmailAddress(preferFirst(change.getEmail(), existingContact.getEmailAddress()))
.setFaxNumber(preferFirst(change.getFax(), existingContact.getFaxNumber()))
.setVoiceNumber(preferFirst(change.getVoice(), existingContact.getVoiceNumber()))
.addStatusValues(statusesToAdd)
.removeStatusValues(statusToRemove)
.build();
ContactResource newContact =
builder
.setLastEppUpdateTime(now)
.setLastEppUpdateRegistrarId(registrarId)
.setAuthInfo(preferFirst(change.getAuthInfo(), existingContact.getAuthInfo()))
.setDisclose(preferFirst(change.getDisclose(), existingContact.getDisclose()))
.setEmailAddress(preferFirst(change.getEmail(), existingContact.getEmailAddress()))
.setFaxNumber(preferFirst(change.getFax(), existingContact.getFaxNumber()))
.setVoiceNumber(preferFirst(change.getVoice(), existingContact.getVoiceNumber()))
.addStatusValues(statusesToAdd)
.removeStatusValues(statusToRemove)
.build();
// If the resource is marked with clientUpdateProhibited, and this update did not clear that
// status, then the update must be disallowed (unless a superuser is requesting the change).
if (!isSuperuser
@@ -56,10 +56,10 @@ public class DomainCreateFlowCustomLogic extends BaseFlowCustomLogic {
/**
* A hook that runs before new entities are persisted, allowing them to be changed.
*
* <p>It returns the actual entity changes that should be persisted to Datastore. It is important
* to be careful when changing the flow behavior for existing entities, because the core logic
* across many different flows expects the existence of these entities and many of the fields on
* them.
* <p>It returns the actual entity changes that should be persisted to the database. It is
* important to be careful when changing the flow behavior for existing entities, because the core
* logic across many different flows expects the existence of these entities and many of the
* fields on them.
*/
@SuppressWarnings("unused")
public EntityChanges beforeSave(BeforeSaveParameters parameters) throws EppException {
@@ -54,10 +54,10 @@ public class DomainDeleteFlowCustomLogic extends BaseFlowCustomLogic {
/**
* A hook that runs before new entities are persisted, allowing them to be changed.
*
* <p>It returns the actual entity changes that should be persisted to Datastore. It is important
* to be careful when changing the flow behavior for existing entities, because the core logic
* across many different flows expects the existence of these entities and many of the fields on
* them.
* <p>It returns the actual entity changes that should be persisted to the database. It is
* important to be careful when changing the flow behavior for existing entities, because the core
* logic across many different flows expects the existence of these entities and many of the
* fields on them.
*/
@SuppressWarnings("unused")
public EntityChanges beforeSave(BeforeSaveParameters parameters) throws EppException {
@@ -55,10 +55,10 @@ public class DomainRenewFlowCustomLogic extends BaseFlowCustomLogic {
/**
* A hook that runs before new entities are persisted, allowing them to be changed.
*
* <p>It returns the actual entity changes that should be persisted to Datastore. It is important
* to be careful when changing the flow behavior for existing entities, because the core logic
* across many different flows expects the existence of these entities and many of the fields on
* them.
* <p>It returns the actual entity changes that should be persisted to the database. It is
* important to be careful when changing the flow behavior for existing entities, because the core
* logic across many different flows expects the existence of these entities and many of the
* fields on them.
*/
@SuppressWarnings("unused")
public EntityChanges beforeSave(BeforeSaveParameters parameters) throws EppException {
@@ -51,10 +51,10 @@ public class DomainUpdateFlowCustomLogic extends BaseFlowCustomLogic {
/**
* A hook that runs before new entities are persisted, allowing them to be changed.
*
* <p>It returns the actual entity changes that should be persisted to Datastore. It is important
* to be careful when changing the flow behavior for existing entities, because the core logic
* across many different flows expects the existence of these entities and many of the fields on
* them.
* <p>It returns the actual entity changes that should be persisted to the database. It is
* important to be careful when changing the flow behavior for existing entities, because the core
* logic across many different flows expects the existence of these entities and many of the
* fields on them.
*/
@SuppressWarnings("unused")
public EntityChanges beforeSave(BeforeSaveParameters parameters) throws EppException {
@@ -19,7 +19,7 @@ import com.google.common.collect.ImmutableSet;
import google.registry.model.ImmutableObject;
import google.registry.persistence.VKey;
/** A wrapper class that encapsulates Datastore entities to both save and delete. */
/** A wrapper class that encapsulates database entities to both save and delete. */
@AutoValue
public abstract class EntityChanges {
@@ -17,7 +17,7 @@ package google.registry.flows.domain;
import static com.google.common.base.Strings.emptyToNull;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.getReservationTypes;
@@ -41,7 +41,7 @@ import google.registry.flows.EppException;
import google.registry.flows.EppException.ParameterValuePolicyErrorException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.custom.DomainCheckFlowCustomLogic;
@@ -113,7 +113,7 @@ public final class DomainCheckFlow implements Flow {
@Inject ResourceCommand resourceCommand;
@Inject ExtensionManager extensionManager;
@Inject EppInput eppInput;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject
@Config("maxChecks")
@@ -135,7 +135,7 @@ public final class DomainCheckFlow implements Flow {
FeeCheckCommandExtension.class, LaunchCheckExtension.class, AllocationTokenExtension.class);
flowCustomLogic.beforeValidation();
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
ImmutableList<String> domainNames = ((Check) resourceCommand).getTargetIds();
verifyTargetIdCount(domainNames, maxChecks);
DateTime now = clock.nowUtc();
@@ -151,7 +151,7 @@ public final class DomainCheckFlow implements Flow {
String tld = parsedDomain.parent().toString();
boolean tldFirstTimeSeen = seenTlds.add(tld);
if (tldFirstTimeSeen && !isSuperuser) {
checkAllowedAccessToTld(clientId, tld);
checkAllowedAccessToTld(registrarId, tld);
verifyNotInPredelegation(Registry.get(tld), now);
}
}
@@ -172,7 +172,7 @@ public final class DomainCheckFlow implements Flow {
allocationTokenFlowUtils.checkDomainsWithToken(
ImmutableList.copyOf(parsedDomains.values()),
tokenExtension.getAllocationToken(),
clientId,
registrarId,
now));
ImmutableList.Builder<DomainCheck> checksBuilder = new ImmutableList.Builder<>();
@@ -14,7 +14,7 @@
package google.registry.flows.domain;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.validateDomainName;
@@ -31,7 +31,7 @@ import google.registry.flows.EppException;
import google.registry.flows.EppException.CommandUseErrorException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.model.domain.DomainCommand.Check;
@@ -69,7 +69,7 @@ public final class DomainClaimsCheckFlow implements Flow {
@Inject ExtensionManager extensionManager;
@Inject EppInput eppInput;
@Inject ResourceCommand resourceCommand;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @Superuser boolean isSuperuser;
@Inject Clock clock;
@Inject @Config("maxChecks") int maxChecks;
@@ -82,7 +82,7 @@ public final class DomainClaimsCheckFlow implements Flow {
public EppResponse run() throws EppException {
extensionManager.register(LaunchCheckExtension.class, AllocationTokenExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
if (eppInput.getSingleExtension(AllocationTokenExtension.class).isPresent()) {
throw new DomainClaimsCheckNotAllowedWithAllocationTokens();
}
@@ -97,7 +97,7 @@ public final class DomainClaimsCheckFlow implements Flow {
// Only validate access to a TLD the first time it is encountered.
if (seenTlds.add(tld)) {
if (!isSuperuser) {
checkAllowedAccessToTld(clientId, tld);
checkAllowedAccessToTld(registrarId, tld);
Registry registry = Registry.get(tld);
DateTime now = clock.nowUtc();
verifyNotInPredelegation(registry, now);
@@ -16,7 +16,7 @@ package google.registry.flows.domain;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.flows.FlowUtils.persistEntityChanges;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyResourceDoesNotExist;
import static google.registry.flows.domain.DomainFlowUtils.COLLISION_MESSAGE;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
@@ -62,7 +62,7 @@ import google.registry.flows.EppException;
import google.registry.flows.EppException.CommandUseErrorException;
import google.registry.flows.EppException.ParameterValuePolicyErrorException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
@@ -204,7 +204,7 @@ public class DomainCreateFlow implements TransactionalFlow {
@Inject ExtensionManager extensionManager;
@Inject EppInput eppInput;
@Inject ResourceCommand resourceCommand;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject @Superuser boolean isSuperuser;
@Inject DomainHistory.Builder historyBuilder;
@@ -226,15 +226,15 @@ public class DomainCreateFlow implements TransactionalFlow {
AllocationTokenExtension.class);
flowCustomLogic.beforeValidation();
extensionManager.validate();
validateClientIsLoggedIn(clientId);
verifyRegistrarIsActive(clientId);
validateRegistrarIsLoggedIn(registrarId);
verifyRegistrarIsActive(registrarId);
DateTime now = tm().getTransactionTime();
DomainCommand.Create command = cloneAndLinkReferences((Create) resourceCommand, now);
Period period = command.getPeriod();
verifyUnitIsYears(period);
int years = period.getValue();
validateRegistrationPeriod(years);
verifyResourceDoesNotExist(DomainBase.class, targetId, now, clientId);
verifyResourceDoesNotExist(DomainBase.class, targetId, now, registrarId);
// Validate that this is actually a legal domain name on a TLD that the registrar has access to.
InternetDomainName domainName = validateDomainName(command.getFullyQualifiedDomainName());
String domainLabel = domainName.parts().get(0);
@@ -252,7 +252,7 @@ public class DomainCreateFlow implements TransactionalFlow {
}
boolean isSunriseCreate = hasSignedMarks && (tldState == START_DATE_SUNRISE);
Optional<AllocationToken> allocationToken =
verifyAllocationTokenIfPresent(command, registry, clientId, now);
verifyAllocationTokenIfPresent(command, registry, registrarId, now);
boolean isAnchorTenant =
isAnchorTenant(
domainName, allocationToken, eppInput.getSingleExtension(MetadataExtension.class));
@@ -261,7 +261,7 @@ public class DomainCreateFlow implements TransactionalFlow {
// notice without specifying a claims key, ignore the registry phase, and override blocks on
// registering premium domains.
if (!isSuperuser) {
checkAllowedAccessToTld(clientId, registry.getTldStr());
checkAllowedAccessToTld(registrarId, registry.getTldStr());
boolean isValidReservedCreate = isValidReservedCreate(domainName, allocationToken);
verifyIsGaOrIsSpecialCase(tldState, isAnchorTenant, isValidReservedCreate, hasSignedMarks);
if (launchCreate.isPresent()) {
@@ -276,7 +276,7 @@ public class DomainCreateFlow implements TransactionalFlow {
if (now.isBefore(registry.getClaimsPeriodEnd())) {
verifyClaimsNoticeIfAndOnlyIfNeeded(domainName, hasSignedMarks, hasClaimsNotice);
}
verifyPremiumNameIsNotBlocked(targetId, now, clientId);
verifyPremiumNameIsNotBlocked(targetId, now, registrarId);
verifySignedMarkOnlyInSunrise(hasSignedMarks, tldState);
}
String signedMarkId = null;
@@ -338,8 +338,8 @@ public class DomainCreateFlow implements TransactionalFlow {
: ImmutableSet.of();
DomainBase domain =
new DomainBase.Builder()
.setCreationClientId(clientId)
.setPersistedCurrentSponsorClientId(clientId)
.setCreationRegistrarId(registrarId)
.setPersistedCurrentSponsorRegistrarId(registrarId)
.setRepoId(repoId)
.setIdnTableName(validateDomainNameWithIdnTables(domainName))
.setRegistrationExpirationTime(registrationExpirationTime)
@@ -361,7 +361,7 @@ public class DomainCreateFlow implements TransactionalFlow {
buildDomainHistory(domain, registry, now, period, registry.getAddGracePeriodLength());
if (reservationTypes.contains(NAME_COLLISION)) {
entitiesToSave.add(
createNameCollisionOneTimePollMessage(targetId, domainHistory, clientId, now));
createNameCollisionOneTimePollMessage(targetId, domainHistory, registrarId, now));
}
entitiesToSave.add(
domain,
@@ -472,14 +472,14 @@ public class DomainCreateFlow implements TransactionalFlow {
/** Verifies and returns the allocation token if one is specified, otherwise does nothing. */
private Optional<AllocationToken> verifyAllocationTokenIfPresent(
DomainCommand.Create command, Registry registry, String clientId, DateTime now)
DomainCommand.Create command, Registry registry, String registrarId, DateTime now)
throws EppException {
Optional<AllocationTokenExtension> extension =
eppInput.getSingleExtension(AllocationTokenExtension.class);
return Optional.ofNullable(
extension.isPresent()
? allocationTokenFlowUtils.loadTokenAndValidateDomainCreate(
command, extension.get().getAllocationToken(), registry, clientId, now)
command, extension.get().getAllocationToken(), registry, registrarId, now)
: null);
}
@@ -524,7 +524,7 @@ public class DomainCreateFlow implements TransactionalFlow {
return new BillingEvent.OneTime.Builder()
.setReason(Reason.CREATE)
.setTargetId(targetId)
.setClientId(clientId)
.setRegistrarId(registrarId)
.setPeriodYears(years)
.setCost(feesAndCredits.getCreateCost())
.setEventTime(now)
@@ -545,7 +545,7 @@ public class DomainCreateFlow implements TransactionalFlow {
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(targetId)
.setClientId(clientId)
.setRegistrarId(registrarId)
.setEventTime(registrationExpirationTime)
.setRecurrenceEndTime(END_OF_TIME)
.setParent(domainHistoryKey)
@@ -556,7 +556,7 @@ public class DomainCreateFlow implements TransactionalFlow {
Key<DomainHistory> domainHistoryKey, DateTime registrationExpirationTime) {
return new PollMessage.Autorenew.Builder()
.setTargetId(targetId)
.setClientId(clientId)
.setRegistrarId(registrarId)
.setEventTime(registrationExpirationTime)
.setMsg("Domain was auto-renewed.")
.setParentKey(domainHistoryKey)
@@ -568,7 +568,7 @@ public class DomainCreateFlow implements TransactionalFlow {
return new BillingEvent.OneTime.Builder()
.setReason(Reason.FEE_EARLY_ACCESS)
.setTargetId(createBillingEvent.getTargetId())
.setClientId(createBillingEvent.getClientId())
.setRegistrarId(createBillingEvent.getRegistrarId())
.setPeriodYears(1)
.setCost(feesAndCredits.getEapCost())
.setEventTime(createBillingEvent.getEventTime())
@@ -579,9 +579,12 @@ public class DomainCreateFlow implements TransactionalFlow {
}
private static PollMessage.OneTime createNameCollisionOneTimePollMessage(
String fullyQualifiedDomainName, HistoryEntry historyEntry, String clientId, DateTime now) {
String fullyQualifiedDomainName,
HistoryEntry historyEntry,
String registrarId,
DateTime now) {
return new PollMessage.OneTime.Builder()
.setClientId(clientId)
.setRegistrarId(registrarId)
.setEventTime(now)
.setMsg(COLLISION_MESSAGE) // Remind the registrar of the name collision policy.
.setResponseData(
@@ -18,7 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static google.registry.flows.FlowUtils.createHistoryKey;
import static google.registry.flows.FlowUtils.persistEntityChanges;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyNoDisallowedStatuses;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
@@ -50,7 +50,7 @@ import google.registry.dns.DnsQueue;
import google.registry.flows.EppException;
import google.registry.flows.EppException.AssociationProhibitsOperationException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.SessionMetadata;
@@ -124,7 +124,7 @@ public final class DomainDeleteFlow implements TransactionalFlow {
@Inject EppInput eppInput;
@Inject SessionMetadata sessionMetadata;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject @Superuser boolean isSuperuser;
@Inject DomainHistory.Builder historyBuilder;
@@ -141,7 +141,7 @@ public final class DomainDeleteFlow implements TransactionalFlow {
MetadataExtension.class, SecDnsCreateExtension.class, DomainDeleteSuperuserExtension.class);
flowCustomLogic.beforeValidation();
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
DateTime now = tm().getTransactionTime();
// Loads the target resource if it exists
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
@@ -153,12 +153,12 @@ public final class DomainDeleteFlow implements TransactionalFlow {
DomainBase.Builder builder;
if (existingDomain.getStatusValues().contains(StatusValue.PENDING_TRANSFER)) {
builder =
denyPendingTransfer(existingDomain, TransferStatus.SERVER_CANCELLED, now, clientId)
denyPendingTransfer(existingDomain, TransferStatus.SERVER_CANCELLED, now, registrarId)
.asBuilder();
} else {
builder = existingDomain.asBuilder();
}
builder.setLastEppUpdateTime(now).setLastEppUpdateClientId(clientId);
builder.setLastEppUpdateTime(now).setLastEppUpdateRegistrarId(registrarId);
Duration redemptionGracePeriodLength = registry.getRedemptionGracePeriodLength();
Duration pendingDeleteLength = registry.getPendingDeleteLength();
Optional<DomainDeleteSuperuserExtension> domainDeleteSuperuserExtension =
@@ -199,7 +199,7 @@ public final class DomainDeleteFlow implements TransactionalFlow {
GracePeriodStatus.REDEMPTION,
existingDomain.getRepoId(),
redemptionTime,
clientId)));
registrarId)));
// Note: The expiration time is unchanged, so if it's before the new deletion time, there will
// be a "phantom autorenew" where the expiration time advances. No poll message will be
// produced (since we are ending the autorenew recurrences at "now" below) and the billing
@@ -220,7 +220,7 @@ public final class DomainDeleteFlow implements TransactionalFlow {
// Send a second poll message immediately if the domain is being deleted asynchronously by a
// registrar other than the sponsoring registrar (which will necessarily be a superuser).
if (durationUntilDelete.isLongerThan(Duration.ZERO)
&& !clientId.equals(existingDomain.getPersistedCurrentSponsorClientId())) {
&& !registrarId.equals(existingDomain.getPersistedCurrentSponsorRegistrarId())) {
entitiesToSave.add(
createImmediateDeletePollMessage(existingDomain, domainHistoryKey, now, deletionTime));
}
@@ -292,9 +292,9 @@ public final class DomainDeleteFlow implements TransactionalFlow {
verifyNoDisallowedStatuses(existingDomain, DISALLOWED_STATUSES);
verifyOptionalAuthInfo(authInfo, existingDomain);
if (!isSuperuser) {
verifyResourceOwnership(clientId, existingDomain);
verifyResourceOwnership(registrarId, existingDomain);
verifyNotInPredelegation(registry, now);
checkAllowedAccessToTld(clientId, registry.getTld().toString());
checkAllowedAccessToTld(registrarId, registry.getTld().toString());
}
if (!existingDomain.getSubordinateHosts().isEmpty()) {
throw new DomainToDeleteHasHostsException();
@@ -347,7 +347,7 @@ public final class DomainDeleteFlow implements TransactionalFlow {
: "Deleted by registry administrator.")
: "Domain deleted.";
return new PollMessage.OneTime.Builder()
.setClientId(existingDomain.getCurrentSponsorClientId())
.setRegistrarId(existingDomain.getCurrentSponsorRegistrarId())
.setEventTime(deletionTime)
.setMsg(message)
.setResponseData(
@@ -364,7 +364,7 @@ public final class DomainDeleteFlow implements TransactionalFlow {
DateTime now,
DateTime deletionTime) {
return new PollMessage.OneTime.Builder()
.setClientId(existingDomain.getPersistedCurrentSponsorClientId())
.setRegistrarId(existingDomain.getPersistedCurrentSponsorRegistrarId())
.setEventTime(now)
.setParentKey(domainHistoryKey)
.setMsg(
@@ -285,8 +285,8 @@ public class DomainFlowUtils {
}
/** Check if the registrar running the flow has access to the TLD in question. */
public static void checkAllowedAccessToTld(String clientId, String tld) throws EppException {
if (!Registrar.loadByClientIdCached(clientId).get().getAllowedTlds().contains(tld)) {
public static void checkAllowedAccessToTld(String registrarId, String tld) throws EppException {
if (!Registrar.loadByRegistrarIdCached(registrarId).get().getAllowedTlds().contains(tld)) {
throw new DomainFlowUtils.NotAuthorizedForTldException(tld);
}
}
@@ -464,10 +464,10 @@ public class DomainFlowUtils {
* where it would not be allowed is if domain name is premium, and premium names are blocked by
* this registrar.
*/
static void verifyPremiumNameIsNotBlocked(String domainName, DateTime priceTime, String clientId)
throws EppException {
static void verifyPremiumNameIsNotBlocked(
String domainName, DateTime priceTime, String registrarId) throws EppException {
if (isDomainPremium(domainName, priceTime)) {
if (Registrar.loadByClientIdCached(clientId).get().getBlockPremiumNames()) {
if (Registrar.loadByRegistrarIdCached(registrarId).get().getBlockPremiumNames()) {
throw new PremiumNameBlockedException();
}
}
@@ -495,7 +495,7 @@ public class DomainFlowUtils {
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(domain.getDomainName())
.setClientId(domain.getCurrentSponsorClientId())
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
.setEventTime(domain.getRegistrationExpirationTime());
}
@@ -506,7 +506,7 @@ public class DomainFlowUtils {
public static PollMessage.Autorenew.Builder newAutorenewPollMessage(DomainBase domain) {
return new PollMessage.Autorenew.Builder()
.setTargetId(domain.getDomainName())
.setClientId(domain.getCurrentSponsorClientId())
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
.setEventTime(domain.getRegistrationExpirationTime())
.setMsg("Domain was auto-renewed.");
}
@@ -896,9 +896,9 @@ public class DomainFlowUtils {
* <p>Non-active registrars are not allowed to run operations that cost money, like domain creates
* or renews.
*/
static void verifyRegistrarIsActive(String clientId)
static void verifyRegistrarIsActive(String registrarId)
throws RegistrarMustBeActiveForThisOperationException {
Registrar registrar = Registrar.loadByClientIdCached(clientId).get();
Registrar registrar = Registrar.loadByRegistrarIdCached(registrarId).get();
if (registrar.getState() != State.ACTIVE) {
throw new RegistrarMustBeActiveForThisOperationException();
}
@@ -1097,10 +1097,11 @@ public class DomainFlowUtils {
} else {
return jpaTm()
.query(
"FROM DomainHistory WHERE modificationTime >= :beginning "
+ "ORDER BY modificationTime ASC",
"FROM DomainHistory WHERE modificationTime >= :beginning AND domainRepoId = "
+ ":repoId ORDER BY modificationTime ASC",
DomainHistory.class)
.setParameter("beginning", now.minus(maxSearchPeriod))
.setParameter("repoId", domainBase.getRepoId())
.getResultList();
}
}
@@ -14,7 +14,7 @@
package google.registry.flows.domain;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
import static google.registry.flows.domain.DomainFlowUtils.addSecDnsExtensionIfPresent;
@@ -30,7 +30,7 @@ import com.google.common.net.InternetDomainName;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.custom.DomainInfoFlowCustomLogic;
@@ -79,7 +79,7 @@ public final class DomainInfoFlow implements Flow {
@Inject ResourceCommand resourceCommand;
@Inject EppInput eppInput;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject Clock clock;
@Inject EppResponse.Builder responseBuilder;
@@ -94,7 +94,7 @@ public final class DomainInfoFlow implements Flow {
extensionManager.register(FeeInfoCommandExtensionV06.class);
flowCustomLogic.beforeValidation();
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
DateTime now = clock.nowUtc();
DomainBase domain = verifyExistence(
DomainBase.class, targetId, loadByForeignKey(DomainBase.class, targetId, now));
@@ -112,12 +112,12 @@ public final class DomainInfoFlow implements Flow {
DomainInfoData.newBuilder()
.setFullyQualifiedDomainName(domain.getDomainName())
.setRepoId(domain.getRepoId())
.setCurrentSponsorClientId(domain.getCurrentSponsorClientId())
.setCurrentSponsorClientId(domain.getCurrentSponsorRegistrarId())
.setRegistrant(
transactIfJpaTm(() -> tm().loadByKey(domain.getRegistrant())).getContactId());
// If authInfo is non-null, then the caller is authorized to see the full information since we
// will have already verified the authInfo is valid.
if (clientId.equals(domain.getCurrentSponsorClientId()) || authInfo.isPresent()) {
if (registrarId.equals(domain.getCurrentSponsorRegistrarId()) || authInfo.isPresent()) {
HostsRequest hostsRequest = ((Info) resourceCommand).getHostsRequest();
infoBuilder
.setStatusValues(domain.getStatusValues())
@@ -126,9 +126,9 @@ public final class DomainInfoFlow implements Flow {
.setNameservers(hostsRequest.requestDelegated() ? domain.loadNameserverHostNames() : null)
.setSubordinateHosts(
hostsRequest.requestSubordinate() ? domain.getSubordinateHosts() : null)
.setCreationClientId(domain.getCreationClientId())
.setCreationClientId(domain.getCreationRegistrarId())
.setCreationTime(domain.getCreationTime())
.setLastEppUpdateClientId(domain.getLastEppUpdateClientId())
.setLastEppUpdateClientId(domain.getLastEppUpdateRegistrarId())
.setLastEppUpdateTime(domain.getLastEppUpdateTime())
.setRegistrationExpirationTime(domain.getRegistrationExpirationTime())
.setLastTransferTime(domain.getLastTransferTime())
@@ -16,7 +16,7 @@ package google.registry.flows.domain;
import static google.registry.flows.FlowUtils.createHistoryKey;
import static google.registry.flows.FlowUtils.persistEntityChanges;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyNoDisallowedStatuses;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
@@ -39,7 +39,7 @@ import com.googlecode.objectify.Key;
import google.registry.flows.EppException;
import google.registry.flows.EppException.ParameterValueRangeErrorException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
@@ -123,7 +123,7 @@ public final class DomainRenewFlow implements TransactionalFlow {
@Inject ExtensionManager extensionManager;
@Inject EppInput eppInput;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject @Superuser boolean isSuperuser;
@Inject DomainHistory.Builder historyBuilder;
@@ -137,8 +137,8 @@ public final class DomainRenewFlow implements TransactionalFlow {
extensionManager.register(FeeRenewCommandExtension.class, MetadataExtension.class);
flowCustomLogic.beforeValidation();
extensionManager.validate();
validateClientIsLoggedIn(clientId);
verifyRegistrarIsActive(clientId);
validateRegistrarIsLoggedIn(registrarId);
verifyRegistrarIsActive(registrarId);
DateTime now = tm().getTransactionTime();
Renew command = (Renew) resourceCommand;
// Loads the target resource if it exists
@@ -182,7 +182,7 @@ public final class DomainRenewFlow implements TransactionalFlow {
existingDomain
.asBuilder()
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(clientId)
.setLastEppUpdateRegistrarId(registrarId)
.setRegistrationExpirationTime(newExpirationTime)
.setAutorenewBillingEvent(newAutorenewEvent.createVKey())
.setAutorenewPollMessage(newAutorenewPollMessage.createVKey())
@@ -250,8 +250,8 @@ public final class DomainRenewFlow implements TransactionalFlow {
verifyOptionalAuthInfo(authInfo, existingDomain);
verifyNoDisallowedStatuses(existingDomain, RENEW_DISALLOWED_STATUSES);
if (!isSuperuser) {
verifyResourceOwnership(clientId, existingDomain);
checkAllowedAccessToTld(clientId, existingDomain.getTld());
verifyResourceOwnership(registrarId, existingDomain);
checkAllowedAccessToTld(registrarId, existingDomain.getTld());
}
verifyUnitIsYears(command.getPeriod());
// If the date they specify doesn't match the expiration, fail. (This is an idempotence check).
@@ -266,7 +266,7 @@ public final class DomainRenewFlow implements TransactionalFlow {
return new BillingEvent.OneTime.Builder()
.setReason(Reason.RENEW)
.setTargetId(targetId)
.setClientId(clientId)
.setRegistrarId(registrarId)
.setPeriodYears(years)
.setCost(renewCost)
.setEventTime(now)
@@ -15,7 +15,7 @@
package google.registry.flows.domain;
import static google.registry.flows.FlowUtils.createHistoryKey;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
@@ -40,7 +40,7 @@ import google.registry.flows.EppException;
import google.registry.flows.EppException.CommandUseErrorException;
import google.registry.flows.EppException.StatusProhibitsOperationException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
@@ -116,7 +116,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
@Inject ExtensionManager extensionManager;
@Inject EppInput eppInput;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject @Superuser boolean isSuperuser;
@Inject DomainHistory.Builder historyBuilder;
@@ -132,8 +132,8 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
MetadataExtension.class,
RgpUpdateExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
verifyRegistrarIsActive(clientId);
validateRegistrarIsLoggedIn(registrarId);
verifyRegistrarIsActive(registrarId);
Update command = (Update) resourceCommand;
DateTime now = tm().getTransactionTime();
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
@@ -174,7 +174,12 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
.build();
DomainBase newDomain =
performRestore(
existingDomain, newExpirationTime, autorenewEvent, autorenewPollMessage, now, clientId);
existingDomain,
newExpirationTime,
autorenewEvent,
autorenewPollMessage,
now,
registrarId);
updateForeignKeyIndexDeletionTime(newDomain);
DomainHistory domainHistory = buildDomainHistory(newDomain, now);
entitiesToSave.add(newDomain, domainHistory, autorenewEvent, autorenewPollMessage);
@@ -205,10 +210,10 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
DateTime now) throws EppException {
verifyOptionalAuthInfo(authInfo, existingDomain);
if (!isSuperuser) {
verifyResourceOwnership(clientId, existingDomain);
verifyResourceOwnership(registrarId, existingDomain);
verifyNotReserved(InternetDomainName.from(targetId), false);
verifyPremiumNameIsNotBlocked(targetId, now, clientId);
checkAllowedAccessToTld(clientId, existingDomain.getTld());
verifyPremiumNameIsNotBlocked(targetId, now, registrarId);
checkAllowedAccessToTld(registrarId, existingDomain.getTld());
}
// No other changes can be specified on a restore request.
if (!command.noChangesPresent()) {
@@ -227,7 +232,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
BillingEvent.Recurring autorenewEvent,
PollMessage.Autorenew autorenewPollMessage,
DateTime now,
String clientId) {
String registrarId) {
return existingDomain
.asBuilder()
.setRegistrationExpirationTime(newExpirationTime)
@@ -241,7 +246,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
// it won't immediately be deleted again.
.setAutorenewEndTime(Optional.empty())
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(clientId)
.setLastEppUpdateRegistrarId(registrarId)
.build();
}
@@ -261,7 +266,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
Key<DomainHistory> domainHistoryKey, Money cost, DateTime now) {
return new BillingEvent.OneTime.Builder()
.setTargetId(targetId)
.setClientId(clientId)
.setRegistrarId(registrarId)
.setEventTime(now)
.setBillingTime(now)
.setPeriodYears(1)
@@ -16,7 +16,7 @@ package google.registry.flows.domain;
import static com.google.common.collect.Iterables.getOnlyElement;
import static google.registry.flows.FlowUtils.createHistoryKey;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.computeExDateForApprovalTime;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyHasPendingTransfer;
@@ -40,7 +40,7 @@ import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
@@ -89,7 +89,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
@Inject ExtensionManager extensionManager;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject @Superuser boolean isSuperuser;
@Inject DomainHistory.Builder historyBuilder;
@@ -104,18 +104,18 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
DateTime now = tm().getTransactionTime();
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
verifyOptionalAuthInfo(authInfo, existingDomain);
verifyHasPendingTransfer(existingDomain);
verifyResourceOwnership(clientId, existingDomain);
verifyResourceOwnership(registrarId, existingDomain);
String tld = existingDomain.getTld();
if (!isSuperuser) {
checkAllowedAccessToTld(clientId, tld);
checkAllowedAccessToTld(registrarId, tld);
}
DomainTransferData transferData = existingDomain.getTransferData();
String gainingClientId = transferData.getGainingClientId();
String gainingRegistrarId = transferData.getGainingRegistrarId();
// Create a transfer billing event for 1 year, unless the superuser extension was used to set
// the transfer period to zero. There is not a transfer cost if the transfer period is zero.
Key<DomainHistory> domainHistoryKey = createHistoryKey(existingDomain, DomainHistory.class);
@@ -127,7 +127,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
new BillingEvent.OneTime.Builder()
.setReason(Reason.TRANSFER)
.setTargetId(targetId)
.setClientId(gainingClientId)
.setRegistrarId(gainingRegistrarId)
.setPeriodYears(1)
.setCost(getDomainRenewCost(targetId, transferData.getTransferRequestTime(), 1))
.setEventTime(now)
@@ -162,7 +162,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(targetId)
.setClientId(gainingClientId)
.setRegistrarId(gainingRegistrarId)
.setEventTime(newExpirationTime)
.setRecurrenceEndTime(END_OF_TIME)
.setParent(domainHistoryKey)
@@ -171,7 +171,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
PollMessage.Autorenew gainingClientAutorenewPollMessage =
new PollMessage.Autorenew.Builder()
.setTargetId(targetId)
.setClientId(gainingClientId)
.setRegistrarId(gainingRegistrarId)
.setEventTime(newExpirationTime)
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
@@ -206,10 +206,10 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
oneTime)))
.orElseGet(ImmutableSet::of))
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(clientId)
.setLastEppUpdateRegistrarId(registrarId)
.build();
Registry registry = Registry.get(existingDomain.getTld());
DomainHistory domainHistory = buildDomainHistory(newDomain, registry, now, gainingClientId);
DomainHistory domainHistory = buildDomainHistory(newDomain, registry, now, gainingRegistrarId);
// Create a poll message for the gaining client.
PollMessage gainingClientPollMessage =
createGainingTransferPollMessage(
@@ -232,7 +232,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
}
private DomainHistory buildDomainHistory(
DomainBase newDomain, Registry registry, DateTime now, String gainingClientId) {
DomainBase newDomain, Registry registry, DateTime now, String gainingRegistrarId) {
ImmutableSet<DomainTransactionRecord> cancelingRecords =
createCancelingRecords(
newDomain,
@@ -241,7 +241,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
ImmutableSet.of(TRANSFER_SUCCESSFUL));
return historyBuilder
.setType(DOMAIN_TRANSFER_APPROVE)
.setOtherClientId(gainingClientId)
.setOtherRegistrarId(gainingRegistrarId)
.setDomain(newDomain)
.setDomainTransactionRecords(
union(
@@ -15,7 +15,7 @@
package google.registry.flows.domain;
import static google.registry.flows.FlowUtils.createHistoryKey;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyHasPendingTransfer;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
@@ -35,7 +35,7 @@ import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
@@ -76,7 +76,7 @@ public final class DomainTransferCancelFlow implements TransactionalFlow {
@Inject ExtensionManager extensionManager;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject @Superuser boolean isSuperuser;
@Inject DomainHistory.Builder historyBuilder;
@@ -87,24 +87,24 @@ public final class DomainTransferCancelFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
DateTime now = tm().getTransactionTime();
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
verifyOptionalAuthInfo(authInfo, existingDomain);
verifyHasPendingTransfer(existingDomain);
verifyTransferInitiator(clientId, existingDomain);
verifyTransferInitiator(registrarId, existingDomain);
if (!isSuperuser) {
checkAllowedAccessToTld(clientId, existingDomain.getTld());
checkAllowedAccessToTld(registrarId, existingDomain.getTld());
}
Registry registry = Registry.get(existingDomain.getTld());
Key<DomainHistory> domainHistoryKey = createHistoryKey(existingDomain, DomainHistory.class);
historyBuilder
.setId(domainHistoryKey.getId())
.setOtherClientId(existingDomain.getTransferData().getLosingClientId());
.setOtherRegistrarId(existingDomain.getTransferData().getLosingRegistrarId());
DomainBase newDomain =
denyPendingTransfer(existingDomain, TransferStatus.CLIENT_CANCELLED, now, clientId);
denyPendingTransfer(existingDomain, TransferStatus.CLIENT_CANCELLED, now, registrarId);
DomainHistory domainHistory = buildDomainHistory(newDomain, registry, now);
tm().putAll(
newDomain,
@@ -14,7 +14,7 @@
package google.registry.flows.domain;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
import static google.registry.flows.domain.DomainTransferUtils.createTransferResponse;
@@ -22,7 +22,7 @@ import static google.registry.flows.domain.DomainTransferUtils.createTransferRes
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.ResourceFlowUtils;
import google.registry.flows.annotations.ReportingSpec;
@@ -59,7 +59,7 @@ public final class DomainTransferQueryFlow implements Flow {
@Inject ExtensionManager extensionManager;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject Clock clock;
@Inject EppResponse.Builder responseBuilder;
@@ -68,7 +68,7 @@ public final class DomainTransferQueryFlow implements Flow {
@Override
public final EppResponse run() throws EppException {
extensionManager.validate(); // There are no legal extensions for this flow.
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
DateTime now = clock.nowUtc();
DomainBase domain = loadAndVerifyExistence(DomainBase.class, targetId, now);
verifyOptionalAuthInfo(authInfo, domain);
@@ -81,8 +81,8 @@ public final class DomainTransferQueryFlow implements Flow {
// Note that the authorization info on the command (if present) has already been verified. If
// it's present, then the other checks are unnecessary.
if (!authInfo.isPresent()
&& !clientId.equals(transferData.getGainingClientId())
&& !clientId.equals(transferData.getLosingClientId())) {
&& !registrarId.equals(transferData.getGainingRegistrarId())
&& !registrarId.equals(transferData.getLosingRegistrarId())) {
throw new NotAuthorizedToViewTransferException();
}
DateTime newExpirationTime = null;
@@ -15,7 +15,7 @@
package google.registry.flows.domain;
import static google.registry.flows.FlowUtils.createHistoryKey;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyHasPendingTransfer;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
@@ -37,7 +37,7 @@ import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
@@ -78,7 +78,7 @@ public final class DomainTransferRejectFlow implements TransactionalFlow {
@Inject ExtensionManager extensionManager;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject @Superuser boolean isSuperuser;
@Inject DomainHistory.Builder historyBuilder;
@@ -89,23 +89,23 @@ public final class DomainTransferRejectFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
DateTime now = tm().getTransactionTime();
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
Registry registry = Registry.get(existingDomain.getTld());
Key<DomainHistory> domainHistoryKey = createHistoryKey(existingDomain, DomainHistory.class);
historyBuilder
.setId(domainHistoryKey.getId())
.setOtherClientId(existingDomain.getTransferData().getGainingClientId());
.setOtherRegistrarId(existingDomain.getTransferData().getGainingRegistrarId());
verifyOptionalAuthInfo(authInfo, existingDomain);
verifyHasPendingTransfer(existingDomain);
verifyResourceOwnership(clientId, existingDomain);
verifyResourceOwnership(registrarId, existingDomain);
if (!isSuperuser) {
checkAllowedAccessToTld(clientId, existingDomain.getTld());
checkAllowedAccessToTld(registrarId, existingDomain.getTld());
}
DomainBase newDomain =
denyPendingTransfer(existingDomain, TransferStatus.CLIENT_REJECTED, now, clientId);
denyPendingTransfer(existingDomain, TransferStatus.CLIENT_REJECTED, now, registrarId);
DomainHistory domainHistory = buildDomainHistory(newDomain, registry, now);
tm().putAll(
newDomain,
@@ -15,7 +15,7 @@
package google.registry.flows.domain;
import static google.registry.flows.FlowUtils.createHistoryKey;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.computeExDateForApprovalTime;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyAuthInfo;
@@ -41,7 +41,7 @@ import com.googlecode.objectify.Key;
import google.registry.batch.AsyncTaskEnqueuer;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
@@ -125,7 +125,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
@Inject ExtensionManager extensionManager;
@Inject EppInput eppInput;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String gainingClientId;
@Inject @RegistrarId String gainingClientId;
@Inject @TargetId String targetId;
@Inject @Superuser boolean isSuperuser;
@Inject DomainHistory.Builder historyBuilder;
@@ -142,7 +142,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
FeeTransferCommandExtension.class,
MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(gainingClientId);
validateRegistrarIsLoggedIn(gainingClientId);
verifyRegistrarIsActive(gainingClientId);
DateTime now = tm().getTransactionTime();
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
@@ -174,7 +174,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
Key<DomainHistory> domainHistoryKey = createHistoryKey(existingDomain, DomainHistory.class);
historyBuilder
.setId(domainHistoryKey.getId())
.setOtherClientId(existingDomain.getCurrentSponsorClientId());
.setOtherRegistrarId(existingDomain.getCurrentSponsorRegistrarId());
DateTime automaticTransferTime =
superuserExtension.isPresent()
? now.plusDays(superuserExtension.get().getAutomaticTransferLength())
@@ -207,8 +207,8 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
new DomainTransferData.Builder()
.setTransferRequestTrid(trid)
.setTransferRequestTime(now)
.setGainingClientId(gainingClientId)
.setLosingClientId(existingDomain.getCurrentSponsorClientId())
.setGainingRegistrarId(gainingClientId)
.setLosingRegistrarId(existingDomain.getCurrentSponsorRegistrarId())
.setPendingTransferExpirationTime(automaticTransferTime)
.setTransferredRegistrationExpirationTime(serverApproveNewExpirationTime),
serverApproveEntities,
@@ -231,7 +231,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
.setTransferData(pendingTransferData)
.addStatusValue(StatusValue.PENDING_TRANSFER)
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(gainingClientId)
.setLastEppUpdateRegistrarId(gainingClientId)
.build();
DomainHistory domainHistory = buildDomainHistory(newDomain, registry, now, period);
@@ -264,7 +264,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
throw new AlreadyPendingTransferException(targetId);
}
// Verify that this client doesn't already sponsor this resource.
if (gainingClientId.equals(existingDomain.getCurrentSponsorClientId())) {
if (gainingClientId.equals(existingDomain.getCurrentSponsorRegistrarId())) {
throw new ObjectAlreadySponsoredException();
}
verifyTransferPeriod(period, superuserExtension);
@@ -108,7 +108,7 @@ public final class DomainTransferUtils {
Key<DomainHistory> domainHistoryKey,
DomainBase existingDomain,
Trid trid,
String gainingClientId,
String gainingRegistrarId,
Optional<Money> transferCost,
DateTime now) {
String targetId = existingDomain.getDomainName();
@@ -117,8 +117,8 @@ public final class DomainTransferUtils {
new DomainTransferData.Builder()
.setTransferRequestTrid(trid)
.setTransferRequestTime(now)
.setGainingClientId(gainingClientId)
.setLosingClientId(existingDomain.getCurrentSponsorClientId())
.setGainingRegistrarId(gainingRegistrarId)
.setLosingRegistrarId(existingDomain.getCurrentSponsorRegistrarId())
.setPendingTransferExpirationTime(automaticTransferTime)
.setTransferredRegistrationExpirationTime(serverApproveNewExpirationTime)
.setTransferStatus(TransferStatus.SERVER_APPROVED)
@@ -132,7 +132,7 @@ public final class DomainTransferUtils {
automaticTransferTime,
domainHistoryKey,
targetId,
gainingClientId,
gainingRegistrarId,
registry,
cost)));
createOptionalAutorenewCancellation(
@@ -141,10 +141,10 @@ public final class DomainTransferUtils {
return builder
.add(
createGainingClientAutorenewEvent(
serverApproveNewExpirationTime, domainHistoryKey, targetId, gainingClientId))
serverApproveNewExpirationTime, domainHistoryKey, targetId, gainingRegistrarId))
.add(
createGainingClientAutorenewPollMessage(
serverApproveNewExpirationTime, domainHistoryKey, targetId, gainingClientId))
serverApproveNewExpirationTime, domainHistoryKey, targetId, gainingRegistrarId))
.add(
createGainingTransferPollMessage(
targetId,
@@ -169,7 +169,7 @@ public final class DomainTransferUtils {
DateTime now,
Key<DomainHistory> domainHistoryKey) {
return new PollMessage.OneTime.Builder()
.setClientId(transferData.getGainingClientId())
.setRegistrarId(transferData.getGainingRegistrarId())
.setEventTime(transferData.getPendingTransferExpirationTime())
.setMsg(transferData.getTransferStatus().getMessage())
.setResponseData(
@@ -191,7 +191,7 @@ public final class DomainTransferUtils {
@Nullable DateTime extendedRegistrationExpirationTime,
Key<DomainHistory> domainHistoryKey) {
return new PollMessage.OneTime.Builder()
.setClientId(transferData.getLosingClientId())
.setRegistrarId(transferData.getLosingRegistrarId())
.setEventTime(transferData.getPendingTransferExpirationTime())
.setMsg(transferData.getTransferStatus().getMessage())
.setResponseData(
@@ -208,8 +208,8 @@ public final class DomainTransferUtils {
@Nullable DateTime extendedRegistrationExpirationTime) {
return new DomainTransferResponse.Builder()
.setFullyQualifiedDomainName(targetId)
.setGainingClientId(transferData.getGainingClientId())
.setLosingClientId(transferData.getLosingClientId())
.setGainingRegistrarId(transferData.getGainingRegistrarId())
.setLosingRegistrarId(transferData.getLosingRegistrarId())
.setPendingTransferExpirationTime(transferData.getPendingTransferExpirationTime())
.setTransferRequestTime(transferData.getTransferRequestTime())
.setTransferStatus(transferData.getTransferStatus())
@@ -221,10 +221,10 @@ public final class DomainTransferUtils {
DateTime serverApproveNewExpirationTime,
Key<DomainHistory> domainHistoryKey,
String targetId,
String gainingClientId) {
String gainingRegistrarId) {
return new PollMessage.Autorenew.Builder()
.setTargetId(targetId)
.setClientId(gainingClientId)
.setRegistrarId(gainingRegistrarId)
.setEventTime(serverApproveNewExpirationTime)
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
@@ -236,12 +236,12 @@ public final class DomainTransferUtils {
DateTime serverApproveNewExpirationTime,
Key<DomainHistory> domainHistoryKey,
String targetId,
String gainingClientId) {
String gainingRegistrarId) {
return new BillingEvent.Recurring.Builder()
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(targetId)
.setClientId(gainingClientId)
.setRegistrarId(gainingRegistrarId)
.setEventTime(serverApproveNewExpirationTime)
.setRecurrenceEndTime(END_OF_TIME)
.setParent(domainHistoryKey)
@@ -291,13 +291,13 @@ public final class DomainTransferUtils {
DateTime automaticTransferTime,
Key<DomainHistory> domainHistoryKey,
String targetId,
String gainingClientId,
String gainingRegistrarId,
Registry registry,
Money transferCost) {
return new BillingEvent.OneTime.Builder()
.setReason(Reason.TRANSFER)
.setTargetId(targetId)
.setClientId(gainingClientId)
.setRegistrarId(gainingRegistrarId)
.setCost(transferCost)
.setPeriodYears(1)
.setEventTime(automaticTransferTime)
@@ -19,7 +19,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.Sets.symmetricDifference;
import static com.google.common.collect.Sets.union;
import static google.registry.flows.FlowUtils.persistEntityChanges;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.checkSameValuesNotAddedAndRemoved;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyAllStatusesAreClientSettable;
@@ -47,7 +47,7 @@ import com.google.common.net.InternetDomainName;
import google.registry.dns.DnsQueue;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
@@ -139,7 +139,7 @@ public final class DomainUpdateFlow implements TransactionalFlow {
@Inject ExtensionManager extensionManager;
@Inject EppInput eppInput;
@Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject @Superuser boolean isSuperuser;
@Inject DomainHistory.Builder historyBuilder;
@@ -158,7 +158,7 @@ public final class DomainUpdateFlow implements TransactionalFlow {
DomainUpdateSuperuserExtension.class);
flowCustomLogic.beforeValidation();
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
DateTime now = tm().getTransactionTime();
Update command = cloneAndLinkReferences((Update) resourceCommand, now);
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
@@ -197,10 +197,10 @@ public final class DomainUpdateFlow implements TransactionalFlow {
String tld = existingDomain.getTld();
if (!isSuperuser) {
verifyNoDisallowedStatuses(existingDomain, UPDATE_DISALLOWED_STATUSES);
verifyResourceOwnership(clientId, existingDomain);
verifyResourceOwnership(registrarId, existingDomain);
verifyClientUpdateNotProhibited(command, existingDomain);
verifyAllStatusesAreClientSettable(union(add.getStatusValues(), remove.getStatusValues()));
checkAllowedAccessToTld(clientId, tld);
checkAllowedAccessToTld(registrarId, tld);
}
Registry registry = Registry.get(tld);
Optional<FeeUpdateCommandExtension> feeUpdate =
@@ -244,7 +244,7 @@ public final class DomainUpdateFlow implements TransactionalFlow {
secDnsUpdate.get())
: domain.getDsData())
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(clientId)
.setLastEppUpdateRegistrarId(registrarId)
.addStatusValues(add.getStatusValues())
.removeStatusValues(remove.getStatusValues())
.addNameservers(add.getNameservers().stream().collect(toImmutableSet()))
@@ -291,15 +291,16 @@ public final class DomainUpdateFlow implements TransactionalFlow {
: symmetricDifference(existingDomain.getStatusValues(), newDomain.getStatusValues())) {
if (statusValue.isChargedStatus()) {
// Only charge once.
return Optional.of(new BillingEvent.OneTime.Builder()
.setReason(Reason.SERVER_STATUS)
.setTargetId(targetId)
.setClientId(clientId)
.setCost(Registry.get(existingDomain.getTld()).getServerStatusChangeCost())
.setEventTime(now)
.setBillingTime(now)
.setParent(historyEntry)
.build());
return Optional.of(
new BillingEvent.OneTime.Builder()
.setReason(Reason.SERVER_STATUS)
.setTargetId(targetId)
.setRegistrarId(registrarId)
.setCost(Registry.get(existingDomain.getTld()).getServerStatusChangeCost())
.setEventTime(now)
.setBillingTime(now)
.setParent(historyEntry)
.build());
}
}
}
@@ -36,7 +36,7 @@ public class AllocationTokenCustomLogic {
DomainCommand.Create command,
AllocationToken token,
Registry registry,
String clientId,
String registrarId,
DateTime now)
throws EppException {
// Do nothing.
@@ -47,7 +47,7 @@ public class AllocationTokenCustomLogic {
public ImmutableMap<InternetDomainName, String> checkDomainsWithToken(
ImmutableList<InternetDomainName> domainNames,
AllocationToken token,
String clientId,
String registrarId,
DateTime now) {
// Do nothing.
return Maps.toMap(domainNames, k -> "");
@@ -58,12 +58,19 @@ public class AllocationTokenFlowUtils {
* for this request.
*/
public AllocationToken loadTokenAndValidateDomainCreate(
DomainCommand.Create command, String token, Registry registry, String clientId, DateTime now)
DomainCommand.Create command,
String token,
Registry registry,
String registrarId,
DateTime now)
throws EppException {
AllocationToken tokenEntity = loadToken(token);
validateToken(
InternetDomainName.from(command.getFullyQualifiedDomainName()), tokenEntity, clientId, now);
return tokenCustomLogic.validateToken(command, tokenEntity, registry, clientId, now);
InternetDomainName.from(command.getFullyQualifiedDomainName()),
tokenEntity,
registrarId,
now);
return tokenCustomLogic.validateToken(command, tokenEntity, registry, registrarId, now);
}
/**
@@ -74,7 +81,7 @@ public class AllocationTokenFlowUtils {
* validate have blank messages (i.e. no error).
*/
public AllocationTokenDomainCheckResults checkDomainsWithToken(
List<InternetDomainName> domainNames, String token, String clientId, DateTime now) {
List<InternetDomainName> domainNames, String token, String registrarId, DateTime now) {
// If the token is completely invalid, return the error message for all domain names
AllocationToken tokenEntity;
try {
@@ -91,7 +98,7 @@ public class AllocationTokenFlowUtils {
ImmutableMap.Builder<InternetDomainName, String> resultsBuilder = new ImmutableMap.Builder<>();
for (InternetDomainName domainName : domainNames) {
try {
validateToken(domainName, tokenEntity, clientId, now);
validateToken(domainName, tokenEntity, registrarId, now);
validDomainNames.add(domainName);
} catch (EppException e) {
resultsBuilder.put(domainName, e.getMessage());
@@ -101,7 +108,7 @@ public class AllocationTokenFlowUtils {
// For all valid domain names, run the custom logic and include the results
resultsBuilder.putAll(
tokenCustomLogic.checkDomainsWithToken(
validDomainNames.build(), tokenEntity, clientId, now));
validDomainNames.build(), tokenEntity, registrarId, now));
return AllocationTokenDomainCheckResults.create(
Optional.of(tokenEntity), resultsBuilder.build());
}
@@ -123,10 +130,10 @@ public class AllocationTokenFlowUtils {
* @throws EppException if the token is invalid in any way
*/
private void validateToken(
InternetDomainName domainName, AllocationToken token, String clientId, DateTime now)
InternetDomainName domainName, AllocationToken token, String registrarId, DateTime now)
throws EppException {
if (!token.getAllowedRegistrarIds().isEmpty()
&& !token.getAllowedRegistrarIds().contains(clientId)) {
&& !token.getAllowedRegistrarIds().contains(registrarId)) {
throw new AllocationTokenNotValidForRegistrarException();
}
if (!token.getAllowedTlds().isEmpty()
@@ -149,7 +156,7 @@ public class AllocationTokenFlowUtils {
private AllocationToken loadToken(String token) throws EppException {
if (Strings.isNullOrEmpty(token)) {
// We load the token directly from the input XML. If it's null or empty we should throw
// an InvalidAllocationTokenException before the Datastore load attempt fails.
// an InvalidAllocationTokenException before the database load attempt fails.
// See https://tools.ietf.org/html/draft-ietf-regext-allocation-token-04#section-2.1
throw new InvalidAllocationTokenException();
}
@@ -14,7 +14,7 @@
package google.registry.flows.host;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount;
import static google.registry.model.EppResourceUtils.checkResourcesExist;
@@ -24,7 +24,7 @@ import google.registry.config.RegistryConfig.Config;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.model.eppinput.ResourceCommand;
import google.registry.model.eppoutput.CheckData.HostCheck;
@@ -47,7 +47,7 @@ import javax.inject.Inject;
public final class HostCheckFlow implements Flow {
@Inject ResourceCommand resourceCommand;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject ExtensionManager extensionManager;
@Inject @Config("maxChecks") int maxChecks;
@Inject Clock clock;
@@ -57,7 +57,7 @@ public final class HostCheckFlow implements Flow {
@Override
public final EppResponse run() throws EppException {
extensionManager.validate(); // There are no legal extensions for this flow.
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
ImmutableList<String> hostnames = ((Check) resourceCommand).getTargetIds();
verifyTargetIdCount(hostnames, maxChecks);
ImmutableSet<String> existingIds =
@@ -14,7 +14,7 @@
package google.registry.flows.host;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyResourceDoesNotExist;
import static google.registry.flows.host.HostFlowUtils.lookupSuperordinateDomain;
import static google.registry.flows.host.HostFlowUtils.validateHostName;
@@ -34,7 +34,7 @@ import google.registry.flows.EppException;
import google.registry.flows.EppException.ParameterValueRangeErrorException;
import google.registry.flows.EppException.RequiredParameterMissingException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
import google.registry.flows.annotations.ReportingSpec;
@@ -84,7 +84,7 @@ public final class HostCreateFlow implements TransactionalFlow {
@Inject ResourceCommand resourceCommand;
@Inject ExtensionManager extensionManager;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject HostHistory.Builder historyBuilder;
@Inject DnsQueue dnsQueue;
@@ -101,17 +101,17 @@ public final class HostCreateFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
Create command = (Create) resourceCommand;
DateTime now = tm().getTransactionTime();
verifyResourceDoesNotExist(HostResource.class, targetId, now, clientId);
verifyResourceDoesNotExist(HostResource.class, targetId, now, registrarId);
// The superordinate domain of the host object if creating an in-bailiwick host, or null if
// creating an external host. This is looked up before we actually create the Host object so
// we can detect error conditions earlier.
Optional<DomainBase> superordinateDomain =
lookupSuperordinateDomain(validateHostName(targetId), now);
verifySuperordinateDomainNotInPendingDelete(superordinateDomain.orElse(null));
verifySuperordinateDomainOwnership(clientId, superordinateDomain.orElse(null));
verifySuperordinateDomainOwnership(registrarId, superordinateDomain.orElse(null));
boolean willBeSubordinate = superordinateDomain.isPresent();
boolean hasIpAddresses = !isNullOrEmpty(command.getInetAddresses());
if (willBeSubordinate != hasIpAddresses) {
@@ -122,8 +122,8 @@ public final class HostCreateFlow implements TransactionalFlow {
}
HostResource newHost =
new HostResource.Builder()
.setCreationClientId(clientId)
.setPersistedCurrentSponsorClientId(clientId)
.setCreationRegistrarId(registrarId)
.setPersistedCurrentSponsorRegistrarId(registrarId)
.setHostName(targetId)
.setInetAddresses(command.getInetAddresses())
.setRepoId(createRepoId(allocateId(), roidSuffix))
@@ -14,7 +14,7 @@
package google.registry.flows.host;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.checkLinkedDomains;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyNoDisallowedStatuses;
@@ -29,7 +29,7 @@ import google.registry.batch.AsyncTaskEnqueuer;
import google.registry.dns.DnsQueue;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
@@ -78,7 +78,7 @@ public final class HostDeleteFlow implements TransactionalFlow {
private static final DnsQueue dnsQueue = DnsQueue.create();
@Inject ExtensionManager extensionManager;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject Trid trid;
@Inject @Superuser boolean isSuperuser;
@@ -93,7 +93,7 @@ public final class HostDeleteFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
DateTime now = tm().getTransactionTime();
validateHostName(targetId);
checkLinkedDomains(targetId, now, HostResource.class, DomainBase::getNameservers);
@@ -106,14 +106,14 @@ public final class HostDeleteFlow implements TransactionalFlow {
existingHost.isSubordinate()
? tm().loadByKey(existingHost.getSuperordinateDomain()).cloneProjectedAtTime(now)
: existingHost;
verifyResourceOwnership(clientId, owningResource);
verifyResourceOwnership(registrarId, owningResource);
}
HistoryEntry.Type historyEntryType;
Result.Code resultCode;
HostResource newHost;
if (tm().isOfy()) {
asyncTaskEnqueuer.enqueueAsyncDelete(
existingHost, tm().getTransactionTime(), clientId, trid, isSuperuser);
existingHost, tm().getTransactionTime(), registrarId, trid, isSuperuser);
newHost = existingHost.asBuilder().addStatusValue(StatusValue.PENDING_DELETE).build();
historyEntryType = Type.HOST_PENDING_DELETE;
resultCode = SUCCESS_WITH_ACTION_PENDING;
@@ -105,11 +105,11 @@ public class HostFlowUtils {
}
}
/** Ensure that the superordinate domain is sponsored by the provided clientId. */
static void verifySuperordinateDomainOwnership(
String clientId, DomainBase superordinateDomain) throws EppException {
/** Ensure that the superordinate domain is sponsored by the provided registrar ID. */
static void verifySuperordinateDomainOwnership(String registrarId, DomainBase superordinateDomain)
throws EppException {
if (superordinateDomain != null
&& !clientId.equals(superordinateDomain.getCurrentSponsorClientId())) {
&& !registrarId.equals(superordinateDomain.getCurrentSponsorRegistrarId())) {
throw new HostDomainNotOwnedException();
}
}
@@ -14,7 +14,7 @@
package google.registry.flows.host;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.host.HostFlowUtils.validateHostName;
import static google.registry.model.EppResourceUtils.isLinked;
@@ -25,7 +25,7 @@ import com.google.common.collect.ImmutableSet;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.model.domain.DomainBase;
@@ -53,7 +53,7 @@ import org.joda.time.DateTime;
public final class HostInfoFlow implements Flow {
@Inject ExtensionManager extensionManager;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject Clock clock;
@Inject EppResponse.Builder responseBuilder;
@@ -62,7 +62,7 @@ public final class HostInfoFlow implements Flow {
@Override
public EppResponse run() throws EppException {
extensionManager.validate(); // There are no legal extensions for this flow.
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
validateHostName(targetId);
DateTime now = clock.nowUtc();
HostResource host = loadAndVerifyExistence(HostResource.class, targetId, now);
@@ -80,14 +80,14 @@ public final class HostInfoFlow implements Flow {
transactIfJpaTm(
() -> tm().loadByKey(host.getSuperordinateDomain()).cloneProjectedAtTime(now));
hostInfoDataBuilder
.setCurrentSponsorClientId(superordinateDomain.getCurrentSponsorClientId())
.setCurrentSponsorClientId(superordinateDomain.getCurrentSponsorRegistrarId())
.setLastTransferTime(host.computeLastTransferTime(superordinateDomain));
if (superordinateDomain.getStatusValues().contains(StatusValue.PENDING_TRANSFER)) {
statusValues.add(StatusValue.PENDING_TRANSFER);
}
} else {
hostInfoDataBuilder
.setCurrentSponsorClientId(host.getPersistedCurrentSponsorClientId())
.setCurrentSponsorClientId(host.getPersistedCurrentSponsorRegistrarId())
.setLastTransferTime(host.getLastTransferTime());
}
return responseBuilder
@@ -97,9 +97,9 @@ public final class HostInfoFlow implements Flow {
.setRepoId(host.getRepoId())
.setStatusValues(statusValues.build())
.setInetAddresses(host.getInetAddresses())
.setCreationClientId(host.getCreationClientId())
.setCreationClientId(host.getCreationRegistrarId())
.setCreationTime(host.getCreationTime())
.setLastEppUpdateClientId(host.getLastEppUpdateClientId())
.setLastEppUpdateClientId(host.getLastEppUpdateRegistrarId())
.setLastEppUpdateTime(host.getLastEppUpdateTime())
.build())
.build();
@@ -16,7 +16,7 @@ package google.registry.flows.host;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.collect.Sets.union;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.checkSameValuesNotAddedAndRemoved;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyAllStatusesAreClientSettable;
@@ -39,7 +39,7 @@ import google.registry.flows.EppException.ObjectAlreadyExistsException;
import google.registry.flows.EppException.ParameterValueRangeErrorException;
import google.registry.flows.EppException.StatusProhibitsOperationException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow;
@@ -113,7 +113,7 @@ public final class HostUpdateFlow implements TransactionalFlow {
@Inject ResourceCommand resourceCommand;
@Inject ExtensionManager extensionManager;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@Inject @Superuser boolean isSuperuser;
@Inject HostHistory.Builder historyBuilder;
@@ -126,7 +126,7 @@ public final class HostUpdateFlow implements TransactionalFlow {
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
Update command = (Update) resourceCommand;
Change change = command.getInnerChange();
String suppliedNewHostName = change.getFullyQualifiedHostName();
@@ -170,10 +170,10 @@ public final class HostUpdateFlow implements TransactionalFlow {
// since external hosts store their own clientId. For subordinate hosts the canonical clientId
// comes from the superordinate domain, but we might as well update the persisted value. For
// non-superusers this is the flow clientId, but for superusers it might not be, so compute it.
String newPersistedClientId =
String newPersistedRegistrarId =
newSuperordinateDomain.isPresent()
? newSuperordinateDomain.get().getCurrentSponsorClientId()
: owningResource.getPersistedCurrentSponsorClientId();
? newSuperordinateDomain.get().getCurrentSponsorRegistrarId()
: owningResource.getPersistedCurrentSponsorRegistrarId();
HostResource newHost =
existingHost
.asBuilder()
@@ -183,11 +183,11 @@ public final class HostUpdateFlow implements TransactionalFlow {
.addInetAddresses(add.getInetAddresses())
.removeInetAddresses(remove.getInetAddresses())
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(clientId)
.setLastEppUpdateRegistrarId(registrarId)
.setSuperordinateDomain(newSuperordinateDomainKey)
.setLastSuperordinateChange(lastSuperordinateChange)
.setLastTransferTime(lastTransferTime)
.setPersistedCurrentSponsorClientId(newPersistedClientId)
.setPersistedCurrentSponsorRegistrarId(newPersistedRegistrarId)
.build();
verifyHasIpsIffIsExternal(command, existingHost, newHost);
ImmutableSet.Builder<ImmutableObject> entitiesToInsert = new ImmutableSet.Builder<>();
@@ -217,12 +217,12 @@ public final class HostUpdateFlow implements TransactionalFlow {
if (!isSuperuser) {
// Verify that the host belongs to this registrar, either directly or because it is currently
// subordinate to a domain owned by this registrar.
verifyResourceOwnership(clientId, owningResource);
verifyResourceOwnership(registrarId, owningResource);
if (isHostRename && !existingHost.isSubordinate()) {
throw new CannotRenameExternalHostException();
}
// Verify that the new superordinate domain belongs to this registrar.
verifySuperordinateDomainOwnership(clientId, newSuperordinateDomain);
verifySuperordinateDomainOwnership(registrarId, newSuperordinateDomain);
ImmutableSet<StatusValue> statusesToAdd = command.getInnerAdd().getStatusValues();
ImmutableSet<StatusValue> statusesToRemove = command.getInnerRemove().getStatusValues();
// If the resource is marked with clientUpdateProhibited, and this update does not clear that
@@ -14,7 +14,7 @@
package google.registry.flows.poll;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.poll.PollFlowUtils.ackPollMessage;
import static google.registry.flows.poll.PollFlowUtils.getPollMessageCount;
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_NO_MESSAGES;
@@ -29,8 +29,8 @@ import google.registry.flows.EppException.ObjectDoesNotExistException;
import google.registry.flows.EppException.ParameterValueSyntaxErrorException;
import google.registry.flows.EppException.RequiredParameterMissingException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.PollMessageId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.TransactionalFlow;
import google.registry.model.eppoutput.EppResponse;
import google.registry.model.poll.MessageQueueInfo;
@@ -58,15 +58,16 @@ import org.joda.time.DateTime;
public class PollAckFlow implements TransactionalFlow {
@Inject ExtensionManager extensionManager;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @PollMessageId String messageId;
@Inject EppResponse.Builder responseBuilder;
@Inject PollAckFlow() {}
@Override
public final EppResponse run() throws EppException {
extensionManager.validate(); // There are no legal extensions for this flow.
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
if (messageId.isEmpty()) {
throw new MissingMessageIdException();
}
@@ -94,7 +95,7 @@ public class PollAckFlow implements TransactionalFlow {
// Make sure this client is authorized to ack this message. It could be that the message is
// supposed to go to a different registrar.
if (!clientId.equals(pollMessage.getClientId())) {
if (!registrarId.equals(pollMessage.getRegistrarId())) {
throw new NotAuthorizedToAckMessageException();
}
@@ -107,7 +108,7 @@ public class PollAckFlow implements TransactionalFlow {
// acked, then we return a special status code indicating that. Note that the query will
// include the message being acked.
int messageCount = tm().doTransactionless(() -> getPollMessageCount(clientId, now));
int messageCount = tm().doTransactionless(() -> getPollMessageCount(registrarId, now));
// Within the same transaction, Datastore will not reflect the updated count (potentially
// reduced by one thanks to the acked poll message). SQL will, however, so we shouldn't reduce
// the count in the SQL case.
@@ -14,7 +14,7 @@
package google.registry.flows.poll;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.poll.PollFlowUtils.getFirstPollMessage;
import static google.registry.flows.poll.PollFlowUtils.getPollMessageCount;
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACK_MESSAGE;
@@ -25,8 +25,8 @@ import google.registry.flows.EppException;
import google.registry.flows.EppException.ParameterValueSyntaxErrorException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.PollMessageId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.model.eppoutput.EppResponse;
import google.registry.model.poll.MessageQueueInfo;
import google.registry.model.poll.PollMessage;
@@ -39,18 +39,18 @@ import org.joda.time.DateTime;
/**
* An EPP flow for requesting {@link PollMessage}s.
*
* <p>This flow uses an eventually consistent Datastore query to return the oldest poll message for
* the registrar, as well as the total number of pending messages. Note that poll messages whose
* event time is in the future (i.e. they are speculative and could still be changed or rescinded)
* are ignored. The externally visible id for the poll message that the registrar sees is generated
* by {@link PollMessageExternalKeyConverter}.
* <p>This flow uses an eventually consistent query to return the oldest poll message for the
* registrar, as well as the total number of pending messages. Note that poll messages whose event
* time is in the future (i.e. they are speculative and could still be changed or rescinded) are
* ignored. The externally visible id for the poll message that the registrar sees is generated by
* {@link PollMessageExternalKeyConverter}.
*
* @error {@link PollRequestFlow.UnexpectedMessageIdException}
*/
public class PollRequestFlow implements Flow {
@Inject ExtensionManager extensionManager;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject @PollMessageId String messageId;
@Inject Clock clock;
@Inject EppResponse.Builder responseBuilder;
@@ -59,13 +59,13 @@ public class PollRequestFlow implements Flow {
@Override
public final EppResponse run() throws EppException {
extensionManager.validate(); // There are no legal extensions for this flow.
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
if (!messageId.isEmpty()) {
throw new UnexpectedMessageIdException();
}
// Return the oldest message from the queue.
DateTime now = clock.nowUtc();
Optional<PollMessage> maybePollMessage = getFirstPollMessage(clientId, now);
Optional<PollMessage> maybePollMessage = getFirstPollMessage(registrarId, now);
if (!maybePollMessage.isPresent()) {
return responseBuilder.setResultFromCode(SUCCESS_WITH_NO_MESSAGES).build();
}
@@ -76,7 +76,7 @@ public class PollRequestFlow implements Flow {
new MessageQueueInfo.Builder()
.setQueueDate(pollMessage.getEventTime())
.setMsg(pollMessage.getMsg())
.setQueueLength(getPollMessageCount(clientId, now))
.setQueueLength(getPollMessageCount(registrarId, now))
.setMessageId(makePollMessageExternalId(pollMessage))
.build())
.setMultipleResData(pollMessage.getResponseData())
@@ -30,7 +30,7 @@ import google.registry.flows.EppException.UnimplementedObjectServiceException;
import google.registry.flows.EppException.UnimplementedOptionException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.SessionMetadata;
import google.registry.flows.TransportCredentials;
import google.registry.model.eppcommon.ProtocolDefinition;
@@ -56,7 +56,7 @@ import javax.inject.Inject;
* @error {@link google.registry.flows.TlsCredentials.MissingRegistrarCertificateException}
* @error {@link google.registry.flows.TransportCredentials.BadRegistrarPasswordException}
* @error {@link LoginFlow.AlreadyLoggedInException}
* @error {@link LoginFlow.BadRegistrarClientIdException}
* @error {@link BadRegistrarIdException}
* @error {@link LoginFlow.TooManyFailedLoginsException}
* @error {@link LoginFlow.PasswordChangesNotSupportedException}
* @error {@link LoginFlow.RegistrarAccountNotActiveException}
@@ -73,8 +73,9 @@ public class LoginFlow implements Flow {
@Inject EppInput eppInput;
@Inject SessionMetadata sessionMetadata;
@Inject TransportCredentials credentials;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject EppResponse.Builder responseBuilder;
@Inject LoginFlow() {}
/** Run the flow and log errors. */
@@ -92,7 +93,7 @@ public class LoginFlow implements Flow {
public final EppResponse runWithoutLogging() throws EppException {
extensionManager.validate(); // There are no legal extensions for this flow.
Login login = (Login) eppInput.getCommandWrapper().getCommand();
if (!clientId.isEmpty()) {
if (!registrarId.isEmpty()) {
throw new AlreadyLoggedInException();
}
Options options = login.getOptions();
@@ -114,9 +115,9 @@ public class LoginFlow implements Flow {
}
serviceExtensionUrisBuilder.add(uri);
}
Optional<Registrar> registrar = Registrar.loadByClientIdCached(login.getClientId());
Optional<Registrar> registrar = Registrar.loadByRegistrarIdCached(login.getClientId());
if (!registrar.isPresent()) {
throw new BadRegistrarClientIdException(login.getClientId());
throw new BadRegistrarIdException(login.getClientId());
}
// AuthenticationErrorExceptions will propagate up through here.
@@ -139,15 +140,15 @@ public class LoginFlow implements Flow {
// We are in!
sessionMetadata.resetFailedLoginAttempts();
sessionMetadata.setClientId(login.getClientId());
sessionMetadata.setRegistrarId(login.getClientId());
sessionMetadata.setServiceExtensionUris(serviceExtensionUrisBuilder.build());
return responseBuilder.setIsLoginResponse().build();
}
/** Registrar with this client ID could not be found. */
static class BadRegistrarClientIdException extends AuthenticationErrorException {
public BadRegistrarClientIdException(String clientId) {
super("Registrar with this client ID could not be found: " + clientId);
/** Registrar with this ID could not be found. */
static class BadRegistrarIdException extends AuthenticationErrorException {
public BadRegistrarIdException(String registrarId) {
super("Registrar with this ID could not be found: " + registrarId);
}
}
@@ -14,13 +14,13 @@
package google.registry.flows.session;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.model.eppoutput.Result.Code.SUCCESS_AND_CLOSE;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.SessionMetadata;
import google.registry.model.eppoutput.EppResponse;
import javax.inject.Inject;
@@ -33,7 +33,7 @@ import javax.inject.Inject;
public class LogoutFlow implements Flow {
@Inject ExtensionManager extensionManager;
@Inject @ClientId String clientId;
@Inject @RegistrarId String registrarId;
@Inject SessionMetadata sessionMetadata;
@Inject EppResponse.Builder responseBuilder;
@Inject LogoutFlow() {}
@@ -41,7 +41,7 @@ public class LogoutFlow implements Flow {
@Override
public final EppResponse run() throws EppException {
extensionManager.validate(); // There are no legal extensions for this flow.
validateClientIsLoggedIn(clientId);
validateRegistrarIsLoggedIn(registrarId);
sessionMetadata.invalidate();
return responseBuilder.setResultFromCode(SUCCESS_AND_CLOSE).build();
}
@@ -74,10 +74,10 @@ public class LoadTestAction implements Runnable {
public static final String PATH = "/_dr/loadtest";
/** The client identifier of the registrar to use for load testing. */
/** The ID of the registrar to use for load testing. */
@Inject
@Parameter("loadtestClientId")
String clientId;
String registrarId;
/**
* The number of seconds to delay the execution of the first load testing tasks by. Preparatory
@@ -276,11 +276,11 @@ public class LoadTestAction implements Runnable {
|| hostInfosPerSecond > 0,
"You must specify at least one of the 'operations per second' parameters.");
logger.atInfo().log(
"Running load test with the following params. clientId: %s, delaySeconds: %d, "
"Running load test with the following params. registrarId: %s, delaySeconds: %d, "
+ "runSeconds: %d, successful|failed domain creates/s: %d|%d, domain infos/s: %d, "
+ "domain checks/s: %d, successful|failed contact creates/s: %d|%d, "
+ "contact infos/s: %d, successful|failed host creates/s: %d|%d, host infos/s: %d.",
clientId,
registrarId,
delaySeconds,
runSeconds,
successfulDomainCreatesPerSecond,
@@ -327,13 +327,14 @@ public class LoadTestAction implements Runnable {
for (int i = 0; i < xmls.size(); i++) {
// Space tasks evenly within across a second.
int offsetMillis = (int) (1000.0 / xmls.size() * i);
tasks.add(TaskOptions.Builder.withUrl("/_dr/epptool")
.etaMillis(start.getMillis() + offsetMillis)
.header(X_CSRF_TOKEN, xsrfToken)
.param("clientId", clientId)
.param("superuser", Boolean.FALSE.toString())
.param("dryRun", Boolean.FALSE.toString())
.param("xml", xmls.get(i)));
tasks.add(
TaskOptions.Builder.withUrl("/_dr/epptool")
.etaMillis(start.getMillis() + offsetMillis)
.header(X_CSRF_TOKEN, xsrfToken)
.param("clientId", registrarId)
.param("superuser", Boolean.FALSE.toString())
.param("dryRun", Boolean.FALSE.toString())
.param("xml", xmls.get(i)));
}
return tasks.build();
}
@@ -175,7 +175,7 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
return creationTime.getTimestamp();
}
public String getCreationClientId() {
public String getCreationRegistrarId() {
return creationClientId;
}
@@ -183,7 +183,7 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
return lastEppUpdateTime;
}
public String getLastEppUpdateClientId() {
public String getLastEppUpdateRegistrarId() {
return lastEppUpdateClientId;
}
@@ -193,7 +193,7 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
* <p>For subordinate hosts, this value may not represent the actual current client id, which is
* the client id of the superordinate host. For all other resources this is the true client id.
*/
public final String getPersistedCurrentSponsorClientId() {
public final String getPersistedCurrentSponsorRegistrarId() {
return currentSponsorClientId;
}
@@ -294,14 +294,14 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
}
/** Set the current sponsoring registrar. */
public B setPersistedCurrentSponsorClientId(String currentSponsorClientId) {
getInstance().currentSponsorClientId = currentSponsorClientId;
public B setPersistedCurrentSponsorRegistrarId(String currentSponsorRegistrarId) {
getInstance().currentSponsorClientId = currentSponsorRegistrarId;
return thisCastToDerived();
}
/** Set the registrar that created this resource. */
public B setCreationClientId(String creationClientId) {
getInstance().creationClientId = creationClientId;
public B setCreationRegistrarId(String creationRegistrarId) {
getInstance().creationClientId = creationRegistrarId;
return thisCastToDerived();
}
@@ -312,8 +312,8 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
}
/** Set the registrar who last performed a {@literal <update>} on this resource. */
public B setLastEppUpdateClientId(String lastEppUpdateClientId) {
getInstance().lastEppUpdateClientId = lastEppUpdateClientId;
public B setLastEppUpdateRegistrarId(String lastEppUpdateRegistrarId) {
getInstance().lastEppUpdateClientId = lastEppUpdateRegistrarId;
return thisCastToDerived();
}
@@ -240,7 +240,7 @@ public final class EppResourceUtils {
.removeStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData((T) transferDataBuilder.build())
.setLastTransferTime(transferData.getPendingTransferExpirationTime())
.setPersistedCurrentSponsorClientId(transferData.getGainingClientId());
.setPersistedCurrentSponsorRegistrarId(transferData.getGainingRegistrarId());
}
/**
@@ -63,7 +63,7 @@ import org.joda.time.Duration;
* <p>Usage example:
*
* <pre>{@code
* OteAccountBuilder.forClientId("example")
* OteAccountBuilder.forRegistrarId("example")
* .addContact("contact@email.com") // OPTIONAL
* .setPassword("password") // OPTIONAL
* .setCertificateHash(certificateHash) // OPTIONAL
@@ -111,7 +111,7 @@ public final class OteAccountBuilder {
DateTime.parse("2030-03-01T00:00:00Z"),
Money.of(CurrencyUnit.USD, 0));
private final ImmutableMap<String, String> clientIdToTld;
private final ImmutableMap<String, String> registrarIdToTld;
private final Registry sunriseTld;
private final Registry gaTld;
private final Registry eapTld;
@@ -121,16 +121,16 @@ public final class OteAccountBuilder {
private ImmutableList<Registrar> registrars;
private boolean replaceExisting = false;
private OteAccountBuilder(String baseClientId) {
private OteAccountBuilder(String baseRegistrarId) {
checkState(
RegistryEnvironment.get() != RegistryEnvironment.PRODUCTION,
"Can't setup OT&E in production");
clientIdToTld = createClientIdToTldMap(baseClientId);
sunriseTld = createTld(baseClientId + "-sunrise", START_DATE_SUNRISE, false, 0);
gaTld = createTld(baseClientId + "-ga", GENERAL_AVAILABILITY, false, 2);
eapTld = createTld(baseClientId + "-eap", GENERAL_AVAILABILITY, true, 3);
registrarIdToTld = createRegistrarIdToTldMap(baseRegistrarId);
sunriseTld = createTld(baseRegistrarId + "-sunrise", START_DATE_SUNRISE, false, 0);
gaTld = createTld(baseRegistrarId + "-ga", GENERAL_AVAILABILITY, false, 2);
eapTld = createTld(baseRegistrarId + "-eap", GENERAL_AVAILABILITY, true, 3);
registrars =
clientIdToTld.keySet().stream()
registrarIdToTld.keySet().stream()
.map(OteAccountBuilder::createRegistrar)
.collect(toImmutableList());
}
@@ -138,11 +138,11 @@ public final class OteAccountBuilder {
/**
* Creates an OteAccountBuilder for the given base client ID.
*
* @param baseClientId the base clientId which will help name all the entities we create. Normally
* is the same as the "prod" clientId designated for this registrar.
* @param baseRegistrarId the base registrar ID which will help name all the entities we create.
* Normally is the same as the "prod" ID designated for this registrar.
*/
public static OteAccountBuilder forClientId(String baseClientId) {
return new OteAccountBuilder(baseClientId);
public static OteAccountBuilder forRegistrarId(String baseRegistrarId) {
return new OteAccountBuilder(baseRegistrarId);
}
/**
@@ -232,14 +232,15 @@ public final class OteAccountBuilder {
*/
public ImmutableMap<String, String> buildAndPersist() {
saveAllEntities();
return clientIdToTld;
return registrarIdToTld;
}
/**
* Return map from the OT&amp;E clientIds we will create to the new TLDs they will have access to.
* Return map from the OT&amp;E registrarIds we will create to the new TLDs they will have access
* to.
*/
public ImmutableMap<String, String> getClientIdToTldMap() {
return clientIdToTld;
public ImmutableMap<String, String> getRegistrarIdToTldMap() {
return registrarIdToTld;
}
/** Saves all the OT&amp;E entities we created. */
@@ -279,7 +280,7 @@ public final class OteAccountBuilder {
}
private Registrar addAllowedTld(Registrar registrar) {
String tld = clientIdToTld.get(registrar.getClientId());
String tld = registrarIdToTld.get(registrar.getRegistrarId());
if (registrar.getAllowedTlds().contains(tld)) {
return registrar;
}
@@ -324,7 +325,7 @@ public final class OteAccountBuilder {
*/
private static Registrar createRegistrar(String registrarName) {
return new Registrar.Builder()
.setClientId(registrarName)
.setRegistrarId(registrarName)
.setRegistrarName(registrarName)
.setType(Registrar.Type.OTE)
.setLocalizedAddress(DEFAULT_ADDRESS)
@@ -346,31 +347,31 @@ public final class OteAccountBuilder {
.build();
}
/** Returns the ClientIds of the OT&amp;E, with the TLDs each has access to. */
public static ImmutableMap<String, String> createClientIdToTldMap(String baseClientId) {
/** Returns the registrar IDs of the OT&amp;E, with the TLDs each has access to. */
public static ImmutableMap<String, String> createRegistrarIdToTldMap(String baseRegistrarId) {
checkArgument(
REGISTRAR_PATTERN.matcher(baseClientId).matches(),
REGISTRAR_PATTERN.matcher(baseRegistrarId).matches(),
"Invalid registrar name: %s",
baseClientId);
baseRegistrarId);
return new ImmutableMap.Builder<String, String>()
.put(baseClientId + "-1", baseClientId + "-sunrise")
.put(baseRegistrarId + "-1", baseRegistrarId + "-sunrise")
// The -2 registrar no longer exists because landrush no longer exists.
.put(baseClientId + "-3", baseClientId + "-ga")
.put(baseClientId + "-4", baseClientId + "-ga")
.put(baseClientId + "-5", baseClientId + "-eap")
.put(baseRegistrarId + "-3", baseRegistrarId + "-ga")
.put(baseRegistrarId + "-4", baseRegistrarId + "-ga")
.put(baseRegistrarId + "-5", baseRegistrarId + "-eap")
.build();
}
/** Returns the base client ID that correspond to a given OT&amp;E client ID. */
public static String getBaseClientId(String oteClientId) {
int index = oteClientId.lastIndexOf('-');
checkArgument(index > 0, "Invalid OT&E client ID: %s", oteClientId);
String baseClientId = oteClientId.substring(0, index);
/** Returns the base registrar ID that corresponds to a given OT&amp;E registrar ID. */
public static String getBaseRegistrarId(String oteRegistrarId) {
int index = oteRegistrarId.lastIndexOf('-');
checkArgument(index > 0, "Invalid OT&E registrar ID: %s", oteRegistrarId);
String baseRegistrarId = oteRegistrarId.substring(0, index);
checkArgument(
createClientIdToTldMap(baseClientId).containsKey(oteClientId),
"ID %s is not one of the OT&E client IDs for base %s",
oteClientId,
baseClientId);
return baseClientId;
createRegistrarIdToTldMap(baseRegistrarId).containsKey(oteRegistrarId),
"ID %s is not one of the OT&E registrar IDs for base %s",
oteRegistrarId,
baseRegistrarId);
return baseRegistrarId;
}
}
@@ -196,7 +196,7 @@ public class OteStats {
*/
private OteStats recordRegistrarHistory(String registrarName) {
ImmutableCollection<String> registrarIds =
OteAccountBuilder.createClientIdToTldMap(registrarName).keySet();
OteAccountBuilder.createRegistrarIdToTldMap(registrarName).keySet();
for (HistoryEntry historyEntry : HistoryEntryDao.loadHistoryObjectsByRegistrars(registrarIds)) {
try {
@@ -72,8 +72,9 @@ public final class ResourceTransferUtils {
? domainTransferData.getTransferredRegistrationExpirationTime()
: null);
}
builder.setGainingClientId(transferData.getGainingClientId())
.setLosingClientId(transferData.getLosingClientId())
builder
.setGainingRegistrarId(transferData.getGainingRegistrarId())
.setLosingRegistrarId(transferData.getLosingRegistrarId())
.setPendingTransferExpirationTime(transferData.getPendingTransferExpirationTime())
.setTransferRequestTime(transferData.getTransferRequestTime())
.setTransferStatus(transferData.getTransferStatus());
@@ -119,7 +120,7 @@ public final class ResourceTransferUtils {
tm().delete(oldTransferData.getServerApproveEntities());
tm().put(
new PollMessage.OneTime.Builder()
.setClientId(oldTransferData.getGainingClientId())
.setRegistrarId(oldTransferData.getGainingRegistrarId())
.setEventTime(now)
.setMsg(TransferStatus.SERVER_CANCELLED.getMessage())
.setResponseData(
@@ -178,7 +179,7 @@ public final class ResourceTransferUtils {
B builder = resolvePendingTransfer(resource, transferStatus, now);
return builder
.setLastTransferTime(now)
.setPersistedCurrentSponsorClientId(resource.getTransferData().getGainingClientId())
.setPersistedCurrentSponsorRegistrarId(resource.getTransferData().getGainingRegistrarId())
.build();
}
@@ -195,7 +196,7 @@ public final class ResourceTransferUtils {
checkArgument(transferStatus.isDenied(), "Not a denial transfer status");
return resolvePendingTransfer(resource, transferStatus, now)
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(lastEppUpdateClientId)
.setLastEppUpdateRegistrarId(lastEppUpdateClientId)
.build();
}
}
@@ -163,7 +163,7 @@ public abstract class BillingEvent extends ImmutableObject
domainRepoId = parent.getParent().getName();
}
public String getClientId() {
public String getRegistrarId() {
return clientId;
}
@@ -223,8 +223,8 @@ public abstract class BillingEvent extends ImmutableObject
return thisCastToDerived();
}
public B setClientId(String clientId) {
getInstance().clientId = clientId;
public B setRegistrarId(String registrarId) {
getInstance().clientId = registrarId;
return thisCastToDerived();
}
@@ -660,7 +660,7 @@ public abstract class BillingEvent extends ImmutableObject
new BillingEvent.Cancellation.Builder()
.setReason(checkNotNull(GRACE_PERIOD_TO_REASON.get(gracePeriod.getType())))
.setTargetId(targetId)
.setClientId(gracePeriod.getClientId())
.setRegistrarId(gracePeriod.getRegistrarId())
.setEventTime(eventTime)
// The charge being cancelled will take place at the grace period's expiration time.
.setBillingTime(gracePeriod.getExpirationTime())
@@ -778,7 +778,7 @@ public abstract class BillingEvent extends ImmutableObject
public static Modification createRefundFor(
OneTime billingEvent, DomainHistory historyEntry, String description) {
return new Builder()
.setClientId(billingEvent.getClientId())
.setRegistrarId(billingEvent.getRegistrarId())
.setFlags(billingEvent.getFlags())
.setReason(billingEvent.getReason())
.setTargetId(billingEvent.getTargetId())
@@ -237,8 +237,8 @@ public class ContactBase extends EppResource implements ResourceWithTransferData
return disclose;
}
public String getCurrentSponsorClientId() {
return getPersistedCurrentSponsorClientId();
public String getCurrentSponsorRegistrarId() {
return getPersistedCurrentSponsorRegistrarId();
}
@Override
@@ -88,7 +88,7 @@ public class ContactResource extends ContactBase
public Builder copyFrom(ContactBase contactBase) {
return this.setAuthInfo(contactBase.getAuthInfo())
.setContactId(contactBase.getContactId())
.setCreationClientId(contactBase.getCreationClientId())
.setCreationRegistrarId(contactBase.getCreationRegistrarId())
.setCreationTime(contactBase.getCreationTime())
.setDeletionTime(contactBase.getDeletionTime())
.setDisclose(contactBase.getDisclose())
@@ -96,10 +96,11 @@ public class ContactResource extends ContactBase
.setFaxNumber(contactBase.getFaxNumber())
.setInternationalizedPostalInfo(contactBase.getInternationalizedPostalInfo())
.setLastTransferTime(contactBase.getLastTransferTime())
.setLastEppUpdateClientId(contactBase.getLastEppUpdateClientId())
.setLastEppUpdateRegistrarId(contactBase.getLastEppUpdateRegistrarId())
.setLastEppUpdateTime(contactBase.getLastEppUpdateTime())
.setLocalizedPostalInfo(contactBase.getLocalizedPostalInfo())
.setPersistedCurrentSponsorClientId(contactBase.getPersistedCurrentSponsorClientId())
.setPersistedCurrentSponsorRegistrarId(
contactBase.getPersistedCurrentSponsorRegistrarId())
.setRepoId(contactBase.getRepoId())
.setStatusValues(contactBase.getStatusValues())
.setTransferData(contactBase.getTransferData())
@@ -65,7 +65,8 @@ import org.joda.time.DateTime;
@Index(columnList = "domainName"),
@Index(columnList = "techContact"),
@Index(columnList = "tld"),
@Index(columnList = "registrantContact")
@Index(columnList = "registrantContact"),
@Index(columnList = "dnsRefreshRequestTime")
})
@WithStringVKey
@ExternalMessagingName("domain")
@@ -193,7 +194,7 @@ public class DomainBase extends DomainContent
.setAutorenewBillingEvent(domainContent.getAutorenewBillingEvent())
.setAutorenewEndTime(domainContent.getAutorenewEndTime())
.setContacts(domainContent.getContacts())
.setCreationClientId(domainContent.getCreationClientId())
.setCreationRegistrarId(domainContent.getCreationRegistrarId())
.setCreationTime(domainContent.getCreationTime())
.setDomainName(domainContent.getDomainName())
.setDeletePollMessage(domainContent.getDeletePollMessage())
@@ -203,17 +204,19 @@ public class DomainBase extends DomainContent
.setIdnTableName(domainContent.getIdnTableName())
.setLastTransferTime(domainContent.getLastTransferTime())
.setLaunchNotice(domainContent.getLaunchNotice())
.setLastEppUpdateClientId(domainContent.getLastEppUpdateClientId())
.setLastEppUpdateRegistrarId(domainContent.getLastEppUpdateRegistrarId())
.setLastEppUpdateTime(domainContent.getLastEppUpdateTime())
.setNameservers(domainContent.getNameservers())
.setPersistedCurrentSponsorClientId(domainContent.getPersistedCurrentSponsorClientId())
.setPersistedCurrentSponsorRegistrarId(
domainContent.getPersistedCurrentSponsorRegistrarId())
.setRegistrant(domainContent.getRegistrant())
.setRegistrationExpirationTime(domainContent.getRegistrationExpirationTime())
.setRepoId(domainContent.getRepoId())
.setSmdId(domainContent.getSmdId())
.setSubordinateHosts(domainContent.getSubordinateHosts())
.setStatusValues(domainContent.getStatusValues())
.setTransferData(domainContent.getTransferData());
.setTransferData(domainContent.getTransferData())
.setDnsRefreshRequestTime(domainContent.getDnsRefreshRequestTime());
}
}
}
@@ -50,6 +50,7 @@ import com.googlecode.objectify.annotation.IgnoreSave;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.OnLoad;
import com.googlecode.objectify.condition.IfNull;
import google.registry.dns.RefreshDnsAction;
import google.registry.flows.ResourceFlowUtils;
import google.registry.model.EppResource;
import google.registry.model.EppResource.ResourceWithTransferData;
@@ -303,6 +304,35 @@ public class DomainContent extends EppResource
*/
@Index DateTime autorenewEndTime;
/**
* When this domain's DNS was requested to be refreshed, or null if its DNS is up-to-date.
*
* <p>This will almost always be null except in the couple minutes' interval between when a
* DNS-affecting create or update operation takes place and when the {@link RefreshDnsAction}
* runs, which resets this back to null upon completion of the DNS refresh task. This is a {@link
* DateTime} rather than a simple dirty boolean so that the DNS refresh action can order by the
* DNS refresh request time and take action on the oldest ones first.
*
* <p>Note that this is a Cloud SQL-based replacement for the {@code dns-pull} task queue. The
* domains that have a non-null value for this field should be exactly the same as the tasks that
* would be in the {@code dns-pull} queue. Because this is Cloud SQL-specific, it is omitted from
* Datastore.
*
* <p>Note that in the {@link DomainHistory} table this value means something slightly different:
* It means that the given domain action requested a DNS update. Unlike on the {@code Domain}
* table, this value is not then subsequently nulled out once the DNS refresh is complete; rather,
* it remains as a permanent record of which actions were DNS-affecting and which were not.
*/
// TODO(mcilwain): Start using this field once we are further along in the DB migration.
@Ignore DateTime dnsRefreshRequestTime;
/**
* Returns the DNS refresh request time iff this domain's DNS needs refreshing, otherwise absent.
*/
public Optional<DateTime> getDnsRefreshRequestTime() {
return Optional.ofNullable(dnsRefreshRequestTime);
}
@OnLoad
void load() {
// Reconstitute all of the contacts so that they have VKeys.
@@ -490,8 +520,8 @@ public class DomainContent extends EppResource
this.dsData = dsData;
}
public final String getCurrentSponsorClientId() {
return getPersistedCurrentSponsorClientId();
public final String getCurrentSponsorRegistrarId() {
return getPersistedCurrentSponsorRegistrarId();
}
/** Returns true if DNS information should be published for the given domain. */
@@ -587,7 +617,7 @@ public class DomainContent extends EppResource
domain.getRepoId(),
transferExpirationTime.plus(
Registry.get(domain.getTld()).getTransferGracePeriodLength()),
transferData.getGainingClientId(),
transferData.getGainingRegistrarId(),
transferData.getServerApproveBillingEvent())));
} else {
// There won't be a billing event, so we don't need a grace period
@@ -597,7 +627,7 @@ public class DomainContent extends EppResource
setAutomaticTransferSuccessProperties(builder, transferData);
builder
.setLastEppUpdateTime(transferExpirationTime)
.setLastEppUpdateClientId(transferData.getGainingClientId());
.setLastEppUpdateRegistrarId(transferData.getGainingRegistrarId());
// Finish projecting to now.
return (T) builder.build().cloneProjectedAtTime(now);
}
@@ -623,7 +653,7 @@ public class DomainContent extends EppResource
domain.getRepoId(),
lastAutorenewTime.plus(
Registry.get(domain.getTld()).getAutoRenewGracePeriodLength()),
domain.getCurrentSponsorClientId(),
domain.getCurrentSponsorRegistrarId(),
domain.getAutorenewBillingEvent()));
newLastEppUpdateTime = Optional.of(lastAutorenewTime);
}
@@ -649,7 +679,7 @@ public class DomainContent extends EppResource
|| newLastEppUpdateTime.get().isAfter(domain.getLastEppUpdateTime())) {
builder
.setLastEppUpdateTime(newLastEppUpdateTime.get())
.setLastEppUpdateClientId(domain.getCurrentSponsorClientId());
.setLastEppUpdateRegistrarId(domain.getCurrentSponsorRegistrarId());
}
}
@@ -967,6 +997,11 @@ public class DomainContent extends EppResource
return thisCastToDerived();
}
public B setDnsRefreshRequestTime(Optional<DateTime> dnsRefreshRequestTime) {
getInstance().dnsRefreshRequestTime = dnsRefreshRequestTime.orElse(null);
return thisCastToDerived();
}
public B setSmdId(String smdId) {
getInstance().smdId = smdId;
return thisCastToDerived();
@@ -176,8 +176,9 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
@Nullable
@Access(AccessType.PROPERTY)
@Column(name = "historyOtherRegistrarId")
@Override
public String getOtherRegistrarId() {
return super.getOtherClientId();
return super.getOtherRegistrarId();
}
/**
@@ -58,7 +58,7 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
GracePeriodStatus type,
String domainRepoId,
DateTime expirationTime,
String clientId,
String registrarId,
@Nullable VKey<BillingEvent.OneTime> billingEventOneTime,
@Nullable VKey<BillingEvent.Recurring> billingEventRecurring,
@Nullable Long gracePeriodId) {
@@ -72,7 +72,7 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
instance.type = checkArgumentNotNull(type);
instance.domainRepoId = checkArgumentNotNull(domainRepoId);
instance.expirationTime = checkArgumentNotNull(expirationTime);
instance.clientId = checkArgumentNotNull(clientId);
instance.clientId = checkArgumentNotNull(registrarId);
instance.billingEventOneTime = BillingEventVKey.create(billingEventOneTime);
instance.billingEventRecurring = BillingRecurrenceVKey.create(billingEventRecurring);
return instance;
@@ -89,10 +89,10 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
GracePeriodStatus type,
String domainRepoId,
DateTime expirationTime,
String clientId,
String registrarId,
@Nullable VKey<BillingEvent.OneTime> billingEventOneTime) {
return createInternal(
type, domainRepoId, expirationTime, clientId, billingEventOneTime, null, null);
type, domainRepoId, expirationTime, registrarId, billingEventOneTime, null, null);
}
/**
@@ -108,11 +108,11 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
GracePeriodStatus type,
String domainRepoId,
DateTime expirationTime,
String clientId,
String registrarId,
@Nullable VKey<BillingEvent.OneTime> billingEventOneTime,
@Nullable Long gracePeriodId) {
return createInternal(
type, domainRepoId, expirationTime, clientId, billingEventOneTime, null, gracePeriodId);
type, domainRepoId, expirationTime, registrarId, billingEventOneTime, null, gracePeriodId);
}
public static GracePeriod createFromHistory(GracePeriodHistory history) {
@@ -131,11 +131,11 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
GracePeriodStatus type,
String domainRepoId,
DateTime expirationTime,
String clientId,
String registrarId,
VKey<Recurring> billingEventRecurring) {
checkArgumentNotNull(billingEventRecurring, "billingEventRecurring cannot be null");
return createInternal(
type, domainRepoId, expirationTime, clientId, null, billingEventRecurring, null);
type, domainRepoId, expirationTime, registrarId, null, billingEventRecurring, null);
}
/** Creates a GracePeriod for a Recurring billing event and a given {@link #gracePeriodId}. */
@@ -144,18 +144,24 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
GracePeriodStatus type,
String domainRepoId,
DateTime expirationTime,
String clientId,
String registrarId,
VKey<Recurring> billingEventRecurring,
@Nullable Long gracePeriodId) {
checkArgumentNotNull(billingEventRecurring, "billingEventRecurring cannot be null");
return createInternal(
type, domainRepoId, expirationTime, clientId, null, billingEventRecurring, gracePeriodId);
type,
domainRepoId,
expirationTime,
registrarId,
null,
billingEventRecurring,
gracePeriodId);
}
/** Creates a GracePeriod with no billing event. */
public static GracePeriod createWithoutBillingEvent(
GracePeriodStatus type, String domainRepoId, DateTime expirationTime, String clientId) {
return createInternal(type, domainRepoId, expirationTime, clientId, null, null, null);
GracePeriodStatus type, String domainRepoId, DateTime expirationTime, String registrarId) {
return createInternal(type, domainRepoId, expirationTime, registrarId, null, null, null);
}
/** Constructs a GracePeriod of the given type from the provided one-time BillingEvent. */
@@ -165,7 +171,7 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
type,
domainRepoId,
billingEvent.getBillingTime(),
billingEvent.getClientId(),
billingEvent.getRegistrarId(),
billingEvent.createVKey());
}
@@ -175,7 +181,7 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
*
* <p>TODO(b/162739503): Remove this function after fully migrating to Cloud SQL.
*/
public GracePeriod cloneAfterOfyLoad(String domainRepoId) {
GracePeriod cloneAfterOfyLoad(String domainRepoId) {
GracePeriod clone = clone(this);
clone.domainRepoId = checkArgumentNotNull(domainRepoId);
return clone;
@@ -91,7 +91,7 @@ public class GracePeriodBase extends ImmutableObject {
return expirationTime;
}
public String getClientId() {
public String getRegistrarId() {
return clientId;
}
@@ -70,16 +70,16 @@ public class HostResource extends HostBase
}
public Builder copyFrom(HostBase hostBase) {
return this.setCreationClientId(hostBase.getCreationClientId())
return this.setCreationRegistrarId(hostBase.getCreationRegistrarId())
.setCreationTime(hostBase.getCreationTime())
.setDeletionTime(hostBase.getDeletionTime())
.setHostName(hostBase.getHostName())
.setInetAddresses(hostBase.getInetAddresses())
.setLastTransferTime(hostBase.getLastTransferTime())
.setLastSuperordinateChange(hostBase.getLastSuperordinateChange())
.setLastEppUpdateClientId(hostBase.getLastEppUpdateClientId())
.setLastEppUpdateRegistrarId(hostBase.getLastEppUpdateRegistrarId())
.setLastEppUpdateTime(hostBase.getLastEppUpdateTime())
.setPersistedCurrentSponsorClientId(hostBase.getPersistedCurrentSponsorClientId())
.setPersistedCurrentSponsorRegistrarId(hostBase.getPersistedCurrentSponsorRegistrarId())
.setRepoId(hostBase.getRepoId())
.setSuperordinateDomain(hostBase.getSuperordinateDomain())
.setStatusValues(hostBase.getStatusValues());
@@ -228,7 +228,7 @@ public abstract class ForeignKeyIndex<E extends EppResource> extends BackupGroup
tm().transact(
() ->
jpaTm()
.query(
.criteriaQuery(
CriteriaQueryBuilder.create(clazz)
.whereFieldIsIn(property, foreignKeys)
.build())
@@ -32,6 +32,7 @@ import com.google.common.collect.Streams;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Result;
import com.googlecode.objectify.cmd.Query;
import google.registry.model.ImmutableObject;
import google.registry.model.annotations.InCrossTld;
import google.registry.model.contact.ContactHistory;
import google.registry.model.domain.DomainHistory;
@@ -127,6 +128,11 @@ public class DatastoreTransactionManager implements TransactionManager {
putAll(entities);
}
@Override
public void insertAll(ImmutableObject... entities) {
putAll(entities);
}
@Override
public void insertWithoutBackup(Object entity) {
putWithoutBackup(entity);
@@ -143,7 +149,7 @@ public class DatastoreTransactionManager implements TransactionManager {
}
@Override
public void putAll(Object... entities) {
public void putAll(ImmutableObject... entities) {
syncIfTransactionless(
getOfy().save().entities(toDatastoreEntities(ImmutableList.copyOf(entities))));
}
@@ -142,7 +142,7 @@ public abstract class PollMessage extends ImmutableObject
return id;
}
public String getClientId() {
public String getRegistrarId() {
return clientId;
}
@@ -219,8 +219,8 @@ public abstract class PollMessage extends ImmutableObject
return thisCastToDerived();
}
public B setClientId(String clientId) {
getInstance().clientId = clientId;
public B setRegistrarId(String registrarId) {
getInstance().clientId = registrarId;
return thisCastToDerived();
}
@@ -441,8 +441,8 @@ public abstract class PollMessage extends ImmutableObject
transferResponse =
new ContactTransferResponse.Builder()
.setContactId(contactId)
.setGainingClientId(transferResponse.getGainingClientId())
.setLosingClientId(transferResponse.getLosingClientId())
.setGainingRegistrarId(transferResponse.getGainingRegistrarId())
.setLosingRegistrarId(transferResponse.getLosingRegistrarId())
.setTransferStatus(transferResponse.getTransferStatus())
.setTransferRequestTime(transferResponse.getTransferRequestTime())
.setPendingTransferExpirationTime(
@@ -453,8 +453,8 @@ public abstract class PollMessage extends ImmutableObject
transferResponse =
new DomainTransferResponse.Builder()
.setFullyQualifiedDomainName(fullyQualifiedDomainName)
.setGainingClientId(transferResponse.getGainingClientId())
.setLosingClientId(transferResponse.getLosingClientId())
.setGainingRegistrarId(transferResponse.getGainingRegistrarId())
.setLosingRegistrarId(transferResponse.getLosingRegistrarId())
.setTransferStatus(transferResponse.getTransferStatus())
.setTransferRequestTime(transferResponse.getTransferRequestTime())
.setPendingTransferExpirationTime(
@@ -222,14 +222,15 @@ public class Registrar extends ImmutableObject
comparing(RegistrarContact::getEmailAddress, String::compareTo);
/**
* A caching {@link Supplier} of a clientId to {@link Registrar} map.
* A caching {@link Supplier} of a registrarId to {@link Registrar} map.
*
* <p>The supplier's get() method enters a transactionless context briefly to avoid enrolling the
* query inside an unrelated client-affecting transaction.
*/
private static final Supplier<ImmutableMap<String, Registrar>> CACHE_BY_CLIENT_ID =
private static final Supplier<ImmutableMap<String, Registrar>> CACHE_BY_REGISTRAR_ID =
memoizeWithShortExpiration(
() -> tm().doTransactionless(() -> Maps.uniqueIndex(loadAll(), Registrar::getClientId)));
() ->
tm().doTransactionless(() -> Maps.uniqueIndex(loadAll(), Registrar::getRegistrarId)));
@Parent @Transient Key<EntityGroupRoot> parent = getCrossTldKey();
@@ -479,7 +480,7 @@ public class Registrar extends ImmutableObject
/** Whether or not registry lock is allowed for this registrar. */
boolean registryLockAllowed = false;
public String getClientId() {
public String getRegistrarId() {
return clientIdentifier;
}
@@ -764,13 +765,13 @@ public class Registrar extends ImmutableObject
super(instance);
}
public Builder setClientId(String clientId) {
// Client id must be [3,16] chars long. See "clIDType" in the base EPP schema of RFC 5730.
public Builder setRegistrarId(String registrarId) {
// Registrar id must be [3,16] chars long. See "clIDType" in the base EPP schema of RFC 5730.
// (Need to validate this here as there's no matching EPP XSD for validation.)
checkArgument(
Range.closed(3, 16).contains(clientId.length()),
"Client identifier must be 3-16 characters long.");
getInstance().clientIdentifier = clientId;
Range.closed(3, 16).contains(registrarId.length()),
"Registrar ID must be 3-16 characters long.");
getInstance().clientIdentifier = registrarId;
return this;
}
@@ -1026,40 +1027,40 @@ public class Registrar extends ImmutableObject
/** Loads all registrar entities using an in-memory cache. */
public static Iterable<Registrar> loadAllCached() {
return CACHE_BY_CLIENT_ID.get().values();
return CACHE_BY_REGISTRAR_ID.get().values();
}
/** Loads all registrar keys using an in-memory cache. */
public static ImmutableSet<VKey<Registrar>> loadAllKeysCached() {
return CACHE_BY_CLIENT_ID.get().keySet().stream()
return CACHE_BY_REGISTRAR_ID.get().keySet().stream()
.map(Registrar::createVKey)
.collect(toImmutableSet());
}
/** Loads and returns a registrar entity by its client id directly from Datastore. */
public static Optional<Registrar> loadByClientId(String clientId) {
checkArgument(!Strings.isNullOrEmpty(clientId), "clientId must be specified");
return transactIfJpaTm(() -> tm().loadByKeyIfPresent(createVKey(clientId)));
/** Loads and returns a registrar entity by its id directly from Datastore. */
public static Optional<Registrar> loadByRegistrarId(String registrarId) {
checkArgument(!Strings.isNullOrEmpty(registrarId), "registrarId must be specified");
return transactIfJpaTm(() -> tm().loadByKeyIfPresent(createVKey(registrarId)));
}
/**
* Loads and returns a registrar entity by its client id using an in-memory cache.
* Loads and returns a registrar entity by its id using an in-memory cache.
*
* <p>Returns empty if the registrar isn't found.
*/
public static Optional<Registrar> loadByClientIdCached(String clientId) {
checkArgument(!Strings.isNullOrEmpty(clientId), "clientId must be specified");
return Optional.ofNullable(CACHE_BY_CLIENT_ID.get().get(clientId));
public static Optional<Registrar> loadByRegistrarIdCached(String registrarId) {
checkArgument(!Strings.isNullOrEmpty(registrarId), "registrarId must be specified");
return Optional.ofNullable(CACHE_BY_REGISTRAR_ID.get().get(registrarId));
}
/**
* Loads and returns a registrar entity by its client id using an in-memory cache.
* Loads and returns a registrar entity by its id using an in-memory cache.
*
* <p>Throws if the registrar isn't found.
*/
public static Registrar loadRequiredRegistrarCached(String clientId) {
Optional<Registrar> registrar = loadByClientIdCached(clientId);
checkArgument(registrar.isPresent(), "couldn't find registrar '%s'", clientId);
public static Registrar loadRequiredRegistrarCached(String registrarId) {
Optional<Registrar> registrar = loadByRegistrarIdCached(registrarId);
checkArgument(registrar.isPresent(), "couldn't find registrar '%s'", registrarId);
return registrar.get();
}
}
@@ -229,7 +229,7 @@ public class RegistrarContact extends ImmutableObject
.query(
"DELETE FROM RegistrarPoc WHERE registrarId = :registrarId AND "
+ "emailAddress NOT IN :emailAddressesToKeep")
.setParameter("registrarId", registrar.getClientId())
.setParameter("registrarId", registrar.getRegistrarId())
.setParameter("emailAddressesToKeep", emailAddressesToKeep)
.executeUpdate();
}
@@ -260,11 +260,11 @@ public class HistoryEntry extends ImmutableObject implements Buildable, Datastor
return modificationTime;
}
public String getClientId() {
public String getRegistrarId() {
return clientId;
}
public String getOtherClientId() {
public String getOtherRegistrarId() {
return otherClientId;
}
@@ -489,13 +489,13 @@ public class HistoryEntry extends ImmutableObject implements Buildable, Datastor
return thisCastToDerived();
}
public B setClientId(String clientId) {
getInstance().clientId = clientId;
public B setRegistrarId(String registrarId) {
getInstance().clientId = registrarId;
return thisCastToDerived();
}
public B setOtherClientId(String otherClientId) {
getInstance().otherClientId = otherClientId;
public B setOtherRegistrarId(String otherRegistrarId) {
getInstance().otherClientId = otherRegistrarId;
return thisCastToDerived();
}

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