diff --git a/java/google/registry/backup/DeleteOldCommitLogsAction.java b/java/google/registry/backup/DeleteOldCommitLogsAction.java
index d8248e084..88c485483 100644
--- a/java/google/registry/backup/DeleteOldCommitLogsAction.java
+++ b/java/google/registry/backup/DeleteOldCommitLogsAction.java
@@ -25,7 +25,7 @@ import com.googlecode.objectify.Key;
import com.googlecode.objectify.Work;
import com.googlecode.objectify.cmd.Loader;
import com.googlecode.objectify.cmd.Query;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.ofy.CommitLogBucket;
import google.registry.model.ofy.CommitLogManifest;
import google.registry.model.ofy.CommitLogMutation;
@@ -58,9 +58,9 @@ import org.joda.time.Duration;
* therefore serves little use as an early warning to increase the number of buckets.
*
*
Before running, this task will perform an eventually consistent count query outside of a
- * transaction to see how much data actually exists to delete. If it's less than a tenth of
- * {@link #maxDeletes}, then we don't bother running the task. This is to minimize contention on the
- * bucket and avoid wasting resources.
+ * transaction to see how much data actually exists to delete. If it's less than a tenth of {@link
+ * #maxDeletes}, then we don't bother running the task. This is to minimize contention on the bucket
+ * and avoid wasting resources.
*
*
Dimensioning
*
@@ -68,8 +68,8 @@ import org.joda.time.Duration;
* there's a 10mB upper bound on transaction size and a four minute time limit, we can only delete
* so many commit logs at once. So given the above constraints, five hundred would make a safe
* default value for {@code maxDeletes}. See {@linkplain
- * google.registry.config.ConfigModule#provideCommitLogMaxDeletes() commitLogMaxDeletes}
- * for further documentation on this matter.
+ * google.registry.config.RegistryConfig.ConfigModule#provideCommitLogMaxDeletes()
+ * commitLogMaxDeletes} for further documentation on this matter.
*
* Finally, we need to pick an appropriate cron interval time for this task. Since a bucket
* represents a single datastore entity group, it's only guaranteed to have one transaction per
diff --git a/java/google/registry/backup/ExportCommitLogDiffAction.java b/java/google/registry/backup/ExportCommitLogDiffAction.java
index 59c0a49ff..dbfa99bc4 100644
--- a/java/google/registry/backup/ExportCommitLogDiffAction.java
+++ b/java/google/registry/backup/ExportCommitLogDiffAction.java
@@ -39,7 +39,7 @@ import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.ImmutableObject;
import google.registry.model.ofy.CommitLogBucket;
import google.registry.model.ofy.CommitLogCheckpoint;
diff --git a/java/google/registry/backup/GcsDiffFileLister.java b/java/google/registry/backup/GcsDiffFileLister.java
index 968865dd3..127fd2140 100644
--- a/java/google/registry/backup/GcsDiffFileLister.java
+++ b/java/google/registry/backup/GcsDiffFileLister.java
@@ -31,7 +31,7 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import google.registry.backup.BackupModule.Backups;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.util.FormattingLogger;
import java.io.IOException;
import java.util.HashMap;
diff --git a/java/google/registry/batch/BatchComponent.java b/java/google/registry/batch/BatchComponent.java
index c5c512bbc..e562e2aa1 100644
--- a/java/google/registry/batch/BatchComponent.java
+++ b/java/google/registry/batch/BatchComponent.java
@@ -16,7 +16,7 @@ package google.registry.batch;
import dagger.Component;
import google.registry.bigquery.BigqueryModule;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.monitoring.whitebox.WhiteboxModule;
import google.registry.request.Modules.DatastoreServiceModule;
import google.registry.util.SystemSleeper.SystemSleeperModule;
diff --git a/java/google/registry/batch/VerifyEntityIntegrityStreamer.java b/java/google/registry/batch/VerifyEntityIntegrityStreamer.java
index fe65ac61a..dcbf62c54 100644
--- a/java/google/registry/batch/VerifyEntityIntegrityStreamer.java
+++ b/java/google/registry/batch/VerifyEntityIntegrityStreamer.java
@@ -37,7 +37,7 @@ import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.bigquery.BigqueryFactory;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.util.Retrier;
import java.io.IOException;
import java.util.List;
diff --git a/java/google/registry/bigquery/BigqueryModule.java b/java/google/registry/bigquery/BigqueryModule.java
index e9bdf83a2..75aaae6c7 100644
--- a/java/google/registry/bigquery/BigqueryModule.java
+++ b/java/google/registry/bigquery/BigqueryModule.java
@@ -25,7 +25,7 @@ import com.google.common.collect.ImmutableList;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.Multibinds;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import java.util.Map;
import java.util.Set;
diff --git a/java/google/registry/braintree/BraintreeModule.java b/java/google/registry/braintree/BraintreeModule.java
index 000c435d8..d3bcbb578 100644
--- a/java/google/registry/braintree/BraintreeModule.java
+++ b/java/google/registry/braintree/BraintreeModule.java
@@ -17,7 +17,7 @@ package google.registry.braintree;
import com.braintreegateway.BraintreeGateway;
import dagger.Module;
import dagger.Provides;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.config.RegistryEnvironment;
import google.registry.keyring.api.KeyModule.Key;
import javax.inject.Singleton;
diff --git a/java/google/registry/config/ConfigModule.java b/java/google/registry/config/ConfigModule.java
deleted file mode 100644
index 5c53aa576..000000000
--- a/java/google/registry/config/ConfigModule.java
+++ /dev/null
@@ -1,1081 +0,0 @@
-// Copyright 2016 The Nomulus Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package google.registry.config;
-
-import static google.registry.config.ConfigUtils.makeUrl;
-import static org.joda.time.Duration.standardDays;
-
-import com.google.appengine.api.utils.SystemProperty;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import dagger.Module;
-import dagger.Provides;
-import java.lang.annotation.Documented;
-import java.net.URI;
-import java.net.URL;
-import javax.annotation.Nullable;
-import javax.inject.Qualifier;
-import javax.inject.Singleton;
-import org.joda.money.CurrencyUnit;
-import org.joda.time.DateTimeConstants;
-import org.joda.time.Duration;
-
-/**
- * Configuration example for the Nomulus codebase.
- *
- *
The Nomulus codebase contains many classes that inject configurable settings. This is
- * the centralized class that is used by default to configure them all, in hard-coded type-safe
- * Java code.
- *
- *
This class does not represent the total configuration of the Nomulus service. It's
- * only meant for settings that need to be configured once. Settings which may
- * be subject to change in the future, should instead be retrieved from Datastore. The
- * {@link google.registry.model.registry.Registry Registry} class is one such example of this.
- *
- *
Customization
- *
- * It is recommended that users do not modify this file within a forked repository. It is
- * preferable to modify these settings by swapping out this module with a separate copied version
- * in the user's repository. For this to work, other files need to be copied too, such as the
- * {@code @Component} instances under {@code google.registry.module}. This allows modules to be
- * substituted at the {@code @Component} level.
- */
-@Module
-public final class ConfigModule {
-
- /** Dagger qualifier for configuration settings. */
- @Qualifier
- @Documented
- public static @interface Config {
- String value() default "";
- }
-
- private static final RegistryEnvironment REGISTRY_ENVIRONMENT = RegistryEnvironment.get();
-
- @Provides
- public static RegistryEnvironment provideRegistryEnvironment() {
- return REGISTRY_ENVIRONMENT;
- }
-
- @Provides
- @Config("projectId")
- public static String provideProjectId() {
- return RegistryConfig.getProjectId();
- }
-
- /**
- * The filename of the logo to be displayed in the header of the registrar console.
- *
- * @see google.registry.ui.server.registrar.ConsoleUiAction
- */
- @Provides
- @Config("logoFilename")
- public static String provideLogoFilename(RegistryEnvironment environment) {
- switch (environment) {
- case UNITTEST:
- case LOCAL:
- return "logo.png";
- default:
- // Change this to the filename of your logo.
- return "google_registry.png";
- }
- }
-
- /**
- * The product name of this specific registry. Used throughout the registrar console.
- *
- * @see google.registry.ui.server.registrar.ConsoleUiAction
- */
- @Provides
- @Config("productName")
- public static String provideProductName(RegistryEnvironment environment) {
- // Change this to the name of your product.
- return "Nomulus";
- }
-
- /**
- * Returns the roid suffix to be used for the roids of all contacts and hosts. E.g. a value of
- * "ROID" would end up creating roids that look like "ABC123-ROID".
- *
- * @see
- * Extensible Provisioning Protocol (EPP) Repository Identifiers
- */
- @Provides
- @Config("contactAndHostRoidSuffix")
- public static String provideContactAndHostRoidSuffix(RegistryEnvironment environment) {
- return LocalTestConfig.CONTACT_AND_HOST_ROID_SUFFIX;
- }
-
- /**
- * The e-mail address for questions about integrating with the registry. Used in the
- * "contact-us" section of the registrar console.
- *
- * @see google.registry.ui.server.registrar.ConsoleUiAction
- */
- @Provides
- @Config("integrationEmail")
- public static String provideIntegrationEmail(RegistryEnvironment environment) {
- // Change this to your integration email address.
- return "integration@example.com";
- }
-
- /**
- * The e-mail address for general support. Used in the "contact-us" section of the registrar
- * console.
- *
- * @see google.registry.ui.server.registrar.ConsoleUiAction
- */
- @Provides
- @Config("supportEmail")
- public static String provideSupportEmail(RegistryEnvironment environment) {
- // Change this to your support email address.
- return "support@example.com";
- }
-
- /**
- * The "From" e-mail address for announcements. Used in the "contact-us" section of the
- * registrar console.
- *
- * @see google.registry.ui.server.registrar.ConsoleUiAction
- */
- @Provides
- @Config("announcementsEmail")
- public static String provideAnnouncementsEmail(RegistryEnvironment environment) {
- // Change this to your announcements e-mail.
- return "announcements@example.com";
- }
-
- /**
- * The contact phone number. Used in the "contact-us" section of the registrar console.
- *
- * @see google.registry.ui.server.registrar.ConsoleUiAction
- */
- @Provides
- @Config("supportPhoneNumber")
- public static String provideSupportPhoneNumber(RegistryEnvironment environment) {
- // Change this to your phone number.
- return "+1 (888) 555 0123";
- }
-
- /**
- * The URL for technical support docs. Used in the "contact-us" section of the registrar console.
- *
- * @see google.registry.ui.server.registrar.ConsoleUiAction
- */
- @Provides
- @Config("technicalDocsUrl")
- public static String provideTechnicalDocsUrl(RegistryEnvironment environment) {
- // Change this to your support docs link.
- return "http://example.com/your_support_docs/";
- }
-
- /**
- * Returns the Google Cloud Storage bucket for storing zone files.
- *
- * @see google.registry.backup.ExportCommitLogDiffAction
- */
- @Provides
- @Config("zoneFilesBucket")
- public static String provideZoneFilesBucket(@Config("projectId") String projectId) {
- return projectId + "-zonefiles";
- }
-
- /**
- * Returns the Google Cloud Storage bucket for storing commit logs.
- *
- * @see google.registry.backup.ExportCommitLogDiffAction
- */
- @Provides
- @Config("commitLogGcsBucket")
- public static String provideCommitLogGcsBucket(@Config("projectId") String projectId) {
- return projectId + "-commits";
- }
-
- /** @see RegistryConfig#getCommitLogDatastoreRetention() */
- @Provides
- @Config("commitLogDatastoreRetention")
- public static Duration provideCommitLogDatastoreRetention() {
- return RegistryConfig.getCommitLogDatastoreRetention();
- }
-
- /**
- * The GCS bucket for exporting domain lists.
- *
- * @see google.registry.export.ExportDomainListsAction
- */
- @Provides
- @Config("domainListsGcsBucket")
- public static String provideDomainListsGcsBucket(@Config("projectId") String projectId) {
- return projectId + "-domain-lists";
- }
-
- /**
- * Maximum number of commit logs to delete per transaction.
- *
- *
If we assume that the average key size is 256 bytes and that each manifest has six
- * mutations, we can do about 5,000 deletes in a single transaction before hitting the 10mB limit.
- * Therefore 500 should be a safe number, since it's an order of a magnitude less space than we
- * need.
- *
- *
Transactions also have a four minute time limit. Since we have to perform N subqueries to
- * fetch mutation keys, 500 would be a safe number if those queries were performed in serial,
- * since each query would have about 500ms to complete, which is an order a magnitude more time
- * than we need. However this does not apply, since the subqueries are performed asynchronously.
- *
- * @see google.registry.backup.DeleteOldCommitLogsAction
- */
- @Provides
- @Config("commitLogMaxDeletes")
- public static int provideCommitLogMaxDeletes() {
- return 500;
- }
-
- /**
- * Batch size for the number of transactions' worth of commit log data to process at once when
- * exporting a commit log diff.
- *
- * @see google.registry.backup.ExportCommitLogDiffAction
- */
- @Provides
- @Config("commitLogDiffExportBatchSize")
- public static int provideCommitLogDiffExportBatchSize() {
- return 100;
- }
-
- /**
- * Returns the Google Cloud Storage bucket for staging BRDA escrow deposits.
- *
- * @see google.registry.rde.PendingDepositChecker
- */
- @Provides
- @Config("brdaBucket")
- public static String provideBrdaBucket(@Config("projectId") String projectId) {
- return projectId + "-icann-brda";
- }
-
- /** @see google.registry.rde.BrdaCopyAction */
- @Provides
- @Config("brdaDayOfWeek")
- public static int provideBrdaDayOfWeek() {
- return DateTimeConstants.TUESDAY;
- }
-
- /**
- * Amount of time between BRDA deposits.
- *
- * @see google.registry.rde.PendingDepositChecker
- */
- @Provides
- @Config("brdaInterval")
- public static Duration provideBrdaInterval() {
- return Duration.standardDays(7);
- }
-
- /**
- * Returns {@code true} if the target zone should be created in DNS if it does not exist.
- */
- @Provides
- @Config("dnsCreateZone")
- public static boolean provideDnsCreateZone(RegistryEnvironment environment) {
- switch (environment) {
- case PRODUCTION:
- return false;
- default:
- return true;
- }
- }
-
- /**
- * The maximum number of domain and host updates to batch together to send to
- * PublishDnsUpdatesAction, to avoid exceeding AppEngine's limits.
- *
- * @see google.registry.dns.ReadDnsQueueAction
- */
- @Provides
- @Config("dnsTldUpdateBatchSize")
- public static int provideDnsTldUpdateBatchSize() {
- return 100;
- }
-
- /**
- * The maximum interval (seconds) to lease tasks from the dns-pull queue.
- *
- * @see google.registry.dns.ReadDnsQueueAction
- * @see google.registry.dns.PublishDnsUpdatesAction
- */
- @Provides
- @Config("dnsWriteLockTimeout")
- public static Duration provideDnsWriteLockTimeout() {
- // Optimally, we would set this to a little less than the length of the DNS refresh cycle, since
- // otherwise, a new PublishDnsUpdatesAction could get kicked off before the current one has
- // finished, which will try and fail to acquire the lock. However, it is more important that it
- // be greater than the DNS write timeout, so that if that timeout occurs, it will be cleaned up
- // gracefully, rather than having the lock time out. So we have to live with the possible lock
- // failures.
- return Duration.standardSeconds(75);
- }
-
- /**
- * Returns the default time to live for DNS records.
- *
- * @see google.registry.dns.writer.clouddns.CloudDnsWriter
- */
- @Provides
- @Config("dnsDefaultTtl")
- public static Duration provideDnsDefaultTtl() {
- return Duration.standardSeconds(180);
- }
-
- /**
- * Number of sharded entity group roots used for performing strongly consistent scans.
- *
- *
Warning: This number may increase but never decrease.
- *
- * @see google.registry.model.index.EppResourceIndex
- */
- @Provides
- @Config("eppResourceIndexBucketCount")
- public static int provideEppResourceIndexBucketCount() {
- return RegistryConfig.getEppResourceIndexBucketCount();
- }
-
- /**
- * Returns size of Google Cloud Storage client connection buffer in bytes.
- *
- * @see google.registry.gcs.GcsUtils
- */
- @Provides
- @Config("gcsBufferSize")
- public static int provideGcsBufferSize() {
- return 1024 * 1024;
- }
-
- /**
- * Gets the email address of the admin account for the Google App.
- *
- * @see google.registry.groups.DirectoryGroupsConnection
- */
- @Provides
- @Config("googleAppsAdminEmailAddress")
- public static String provideGoogleAppsAdminEmailAddress(RegistryEnvironment environment) {
- // Change this to your admin account.
- return "admin@example.com";
- }
-
- /**
- * Returns the email address(es) that notifications of registrar and/or registrar contact updates
- * should be sent to, or the empty list if updates should not be sent.
- *
- * @see google.registry.ui.server.registrar.RegistrarSettingsAction
- */
- @Provides
- @Config("registrarChangesNotificationEmailAddresses")
- public static ImmutableList provideRegistrarChangesNotificationEmailAddresses(
- RegistryEnvironment environment) {
- switch (environment) {
- case PRODUCTION:
- // Change this to an appropriate notification e-mail address.
- return ImmutableList.of("notification@registry.example");
- case UNITTEST:
- return ImmutableList.of("notification@test.example", "notification2@test.example");
- default:
- return ImmutableList.of();
- }
- }
-
- /**
- * Returns the publicly accessible domain name for the running Google Apps instance.
- *
- * @see google.registry.export.SyncGroupMembersAction
- * @see google.registry.tools.server.CreateGroupsAction
- */
- @Provides
- @Config("publicDomainName")
- public static String providePublicDomainName(RegistryEnvironment environment) {
- // Change this to your domain name.
- return "registry.example.com";
- }
-
- /**
- * Returns {@code true} if TMCH certificate authority should be in testing mode.
- *
- * @see RegistryConfig#getTmchCaTestingMode()
- */
- @Provides
- @Config("tmchCaTestingMode")
- public static boolean provideTmchCaTestingMode() {
- return RegistryConfig.getTmchCaTestingMode();
- }
-
- /**
- * ICANN TMCH Certificate Revocation List URL.
- *
- * This file needs to be downloaded at least once a day and verified to make sure it was
- * signed by {@code icann-tmch.crt}.
- *
- * @see google.registry.tmch.TmchCrlAction
- * @see "http://tools.ietf.org/html/draft-lozano-tmch-func-spec-08#section-5.2.3.2"
- */
- @Provides
- @Config("tmchCrlUrl")
- public static URL provideTmchCrlUrl(RegistryEnvironment environment) {
- switch (environment) {
- case PRODUCTION:
- return makeUrl("http://crl.icann.org/tmch.crl");
- default:
- return makeUrl("http://crl.icann.org/tmch_pilot.crl");
- }
- }
-
- /**
- * URL prefix for communicating with MarksDB ry interface.
- *
- *
This URL is used for DNL, SMDRL, and LORDN.
- *
- * @see google.registry.tmch.Marksdb
- * @see google.registry.tmch.NordnUploadAction
- */
- @Provides
- @Config("tmchMarksdbUrl")
- public static String provideTmchMarksdbUrl(RegistryEnvironment environment) {
- switch (environment) {
- case PRODUCTION:
- case UNITTEST:
- return "https://ry.marksdb.org";
- default:
- return "https://test.ry.marksdb.org";
- }
- }
-
- /**
- * The email address that outgoing emails from the app are sent from.
- *
- * @see google.registry.util.SendEmailUtils
- */
- @Provides
- @Config("googleAppsSendFromEmailAddress")
- public static String provideGoogleAppsSendFromEmailAddress() {
- return String.format("noreply@%s.appspotmail.com", SystemProperty.applicationId.get());
- }
-
- /**
- * The display name that is used on outgoing emails sent by Nomulus.
- *
- * @see google.registry.util.SendEmailUtils
- */
- @Provides
- @Config("googleAppsAdminEmailDisplayName")
- public static String provideGoogleAppsAdminEmailDisplayName() {
- // Production example: "Example Registry"
- return "Google Domain Registry";
- }
-
- /**
- * Returns the Google Cloud Storage bucket for staging escrow deposits pending upload.
- *
- * @see google.registry.rde.RdeStagingAction
- */
- @Provides
- @Config("rdeBucket")
- public static String provideRdeBucket(@Config("projectId") String projectId) {
- return projectId + "-rde";
- }
-
- /**
- * Returns the Google Cloud Storage bucket for importing escrow files.
- *
- * @see google.registry.rde.imports.RdeContactImportAction
- * @see google.registry.rde.imports.RdeHostImportAction
- */
- @Provides
- @Config("rdeImportBucket")
- public static String provideRdeImportBucket(@Config("projectId") String projectId) {
- return projectId + "-rde-import";
- }
-
- /**
- * Size of Ghostryde buffer in bytes for each layer in the pipeline.
- *
- * @see google.registry.rde.Ghostryde
- */
- @Provides
- @Config("rdeGhostrydeBufferSize")
- public static Integer provideRdeGhostrydeBufferSize() {
- return 64 * 1024;
- }
-
- /**
- * Amount of time between RDE deposits.
- *
- * @see google.registry.rde.PendingDepositChecker
- * @see google.registry.rde.RdeReportAction
- * @see google.registry.rde.RdeUploadAction
- */
- @Provides
- @Config("rdeInterval")
- public static Duration provideRdeInterval() {
- return Duration.standardDays(1);
- }
-
- /**
- * Maximum amount of time for sending a small XML file to ICANN via HTTP, before killing.
- *
- * @see google.registry.rde.RdeReportAction
- */
- @Provides
- @Config("rdeReportLockTimeout")
- public static Duration provideRdeReportLockTimeout() {
- return Duration.standardSeconds(60);
- }
-
- /**
- * URL of ICANN's HTTPS server to which the RDE report should be {@code PUT}.
- *
- *
You must append {@code "/TLD/ID"} to this URL.
- *
- * @see google.registry.rde.RdeReportAction
- */
- @Provides
- @Config("rdeReportUrlPrefix")
- public static String provideRdeReportUrlPrefix(RegistryEnvironment environment) {
- switch (environment) {
- case PRODUCTION:
- return "https://ry-api.icann.org/report/registry-escrow-report";
- default:
- return "https://test-ry-api.icann.org:8543/report/registry-escrow-report";
- }
- }
-
- /**
- * Size of RYDE generator buffer in bytes for each of the five layers.
- *
- * @see google.registry.rde.RydePgpCompressionOutputStream
- * @see google.registry.rde.RydePgpFileOutputStream
- * @see google.registry.rde.RydePgpSigningOutputStream
- * @see google.registry.rde.RydeTarOutputStream
- */
- @Provides
- @Config("rdeRydeBufferSize")
- public static Integer provideRdeRydeBufferSize() {
- return 64 * 1024;
- }
-
- /**
- * Maximum amount of time generating an escrow deposit for a TLD could take, before killing.
- *
- * @see google.registry.rde.RdeStagingReducer
- */
- @Provides
- @Config("rdeStagingLockTimeout")
- public static Duration provideRdeStagingLockTimeout() {
- return Duration.standardHours(5);
- }
-
- /**
- * Maximum amount of time it should ever take to upload an escrow deposit, before killing.
- *
- * @see google.registry.rde.RdeUploadAction
- */
- @Provides
- @Config("rdeUploadLockTimeout")
- public static Duration provideRdeUploadLockTimeout() {
- return Duration.standardMinutes(30);
- }
-
- /**
- * Minimum amount of time to wait between consecutive SFTP uploads on a single TLD.
- *
- *
This value was communicated to us by the escrow provider.
- *
- * @see google.registry.rde.RdeStagingReducer
- */
- @Provides
- @Config("rdeUploadSftpCooldown")
- public static Duration provideRdeUploadSftpCooldown() {
- return Duration.standardHours(2);
- }
-
- /**
- * Returns the identity (an email address) used for the SSH keys used in RDE SFTP uploads.
- *
- * @see google.registry.keyring.api.Keyring#getRdeSshClientPublicKey()
- * @see google.registry.keyring.api.Keyring#getRdeSshClientPrivateKey()
- */
- @Provides
- @Config("rdeSshIdentity")
- public static String provideSshIdentity() {
- // Change this to your RDE identity.
- return "rde@example.com";
- }
-
- /**
- * Returns SFTP URL containing a username, hostname, port (optional), and directory (optional) to
- * which cloud storage files are uploaded. The password should not be included, as it's better to
- * use public key authentication.
- *
- * @see google.registry.rde.RdeUploadAction
- */
- @Provides
- @Config("rdeUploadUrl")
- public static URI provideRdeUploadUrl(RegistryEnvironment environment) {
- switch (environment) {
- case PRODUCTION:
- return URI.create("sftp://GoogleTLD@sftpipm2.ironmountain.com/Outbox");
- default:
- return URI.create("sftp://google@ppftpipm.ironmountain.com/Outbox");
- }
- }
-
- /**
- * Whether or not the registrar console is enabled.
- *
- * @see google.registry.ui.server.registrar.ConsoleUiAction
- */
- @Provides
- @Config("registrarConsoleEnabled")
- public static boolean provideRegistrarConsoleEnabled() {
- return true;
- }
-
- /**
- * Maximum amount of time for syncing a spreadsheet, before killing.
- *
- * @see google.registry.export.sheet.SyncRegistrarsSheetAction
- */
- @Provides
- @Config("sheetLockTimeout")
- public static Duration provideSheetLockTimeout() {
- return Duration.standardHours(1);
- }
-
- /**
- * Returns ID of Google Spreadsheet to which Registrar entities should be synced.
- *
- *
This ID, as you'd expect, comes from the URL of the spreadsheet.
- *
- * @see google.registry.export.sheet.SyncRegistrarsSheetAction
- */
- @Provides
- @Config("sheetRegistrarId")
- public static Optional provideSheetRegistrarId(RegistryEnvironment environment) {
- switch (environment) {
- case PRODUCTION:
- return Optional.of("1n2Gflqsgo9iDXcdt9VEskOVySZ8qIhQHJgjqsleCKdE");
- case ALPHA:
- case CRASH:
- return Optional.of("16BwRt6v11Iw-HujCbAkmMxqw3sUG13B8lmXLo-uJTsE");
- case SANDBOX:
- return Optional.of("1TlR_UMCtfpkxT9oUEoF5JEbIvdWNkLRuURltFkJ_7_8");
- case QA:
- return Optional.of("1RoY1XZhLLwqBkrz0WbEtaT9CU6c8nUAXfId5BtM837o");
- default:
- return Optional.absent();
- }
- }
-
- /**
- * Returns SSH client connection and read timeout.
- *
- * @see google.registry.rde.RdeUploadAction
- */
- @Provides
- @Config("sshTimeout")
- public static Duration provideSshTimeout() {
- return Duration.standardSeconds(30);
- }
-
- /**
- * Duration after watermark where we shouldn't deposit, because transactions might be pending.
- *
- * @see google.registry.rde.RdeStagingAction
- */
- @Provides
- @Config("transactionCooldown")
- public static Duration provideTransactionCooldown() {
- return Duration.standardMinutes(5);
- }
-
- /**
- * Number of times to retry a GAE operation when {@code TransientFailureException} is thrown.
- *
- * The number of milliseconds it'll sleep before giving up is {@code 2^n - 2}.
- *
- * @see google.registry.util.TaskEnqueuer
- */
- @Provides
- @Config("transientFailureRetries")
- public static int provideTransientFailureRetries() {
- return 12; // Four seconds.
- }
-
- /**
- * Amount of time public HTTP proxies are permitted to cache our WHOIS responses.
- *
- * @see google.registry.whois.WhoisHttpServer
- */
- @Provides
- @Config("whoisHttpExpires")
- public static Duration provideWhoisHttpExpires() {
- return Duration.standardDays(1);
- }
-
- /**
- * Maximum number of results to return for an RDAP search query
- *
- * @see google.registry.rdap.RdapActionBase
- */
- @Provides
- @Config("rdapResultSetMaxSize")
- public static int provideRdapResultSetMaxSize() {
- return 100;
- }
-
- /**
- * Base for RDAP link paths.
- *
- * @see google.registry.rdap.RdapActionBase
- */
- @Provides
- @Config("rdapLinkBase")
- public static String provideRdapLinkBase() {
- return "https://nic.google/rdap/";
- }
-
- /**
- * WHOIS server displayed in RDAP query responses. As per Gustavo Lozano of ICANN, this should be
- * omitted, but the ICANN operational profile doesn't actually say that, so it's good to have the
- * ability to reinstate this field if necessary.
- *
- * @see google.registry.rdap.RdapActionBase
- */
- @Nullable
- @Provides
- @Config("rdapWhoisServer")
- public static String provideRdapWhoisServer() {
- return null;
- }
-
- /**
- * Returns Braintree Merchant Account IDs for each supported currency.
- *
- * @see google.registry.ui.server.registrar.RegistrarPaymentAction
- * @see google.registry.ui.server.registrar.RegistrarPaymentSetupAction
- */
- @Provides
- @Config("braintreeMerchantAccountIds")
- public static ImmutableMap provideBraintreeMerchantAccountId(
- RegistryEnvironment environment) {
- switch (environment) {
- case PRODUCTION:
- return ImmutableMap.of(
- CurrencyUnit.USD, "charlestonregistryUSD",
- CurrencyUnit.JPY, "charlestonregistryJPY");
- default:
- return ImmutableMap.of(
- CurrencyUnit.USD, "google",
- CurrencyUnit.JPY, "google-jpy");
- }
- }
-
- /**
- * Returns Braintree Merchant ID of Registry, used for accessing Braintree API.
- *
- * This is a base32 value copied from the Braintree website.
- *
- * @see google.registry.braintree.BraintreeModule
- */
- @Provides
- @Config("braintreeMerchantId")
- public static String provideBraintreeMerchantId(RegistryEnvironment environment) {
- switch (environment) {
- case PRODUCTION:
- return "6gm2mm48k9ty4zmx";
- default:
- // Valentine: Nomulus Braintree Sandbox
- return "vqgn8khkq2cs6y9s";
- }
- }
-
- /**
- * Returns Braintree Public Key of Registry, used for accessing Braintree API.
- *
- *
This is a base32 value copied from the Braintree website.
- *
- * @see google.registry.braintree.BraintreeModule
- * @see google.registry.keyring.api.Keyring#getBraintreePrivateKey()
- */
- @Provides
- @Config("braintreePublicKey")
- public static String provideBraintreePublicKey(RegistryEnvironment environment) {
- switch (environment) {
- case PRODUCTION:
- return "tzcfxggzgbh2jg5x";
- default:
- // Valentine: Nomulus Braintree Sandbox
- return "tzcyzvm3mn7zkdnx";
- }
- }
-
- /**
- * Disclaimer displayed at the end of WHOIS query results.
- *
- * @see google.registry.whois.WhoisResponse
- */
- @Provides
- @Config("whoisDisclaimer")
- public static String provideWhoisDisclaimer() {
- return "WHOIS information is provided by Charleston Road Registry Inc. (CRR) solely for\n"
- + "query-based, informational purposes. By querying our WHOIS database, you are\n"
- + "agreeing to comply with these terms\n"
- + "(http://www.registry.google/about/whois-disclaimer.html) so please read them\n"
- + "carefully. Any information provided is \"as is\" without any guarantee of\n"
- + "accuracy. You may not use such information to (a) allow, enable, or otherwise\n"
- + "support the transmission of mass unsolicited, commercial advertising or\n"
- + "solicitations; (b) enable high volume, automated, electronic processes that\n"
- + "access the systems of CRR or any ICANN-Accredited Registrar, except as\n"
- + "reasonably necessary to register domain names or modify existing registrations;\n"
- + "or (c) engage in or support unlawful behavior. CRR reserves the right to\n"
- + "restrict or deny your access to the Whois database, and may modify these terms\n"
- + "at any time.\n";
- }
-
- /**
- * Maximum QPS for the Google Cloud Monitoring V3 (aka Stackdriver) API. The QPS limit can be
- * adjusted by contacting Cloud Support.
- *
- * @see google.registry.monitoring.metrics.StackdriverWriter
- */
- @Provides
- @Config("stackdriverMaxQps")
- public static int provideStackdriverMaxQps() {
- return 30;
- }
-
- /**
- * Maximum number of points that can be sent to Stackdriver in a single TimeSeries.Create API
- * call.
- *
- * @see google.registry.monitoring.metrics.StackdriverWriter
- */
- @Provides
- @Config("stackdriverMaxPointsPerRequest")
- public static int provideStackdriverMaxPointsPerRequest() {
- return 200;
- }
-
- /**
- * The reporting interval, for BigQueryMetricsEnqueuer to be sent to a {@link
- * google.registry.monitoring.metrics.MetricWriter}.
- *
- * @see google.registry.monitoring.metrics.MetricReporter
- */
- @Provides
- @Config("metricsWriteInterval")
- public static Duration provideMetricsWriteInterval() {
- return Duration.standardSeconds(60);
- }
-
- /**
- * The global automatic transfer length for contacts. After this amount of time has
- * elapsed, the transfer is automatically approved.
- *
- * @see google.registry.flows.contact.ContactTransferRequestFlow
- */
- @Provides
- @Config("contactAutomaticTransferLength")
- public static Duration provideContactAutomaticTransferLength() {
- return standardDays(5);
- }
-
- /**
- * Returns the maximum number of entities that can be checked at one time in an EPP check flow.
- */
- @Provides
- @Config("maxChecks")
- public static int provideMaxChecks() {
- return 50;
- }
-
- /**
- * Returns the delay before executing async delete flow mapreduces.
- *
- *
This delay should be sufficiently longer than a transaction, to solve the following problem:
- *
- * - a domain mutation flow starts a transaction
- *
- the domain flow non-transactionally reads a resource and sees that it's not in
- * PENDING_DELETE
- *
- the domain flow creates a new reference to this resource
- *
- a contact/host delete flow runs and marks the resource PENDING_DELETE and commits
- *
- the domain flow commits
- *
- *
- * Although we try not to add references to a PENDING_DELETE resource, strictly speaking that
- * is ok as long as the mapreduce eventually sees the new reference (and therefore asynchronously
- * fails the delete). Without this delay, the mapreduce might have started before the domain flow
- * committed, and could potentially miss the reference.
- *
- * @see google.registry.flows.async.AsyncFlowEnqueuer
- */
- @Provides
- @Config("asyncDeleteFlowMapreduceDelay")
- public static Duration provideAsyncDeleteFlowMapreduceDelay() {
- return Duration.standardSeconds(90);
- }
-
- /**
- * The server ID used in the 'svID' element of an EPP 'greeting'.
- *
- * @see RFC 7530
- */
- @Provides
- @Config("greetingServerId")
- public static String provideGreetingServerId() {
- return "Charleston Road Registry";
- }
-
- @Provides
- @Config("customLogicFactoryClass")
- public static String provideCustomLogicFactoryClass() {
- // TODO(b/32875427): This will be moved into configuration in a text file in a future refactor.
- return "google.registry.flows.custom.CustomLogicFactory";
- }
-
- private static final String RESERVED_TERMS_EXPORT_DISCLAIMER = ""
- + "# This list contains reserve terms for the TLD. Other terms may be reserved\n"
- + "# but not included in this list, including terms EXAMPLE REGISTRY chooses not\n"
- + "# to publish, and terms that ICANN commonly mandates to be reserved. This\n"
- + "# list is subject to change and the most up-to-date source is always to\n"
- + "# check availability directly with the Registry server.\n";
-
- /**
- * Returns the header text at the top of the reserved terms exported list.
- *
- * @see google.registry.export.ExportUtils#exportReservedTerms
- */
- @Provides
- @Config("reservedTermsExportDisclaimer")
- public static String provideReservedTermsExportDisclaimer() {
- return RESERVED_TERMS_EXPORT_DISCLAIMER;
- }
-
- /**
- * Returns the clientId of the registrar used by the {@code CheckApiServlet}.
- */
- @Provides
- @Config("checkApiServletRegistrarClientId")
- public static String provideCheckApiServletRegistrarClientId() {
- return "TheRegistrar";
- }
-
- /**
- * Returns the help path for the RDAP terms of service.
- *
- *
Make sure that this path is equal to the key of the entry in the RDAP help map containing
- * the terms of service. The ICANN operational profile requires that the TOS be included in all
- * responses, and this string is used to find the TOS in the help map.
- */
- @Provides
- @Config("rdapTosPath")
- public static String provideRdapTosPath() {
- return "/tos";
- }
-
- /**
- * Returns the help text to be used by RDAP.
- *
- *
Make sure that the map entry for the terms of service use the same key as specified in
- * rdapTosPath above.
- */
- @Singleton
- @Provides
- @Config("rdapHelpMap")
- public static ImmutableMap provideRdapHelpMap() {
- return new ImmutableMap.Builder()
- .put("/", RdapNoticeDescriptor.builder()
- .setTitle("RDAP Help")
- .setDescription(ImmutableList.of(
- "RDAP Help Topics (use /help/topic for information)",
- "syntax",
- "tos (Terms of Service)"))
- .setLinkValueSuffix("help/")
- .build())
- .put("/index", RdapNoticeDescriptor.builder()
- .setTitle("RDAP Help")
- .setDescription(ImmutableList.of(
- "RDAP Help Topics (use /help/topic for information)",
- "syntax",
- "tos (Terms of Service)"))
- .setLinkValueSuffix("help/index")
- .build())
- .put("/syntax", RdapNoticeDescriptor.builder()
- .setTitle("RDAP Command Syntax")
- .setDescription(ImmutableList.of(
- "domain/XXXX",
- "nameserver/XXXX",
- "entity/XXXX",
- "domains?name=XXXX",
- "domains?nsLdhName=XXXX",
- "domains?nsIp=XXXX",
- "nameservers?name=XXXX",
- "nameservers?ip=XXXX",
- "entities?fn=XXXX",
- "entities?handle=XXXX",
- "help/XXXX"))
- .setLinkValueSuffix("help/syntax")
- .build())
- .put("/tos", RdapNoticeDescriptor.builder()
- .setTitle("RDAP Terms of Service")
- .setDescription(ImmutableList.of(
- "By querying our Domain Database, you are agreeing to comply with these terms so"
- + " please read them carefully.",
- "Any information provided is 'as is' without any guarantee of accuracy.",
- "Please do not misuse the Domain Database. It is intended solely for"
- + " query-based access.",
- "Don't use the Domain Database to allow, enable, or otherwise support the"
- + " transmission of mass unsolicited, commercial advertising or"
- + " solicitations.",
- "Don't access our Domain Database through the use of high volume, automated"
- + " electronic processes that send queries or data to the systems of any"
- + " ICANN-accredited registrar.",
- "You may only use the information contained in the Domain Database for lawful"
- + " purposes.",
- "Do not compile, repackage, disseminate, or otherwise use the information"
- + " contained in the Domain Database in its entirety, or in any substantial"
- + " portion, without our prior written permission.",
- "We may retain certain details about queries to our Domain Database for the"
- + " purposes of detecting and preventing misuse.",
- "We reserve the right to restrict or deny your access to the database if we"
- + " suspect that you have failed to comply with these terms.",
- "We reserve the right to modify this agreement at any time."))
- .setLinkValueSuffix("help/tos")
- .build())
- .build();
- }
-
- /** Config values used for local and unit test environments. */
- public static class LocalTestConfig {
-
- public static final String CONTACT_AND_HOST_ROID_SUFFIX = "ROID";
-
- public static final String RESERVED_TERMS_TEST_EXPORT_DISCLAIMER = "This is a disclaimer.\n";
-
- public static final String GOOGLE_APPS_SEND_FROM_EMAIL_ADDRESS = "noreply@testing.example";
-
- public static final String GOOGLE_APPS_ADMIN_EMAIL_DISPLAY_NAME = "Testing Nomulus";
-
- public static final Duration CONTACT_AUTOMATIC_TRANSFER_LENGTH = standardDays(5);
- }
-}
diff --git a/java/google/registry/config/RegistryConfig.java b/java/google/registry/config/RegistryConfig.java
index 7e56099a6..ce8b9d6de 100644
--- a/java/google/registry/config/RegistryConfig.java
+++ b/java/google/registry/config/RegistryConfig.java
@@ -15,17 +15,1070 @@
package google.registry.config;
import static google.registry.config.ConfigUtils.makeUrl;
+import static org.joda.time.Duration.standardDays;
+import com.google.appengine.api.utils.SystemProperty;
import com.google.common.base.Ascii;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.net.HostAndPort;
+import dagger.Module;
+import dagger.Provides;
+import java.lang.annotation.Documented;
+import java.net.URI;
import java.net.URL;
+import javax.annotation.Nullable;
+import javax.inject.Qualifier;
+import javax.inject.Singleton;
+import org.joda.money.CurrencyUnit;
+import org.joda.time.DateTimeConstants;
import org.joda.time.Duration;
/**
- * Registry configuration for global constants that can't be injected.
+ * Central clearing-house for all configuration.
*/
public final class RegistryConfig {
+ /** Dagger qualifier for configuration settings. */
+ @Qualifier
+ @Documented
+ public static @interface Config {
+ String value() default "";
+ }
+
+ /**
+ * Configuration example for the Nomulus codebase.
+ *
+ * The Nomulus codebase contains many classes that inject configurable settings. This is
+ * the centralized class that is used by default to configure them all, in hard-coded type-safe
+ * Java code.
+ *
+ *
This class does not represent the total configuration of the Nomulus service. It's
+ * only meant for settings that need to be configured once. Settings which may
+ * be subject to change in the future, should instead be retrieved from Datastore. The
+ * {@link google.registry.model.registry.Registry Registry} class is one such example of this.
+ *
+ *
Customization
+ *
+ * It is recommended that users do not modify this file within a forked repository. It is
+ * preferable to modify these settings by swapping out this module with a separate copied version
+ * in the user's repository. For this to work, other files need to be copied too, such as the
+ * {@code @Component} instances under {@code google.registry.module}. This allows modules to be
+ * substituted at the {@code @Component} level.
+ */
+ @Module
+ public static final class ConfigModule {
+
+ private static final RegistryEnvironment REGISTRY_ENVIRONMENT = RegistryEnvironment.get();
+
+ @Provides
+ public static RegistryEnvironment provideRegistryEnvironment() {
+ return REGISTRY_ENVIRONMENT;
+ }
+
+ @Provides
+ @Config("projectId")
+ public static String provideProjectId() {
+ return RegistryConfig.getProjectId();
+ }
+
+ /**
+ * The filename of the logo to be displayed in the header of the registrar console.
+ *
+ * @see google.registry.ui.server.registrar.ConsoleUiAction
+ */
+ @Provides
+ @Config("logoFilename")
+ public static String provideLogoFilename(RegistryEnvironment environment) {
+ switch (environment) {
+ case UNITTEST:
+ case LOCAL:
+ return "logo.png";
+ default:
+ // Change this to the filename of your logo.
+ return "google_registry.png";
+ }
+ }
+
+ /**
+ * The product name of this specific registry. Used throughout the registrar console.
+ *
+ * @see google.registry.ui.server.registrar.ConsoleUiAction
+ */
+ @Provides
+ @Config("productName")
+ public static String provideProductName(RegistryEnvironment environment) {
+ // Change this to the name of your product.
+ return "Nomulus";
+ }
+
+ /**
+ * Returns the roid suffix to be used for the roids of all contacts and hosts. E.g. a value of
+ * "ROID" would end up creating roids that look like "ABC123-ROID".
+ *
+ * @see
+ * Extensible Provisioning Protocol (EPP) Repository Identifiers
+ */
+ @Provides
+ @Config("contactAndHostRoidSuffix")
+ public static String provideContactAndHostRoidSuffix(RegistryEnvironment environment) {
+ return LocalTestConfig.CONTACT_AND_HOST_ROID_SUFFIX;
+ }
+
+ /**
+ * The e-mail address for questions about integrating with the registry. Used in the
+ * "contact-us" section of the registrar console.
+ *
+ * @see google.registry.ui.server.registrar.ConsoleUiAction
+ */
+ @Provides
+ @Config("integrationEmail")
+ public static String provideIntegrationEmail(RegistryEnvironment environment) {
+ // Change this to your integration email address.
+ return "integration@example.com";
+ }
+
+ /**
+ * The e-mail address for general support. Used in the "contact-us" section of the registrar
+ * console.
+ *
+ * @see google.registry.ui.server.registrar.ConsoleUiAction
+ */
+ @Provides
+ @Config("supportEmail")
+ public static String provideSupportEmail(RegistryEnvironment environment) {
+ // Change this to your support email address.
+ return "support@example.com";
+ }
+
+ /**
+ * The "From" e-mail address for announcements. Used in the "contact-us" section of the
+ * registrar console.
+ *
+ * @see google.registry.ui.server.registrar.ConsoleUiAction
+ */
+ @Provides
+ @Config("announcementsEmail")
+ public static String provideAnnouncementsEmail(RegistryEnvironment environment) {
+ // Change this to your announcements e-mail.
+ return "announcements@example.com";
+ }
+
+ /**
+ * The contact phone number. Used in the "contact-us" section of the registrar console.
+ *
+ * @see google.registry.ui.server.registrar.ConsoleUiAction
+ */
+ @Provides
+ @Config("supportPhoneNumber")
+ public static String provideSupportPhoneNumber(RegistryEnvironment environment) {
+ // Change this to your phone number.
+ return "+1 (888) 555 0123";
+ }
+
+ /**
+ * The URL for technical support docs. Used in the "contact-us" section of the registrar
+ * console.
+ *
+ * @see google.registry.ui.server.registrar.ConsoleUiAction
+ */
+ @Provides
+ @Config("technicalDocsUrl")
+ public static String provideTechnicalDocsUrl(RegistryEnvironment environment) {
+ // Change this to your support docs link.
+ return "http://example.com/your_support_docs/";
+ }
+
+ /**
+ * Returns the Google Cloud Storage bucket for storing zone files.
+ *
+ * @see google.registry.backup.ExportCommitLogDiffAction
+ */
+ @Provides
+ @Config("zoneFilesBucket")
+ public static String provideZoneFilesBucket(@Config("projectId") String projectId) {
+ return projectId + "-zonefiles";
+ }
+
+ /**
+ * Returns the Google Cloud Storage bucket for storing commit logs.
+ *
+ * @see google.registry.backup.ExportCommitLogDiffAction
+ */
+ @Provides
+ @Config("commitLogGcsBucket")
+ public static String provideCommitLogGcsBucket(@Config("projectId") String projectId) {
+ return projectId + "-commits";
+ }
+
+ /** @see RegistryConfig#getCommitLogDatastoreRetention() */
+ @Provides
+ @Config("commitLogDatastoreRetention")
+ public static Duration provideCommitLogDatastoreRetention() {
+ return RegistryConfig.getCommitLogDatastoreRetention();
+ }
+
+ /**
+ * The GCS bucket for exporting domain lists.
+ *
+ * @see google.registry.export.ExportDomainListsAction
+ */
+ @Provides
+ @Config("domainListsGcsBucket")
+ public static String provideDomainListsGcsBucket(@Config("projectId") String projectId) {
+ return projectId + "-domain-lists";
+ }
+
+ /**
+ * Maximum number of commit logs to delete per transaction.
+ *
+ *
If we assume that the average key size is 256 bytes and that each manifest has six
+ * mutations, we can do about 5,000 deletes in a single transaction before hitting the 10mB
+ * limit. Therefore 500 should be a safe number, since it's an order of a magnitude less space
+ * than we need.
+ *
+ *
Transactions also have a four minute time limit. Since we have to perform N subqueries to
+ * fetch mutation keys, 500 would be a safe number if those queries were performed in serial,
+ * since each query would have about 500ms to complete, which is an order a magnitude more time
+ * than we need. However this does not apply, since the subqueries are performed asynchronously.
+ *
+ * @see google.registry.backup.DeleteOldCommitLogsAction
+ */
+ @Provides
+ @Config("commitLogMaxDeletes")
+ public static int provideCommitLogMaxDeletes() {
+ return 500;
+ }
+
+ /**
+ * Batch size for the number of transactions' worth of commit log data to process at once when
+ * exporting a commit log diff.
+ *
+ * @see google.registry.backup.ExportCommitLogDiffAction
+ */
+ @Provides
+ @Config("commitLogDiffExportBatchSize")
+ public static int provideCommitLogDiffExportBatchSize() {
+ return 100;
+ }
+
+ /**
+ * Returns the Google Cloud Storage bucket for staging BRDA escrow deposits.
+ *
+ * @see google.registry.rde.PendingDepositChecker
+ */
+ @Provides
+ @Config("brdaBucket")
+ public static String provideBrdaBucket(@Config("projectId") String projectId) {
+ return projectId + "-icann-brda";
+ }
+
+ /** @see google.registry.rde.BrdaCopyAction */
+ @Provides
+ @Config("brdaDayOfWeek")
+ public static int provideBrdaDayOfWeek() {
+ return DateTimeConstants.TUESDAY;
+ }
+
+ /**
+ * Amount of time between BRDA deposits.
+ *
+ * @see google.registry.rde.PendingDepositChecker
+ */
+ @Provides
+ @Config("brdaInterval")
+ public static Duration provideBrdaInterval() {
+ return Duration.standardDays(7);
+ }
+
+ /**
+ * Returns {@code true} if the target zone should be created in DNS if it does not exist.
+ */
+ @Provides
+ @Config("dnsCreateZone")
+ public static boolean provideDnsCreateZone(RegistryEnvironment environment) {
+ switch (environment) {
+ case PRODUCTION:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ /**
+ * The maximum number of domain and host updates to batch together to send to
+ * PublishDnsUpdatesAction, to avoid exceeding AppEngine's limits.
+ *
+ * @see google.registry.dns.ReadDnsQueueAction
+ */
+ @Provides
+ @Config("dnsTldUpdateBatchSize")
+ public static int provideDnsTldUpdateBatchSize() {
+ return 100;
+ }
+
+ /**
+ * The maximum interval (seconds) to lease tasks from the dns-pull queue.
+ *
+ * @see google.registry.dns.ReadDnsQueueAction
+ * @see google.registry.dns.PublishDnsUpdatesAction
+ */
+ @Provides
+ @Config("dnsWriteLockTimeout")
+ public static Duration provideDnsWriteLockTimeout() {
+ /*
+ * Optimally, we would set this to a little less than the length of the DNS refresh cycle,
+ * since otherwise, a new PublishDnsUpdatesAction could get kicked off before the current one
+ * has finished, which will try and fail to acquire the lock. However, it is more important
+ * that it be greater than the DNS write timeout, so that if that timeout occurs, it will be
+ * cleaned up gracefully, rather than having the lock time out. So we have to live with the
+ * possible lock failures.
+ */
+ return Duration.standardSeconds(75);
+ }
+
+ /**
+ * Returns the default time to live for DNS records.
+ *
+ * @see google.registry.dns.writer.clouddns.CloudDnsWriter
+ */
+ @Provides
+ @Config("dnsDefaultTtl")
+ public static Duration provideDnsDefaultTtl() {
+ return Duration.standardSeconds(180);
+ }
+
+ /**
+ * Number of sharded entity group roots used for performing strongly consistent scans.
+ *
+ *
Warning: This number may increase but never decrease.
+ *
+ * @see google.registry.model.index.EppResourceIndex
+ */
+ @Provides
+ @Config("eppResourceIndexBucketCount")
+ public static int provideEppResourceIndexBucketCount() {
+ return RegistryConfig.getEppResourceIndexBucketCount();
+ }
+
+ /**
+ * Returns size of Google Cloud Storage client connection buffer in bytes.
+ *
+ * @see google.registry.gcs.GcsUtils
+ */
+ @Provides
+ @Config("gcsBufferSize")
+ public static int provideGcsBufferSize() {
+ return 1024 * 1024;
+ }
+
+ /**
+ * Gets the email address of the admin account for the Google App.
+ *
+ * @see google.registry.groups.DirectoryGroupsConnection
+ */
+ @Provides
+ @Config("googleAppsAdminEmailAddress")
+ public static String provideGoogleAppsAdminEmailAddress(RegistryEnvironment environment) {
+ // Change this to your admin account.
+ return "admin@example.com";
+ }
+
+ /**
+ * Returns the email address(es) that notifications of registrar and/or registrar contact
+ * updates should be sent to, or the empty list if updates should not be sent.
+ *
+ * @see google.registry.ui.server.registrar.RegistrarSettingsAction
+ */
+ @Provides
+ @Config("registrarChangesNotificationEmailAddresses")
+ public static ImmutableList provideRegistrarChangesNotificationEmailAddresses(
+ RegistryEnvironment environment) {
+ switch (environment) {
+ case PRODUCTION:
+ // Change this to an appropriate notification e-mail address.
+ return ImmutableList.of("notification@registry.example");
+ case UNITTEST:
+ return ImmutableList.of("notification@test.example", "notification2@test.example");
+ default:
+ return ImmutableList.of();
+ }
+ }
+
+ /**
+ * Returns the publicly accessible domain name for the running Google Apps instance.
+ *
+ * @see google.registry.export.SyncGroupMembersAction
+ * @see google.registry.tools.server.CreateGroupsAction
+ */
+ @Provides
+ @Config("publicDomainName")
+ public static String providePublicDomainName(RegistryEnvironment environment) {
+ // Change this to your domain name.
+ return "registry.example.com";
+ }
+
+ /**
+ * Returns {@code true} if TMCH certificate authority should be in testing mode.
+ *
+ * @see RegistryConfig#getTmchCaTestingMode()
+ */
+ @Provides
+ @Config("tmchCaTestingMode")
+ public static boolean provideTmchCaTestingMode() {
+ return RegistryConfig.getTmchCaTestingMode();
+ }
+
+ /**
+ * ICANN TMCH Certificate Revocation List URL.
+ *
+ * This file needs to be downloaded at least once a day and verified to make sure it was
+ * signed by {@code icann-tmch.crt}.
+ *
+ * @see google.registry.tmch.TmchCrlAction
+ * @see TMCH
+ * RFC
+ */
+ @Provides
+ @Config("tmchCrlUrl")
+ public static URL provideTmchCrlUrl(RegistryEnvironment environment) {
+ switch (environment) {
+ case PRODUCTION:
+ return makeUrl("http://crl.icann.org/tmch.crl");
+ default:
+ return makeUrl("http://crl.icann.org/tmch_pilot.crl");
+ }
+ }
+
+ /**
+ * URL prefix for communicating with MarksDB ry interface.
+ *
+ *
This URL is used for DNL, SMDRL, and LORDN.
+ *
+ * @see google.registry.tmch.Marksdb
+ * @see google.registry.tmch.NordnUploadAction
+ */
+ @Provides
+ @Config("tmchMarksdbUrl")
+ public static String provideTmchMarksdbUrl(RegistryEnvironment environment) {
+ switch (environment) {
+ case PRODUCTION:
+ case UNITTEST:
+ return "https://ry.marksdb.org";
+ default:
+ return "https://test.ry.marksdb.org";
+ }
+ }
+
+ /**
+ * The email address that outgoing emails from the app are sent from.
+ *
+ * @see google.registry.util.SendEmailUtils
+ */
+ @Provides
+ @Config("googleAppsSendFromEmailAddress")
+ public static String provideGoogleAppsSendFromEmailAddress() {
+ return String.format("noreply@%s.appspotmail.com", SystemProperty.applicationId.get());
+ }
+
+ /**
+ * The display name that is used on outgoing emails sent by Nomulus.
+ *
+ * @see google.registry.util.SendEmailUtils
+ */
+ @Provides
+ @Config("googleAppsAdminEmailDisplayName")
+ public static String provideGoogleAppsAdminEmailDisplayName() {
+ // Production example: "Example Registry"
+ return "Google Domain Registry";
+ }
+
+ /**
+ * Returns the Google Cloud Storage bucket for staging escrow deposits pending upload.
+ *
+ * @see google.registry.rde.RdeStagingAction
+ */
+ @Provides
+ @Config("rdeBucket")
+ public static String provideRdeBucket(@Config("projectId") String projectId) {
+ return projectId + "-rde";
+ }
+
+ /**
+ * Returns the Google Cloud Storage bucket for importing escrow files.
+ *
+ * @see google.registry.rde.imports.RdeContactImportAction
+ * @see google.registry.rde.imports.RdeHostImportAction
+ */
+ @Provides
+ @Config("rdeImportBucket")
+ public static String provideRdeImportBucket(@Config("projectId") String projectId) {
+ return projectId + "-rde-import";
+ }
+
+ /**
+ * Size of Ghostryde buffer in bytes for each layer in the pipeline.
+ *
+ * @see google.registry.rde.Ghostryde
+ */
+ @Provides
+ @Config("rdeGhostrydeBufferSize")
+ public static Integer provideRdeGhostrydeBufferSize() {
+ return 64 * 1024;
+ }
+
+ /**
+ * Amount of time between RDE deposits.
+ *
+ * @see google.registry.rde.PendingDepositChecker
+ * @see google.registry.rde.RdeReportAction
+ * @see google.registry.rde.RdeUploadAction
+ */
+ @Provides
+ @Config("rdeInterval")
+ public static Duration provideRdeInterval() {
+ return Duration.standardDays(1);
+ }
+
+ /**
+ * Maximum amount of time for sending a small XML file to ICANN via HTTP, before killing.
+ *
+ * @see google.registry.rde.RdeReportAction
+ */
+ @Provides
+ @Config("rdeReportLockTimeout")
+ public static Duration provideRdeReportLockTimeout() {
+ return Duration.standardSeconds(60);
+ }
+
+ /**
+ * URL of ICANN's HTTPS server to which the RDE report should be {@code PUT}.
+ *
+ *
You must append {@code "/TLD/ID"} to this URL.
+ *
+ * @see google.registry.rde.RdeReportAction
+ */
+ @Provides
+ @Config("rdeReportUrlPrefix")
+ public static String provideRdeReportUrlPrefix(RegistryEnvironment environment) {
+ switch (environment) {
+ case PRODUCTION:
+ return "https://ry-api.icann.org/report/registry-escrow-report";
+ default:
+ return "https://test-ry-api.icann.org:8543/report/registry-escrow-report";
+ }
+ }
+
+ /**
+ * Size of RYDE generator buffer in bytes for each of the five layers.
+ *
+ * @see google.registry.rde.RydePgpCompressionOutputStream
+ * @see google.registry.rde.RydePgpFileOutputStream
+ * @see google.registry.rde.RydePgpSigningOutputStream
+ * @see google.registry.rde.RydeTarOutputStream
+ */
+ @Provides
+ @Config("rdeRydeBufferSize")
+ public static Integer provideRdeRydeBufferSize() {
+ return 64 * 1024;
+ }
+
+ /**
+ * Maximum amount of time generating an escrow deposit for a TLD could take, before killing.
+ *
+ * @see google.registry.rde.RdeStagingReducer
+ */
+ @Provides
+ @Config("rdeStagingLockTimeout")
+ public static Duration provideRdeStagingLockTimeout() {
+ return Duration.standardHours(5);
+ }
+
+ /**
+ * Maximum amount of time it should ever take to upload an escrow deposit, before killing.
+ *
+ * @see google.registry.rde.RdeUploadAction
+ */
+ @Provides
+ @Config("rdeUploadLockTimeout")
+ public static Duration provideRdeUploadLockTimeout() {
+ return Duration.standardMinutes(30);
+ }
+
+ /**
+ * Minimum amount of time to wait between consecutive SFTP uploads on a single TLD.
+ *
+ *
This value was communicated to us by the escrow provider.
+ *
+ * @see google.registry.rde.RdeStagingReducer
+ */
+ @Provides
+ @Config("rdeUploadSftpCooldown")
+ public static Duration provideRdeUploadSftpCooldown() {
+ return Duration.standardHours(2);
+ }
+
+ /**
+ * Returns the identity (an email address) used for the SSH keys used in RDE SFTP uploads.
+ *
+ * @see google.registry.keyring.api.Keyring#getRdeSshClientPublicKey()
+ * @see google.registry.keyring.api.Keyring#getRdeSshClientPrivateKey()
+ */
+ @Provides
+ @Config("rdeSshIdentity")
+ public static String provideSshIdentity() {
+ // Change this to your RDE identity.
+ return "rde@example.com";
+ }
+
+ /**
+ * Returns SFTP URL containing a username, hostname, port (optional), and directory (optional)
+ * to which cloud storage files are uploaded. The password should not be included, as it's
+ * better to use public key authentication.
+ *
+ * @see google.registry.rde.RdeUploadAction
+ */
+ @Provides
+ @Config("rdeUploadUrl")
+ public static URI provideRdeUploadUrl(RegistryEnvironment environment) {
+ switch (environment) {
+ case PRODUCTION:
+ return URI.create("sftp://GoogleTLD@sftpipm2.ironmountain.com/Outbox");
+ default:
+ return URI.create("sftp://google@ppftpipm.ironmountain.com/Outbox");
+ }
+ }
+
+ /**
+ * Whether or not the registrar console is enabled.
+ *
+ * @see google.registry.ui.server.registrar.ConsoleUiAction
+ */
+ @Provides
+ @Config("registrarConsoleEnabled")
+ public static boolean provideRegistrarConsoleEnabled() {
+ return true;
+ }
+
+ /**
+ * Maximum amount of time for syncing a spreadsheet, before killing.
+ *
+ * @see google.registry.export.sheet.SyncRegistrarsSheetAction
+ */
+ @Provides
+ @Config("sheetLockTimeout")
+ public static Duration provideSheetLockTimeout() {
+ return Duration.standardHours(1);
+ }
+
+ /**
+ * Returns ID of Google Spreadsheet to which Registrar entities should be synced.
+ *
+ *
This ID, as you'd expect, comes from the URL of the spreadsheet.
+ *
+ * @see google.registry.export.sheet.SyncRegistrarsSheetAction
+ */
+ @Provides
+ @Config("sheetRegistrarId")
+ public static Optional provideSheetRegistrarId(RegistryEnvironment environment) {
+ switch (environment) {
+ case PRODUCTION:
+ return Optional.of("1n2Gflqsgo9iDXcdt9VEskOVySZ8qIhQHJgjqsleCKdE");
+ case ALPHA:
+ case CRASH:
+ return Optional.of("16BwRt6v11Iw-HujCbAkmMxqw3sUG13B8lmXLo-uJTsE");
+ case SANDBOX:
+ return Optional.of("1TlR_UMCtfpkxT9oUEoF5JEbIvdWNkLRuURltFkJ_7_8");
+ case QA:
+ return Optional.of("1RoY1XZhLLwqBkrz0WbEtaT9CU6c8nUAXfId5BtM837o");
+ default:
+ return Optional.absent();
+ }
+ }
+
+ /**
+ * Returns SSH client connection and read timeout.
+ *
+ * @see google.registry.rde.RdeUploadAction
+ */
+ @Provides
+ @Config("sshTimeout")
+ public static Duration provideSshTimeout() {
+ return Duration.standardSeconds(30);
+ }
+
+ /**
+ * Duration after watermark where we shouldn't deposit, because transactions might be pending.
+ *
+ * @see google.registry.rde.RdeStagingAction
+ */
+ @Provides
+ @Config("transactionCooldown")
+ public static Duration provideTransactionCooldown() {
+ return Duration.standardMinutes(5);
+ }
+
+ /**
+ * Number of times to retry a GAE operation when {@code TransientFailureException} is thrown.
+ *
+ * The number of milliseconds it'll sleep before giving up is {@code 2^n - 2}.
+ *
+ * @see google.registry.util.TaskEnqueuer
+ */
+ @Provides
+ @Config("transientFailureRetries")
+ public static int provideTransientFailureRetries() {
+ return 12; // Four seconds.
+ }
+
+ /**
+ * Amount of time public HTTP proxies are permitted to cache our WHOIS responses.
+ *
+ * @see google.registry.whois.WhoisHttpServer
+ */
+ @Provides
+ @Config("whoisHttpExpires")
+ public static Duration provideWhoisHttpExpires() {
+ return Duration.standardDays(1);
+ }
+
+ /**
+ * Maximum number of results to return for an RDAP search query
+ *
+ * @see google.registry.rdap.RdapActionBase
+ */
+ @Provides
+ @Config("rdapResultSetMaxSize")
+ public static int provideRdapResultSetMaxSize() {
+ return 100;
+ }
+
+ /**
+ * Base for RDAP link paths.
+ *
+ * @see google.registry.rdap.RdapActionBase
+ */
+ @Provides
+ @Config("rdapLinkBase")
+ public static String provideRdapLinkBase() {
+ return "https://nic.google/rdap/";
+ }
+
+ /**
+ * WHOIS server displayed in RDAP query responses. As per Gustavo Lozano of ICANN, this should
+ * be omitted, but the ICANN operational profile doesn't actually say that, so it's good to have
+ * the ability to reinstate this field if necessary.
+ *
+ * @see google.registry.rdap.RdapActionBase
+ */
+ @Nullable
+ @Provides
+ @Config("rdapWhoisServer")
+ public static String provideRdapWhoisServer() {
+ return null;
+ }
+
+ /**
+ * Returns Braintree Merchant Account IDs for each supported currency.
+ *
+ * @see google.registry.ui.server.registrar.RegistrarPaymentAction
+ * @see google.registry.ui.server.registrar.RegistrarPaymentSetupAction
+ */
+ @Provides
+ @Config("braintreeMerchantAccountIds")
+ public static ImmutableMap provideBraintreeMerchantAccountId(
+ RegistryEnvironment environment) {
+ switch (environment) {
+ case PRODUCTION:
+ return ImmutableMap.of(
+ CurrencyUnit.USD, "charlestonregistryUSD",
+ CurrencyUnit.JPY, "charlestonregistryJPY");
+ default:
+ return ImmutableMap.of(
+ CurrencyUnit.USD, "google",
+ CurrencyUnit.JPY, "google-jpy");
+ }
+ }
+
+ /**
+ * Returns Braintree Merchant ID of Registry, used for accessing Braintree API.
+ *
+ * This is a base32 value copied from the Braintree website.
+ *
+ * @see google.registry.braintree.BraintreeModule
+ */
+ @Provides
+ @Config("braintreeMerchantId")
+ public static String provideBraintreeMerchantId(RegistryEnvironment environment) {
+ switch (environment) {
+ case PRODUCTION:
+ return "6gm2mm48k9ty4zmx";
+ default:
+ // Valentine: Nomulus Braintree Sandbox
+ return "vqgn8khkq2cs6y9s";
+ }
+ }
+
+ /**
+ * Returns Braintree Public Key of Registry, used for accessing Braintree API.
+ *
+ *
This is a base32 value copied from the Braintree website.
+ *
+ * @see google.registry.braintree.BraintreeModule
+ * @see google.registry.keyring.api.Keyring#getBraintreePrivateKey()
+ */
+ @Provides
+ @Config("braintreePublicKey")
+ public static String provideBraintreePublicKey(RegistryEnvironment environment) {
+ switch (environment) {
+ case PRODUCTION:
+ return "tzcfxggzgbh2jg5x";
+ default:
+ // Valentine: Nomulus Braintree Sandbox
+ return "tzcyzvm3mn7zkdnx";
+ }
+ }
+
+ /**
+ * Disclaimer displayed at the end of WHOIS query results.
+ *
+ * @see google.registry.whois.WhoisResponse
+ */
+ @Provides
+ @Config("whoisDisclaimer")
+ public static String provideWhoisDisclaimer() {
+ return "WHOIS information is provided by Charleston Road Registry Inc. (CRR) solely for\n"
+ + "query-based, informational purposes. By querying our WHOIS database, you are\n"
+ + "agreeing to comply with these terms\n"
+ + "(http://www.registry.google/about/whois-disclaimer.html) so please read them\n"
+ + "carefully. Any information provided is \"as is\" without any guarantee of\n"
+ + "accuracy. You may not use such information to (a) allow, enable, or otherwise\n"
+ + "support the transmission of mass unsolicited, commercial advertising or\n"
+ + "solicitations; (b) enable high volume, automated, electronic processes that\n"
+ + "access the systems of CRR or any ICANN-Accredited Registrar, except as\n"
+ + "reasonably necessary to register domain names or modify existing registrations;\n"
+ + "or (c) engage in or support unlawful behavior. CRR reserves the right to\n"
+ + "restrict or deny your access to the Whois database, and may modify these terms\n"
+ + "at any time.\n";
+ }
+
+ /**
+ * Maximum QPS for the Google Cloud Monitoring V3 (aka Stackdriver) API. The QPS limit can be
+ * adjusted by contacting Cloud Support.
+ *
+ * @see google.registry.monitoring.metrics.StackdriverWriter
+ */
+ @Provides
+ @Config("stackdriverMaxQps")
+ public static int provideStackdriverMaxQps() {
+ return 30;
+ }
+
+ /**
+ * Maximum number of points that can be sent to Stackdriver in a single TimeSeries.Create API
+ * call.
+ *
+ * @see google.registry.monitoring.metrics.StackdriverWriter
+ */
+ @Provides
+ @Config("stackdriverMaxPointsPerRequest")
+ public static int provideStackdriverMaxPointsPerRequest() {
+ return 200;
+ }
+
+ /**
+ * The reporting interval, for BigQueryMetricsEnqueuer to be sent to a {@link
+ * google.registry.monitoring.metrics.MetricWriter}.
+ *
+ * @see google.registry.monitoring.metrics.MetricReporter
+ */
+ @Provides
+ @Config("metricsWriteInterval")
+ public static Duration provideMetricsWriteInterval() {
+ return Duration.standardSeconds(60);
+ }
+
+ /**
+ * The global automatic transfer length for contacts. After this amount of time has
+ * elapsed, the transfer is automatically approved.
+ *
+ * @see google.registry.flows.contact.ContactTransferRequestFlow
+ */
+ @Provides
+ @Config("contactAutomaticTransferLength")
+ public static Duration provideContactAutomaticTransferLength() {
+ return standardDays(5);
+ }
+
+ /**
+ * Returns the maximum number of entities that can be checked at one time in an EPP check flow.
+ */
+ @Provides
+ @Config("maxChecks")
+ public static int provideMaxChecks() {
+ return 50;
+ }
+
+ /**
+ * Returns the delay before executing async delete flow mapreduces.
+ *
+ *
This delay should be sufficiently longer than a transaction, to solve the following
+ * problem:
+ *
+ *
+ * - a domain mutation flow starts a transaction
+ *
- the domain flow non-transactionally reads a resource and sees that it's not in
+ * PENDING_DELETE
+ *
- the domain flow creates a new reference to this resource
+ *
- a contact/host delete flow runs and marks the resource PENDING_DELETE and commits
+ *
- the domain flow commits
+ *
+ *
+ * Although we try not to add references to a PENDING_DELETE resource, strictly speaking that
+ * is ok as long as the mapreduce eventually sees the new reference (and therefore
+ * asynchronously fails the delete). Without this delay, the mapreduce might have started before
+ * the domain flow committed, and could potentially miss the reference.
+ *
+ * @see google.registry.flows.async.AsyncFlowEnqueuer
+ */
+ @Provides
+ @Config("asyncDeleteFlowMapreduceDelay")
+ public static Duration provideAsyncDeleteFlowMapreduceDelay() {
+ return Duration.standardSeconds(90);
+ }
+
+ /**
+ * The server ID used in the 'svID' element of an EPP 'greeting'.
+ *
+ * @see RFC 7530
+ */
+ @Provides
+ @Config("greetingServerId")
+ public static String provideGreetingServerId() {
+ return "Charleston Road Registry";
+ }
+
+ @Provides
+ @Config("customLogicFactoryClass")
+ public static String provideCustomLogicFactoryClass() {
+ // TODO(b/32875427): This will be converted to YAML configuration in a future refactor.
+ return "google.registry.flows.custom.CustomLogicFactory";
+ }
+
+ private static final String RESERVED_TERMS_EXPORT_DISCLAIMER = ""
+ + "# This list contains reserve terms for the TLD. Other terms may be reserved\n"
+ + "# but not included in this list, including terms EXAMPLE REGISTRY chooses not\n"
+ + "# to publish, and terms that ICANN commonly mandates to be reserved. This\n"
+ + "# list is subject to change and the most up-to-date source is always to\n"
+ + "# check availability directly with the Registry server.\n";
+
+ /**
+ * Returns the header text at the top of the reserved terms exported list.
+ *
+ * @see google.registry.export.ExportUtils#exportReservedTerms
+ */
+ @Provides
+ @Config("reservedTermsExportDisclaimer")
+ public static String provideReservedTermsExportDisclaimer() {
+ return RESERVED_TERMS_EXPORT_DISCLAIMER;
+ }
+
+ /**
+ * Returns the clientId of the registrar used by the {@code CheckApiServlet}.
+ */
+ @Provides
+ @Config("checkApiServletRegistrarClientId")
+ public static String provideCheckApiServletRegistrarClientId() {
+ return "TheRegistrar";
+ }
+
+ /**
+ * Returns the help path for the RDAP terms of service.
+ *
+ *
Make sure that this path is equal to the key of the entry in the RDAP help map containing
+ * the terms of service. The ICANN operational profile requires that the TOS be included in all
+ * responses, and this string is used to find the TOS in the help map.
+ */
+ @Provides
+ @Config("rdapTosPath")
+ public static String provideRdapTosPath() {
+ return "/tos";
+ }
+
+ /**
+ * Returns the help text to be used by RDAP.
+ *
+ *
Make sure that the map entry for the terms of service use the same key as specified in
+ * rdapTosPath above.
+ */
+ @Singleton
+ @Provides
+ @Config("rdapHelpMap")
+ public static ImmutableMap provideRdapHelpMap() {
+ return new ImmutableMap.Builder()
+ .put("/", RdapNoticeDescriptor.builder()
+ .setTitle("RDAP Help")
+ .setDescription(ImmutableList.of(
+ "RDAP Help Topics (use /help/topic for information)",
+ "syntax",
+ "tos (Terms of Service)"))
+ .setLinkValueSuffix("help/")
+ .build())
+ .put("/index", RdapNoticeDescriptor.builder()
+ .setTitle("RDAP Help")
+ .setDescription(ImmutableList.of(
+ "RDAP Help Topics (use /help/topic for information)",
+ "syntax",
+ "tos (Terms of Service)"))
+ .setLinkValueSuffix("help/index")
+ .build())
+ .put("/syntax", RdapNoticeDescriptor.builder()
+ .setTitle("RDAP Command Syntax")
+ .setDescription(ImmutableList.of(
+ "domain/XXXX",
+ "nameserver/XXXX",
+ "entity/XXXX",
+ "domains?name=XXXX",
+ "domains?nsLdhName=XXXX",
+ "domains?nsIp=XXXX",
+ "nameservers?name=XXXX",
+ "nameservers?ip=XXXX",
+ "entities?fn=XXXX",
+ "entities?handle=XXXX",
+ "help/XXXX"))
+ .setLinkValueSuffix("help/syntax")
+ .build())
+ .put("/tos", RdapNoticeDescriptor.builder()
+ .setTitle("RDAP Terms of Service")
+ .setDescription(ImmutableList.of(
+ "By querying our Domain Database, you are agreeing to comply with these terms so"
+ + " please read them carefully.",
+ "Any information provided is 'as is' without any guarantee of accuracy.",
+ "Please do not misuse the Domain Database. It is intended solely for"
+ + " query-based access.",
+ "Don't use the Domain Database to allow, enable, or otherwise support the"
+ + " transmission of mass unsolicited, commercial advertising or"
+ + " solicitations.",
+ "Don't access our Domain Database through the use of high volume, automated"
+ + " electronic processes that send queries or data to the systems of any"
+ + " ICANN-accredited registrar.",
+ "You may only use the information contained in the Domain Database for lawful"
+ + " purposes.",
+ "Do not compile, repackage, disseminate, or otherwise use the information"
+ + " contained in the Domain Database in its entirety, or in any substantial"
+ + " portion, without our prior written permission.",
+ "We may retain certain details about queries to our Domain Database for the"
+ + " purposes of detecting and preventing misuse.",
+ "We reserve the right to restrict or deny your access to the database if we"
+ + " suspect that you have failed to comply with these terms.",
+ "We reserve the right to modify this agreement at any time."))
+ .setLinkValueSuffix("help/tos")
+ .build())
+ .build();
+ }
+ }
+
/**
* Returns the App Engine project ID, which is based off the environment name.
*/
@@ -205,5 +1258,19 @@ public final class RegistryConfig {
}
}
+ /** Config values used for local and unit test environments. */
+ public static class LocalTestConfig {
+
+ public static final String CONTACT_AND_HOST_ROID_SUFFIX = "ROID";
+
+ public static final String RESERVED_TERMS_TEST_EXPORT_DISCLAIMER = "This is a disclaimer.\n";
+
+ public static final String GOOGLE_APPS_SEND_FROM_EMAIL_ADDRESS = "noreply@testing.example";
+
+ public static final String GOOGLE_APPS_ADMIN_EMAIL_DISPLAY_NAME = "Testing Nomulus";
+
+ public static final Duration CONTACT_AUTOMATIC_TRANSFER_LENGTH = standardDays(5);
+ }
+
private RegistryConfig() {}
}
diff --git a/java/google/registry/dns/PublishDnsUpdatesAction.java b/java/google/registry/dns/PublishDnsUpdatesAction.java
index 7c2953503..29273e32a 100644
--- a/java/google/registry/dns/PublishDnsUpdatesAction.java
+++ b/java/google/registry/dns/PublishDnsUpdatesAction.java
@@ -19,7 +19,7 @@ import static google.registry.request.Action.Method.POST;
import static google.registry.util.CollectionUtils.nullToEmpty;
import com.google.common.net.InternetDomainName;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.dns.DnsMetrics.Status;
import google.registry.dns.writer.DnsWriter;
import google.registry.request.Action;
diff --git a/java/google/registry/dns/ReadDnsQueueAction.java b/java/google/registry/dns/ReadDnsQueueAction.java
index 39843da52..9b77870b4 100644
--- a/java/google/registry/dns/ReadDnsQueueAction.java
+++ b/java/google/registry/dns/ReadDnsQueueAction.java
@@ -34,7 +34,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.dns.DnsConstants.TargetType;
import google.registry.model.registry.Registry;
import google.registry.request.Action;
diff --git a/java/google/registry/dns/writer/clouddns/CloudDnsWriter.java b/java/google/registry/dns/writer/clouddns/CloudDnsWriter.java
index 964e3fca3..73b6644f1 100644
--- a/java/google/registry/dns/writer/clouddns/CloudDnsWriter.java
+++ b/java/google/registry/dns/writer/clouddns/CloudDnsWriter.java
@@ -31,7 +31,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.net.InternetDomainName;
import com.google.common.util.concurrent.RateLimiter;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.dns.writer.DnsWriter;
import google.registry.dns.writer.DnsWriterZone;
import google.registry.model.domain.DomainResource;
diff --git a/java/google/registry/dns/writer/clouddns/CloudDnsWriterModule.java b/java/google/registry/dns/writer/clouddns/CloudDnsWriterModule.java
index ce7b8e478..297dfea09 100644
--- a/java/google/registry/dns/writer/clouddns/CloudDnsWriterModule.java
+++ b/java/google/registry/dns/writer/clouddns/CloudDnsWriterModule.java
@@ -26,7 +26,7 @@ import dagger.Provides;
import dagger.multibindings.IntoMap;
import dagger.multibindings.IntoSet;
import dagger.multibindings.StringKey;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.dns.writer.DnsWriter;
import java.util.Set;
import javax.inject.Named;
diff --git a/java/google/registry/dns/writer/dnsupdate/DnsMessageTransport.java b/java/google/registry/dns/writer/dnsupdate/DnsMessageTransport.java
index d00c2cea3..0e72b74b5 100644
--- a/java/google/registry/dns/writer/dnsupdate/DnsMessageTransport.java
+++ b/java/google/registry/dns/writer/dnsupdate/DnsMessageTransport.java
@@ -19,7 +19,7 @@ import static com.google.common.base.Verify.verify;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.primitives.Ints;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
diff --git a/java/google/registry/dns/writer/dnsupdate/DnsUpdateConfigModule.java b/java/google/registry/dns/writer/dnsupdate/DnsUpdateConfigModule.java
index 6128c73f6..1177aaf90 100644
--- a/java/google/registry/dns/writer/dnsupdate/DnsUpdateConfigModule.java
+++ b/java/google/registry/dns/writer/dnsupdate/DnsUpdateConfigModule.java
@@ -16,7 +16,7 @@ package google.registry.dns.writer.dnsupdate;
import dagger.Module;
import dagger.Provides;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import org.joda.time.Duration;
/** Dagger module that provides DNS configuration settings. */
diff --git a/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java b/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java
index c00ee7621..50fa540ef 100644
--- a/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java
+++ b/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java
@@ -24,7 +24,7 @@ import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InternetDomainName;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.dns.writer.DnsWriter;
import google.registry.model.domain.DomainResource;
import google.registry.model.domain.secdns.DelegationSignerData;
diff --git a/java/google/registry/export/DriveModule.java b/java/google/registry/export/DriveModule.java
index 61d9732da..c13d6c14b 100644
--- a/java/google/registry/export/DriveModule.java
+++ b/java/google/registry/export/DriveModule.java
@@ -22,7 +22,7 @@ import com.google.api.services.drive.DriveScopes;
import com.google.common.base.Function;
import dagger.Module;
import dagger.Provides;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import java.util.Set;
/** Dagger module for Google {@link Drive} service connection objects. */
diff --git a/java/google/registry/export/ExportDomainListsAction.java b/java/google/registry/export/ExportDomainListsAction.java
index 947ebada5..2cfc64b0c 100644
--- a/java/google/registry/export/ExportDomainListsAction.java
+++ b/java/google/registry/export/ExportDomainListsAction.java
@@ -30,7 +30,7 @@ import com.google.appengine.tools.mapreduce.Reducer;
import com.google.appengine.tools.mapreduce.ReducerInput;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.gcs.GcsUtils;
import google.registry.mapreduce.MapreduceRunner;
import google.registry.model.domain.DomainResource;
diff --git a/java/google/registry/export/ExportUtils.java b/java/google/registry/export/ExportUtils.java
index 89cca91aa..d4e37f192 100644
--- a/java/google/registry/export/ExportUtils.java
+++ b/java/google/registry/export/ExportUtils.java
@@ -18,7 +18,7 @@ import static google.registry.model.registry.label.ReservationType.UNRESERVED;
import com.google.common.base.Joiner;
import com.googlecode.objectify.Key;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.registry.Registry;
import google.registry.model.registry.label.ReservedList;
import google.registry.model.registry.label.ReservedList.ReservedListEntry;
diff --git a/java/google/registry/export/LoadSnapshotAction.java b/java/google/registry/export/LoadSnapshotAction.java
index 9cd63d139..85c2ec8a3 100644
--- a/java/google/registry/export/LoadSnapshotAction.java
+++ b/java/google/registry/export/LoadSnapshotAction.java
@@ -37,7 +37,7 @@ import com.google.common.collect.ImmutableSet;
import google.registry.bigquery.BigqueryFactory;
import google.registry.bigquery.BigqueryUtils.SourceFormat;
import google.registry.bigquery.BigqueryUtils.WriteDisposition;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.export.BigqueryPollJobAction.BigqueryPollJobEnqueuer;
import google.registry.request.Action;
import google.registry.request.HttpException.BadRequestException;
diff --git a/java/google/registry/export/SyncGroupMembersAction.java b/java/google/registry/export/SyncGroupMembersAction.java
index 92a102697..7a61f22c1 100644
--- a/java/google/registry/export/SyncGroupMembersAction.java
+++ b/java/google/registry/export/SyncGroupMembersAction.java
@@ -29,7 +29,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.googlecode.objectify.VoidWork;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.groups.GroupsConnection;
import google.registry.groups.GroupsConnection.Role;
import google.registry.model.registrar.Registrar;
diff --git a/java/google/registry/export/UpdateSnapshotViewAction.java b/java/google/registry/export/UpdateSnapshotViewAction.java
index 6dfac1f11..7d437f845 100644
--- a/java/google/registry/export/UpdateSnapshotViewAction.java
+++ b/java/google/registry/export/UpdateSnapshotViewAction.java
@@ -23,7 +23,7 @@ import com.google.api.services.bigquery.model.ViewDefinition;
import com.google.appengine.api.taskqueue.TaskOptions;
import com.google.appengine.api.taskqueue.TaskOptions.Method;
import google.registry.bigquery.BigqueryFactory;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.request.Action;
import google.registry.request.HttpException.InternalServerErrorException;
import google.registry.request.Parameter;
diff --git a/java/google/registry/export/sheet/SyncRegistrarsSheetAction.java b/java/google/registry/export/sheet/SyncRegistrarsSheetAction.java
index 842d72caa..7549e04a3 100644
--- a/java/google/registry/export/sheet/SyncRegistrarsSheetAction.java
+++ b/java/google/registry/export/sheet/SyncRegistrarsSheetAction.java
@@ -29,7 +29,7 @@ import com.google.appengine.api.taskqueue.TaskHandle;
import com.google.appengine.api.taskqueue.TaskOptions.Method;
import com.google.common.base.Optional;
import com.google.gdata.util.ServiceException;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.server.Lock;
import google.registry.request.Action;
import google.registry.request.Parameter;
diff --git a/java/google/registry/flows/CheckApiAction.java b/java/google/registry/flows/CheckApiAction.java
index 235b61bdb..e16079a0f 100644
--- a/java/google/registry/flows/CheckApiAction.java
+++ b/java/google/registry/flows/CheckApiAction.java
@@ -35,7 +35,7 @@ import com.google.template.soy.SoyFileSet;
import com.google.template.soy.tofu.SoyTofu;
import dagger.Module;
import dagger.Provides;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.flows.soy.DomainCheckFeeEppSoyInfo;
import google.registry.model.domain.fee.FeeCheckResponseExtension;
import google.registry.model.eppoutput.CheckData.DomainCheck;
diff --git a/java/google/registry/flows/async/AsyncFlowEnqueuer.java b/java/google/registry/flows/async/AsyncFlowEnqueuer.java
index 9cfa8c7ae..422c51af0 100644
--- a/java/google/registry/flows/async/AsyncFlowEnqueuer.java
+++ b/java/google/registry/flows/async/AsyncFlowEnqueuer.java
@@ -20,7 +20,7 @@ import com.google.appengine.api.taskqueue.TaskOptions.Method;
import com.google.appengine.api.taskqueue.TransientFailureException;
import com.google.common.annotations.VisibleForTesting;
import com.googlecode.objectify.Key;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.EppResource;
import google.registry.model.host.HostResource;
import google.registry.util.FormattingLogger;
diff --git a/java/google/registry/flows/contact/ContactCheckFlow.java b/java/google/registry/flows/contact/ContactCheckFlow.java
index 0b3329347..25176b252 100644
--- a/java/google/registry/flows/contact/ContactCheckFlow.java
+++ b/java/google/registry/flows/contact/ContactCheckFlow.java
@@ -19,7 +19,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount;
import static google.registry.model.EppResourceUtils.checkResourcesExist;
import com.google.common.collect.ImmutableList;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
diff --git a/java/google/registry/flows/contact/ContactCreateFlow.java b/java/google/registry/flows/contact/ContactCreateFlow.java
index 0699d8cba..9f0fa900a 100644
--- a/java/google/registry/flows/contact/ContactCreateFlow.java
+++ b/java/google/registry/flows/contact/ContactCreateFlow.java
@@ -22,7 +22,7 @@ import static google.registry.model.EppResourceUtils.createRepoId;
import static google.registry.model.ofy.ObjectifyService.ofy;
import com.googlecode.objectify.Key;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
diff --git a/java/google/registry/flows/contact/ContactTransferRequestFlow.java b/java/google/registry/flows/contact/ContactTransferRequestFlow.java
index 2ff2ed511..9f07388b9 100644
--- a/java/google/registry/flows/contact/ContactTransferRequestFlow.java
+++ b/java/google/registry/flows/contact/ContactTransferRequestFlow.java
@@ -28,7 +28,7 @@ import static google.registry.model.ofy.ObjectifyService.ofy;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId;
diff --git a/java/google/registry/flows/custom/CustomLogicFactory.java b/java/google/registry/flows/custom/CustomLogicFactory.java
index 234919a06..11a9a5f8a 100644
--- a/java/google/registry/flows/custom/CustomLogicFactory.java
+++ b/java/google/registry/flows/custom/CustomLogicFactory.java
@@ -14,7 +14,7 @@
package google.registry.flows.custom;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.flows.SessionMetadata;
import google.registry.model.eppinput.EppInput;
diff --git a/java/google/registry/flows/custom/CustomLogicFactoryModule.java b/java/google/registry/flows/custom/CustomLogicFactoryModule.java
index 050c04011..016e1a32a 100644
--- a/java/google/registry/flows/custom/CustomLogicFactoryModule.java
+++ b/java/google/registry/flows/custom/CustomLogicFactoryModule.java
@@ -19,7 +19,7 @@ import static google.registry.util.TypeUtils.instantiate;
import dagger.Module;
import dagger.Provides;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
/** Dagger module for custom logic factories. */
@Module
diff --git a/java/google/registry/flows/domain/ClaimsCheckFlow.java b/java/google/registry/flows/domain/ClaimsCheckFlow.java
index a81549c4b..cb1699e44 100644
--- a/java/google/registry/flows/domain/ClaimsCheckFlow.java
+++ b/java/google/registry/flows/domain/ClaimsCheckFlow.java
@@ -26,7 +26,7 @@ import static google.registry.model.domain.launch.LaunchPhase.CLAIMS;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InternetDomainName;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.flows.EppException;
import google.registry.flows.EppException.CommandUseErrorException;
import google.registry.flows.ExtensionManager;
diff --git a/java/google/registry/flows/domain/DomainCheckFlow.java b/java/google/registry/flows/domain/DomainCheckFlow.java
index 9c4f850b7..34132420b 100644
--- a/java/google/registry/flows/domain/DomainCheckFlow.java
+++ b/java/google/registry/flows/domain/DomainCheckFlow.java
@@ -34,7 +34,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.net.InternetDomainName;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.flows.EppException;
import google.registry.flows.EppException.ParameterValuePolicyErrorException;
import google.registry.flows.ExtensionManager;
diff --git a/java/google/registry/flows/host/HostCheckFlow.java b/java/google/registry/flows/host/HostCheckFlow.java
index f520ea8a8..33ad3c5fb 100644
--- a/java/google/registry/flows/host/HostCheckFlow.java
+++ b/java/google/registry/flows/host/HostCheckFlow.java
@@ -19,7 +19,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount;
import static google.registry.model.EppResourceUtils.checkResourcesExist;
import com.google.common.collect.ImmutableList;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
diff --git a/java/google/registry/flows/host/HostCreateFlow.java b/java/google/registry/flows/host/HostCreateFlow.java
index da1756990..92cf849b0 100644
--- a/java/google/registry/flows/host/HostCreateFlow.java
+++ b/java/google/registry/flows/host/HostCreateFlow.java
@@ -27,7 +27,7 @@ import static google.registry.util.CollectionUtils.union;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.dns.DnsQueue;
import google.registry.flows.EppException;
import google.registry.flows.EppException.ParameterValueRangeErrorException;
diff --git a/java/google/registry/flows/session/HelloFlow.java b/java/google/registry/flows/session/HelloFlow.java
index 141271088..f8310b5eb 100644
--- a/java/google/registry/flows/session/HelloFlow.java
+++ b/java/google/registry/flows/session/HelloFlow.java
@@ -14,7 +14,7 @@
package google.registry.flows.session;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.Flow;
diff --git a/java/google/registry/gcs/GcsUtils.java b/java/google/registry/gcs/GcsUtils.java
index b8817ca6c..0a0a5c77b 100644
--- a/java/google/registry/gcs/GcsUtils.java
+++ b/java/google/registry/gcs/GcsUtils.java
@@ -24,7 +24,7 @@ import com.google.appengine.tools.cloudstorage.GcsService;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.net.MediaType;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.util.FormattingLogger;
import java.io.IOException;
import java.io.InputStream;
diff --git a/java/google/registry/groups/DirectoryGroupsConnection.java b/java/google/registry/groups/DirectoryGroupsConnection.java
index 26aa96143..6dbf28d7b 100644
--- a/java/google/registry/groups/DirectoryGroupsConnection.java
+++ b/java/google/registry/groups/DirectoryGroupsConnection.java
@@ -29,7 +29,7 @@ import com.google.api.services.groupssettings.model.Groups;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.util.FormattingLogger;
import java.io.IOException;
import java.util.Set;
diff --git a/java/google/registry/groups/DirectoryModule.java b/java/google/registry/groups/DirectoryModule.java
index 385f67579..9344ff702 100644
--- a/java/google/registry/groups/DirectoryModule.java
+++ b/java/google/registry/groups/DirectoryModule.java
@@ -20,7 +20,7 @@ import com.google.api.services.admin.directory.DirectoryScopes;
import com.google.common.collect.ImmutableSet;
import dagger.Module;
import dagger.Provides;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import javax.inject.Named;
/** Dagger module for the Google {@link Directory} service. */
diff --git a/java/google/registry/groups/GroupssettingsModule.java b/java/google/registry/groups/GroupssettingsModule.java
index 9a9289644..21fe2bba2 100644
--- a/java/google/registry/groups/GroupssettingsModule.java
+++ b/java/google/registry/groups/GroupssettingsModule.java
@@ -20,7 +20,7 @@ import com.google.api.services.groupssettings.GroupssettingsScopes;
import com.google.common.collect.ImmutableSet;
import dagger.Module;
import dagger.Provides;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import javax.inject.Named;
/** Dagger module for the Google {@link Groupssettings} service. */
diff --git a/java/google/registry/module/backend/BackendComponent.java b/java/google/registry/module/backend/BackendComponent.java
index 120c81ef5..59b4bd76b 100644
--- a/java/google/registry/module/backend/BackendComponent.java
+++ b/java/google/registry/module/backend/BackendComponent.java
@@ -16,7 +16,7 @@ package google.registry.module.backend;
import dagger.Component;
import google.registry.bigquery.BigqueryModule;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.dns.writer.VoidDnsWriterModule;
import google.registry.export.DriveModule;
import google.registry.export.sheet.SpreadsheetServiceModule;
diff --git a/java/google/registry/module/frontend/FrontendComponent.java b/java/google/registry/module/frontend/FrontendComponent.java
index a00d9e6dd..a120f79de 100644
--- a/java/google/registry/module/frontend/FrontendComponent.java
+++ b/java/google/registry/module/frontend/FrontendComponent.java
@@ -16,7 +16,7 @@ package google.registry.module.frontend;
import dagger.Component;
import google.registry.braintree.BraintreeModule;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.flows.custom.CustomLogicFactoryModule;
import google.registry.keyring.api.DummyKeyringModule;
import google.registry.keyring.api.KeyModule;
diff --git a/java/google/registry/module/tools/ToolsComponent.java b/java/google/registry/module/tools/ToolsComponent.java
index a8fd8f27f..6414a6171 100644
--- a/java/google/registry/module/tools/ToolsComponent.java
+++ b/java/google/registry/module/tools/ToolsComponent.java
@@ -15,7 +15,7 @@
package google.registry.module.tools;
import dagger.Component;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.export.DriveModule;
import google.registry.flows.custom.CustomLogicFactoryModule;
import google.registry.gcs.GcsServiceModule;
diff --git a/java/google/registry/monitoring/whitebox/MetricsExportAction.java b/java/google/registry/monitoring/whitebox/MetricsExportAction.java
index 86d8d35b4..44d8d1a08 100644
--- a/java/google/registry/monitoring/whitebox/MetricsExportAction.java
+++ b/java/google/registry/monitoring/whitebox/MetricsExportAction.java
@@ -32,7 +32,7 @@ import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import google.registry.bigquery.BigqueryFactory;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.request.Action;
import google.registry.request.Parameter;
import google.registry.request.ParameterMap;
diff --git a/java/google/registry/monitoring/whitebox/StackdriverModule.java b/java/google/registry/monitoring/whitebox/StackdriverModule.java
index 1949f518e..8a5ad0bda 100644
--- a/java/google/registry/monitoring/whitebox/StackdriverModule.java
+++ b/java/google/registry/monitoring/whitebox/StackdriverModule.java
@@ -26,7 +26,7 @@ import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import dagger.Module;
import dagger.Provides;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.monitoring.metrics.MetricWriter;
import google.registry.monitoring.metrics.StackdriverWriter;
import java.util.Set;
diff --git a/java/google/registry/rdap/RdapActionBase.java b/java/google/registry/rdap/RdapActionBase.java
index 3d548c2a4..986edaf2a 100644
--- a/java/google/registry/rdap/RdapActionBase.java
+++ b/java/google/registry/rdap/RdapActionBase.java
@@ -31,7 +31,7 @@ import com.google.common.net.InternetDomainName;
import com.google.common.net.MediaType;
import com.google.re2j.Pattern;
import com.googlecode.objectify.cmd.Query;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.EppResource;
import google.registry.request.Action;
import google.registry.request.HttpException;
diff --git a/java/google/registry/rdap/RdapDomainSearchAction.java b/java/google/registry/rdap/RdapDomainSearchAction.java
index f90d8aa29..5582a3a70 100644
--- a/java/google/registry/rdap/RdapDomainSearchAction.java
+++ b/java/google/registry/rdap/RdapDomainSearchAction.java
@@ -30,7 +30,7 @@ import com.google.common.collect.Iterables;
import com.google.common.primitives.Booleans;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.cmd.Query;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.EppResourceUtils;
import google.registry.model.domain.DomainResource;
import google.registry.model.host.HostResource;
diff --git a/java/google/registry/rdap/RdapEntitySearchAction.java b/java/google/registry/rdap/RdapEntitySearchAction.java
index e2d452754..6d9e3a1ba 100644
--- a/java/google/registry/rdap/RdapEntitySearchAction.java
+++ b/java/google/registry/rdap/RdapEntitySearchAction.java
@@ -25,7 +25,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.primitives.Booleans;
import com.googlecode.objectify.Key;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.registrar.Registrar;
diff --git a/java/google/registry/rdap/RdapJsonFormatter.java b/java/google/registry/rdap/RdapJsonFormatter.java
index bb1a10aa3..f5ce22b1d 100644
--- a/java/google/registry/rdap/RdapJsonFormatter.java
+++ b/java/google/registry/rdap/RdapJsonFormatter.java
@@ -29,8 +29,8 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.net.InetAddresses;
import com.googlecode.objectify.Key;
-import google.registry.config.ConfigModule.Config;
import google.registry.config.RdapNoticeDescriptor;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.EppResource;
import google.registry.model.contact.ContactPhoneNumber;
import google.registry.model.contact.ContactResource;
diff --git a/java/google/registry/rdap/RdapNameserverSearchAction.java b/java/google/registry/rdap/RdapNameserverSearchAction.java
index 35da3af1f..99523b34f 100644
--- a/java/google/registry/rdap/RdapNameserverSearchAction.java
+++ b/java/google/registry/rdap/RdapNameserverSearchAction.java
@@ -27,7 +27,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.primitives.Booleans;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.domain.DomainResource;
import google.registry.model.host.HostResource;
import google.registry.rdap.RdapJsonFormatter.BoilerplateType;
diff --git a/java/google/registry/rde/BrdaCopyAction.java b/java/google/registry/rde/BrdaCopyAction.java
index 717f0497e..c4e8890a4 100644
--- a/java/google/registry/rde/BrdaCopyAction.java
+++ b/java/google/registry/rde/BrdaCopyAction.java
@@ -20,7 +20,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.appengine.tools.cloudstorage.GcsFilename;
import com.google.common.io.ByteStreams;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.gcs.GcsUtils;
import google.registry.keyring.api.KeyModule.Key;
import google.registry.model.rde.RdeNamingUtils;
diff --git a/java/google/registry/rde/Ghostryde.java b/java/google/registry/rde/Ghostryde.java
index 4185e0fa5..1905b7de5 100644
--- a/java/google/registry/rde/Ghostryde.java
+++ b/java/google/registry/rde/Ghostryde.java
@@ -24,7 +24,7 @@ import static org.bouncycastle.openpgp.PGPLiteralData.BINARY;
import static org.joda.time.DateTimeZone.UTC;
import com.google.common.io.ByteStreams;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.util.FormattingLogger;
import google.registry.util.ImprovedInputStream;
import google.registry.util.ImprovedOutputStream;
diff --git a/java/google/registry/rde/JSchModule.java b/java/google/registry/rde/JSchModule.java
index 3245048aa..a1173b4d5 100644
--- a/java/google/registry/rde/JSchModule.java
+++ b/java/google/registry/rde/JSchModule.java
@@ -21,7 +21,7 @@ import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import dagger.Module;
import dagger.Provides;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.keyring.api.KeyModule.Key;
/** Dagger module for {@link JSch} which provides SSH/SFTP connectivity. */
diff --git a/java/google/registry/rde/JSchSshSession.java b/java/google/registry/rde/JSchSshSession.java
index 0b06239dd..52b1e9f4e 100644
--- a/java/google/registry/rde/JSchSshSession.java
+++ b/java/google/registry/rde/JSchSshSession.java
@@ -20,7 +20,7 @@ import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.util.FormattingLogger;
import java.io.Closeable;
import java.io.IOException;
diff --git a/java/google/registry/rde/PendingDepositChecker.java b/java/google/registry/rde/PendingDepositChecker.java
index 40a8f87e4..b32bdad6a 100644
--- a/java/google/registry/rde/PendingDepositChecker.java
+++ b/java/google/registry/rde/PendingDepositChecker.java
@@ -20,7 +20,7 @@ import static google.registry.util.DateTimeUtils.isBeforeOrAt;
import com.google.common.collect.ImmutableSetMultimap;
import com.googlecode.objectify.Work;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.common.Cursor;
import google.registry.model.common.Cursor.CursorType;
import google.registry.model.rde.RdeMode;
diff --git a/java/google/registry/rde/RdeReportAction.java b/java/google/registry/rde/RdeReportAction.java
index edc5bcb51..c92308f33 100644
--- a/java/google/registry/rde/RdeReportAction.java
+++ b/java/google/registry/rde/RdeReportAction.java
@@ -23,7 +23,7 @@ import static google.registry.request.Action.Method.POST;
import com.google.appengine.tools.cloudstorage.GcsFilename;
import com.google.common.io.ByteStreams;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.gcs.GcsUtils;
import google.registry.keyring.api.KeyModule.Key;
import google.registry.model.common.Cursor;
diff --git a/java/google/registry/rde/RdeReporter.java b/java/google/registry/rde/RdeReporter.java
index ef9523f05..faa4f7efa 100644
--- a/java/google/registry/rde/RdeReporter.java
+++ b/java/google/registry/rde/RdeReporter.java
@@ -28,7 +28,7 @@ import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.keyring.api.KeyModule.Key;
import google.registry.request.HttpException.InternalServerErrorException;
import google.registry.util.FormattingLogger;
diff --git a/java/google/registry/rde/RdeStagingAction.java b/java/google/registry/rde/RdeStagingAction.java
index 550902dbb..9040a01d2 100644
--- a/java/google/registry/rde/RdeStagingAction.java
+++ b/java/google/registry/rde/RdeStagingAction.java
@@ -21,7 +21,7 @@ import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimaps;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.mapreduce.MapreduceRunner;
import google.registry.mapreduce.inputs.EppResourceInputs;
import google.registry.mapreduce.inputs.NullInput;
diff --git a/java/google/registry/rde/RdeStagingReducer.java b/java/google/registry/rde/RdeStagingReducer.java
index eaa56c949..1c180beb1 100644
--- a/java/google/registry/rde/RdeStagingReducer.java
+++ b/java/google/registry/rde/RdeStagingReducer.java
@@ -28,7 +28,7 @@ import com.google.appengine.tools.cloudstorage.RetryParams;
import com.google.appengine.tools.mapreduce.Reducer;
import com.google.appengine.tools.mapreduce.ReducerInput;
import com.googlecode.objectify.VoidWork;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.gcs.GcsUtils;
import google.registry.keyring.api.KeyModule;
import google.registry.keyring.api.PgpHelper;
diff --git a/java/google/registry/rde/RdeUploadAction.java b/java/google/registry/rde/RdeUploadAction.java
index 11cf1e4ca..314184448 100644
--- a/java/google/registry/rde/RdeUploadAction.java
+++ b/java/google/registry/rde/RdeUploadAction.java
@@ -32,7 +32,7 @@ import com.google.common.io.ByteStreams;
import com.googlecode.objectify.VoidWork;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.gcs.GcsUtils;
import google.registry.keyring.api.KeyModule.Key;
import google.registry.model.common.Cursor;
diff --git a/java/google/registry/rde/RydePgpCompressionOutputStream.java b/java/google/registry/rde/RydePgpCompressionOutputStream.java
index 28cecfd2b..51a29db0d 100644
--- a/java/google/registry/rde/RydePgpCompressionOutputStream.java
+++ b/java/google/registry/rde/RydePgpCompressionOutputStream.java
@@ -18,7 +18,7 @@ import static org.bouncycastle.bcpg.CompressionAlgorithmTags.ZIP;
import com.google.auto.factory.AutoFactory;
import com.google.auto.factory.Provided;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.util.ImprovedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
diff --git a/java/google/registry/rde/RydePgpEncryptionOutputStream.java b/java/google/registry/rde/RydePgpEncryptionOutputStream.java
index 4f3050e25..fb42d6829 100644
--- a/java/google/registry/rde/RydePgpEncryptionOutputStream.java
+++ b/java/google/registry/rde/RydePgpEncryptionOutputStream.java
@@ -19,7 +19,7 @@ import static org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME;
import com.google.auto.factory.AutoFactory;
import com.google.auto.factory.Provided;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.util.ImprovedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
diff --git a/java/google/registry/rde/RydePgpFileOutputStream.java b/java/google/registry/rde/RydePgpFileOutputStream.java
index eff4d74d3..b9dcf53be 100644
--- a/java/google/registry/rde/RydePgpFileOutputStream.java
+++ b/java/google/registry/rde/RydePgpFileOutputStream.java
@@ -19,7 +19,7 @@ import static org.bouncycastle.openpgp.PGPLiteralData.BINARY;
import com.google.auto.factory.AutoFactory;
import com.google.auto.factory.Provided;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.util.ImprovedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
diff --git a/java/google/registry/rde/imports/RdeContactImportAction.java b/java/google/registry/rde/imports/RdeContactImportAction.java
index 6c813fae7..cebca67da 100644
--- a/java/google/registry/rde/imports/RdeContactImportAction.java
+++ b/java/google/registry/rde/imports/RdeContactImportAction.java
@@ -24,8 +24,8 @@ import com.google.appengine.tools.cloudstorage.RetryParams;
import com.google.appengine.tools.mapreduce.Mapper;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
-import google.registry.config.ConfigModule;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils;
import google.registry.mapreduce.MapreduceRunner;
import google.registry.model.contact.ContactResource;
diff --git a/java/google/registry/rde/imports/RdeContactInput.java b/java/google/registry/rde/imports/RdeContactInput.java
index 66721ffcc..0c2d268d8 100644
--- a/java/google/registry/rde/imports/RdeContactInput.java
+++ b/java/google/registry/rde/imports/RdeContactInput.java
@@ -26,7 +26,7 @@ import com.google.appengine.tools.mapreduce.Input;
import com.google.appengine.tools.mapreduce.InputReader;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils;
import google.registry.model.contact.ContactResource;
import google.registry.rde.imports.RdeParser.RdeHeader;
diff --git a/java/google/registry/rde/imports/RdeContactReader.java b/java/google/registry/rde/imports/RdeContactReader.java
index d4664ca20..b863768db 100644
--- a/java/google/registry/rde/imports/RdeContactReader.java
+++ b/java/google/registry/rde/imports/RdeContactReader.java
@@ -19,7 +19,7 @@ import com.google.appengine.tools.cloudstorage.GcsService;
import com.google.appengine.tools.cloudstorage.GcsServiceFactory;
import com.google.appengine.tools.cloudstorage.RetryParams;
import com.google.appengine.tools.mapreduce.InputReader;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils;
import google.registry.model.contact.ContactResource;
import google.registry.util.FormattingLogger;
diff --git a/java/google/registry/rde/imports/RdeHostImportAction.java b/java/google/registry/rde/imports/RdeHostImportAction.java
index 2d3cb4915..f4f7201cb 100644
--- a/java/google/registry/rde/imports/RdeHostImportAction.java
+++ b/java/google/registry/rde/imports/RdeHostImportAction.java
@@ -24,8 +24,8 @@ import com.google.appengine.tools.cloudstorage.RetryParams;
import com.google.appengine.tools.mapreduce.Mapper;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
-import google.registry.config.ConfigModule;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils;
import google.registry.mapreduce.MapreduceRunner;
import google.registry.model.host.HostResource;
diff --git a/java/google/registry/rde/imports/RdeHostInput.java b/java/google/registry/rde/imports/RdeHostInput.java
index 572d37b5d..8737b575a 100644
--- a/java/google/registry/rde/imports/RdeHostInput.java
+++ b/java/google/registry/rde/imports/RdeHostInput.java
@@ -24,7 +24,7 @@ import com.google.appengine.tools.mapreduce.Input;
import com.google.appengine.tools.mapreduce.InputReader;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils;
import google.registry.model.host.HostResource;
import google.registry.rde.imports.RdeParser.RdeHeader;
diff --git a/java/google/registry/rde/imports/RdeHostReader.java b/java/google/registry/rde/imports/RdeHostReader.java
index 897d518af..5915f879f 100644
--- a/java/google/registry/rde/imports/RdeHostReader.java
+++ b/java/google/registry/rde/imports/RdeHostReader.java
@@ -19,7 +19,7 @@ import com.google.appengine.tools.cloudstorage.GcsService;
import com.google.appengine.tools.cloudstorage.GcsServiceFactory;
import com.google.appengine.tools.cloudstorage.RetryParams;
import com.google.appengine.tools.mapreduce.InputReader;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils;
import google.registry.model.host.HostResource;
import google.registry.util.FormattingLogger;
diff --git a/java/google/registry/rde/imports/RdeImportUtils.java b/java/google/registry/rde/imports/RdeImportUtils.java
index 9715c5d6a..4cea6496e 100644
--- a/java/google/registry/rde/imports/RdeImportUtils.java
+++ b/java/google/registry/rde/imports/RdeImportUtils.java
@@ -20,7 +20,7 @@ import static com.google.common.base.Preconditions.checkState;
import com.google.appengine.tools.cloudstorage.GcsFilename;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Work;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.gcs.GcsUtils;
import google.registry.model.EppResource;
import google.registry.model.contact.ContactResource;
diff --git a/java/google/registry/request/Modules.java b/java/google/registry/request/Modules.java
index 760f193f8..8ddf95661 100644
--- a/java/google/registry/request/Modules.java
+++ b/java/google/registry/request/Modules.java
@@ -36,7 +36,7 @@ import com.google.common.collect.ImmutableSet;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.keyring.api.KeyModule.Key;
import java.io.ByteArrayInputStream;
import java.io.IOException;
diff --git a/java/google/registry/tmch/Marksdb.java b/java/google/registry/tmch/Marksdb.java
index 9bc4b8522..e5c5849ea 100644
--- a/java/google/registry/tmch/Marksdb.java
+++ b/java/google/registry/tmch/Marksdb.java
@@ -26,7 +26,7 @@ import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.common.base.Optional;
import com.google.common.io.ByteSource;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.keyring.api.KeyModule.Key;
import google.registry.util.UrlFetchException;
import java.io.ByteArrayInputStream;
diff --git a/java/google/registry/tmch/NordnUploadAction.java b/java/google/registry/tmch/NordnUploadAction.java
index c6bdd4425..afe00432d 100644
--- a/java/google/registry/tmch/NordnUploadAction.java
+++ b/java/google/registry/tmch/NordnUploadAction.java
@@ -35,7 +35,7 @@ import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.common.base.Optional;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.request.Action;
import google.registry.request.Parameter;
import google.registry.request.RequestParameters;
diff --git a/java/google/registry/tmch/TmchCertificateAuthority.java b/java/google/registry/tmch/TmchCertificateAuthority.java
index 373a684d5..56c881fc0 100644
--- a/java/google/registry/tmch/TmchCertificateAuthority.java
+++ b/java/google/registry/tmch/TmchCertificateAuthority.java
@@ -22,7 +22,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.tmch.TmchCrl;
import google.registry.util.Clock;
import google.registry.util.NonFinalForTesting;
diff --git a/java/google/registry/tmch/TmchCrlAction.java b/java/google/registry/tmch/TmchCrlAction.java
index 95fdb971f..bb420a378 100644
--- a/java/google/registry/tmch/TmchCrlAction.java
+++ b/java/google/registry/tmch/TmchCrlAction.java
@@ -18,7 +18,7 @@ import static google.registry.request.Action.Method.POST;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.base.Optional;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.request.Action;
import java.io.IOException;
import java.net.URL;
diff --git a/java/google/registry/tools/GenerateEscrowDepositCommand.java b/java/google/registry/tools/GenerateEscrowDepositCommand.java
index 07d16f475..37fdf7173 100644
--- a/java/google/registry/tools/GenerateEscrowDepositCommand.java
+++ b/java/google/registry/tools/GenerateEscrowDepositCommand.java
@@ -29,7 +29,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Result;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.EppResource;
import google.registry.model.EppResourceUtils;
import google.registry.model.ImmutableObject;
diff --git a/java/google/registry/tools/RegistryToolComponent.java b/java/google/registry/tools/RegistryToolComponent.java
index f82c6761c..5a2d52d32 100644
--- a/java/google/registry/tools/RegistryToolComponent.java
+++ b/java/google/registry/tools/RegistryToolComponent.java
@@ -15,7 +15,7 @@
package google.registry.tools;
import dagger.Component;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.dns.writer.VoidDnsWriterModule;
import google.registry.dns.writer.clouddns.CloudDnsWriterModule;
import google.registry.dns.writer.dnsupdate.DnsUpdateWriterModule;
diff --git a/java/google/registry/tools/server/CreateGroupsAction.java b/java/google/registry/tools/server/CreateGroupsAction.java
index 1dc6e5727..d1a80ae7c 100644
--- a/java/google/registry/tools/server/CreateGroupsAction.java
+++ b/java/google/registry/tools/server/CreateGroupsAction.java
@@ -21,7 +21,7 @@ import static javax.servlet.http.HttpServletResponse.SC_OK;
import com.google.common.base.Function;
import com.google.common.base.Optional;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.groups.GroupsConnection;
import google.registry.groups.GroupsConnection.Role;
import google.registry.model.registrar.Registrar;
diff --git a/java/google/registry/tools/server/GenerateZoneFilesAction.java b/java/google/registry/tools/server/GenerateZoneFilesAction.java
index b32718ce5..6985224a8 100644
--- a/java/google/registry/tools/server/GenerateZoneFilesAction.java
+++ b/java/google/registry/tools/server/GenerateZoneFilesAction.java
@@ -36,7 +36,7 @@ import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.gcs.GcsUtils;
import google.registry.mapreduce.MapreduceRunner;
import google.registry.mapreduce.inputs.NullInput;
diff --git a/java/google/registry/ui/ConsoleConfigModule.java b/java/google/registry/ui/ConsoleConfigModule.java
index 8efbfbed3..176ee3f0c 100644
--- a/java/google/registry/ui/ConsoleConfigModule.java
+++ b/java/google/registry/ui/ConsoleConfigModule.java
@@ -17,7 +17,7 @@ package google.registry.ui;
import com.google.appengine.api.users.UserService;
import dagger.Module;
import dagger.Provides;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
/** Dagger module for UI configuration. */
@Module
diff --git a/java/google/registry/ui/server/registrar/ConsoleUiAction.java b/java/google/registry/ui/server/registrar/ConsoleUiAction.java
index d5a17af2c..70bdb1d7b 100644
--- a/java/google/registry/ui/server/registrar/ConsoleUiAction.java
+++ b/java/google/registry/ui/server/registrar/ConsoleUiAction.java
@@ -26,7 +26,7 @@ import com.google.common.net.MediaType;
import com.google.template.soy.data.SoyMapData;
import com.google.template.soy.shared.SoyCssRenamingMap;
import com.google.template.soy.tofu.SoyTofu;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.flows.EppConsoleAction;
import google.registry.model.registrar.Registrar;
import google.registry.request.Action;
diff --git a/java/google/registry/ui/server/registrar/RegistrarPaymentAction.java b/java/google/registry/ui/server/registrar/RegistrarPaymentAction.java
index 93d63ebae..a1052a86e 100644
--- a/java/google/registry/ui/server/registrar/RegistrarPaymentAction.java
+++ b/java/google/registry/ui/server/registrar/RegistrarPaymentAction.java
@@ -30,7 +30,7 @@ import com.braintreegateway.ValidationErrors;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.re2j.Pattern;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.registrar.Registrar;
import google.registry.request.Action;
import google.registry.request.JsonActionRunner;
diff --git a/java/google/registry/ui/server/registrar/RegistrarPaymentSetupAction.java b/java/google/registry/ui/server/registrar/RegistrarPaymentSetupAction.java
index 0ba964fbb..8359054a3 100644
--- a/java/google/registry/ui/server/registrar/RegistrarPaymentSetupAction.java
+++ b/java/google/registry/ui/server/registrar/RegistrarPaymentSetupAction.java
@@ -23,7 +23,7 @@ import com.braintreegateway.BraintreeGateway;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableMap;
import google.registry.braintree.BraintreeRegistrarSyncer;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.model.registrar.Registrar;
import google.registry.request.Action;
import google.registry.request.JsonActionRunner;
diff --git a/java/google/registry/ui/server/registrar/RegistrarSettingsAction.java b/java/google/registry/ui/server/registrar/RegistrarSettingsAction.java
index 396130479..2bf07705e 100644
--- a/java/google/registry/ui/server/registrar/RegistrarSettingsAction.java
+++ b/java/google/registry/ui/server/registrar/RegistrarSettingsAction.java
@@ -31,7 +31,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.googlecode.objectify.Work;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.export.sheet.SyncRegistrarsSheetAction;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarContact;
diff --git a/java/google/registry/util/Retrier.java b/java/google/registry/util/Retrier.java
index 1001c4610..0f29bbc14 100644
--- a/java/google/registry/util/Retrier.java
+++ b/java/google/registry/util/Retrier.java
@@ -21,7 +21,7 @@ import static google.registry.util.PredicateUtils.supertypeOf;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import java.io.Serializable;
import java.util.Set;
import java.util.concurrent.Callable;
diff --git a/java/google/registry/util/SendEmailUtils.java b/java/google/registry/util/SendEmailUtils.java
index f297f6011..9cbb57fb3 100644
--- a/java/google/registry/util/SendEmailUtils.java
+++ b/java/google/registry/util/SendEmailUtils.java
@@ -20,7 +20,7 @@ import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import java.util.List;
import javax.inject.Inject;
import javax.mail.Message;
diff --git a/java/google/registry/whois/Whois.java b/java/google/registry/whois/Whois.java
index a5162b618..a1cf733e0 100644
--- a/java/google/registry/whois/Whois.java
+++ b/java/google/registry/whois/Whois.java
@@ -14,7 +14,7 @@
package google.registry.whois;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.util.Clock;
import java.io.IOException;
import java.io.StringReader;
diff --git a/java/google/registry/whois/WhoisHttpServer.java b/java/google/registry/whois/WhoisHttpServer.java
index 0745ce312..6fd56d668 100644
--- a/java/google/registry/whois/WhoisHttpServer.java
+++ b/java/google/registry/whois/WhoisHttpServer.java
@@ -27,7 +27,7 @@ import static javax.servlet.http.HttpServletResponse.SC_OK;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.request.Action;
import google.registry.request.RequestPath;
import google.registry.request.Response;
diff --git a/java/google/registry/whois/WhoisServer.java b/java/google/registry/whois/WhoisServer.java
index 02cf0c248..8f6731f08 100644
--- a/java/google/registry/whois/WhoisServer.java
+++ b/java/google/registry/whois/WhoisServer.java
@@ -18,7 +18,7 @@ import static google.registry.request.Action.Method.POST;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import com.google.common.net.MediaType;
-import google.registry.config.ConfigModule.Config;
+import google.registry.config.RegistryConfig.Config;
import google.registry.request.Action;
import google.registry.request.Response;
import google.registry.util.Clock;
diff --git a/javatests/google/registry/dns/DnsTestComponent.java b/javatests/google/registry/dns/DnsTestComponent.java
index 66bb638df..50e394baf 100644
--- a/javatests/google/registry/dns/DnsTestComponent.java
+++ b/javatests/google/registry/dns/DnsTestComponent.java
@@ -15,7 +15,7 @@
package google.registry.dns;
import dagger.Component;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.cron.CronModule;
import google.registry.dns.writer.VoidDnsWriterModule;
import google.registry.module.backend.BackendModule;
diff --git a/javatests/google/registry/export/ExportReservedTermsActionTest.java b/javatests/google/registry/export/ExportReservedTermsActionTest.java
index c0aae6de0..3da2906c8 100644
--- a/javatests/google/registry/export/ExportReservedTermsActionTest.java
+++ b/javatests/google/registry/export/ExportReservedTermsActionTest.java
@@ -32,7 +32,7 @@ import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.MediaType;
-import google.registry.config.ConfigModule.LocalTestConfig;
+import google.registry.config.RegistryConfig.LocalTestConfig;
import google.registry.model.registry.Registry;
import google.registry.model.registry.label.ReservedList;
import google.registry.request.Response;
diff --git a/javatests/google/registry/export/ExportUtilsTest.java b/javatests/google/registry/export/ExportUtilsTest.java
index fd3bdc5e3..eabc4b60e 100644
--- a/javatests/google/registry/export/ExportUtilsTest.java
+++ b/javatests/google/registry/export/ExportUtilsTest.java
@@ -15,7 +15,7 @@
package google.registry.export;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.config.ConfigModule.LocalTestConfig.RESERVED_TERMS_TEST_EXPORT_DISCLAIMER;
+import static google.registry.config.RegistryConfig.LocalTestConfig.RESERVED_TERMS_TEST_EXPORT_DISCLAIMER;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.persistReservedList;
import static google.registry.testing.DatastoreHelper.persistResource;
diff --git a/javatests/google/registry/flows/EppTestComponent.java b/javatests/google/registry/flows/EppTestComponent.java
index 5dc00a463..331c04bf3 100644
--- a/javatests/google/registry/flows/EppTestComponent.java
+++ b/javatests/google/registry/flows/EppTestComponent.java
@@ -21,7 +21,7 @@ import dagger.Component;
import dagger.Module;
import dagger.Provides;
import dagger.Subcomponent;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.dns.DnsQueue;
import google.registry.flows.custom.CustomLogicFactory;
import google.registry.flows.custom.TestCustomLogicFactory;
diff --git a/javatests/google/registry/flows/contact/ContactTransferRequestFlowTest.java b/javatests/google/registry/flows/contact/ContactTransferRequestFlowTest.java
index 8c42f69c8..bbe88fc35 100644
--- a/javatests/google/registry/flows/contact/ContactTransferRequestFlowTest.java
+++ b/javatests/google/registry/flows/contact/ContactTransferRequestFlowTest.java
@@ -22,7 +22,7 @@ import static google.registry.testing.DatastoreHelper.getPollMessages;
import static google.registry.testing.DatastoreHelper.persistActiveContact;
import static google.registry.testing.DatastoreHelper.persistResource;
-import google.registry.config.ConfigModule.LocalTestConfig;
+import google.registry.config.RegistryConfig.LocalTestConfig;
import google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException;
import google.registry.flows.ResourceFlowUtils.ResourceDoesNotExistException;
import google.registry.flows.exceptions.AlreadyPendingTransferException;
diff --git a/javatests/google/registry/rde/imports/RdeContactImportActionTest.java b/javatests/google/registry/rde/imports/RdeContactImportActionTest.java
index 761df5b45..721873f11 100644
--- a/javatests/google/registry/rde/imports/RdeContactImportActionTest.java
+++ b/javatests/google/registry/rde/imports/RdeContactImportActionTest.java
@@ -24,7 +24,7 @@ import com.google.appengine.tools.cloudstorage.RetryParams;
import com.google.common.base.Optional;
import com.google.common.io.ByteSource;
import com.google.common.io.ByteStreams;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils;
import google.registry.mapreduce.MapreduceRunner;
import google.registry.model.contact.ContactResource;
diff --git a/javatests/google/registry/rde/imports/RdeContactInputTest.java b/javatests/google/registry/rde/imports/RdeContactInputTest.java
index 7856959e6..f50c68181 100644
--- a/javatests/google/registry/rde/imports/RdeContactInputTest.java
+++ b/javatests/google/registry/rde/imports/RdeContactInputTest.java
@@ -23,7 +23,7 @@ import com.google.appengine.tools.cloudstorage.RetryParams;
import com.google.common.base.Optional;
import com.google.common.io.ByteSource;
import com.google.common.io.ByteStreams;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils;
import google.registry.testing.AppEngineRule;
import java.io.IOException;
diff --git a/javatests/google/registry/rde/imports/RdeContactReaderTest.java b/javatests/google/registry/rde/imports/RdeContactReaderTest.java
index 0966f54aa..8cb5e045d 100644
--- a/javatests/google/registry/rde/imports/RdeContactReaderTest.java
+++ b/javatests/google/registry/rde/imports/RdeContactReaderTest.java
@@ -22,7 +22,7 @@ import com.google.appengine.tools.cloudstorage.GcsServiceFactory;
import com.google.appengine.tools.cloudstorage.RetryParams;
import com.google.common.io.ByteSource;
import com.google.common.io.ByteStreams;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils;
import google.registry.model.contact.ContactResource;
import google.registry.testing.AppEngineRule;
diff --git a/javatests/google/registry/rde/imports/RdeHostImportActionTest.java b/javatests/google/registry/rde/imports/RdeHostImportActionTest.java
index 092ad94b2..1c6b2aec7 100644
--- a/javatests/google/registry/rde/imports/RdeHostImportActionTest.java
+++ b/javatests/google/registry/rde/imports/RdeHostImportActionTest.java
@@ -24,7 +24,7 @@ import com.google.appengine.tools.cloudstorage.RetryParams;
import com.google.common.base.Optional;
import com.google.common.io.ByteSource;
import com.google.common.io.ByteStreams;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils;
import google.registry.mapreduce.MapreduceRunner;
import google.registry.model.host.HostResource;
diff --git a/javatests/google/registry/rde/imports/RdeHostInputTest.java b/javatests/google/registry/rde/imports/RdeHostInputTest.java
index d2975d94c..2154d4efb 100644
--- a/javatests/google/registry/rde/imports/RdeHostInputTest.java
+++ b/javatests/google/registry/rde/imports/RdeHostInputTest.java
@@ -23,7 +23,7 @@ import com.google.appengine.tools.cloudstorage.RetryParams;
import com.google.common.base.Optional;
import com.google.common.io.ByteSource;
import com.google.common.io.ByteStreams;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils;
import google.registry.testing.AppEngineRule;
import google.registry.testing.ExceptionRule;
diff --git a/javatests/google/registry/rde/imports/RdeHostReaderTest.java b/javatests/google/registry/rde/imports/RdeHostReaderTest.java
index d23b25dc0..e2beb70d1 100644
--- a/javatests/google/registry/rde/imports/RdeHostReaderTest.java
+++ b/javatests/google/registry/rde/imports/RdeHostReaderTest.java
@@ -22,7 +22,7 @@ import com.google.appengine.tools.cloudstorage.GcsServiceFactory;
import com.google.appengine.tools.cloudstorage.RetryParams;
import com.google.common.io.ByteSource;
import com.google.common.io.ByteStreams;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils;
import google.registry.model.host.HostResource;
import google.registry.testing.AppEngineRule;
diff --git a/javatests/google/registry/testing/DatastoreHelper.java b/javatests/google/registry/testing/DatastoreHelper.java
index 0dfe8208f..2ff7a3785 100644
--- a/javatests/google/registry/testing/DatastoreHelper.java
+++ b/javatests/google/registry/testing/DatastoreHelper.java
@@ -20,8 +20,8 @@ import static com.google.common.base.Suppliers.memoize;
import static com.google.common.collect.Iterables.toArray;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static google.registry.config.ConfigModule.LocalTestConfig.CONTACT_AND_HOST_ROID_SUFFIX;
-import static google.registry.config.ConfigModule.LocalTestConfig.CONTACT_AUTOMATIC_TRANSFER_LENGTH;
+import static google.registry.config.RegistryConfig.LocalTestConfig.CONTACT_AND_HOST_ROID_SUFFIX;
+import static google.registry.config.RegistryConfig.LocalTestConfig.CONTACT_AUTOMATIC_TRANSFER_LENGTH;
import static google.registry.flows.ResourceFlowUtils.createTransferResponse;
import static google.registry.model.EppResourceUtils.createDomainRepoId;
import static google.registry.model.EppResourceUtils.createRepoId;
diff --git a/javatests/google/registry/ui/server/registrar/RegistrarSettingsActionTestCase.java b/javatests/google/registry/ui/server/registrar/RegistrarSettingsActionTestCase.java
index bd1243e81..14100f458 100644
--- a/javatests/google/registry/ui/server/registrar/RegistrarSettingsActionTestCase.java
+++ b/javatests/google/registry/ui/server/registrar/RegistrarSettingsActionTestCase.java
@@ -14,8 +14,8 @@
package google.registry.ui.server.registrar;
-import static google.registry.config.ConfigModule.LocalTestConfig.GOOGLE_APPS_ADMIN_EMAIL_DISPLAY_NAME;
-import static google.registry.config.ConfigModule.LocalTestConfig.GOOGLE_APPS_SEND_FROM_EMAIL_ADDRESS;
+import static google.registry.config.RegistryConfig.LocalTestConfig.GOOGLE_APPS_ADMIN_EMAIL_DISPLAY_NAME;
+import static google.registry.config.RegistryConfig.LocalTestConfig.GOOGLE_APPS_SEND_FROM_EMAIL_ADDRESS;
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
import static google.registry.security.JsonHttpTestUtils.createJsonResponseSupplier;
import static google.registry.security.XsrfTokenManager.generateToken;
diff --git a/javatests/google/registry/util/SendEmailUtilsTest.java b/javatests/google/registry/util/SendEmailUtilsTest.java
index 3190515cd..3d500c061 100644
--- a/javatests/google/registry/util/SendEmailUtilsTest.java
+++ b/javatests/google/registry/util/SendEmailUtilsTest.java
@@ -22,7 +22,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
-import google.registry.config.ConfigModule.LocalTestConfig;
+import google.registry.config.RegistryConfig.LocalTestConfig;
import google.registry.testing.ExceptionRule;
import google.registry.testing.InjectRule;
import java.util.Properties;
diff --git a/javatests/google/registry/whois/WhoisTestComponent.java b/javatests/google/registry/whois/WhoisTestComponent.java
index 2314153fc..0ec730834 100644
--- a/javatests/google/registry/whois/WhoisTestComponent.java
+++ b/javatests/google/registry/whois/WhoisTestComponent.java
@@ -15,7 +15,7 @@
package google.registry.whois;
import dagger.Component;
-import google.registry.config.ConfigModule;
+import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.request.RequestModule;
import google.registry.util.SystemClock.SystemClockModule;
import javax.inject.Singleton;