Add dagger map for injecting DnsWriter implementations

This is one of several CLs in a sequence for allowing per-TLD DNS
implementations.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=129445641
This commit is contained in:
Greg Shikhman 2016-08-05 08:45:02 -07:00 committed by Justine Tunney
parent 770fd35e20
commit a620d06239
24 changed files with 173 additions and 215 deletions

View file

@ -36,6 +36,7 @@ java_library(
"//third_party/java/objectify:objectify-v4_1", "//third_party/java/objectify:objectify-v4_1",
"//third_party/java/servlet/servlet_api", "//third_party/java/servlet/servlet_api",
"//java/google/registry/config", "//java/google/registry/config",
"//java/google/registry/dns/writer",
"//java/google/registry/model", "//java/google/registry/model",
"//java/google/registry/request", "//java/google/registry/request",
"//java/google/registry/util", "//java/google/registry/util",

View file

@ -30,7 +30,7 @@ import dagger.Binds;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
import google.registry.dns.DnsConstants.TargetType; import google.registry.dns.DnsConstants.TargetType;
import google.registry.model.dns.DnsWriterZone; import google.registry.dns.writer.DnsWriterZone;
import google.registry.request.Parameter; import google.registry.request.Parameter;
import google.registry.request.RequestParameters; import google.registry.request.RequestParameters;
import java.util.Set; import java.util.Set;

View file

@ -0,0 +1,42 @@
// Copyright 2016 The Domain Registry 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.dns;
import static com.google.common.base.Preconditions.checkState;
import com.google.common.collect.ImmutableMap;
import google.registry.dns.writer.DnsWriter;
import google.registry.model.registry.Registry;
import java.util.Map;
import javax.inject.Inject;
/** Proxy for retrieving {@link DnsWriter} implementations. */
public final class DnsWriterProxy {
private final ImmutableMap<String, DnsWriter> dnsWriters;
@Inject
DnsWriterProxy(Map<String, DnsWriter> dnsWriters) {
this.dnsWriters = ImmutableMap.copyOf(dnsWriters);
}
/** Return the {@link DnsWriter} for the given tld. */
public DnsWriter getForTld(String tld) {
String clazz = Registry.get(tld).getDnsWriter();
DnsWriter dnsWriter = dnsWriters.get(clazz);
checkState(dnsWriter != null, "Could not load DnsWriter %s for TLD %s", clazz, tld);
return dnsWriter;
}
}

View file

@ -20,7 +20,7 @@ import static google.registry.util.CollectionUtils.nullToEmpty;
import com.google.common.net.InternetDomainName; import com.google.common.net.InternetDomainName;
import google.registry.config.ConfigModule.Config; import google.registry.config.ConfigModule.Config;
import google.registry.model.dns.DnsWriter; import google.registry.dns.writer.DnsWriter;
import google.registry.request.Action; import google.registry.request.Action;
import google.registry.request.HttpException.ServiceUnavailableException; import google.registry.request.HttpException.ServiceUnavailableException;
import google.registry.request.Parameter; import google.registry.request.Parameter;
@ -30,7 +30,6 @@ import google.registry.util.FormattingLogger;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Provider;
import org.joda.time.Duration; import org.joda.time.Duration;
/** Task that sends domain and host updates to the DNS server. */ /** Task that sends domain and host updates to the DNS server. */
@ -44,7 +43,7 @@ public final class PublishDnsUpdatesAction implements Runnable, Callable<Void> {
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass(); private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
@Inject DnsQueue dnsQueue; @Inject DnsQueue dnsQueue;
@Inject Provider<DnsWriter> writerProvider; @Inject DnsWriterProxy dnsWriterProxy;
@Inject @Config("dnsWriteLockTimeout") Duration timeout; @Inject @Config("dnsWriteLockTimeout") Duration timeout;
@Inject @Parameter(RequestParameters.PARAM_TLD) String tld; @Inject @Parameter(RequestParameters.PARAM_TLD) String tld;
@Inject @Parameter(DOMAINS_PARAM) Set<String> domains; @Inject @Parameter(DOMAINS_PARAM) Set<String> domains;
@ -73,7 +72,7 @@ public final class PublishDnsUpdatesAction implements Runnable, Callable<Void> {
/** Steps through the domain and host refreshes contained in the parameters and processes them. */ /** Steps through the domain and host refreshes contained in the parameters and processes them. */
private void processBatch() { private void processBatch() {
try (DnsWriter writer = writerProvider.get()) { try (DnsWriter writer = dnsWriterProxy.getForTld(tld)) {
for (String domain : nullToEmpty(domains)) { for (String domain : nullToEmpty(domains)) {
if (!DomainNameUtils.isUnder( if (!DomainNameUtils.isUnder(
InternetDomainName.from(domain), InternetDomainName.from(tld))) { InternetDomainName.from(domain), InternetDomainName.from(tld))) {

View file

@ -1,18 +0,0 @@
package(
default_visibility = ["//java/google/registry:registry_project"],
)
licenses(["notice"]) # Apache 2.0
java_library(
name = "writer",
srcs = glob(["*.java"]),
deps = [
"//java/com/google/common/base",
"//third_party/java/dagger",
"//third_party/java/jsr305_annotations",
"//third_party/java/jsr330_inject",
"//java/google/registry/model",
],
)

View file

@ -1,49 +0,0 @@
// Copyright 2016 The Domain Registry 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.dns.writer;
import com.google.common.base.Joiner;
import google.registry.model.dns.DnsWriter;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
/**
* {@link DnsWriter} that doesn't actually update records in a DNS server.
*
* <p>All this class does is write its displeasure to the logs.
*/
public final class VoidDnsWriter implements DnsWriter {
private static final Logger logger = Logger.getLogger(VoidDnsWriter.class.getName());
private final Set<String> names = new HashSet<>();
@Override
public void publishDomain(String domainName) {
names.add(domainName);
}
@Override
public void publishHost(String hostName) {
names.add(hostName);
}
@Override
public void close() {
logger.warning("Ignoring DNS zone updates! No DnsWriterFactory implementation specified!\n"
+ Joiner.on('\n').join(names));
}
}

View file

@ -1,29 +0,0 @@
// Copyright 2016 The Domain Registry 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.dns.writer;
import dagger.Module;
import dagger.Provides;
import google.registry.model.dns.DnsWriter;
/** Dagger module that disables DNS updates. */
@Module
public final class VoidDnsWriterModule {
@Provides
static DnsWriter provideDnsWriter() {
return new VoidDnsWriter();
}
}

View file

@ -21,6 +21,7 @@ java_library(
"//third_party/java/dagger", "//third_party/java/dagger",
"//third_party/java/joda_time", "//third_party/java/joda_time",
"//java/google/registry/config", "//java/google/registry/config",
"//java/google/registry/dns/writer",
"//java/google/registry/model", "//java/google/registry/model",
"//java/google/registry/util", "//java/google/registry/util",
], ],

View file

@ -22,7 +22,10 @@ import com.google.api.services.dns.DnsScopes;
import com.google.common.base.Function; import com.google.common.base.Function;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
import dagger.multibindings.IntoMap;
import dagger.multibindings.StringKey;
import google.registry.config.ConfigModule.Config; import google.registry.config.ConfigModule.Config;
import google.registry.dns.writer.DnsWriter;
import java.util.Set; import java.util.Set;
/** Dagger module for Google Cloud DNS service connection objects. */ /** Dagger module for Google Cloud DNS service connection objects. */
@ -39,4 +42,11 @@ public final class CloudDnsModule {
.setApplicationName(projectId) .setApplicationName(projectId)
.build(); .build();
} }
@Provides
@IntoMap
@StringKey(CloudDnsWriter.NAME)
static DnsWriter provideCloudDnsWriter(CloudDnsWriter writer) {
return writer;
}
} }

View file

@ -32,8 +32,8 @@ import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.net.InternetDomainName; import com.google.common.net.InternetDomainName;
import com.google.common.util.concurrent.RateLimiter; import com.google.common.util.concurrent.RateLimiter;
import google.registry.config.ConfigModule.Config; import google.registry.config.ConfigModule.Config;
import google.registry.model.dns.DnsWriter; import google.registry.dns.writer.DnsWriter;
import google.registry.model.dns.DnsWriterZone; import google.registry.dns.writer.DnsWriterZone;
import google.registry.model.domain.DomainResource; import google.registry.model.domain.DomainResource;
import google.registry.model.domain.secdns.DelegationSignerData; import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.host.HostResource; import google.registry.model.host.HostResource;
@ -59,6 +59,12 @@ import org.joda.time.Duration;
*/ */
class CloudDnsWriter implements DnsWriter { class CloudDnsWriter implements DnsWriter {
/**
* The name of the pricing engine, as used in {@code Registry.dnsWriter}. Remember to change
* the value on affected Registry objects to prevent runtime failures.
*/
public static final String NAME = "CloudDnsWriter";
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass(); private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
// This is the default max QPS for Cloud DNS. It can be increased by contacting the team // This is the default max QPS for Cloud DNS. It can be increased by contacting the team

View file

@ -21,6 +21,7 @@ java_library(
"//third_party/java/jsr305_annotations", "//third_party/java/jsr305_annotations",
"//third_party/java/jsr330_inject", "//third_party/java/jsr330_inject",
"//java/google/registry/config", "//java/google/registry/config",
"//java/google/registry/dns/writer",
"//java/google/registry/model", "//java/google/registry/model",
"//java/google/registry/util", "//java/google/registry/util",
], ],

View file

@ -25,7 +25,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.net.InternetDomainName; import com.google.common.net.InternetDomainName;
import google.registry.config.ConfigModule.Config; import google.registry.config.ConfigModule.Config;
import google.registry.model.dns.DnsWriter; import google.registry.dns.writer.DnsWriter;
import google.registry.model.domain.DomainResource; import google.registry.model.domain.DomainResource;
import google.registry.model.domain.secdns.DelegationSignerData; import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.host.HostResource; import google.registry.model.host.HostResource;
@ -75,6 +75,12 @@ import org.xbill.DNS.Update;
*/ */
public class DnsUpdateWriter implements DnsWriter { public class DnsUpdateWriter implements DnsWriter {
/**
* The name of the pricing engine, as used in {@code Registry.dnsWriter}. Remember to change
* the value on affected Registry objects to prevent runtime failures.
*/
public static final String NAME = "DnsUpdateWriter";
private final Duration dnsTimeToLive; private final Duration dnsTimeToLive;
private final DnsMessageTransport transport; private final DnsMessageTransport transport;
private final Clock clock; private final Clock clock;

View file

@ -14,21 +14,26 @@
package google.registry.dns.writer.dnsupdate; package google.registry.dns.writer.dnsupdate;
import dagger.Binds;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
import google.registry.model.dns.DnsWriter; import dagger.multibindings.IntoMap;
import dagger.multibindings.StringKey;
import google.registry.dns.writer.DnsWriter;
import javax.net.SocketFactory; import javax.net.SocketFactory;
/** Dagger module that provides a DnsUpdateWriter. */ /** Dagger module that provides a DnsUpdateWriter. */
@Module @Module
public abstract class DnsUpdateWriterModule { public abstract class DnsUpdateWriterModule {
@Binds
abstract DnsWriter provideDnsWriter(DnsUpdateWriter dnsWriter);
@Provides @Provides
static SocketFactory provideSocketFactory() { static SocketFactory provideSocketFactory() {
return SocketFactory.getDefault(); return SocketFactory.getDefault();
} }
@Provides
@IntoMap
@StringKey(DnsUpdateWriter.NAME)
static DnsWriter provideDnsUpdateWriter(DnsUpdateWriter writer) {
return writer;
}
} }

View file

@ -1,56 +0,0 @@
// Copyright 2016 The Domain Registry Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.dns;
/**
* Transaction object for sending an atomic batch of updates for a single zone to the DNS server.
*
* <p>Here's an example of how you would publish updates for a domain and host:
* <pre>
* &#064;Inject Provider&lt;DnsWriter&gt; dnsWriter;
* try (DnsWriter writer = dnsWriter.get()) {
* writer.publishDomain(domainName);
* writer.publishHost(hostName);
* }
* </pre>
*/
public interface DnsWriter extends AutoCloseable {
/**
* Loads {@code domainName} from datastore and publishes its NS/DS records to the DNS server.
* Replaces existing records for the exact name supplied with an NS record for each name server
* and a DS record for each delegation signer stored in the registry for the supplied domain name.
* If the domain is deleted or is in a "non-publish" state then any existing records are deleted.
*
* @param domainName the fully qualified domain name, with no trailing dot
*/
void publishDomain(String domainName);
/**
* Loads {@code hostName} from datastore and publishes its A/AAAA glue records to the DNS server,
* if it is used as an in-bailiwick nameserver. Orphaned glue records are prohibited. Replaces
* existing records for the exact name supplied, with an A or AAAA record (as appropriate) for
* each address stored in the registry, for the supplied host name. If the host is deleted then
* the existing records are deleted. Assumes that this method will only be called for in-bailiwick
* hosts. The registry does not have addresses for other hosts.
*
* @param hostName the fully qualified host name, with no trailing dot
*/
void publishHost(String hostName);
/** Commits the updates to the DNS server atomically. */
@Override
void close();
}

View file

@ -1,23 +0,0 @@
// Copyright 2016 The Domain Registry Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.dns;
import java.lang.annotation.Documented;
import javax.inject.Qualifier;
/** Dagger qualifier for the fully-qualified zone name that's being updated. */
@Qualifier
@Documented
public @interface DnsWriterZone {}

View file

@ -255,6 +255,16 @@ public class Registry extends ImmutableObject implements Buildable {
} }
} }
/** Backfill the Registry entities that were saved before this field was added. */
// TODO(shikhman): Remove this backfill once it is populated on all Registry entities.
@OnLoad
void backfillDnsWriter() {
if (dnsWriter == null) {
dnsWriter = "VoidDnsWriter";
}
}
/** /**
* The name of the pricing engine that this TLD uses. * The name of the pricing engine that this TLD uses.
* *
@ -266,6 +276,14 @@ public class Registry extends ImmutableObject implements Buildable {
*/ */
String pricingEngineClassName; String pricingEngineClassName;
/**
* The name of the DnsWriter that this TLD uses.
*
* <p>This must be a valid key for the map of DnsWriters injected by <code>
* @Inject Map<String, DnsWriter></code>
*/
String dnsWriter;
/** /**
* The unicode-aware representation of the TLD associated with this {@link Registry}. * The unicode-aware representation of the TLD associated with this {@link Registry}.
* *
@ -545,6 +563,10 @@ public class Registry extends ImmutableObject implements Buildable {
return pricingEngineClassName; return pricingEngineClassName;
} }
public String getDnsWriter() {
return dnsWriter;
}
public ImmutableSet<String> getAllowedRegistrantContactIds() { public ImmutableSet<String> getAllowedRegistrantContactIds() {
return nullToEmptyImmutableCopy(allowedRegistrantContactIds); return nullToEmptyImmutableCopy(allowedRegistrantContactIds);
} }
@ -616,6 +638,12 @@ public class Registry extends ImmutableObject implements Buildable {
return this; return this;
} }
public Builder setDnsWriter(String dnsWriter) {
getInstance().dnsWriter = checkArgumentNotNull(dnsWriter);
return this;
}
public Builder setAddGracePeriodLength(Duration addGracePeriodLength) { public Builder setAddGracePeriodLength(Duration addGracePeriodLength) {
checkArgument(addGracePeriodLength.isLongerThan(Duration.ZERO), checkArgument(addGracePeriodLength.isLongerThan(Duration.ZERO),
"addGracePeriodLength must be non-zero"); "addGracePeriodLength must be non-zero");

View file

@ -13,6 +13,12 @@ java_library(
"//java/com/google/common/base", "//java/com/google/common/base",
"//java/com/google/common/collect", "//java/com/google/common/collect",
"//java/com/google/common/net", "//java/com/google/common/net",
"//third_party/java/bouncycastle",
"//third_party/java/dagger",
"//third_party/java/joda_time",
"//third_party/java/jsr305_annotations",
"//third_party/java/jsr330_inject",
"//third_party/java/servlet/servlet_api",
"//java/google/registry/backup", "//java/google/registry/backup",
"//java/google/registry/bigquery", "//java/google/registry/bigquery",
"//java/google/registry/billing", "//java/google/registry/billing",
@ -20,6 +26,8 @@ java_library(
"//java/google/registry/cron", "//java/google/registry/cron",
"//java/google/registry/dns", "//java/google/registry/dns",
"//java/google/registry/dns/writer", "//java/google/registry/dns/writer",
"//java/google/registry/dns/writer/clouddns",
"//java/google/registry/dns/writer/dnsupdate",
"//java/google/registry/export", "//java/google/registry/export",
"//java/google/registry/export/sheet", "//java/google/registry/export/sheet",
"//java/google/registry/flows", "//java/google/registry/flows",
@ -34,12 +42,6 @@ java_library(
"//java/google/registry/request:modules", "//java/google/registry/request:modules",
"//java/google/registry/tmch", "//java/google/registry/tmch",
"//java/google/registry/util", "//java/google/registry/util",
"//third_party/java/bouncycastle",
"//third_party/java/dagger",
"//third_party/java/joda_time",
"//third_party/java/jsr305_annotations",
"//third_party/java/jsr330_inject",
"//third_party/java/servlet/servlet_api",
], ],
) )

View file

@ -28,6 +28,8 @@ import google.registry.dns.DnsModule;
import google.registry.dns.PublishDnsUpdatesAction; import google.registry.dns.PublishDnsUpdatesAction;
import google.registry.dns.ReadDnsQueueAction; import google.registry.dns.ReadDnsQueueAction;
import google.registry.dns.RefreshDnsAction; import google.registry.dns.RefreshDnsAction;
import google.registry.dns.writer.clouddns.CloudDnsModule;
import google.registry.dns.writer.dnsupdate.DnsUpdateWriterModule;
import google.registry.export.BigqueryPollJobAction; import google.registry.export.BigqueryPollJobAction;
import google.registry.export.ExportDomainListsAction; import google.registry.export.ExportDomainListsAction;
import google.registry.export.ExportRequestModule; import google.registry.export.ExportRequestModule;
@ -67,8 +69,10 @@ import google.registry.tmch.TmchSmdrlAction;
AsyncFlowsModule.class, AsyncFlowsModule.class,
BackendModule.class, BackendModule.class,
BackupModule.class, BackupModule.class,
CloudDnsModule.class,
CronModule.class, CronModule.class,
DnsModule.class, DnsModule.class,
DnsUpdateWriterModule.class,
ExportRequestModule.class, ExportRequestModule.class,
MapreduceModule.class, MapreduceModule.class,
RdeModule.class, RdeModule.class,

View file

@ -45,6 +45,7 @@ java_library(
"//java/com/google/common/util/concurrent", "//java/com/google/common/util/concurrent",
"//java/google/registry/bigquery", "//java/google/registry/bigquery",
"//java/google/registry/config", "//java/google/registry/config",
"//java/google/registry/dns/writer",
"//java/google/registry/export", "//java/google/registry/export",
"//java/google/registry/flows", "//java/google/registry/flows",
"//java/google/registry/keyring/api", "//java/google/registry/keyring/api",

View file

@ -15,6 +15,7 @@
package google.registry.tools; package google.registry.tools;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static google.registry.model.RoidSuffixes.isRoidSuffixUsed; import static google.registry.model.RoidSuffixes.isRoidSuffixUsed;
import static google.registry.util.CollectionUtils.findDuplicates; import static google.registry.util.CollectionUtils.findDuplicates;
import static google.registry.util.DomainNameUtils.canonicalizeDomainName; import static google.registry.util.DomainNameUtils.canonicalizeDomainName;
@ -26,6 +27,7 @@ import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.ImmutableSortedMap;
import google.registry.dns.writer.DnsWriter;
import google.registry.model.pricing.StaticPremiumListPricingEngine; import google.registry.model.pricing.StaticPremiumListPricingEngine;
import google.registry.model.registry.Registries; import google.registry.model.registry.Registries;
import google.registry.model.registry.Registry; import google.registry.model.registry.Registry;
@ -39,6 +41,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject;
import org.joda.money.Money; import org.joda.money.Money;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.Duration; import org.joda.time.Duration;
@ -46,6 +49,8 @@ import org.joda.time.Duration;
/** Shared base class for commands to create or update a TLD. */ /** Shared base class for commands to create or update a TLD. */
abstract class CreateOrUpdateTldCommand extends MutatingCommand { abstract class CreateOrUpdateTldCommand extends MutatingCommand {
@Inject Map<String, DnsWriter> dnsWriters;
@Parameter( @Parameter(
description = "Names of the TLDs", description = "Names of the TLDs",
required = true) required = true)
@ -205,6 +210,15 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
description = "The end of the claims period") description = "The end of the claims period")
DateTime claimsPeriodEnd; DateTime claimsPeriodEnd;
@Nullable
@Parameter(
names = "--dns_writer",
description = "The name of the DnsWriter implementation to use",
converter = OptionalStringParameter.class,
validateWith = OptionalStringParameter.class
)
Optional<String> dnsWriter;
/** Returns the existing registry (for update) or null (for creates). */ /** Returns the existing registry (for update) or null (for creates). */
@Nullable @Nullable
abstract Registry getOldRegistry(String tld); abstract Registry getOldRegistry(String tld);
@ -361,6 +375,16 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
} }
} }
if (dnsWriter != null) {
if (dnsWriter.isPresent()) {
checkNotNull(
dnsWriters.get(dnsWriter.get()),
"The DNS writer '%s' doesn't exist",
dnsWriter.get());
builder.setDnsWriter(dnsWriter.get());
}
}
ImmutableSet<String> newReservedListNames = getReservedLists(oldRegistry); ImmutableSet<String> newReservedListNames = getReservedLists(oldRegistry);
checkReservedListValidityForTld(tld, newReservedListNames); checkReservedListValidityForTld(tld, newReservedListNames);
builder.setReservedListsByName(newReservedListNames); builder.setReservedListsByName(newReservedListNames);

View file

@ -17,18 +17,20 @@ package google.registry.dns;
import static google.registry.testing.DatastoreHelper.createTld; import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.persistActiveDomain; import static google.registry.testing.DatastoreHelper.persistActiveDomain;
import static google.registry.testing.DatastoreHelper.persistActiveSubordinateHost; import static google.registry.testing.DatastoreHelper.persistActiveSubordinateHost;
import static google.registry.testing.DatastoreHelper.persistResource;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import google.registry.model.dns.DnsWriter; import google.registry.dns.writer.DnsWriter;
import google.registry.model.domain.DomainResource; import google.registry.model.domain.DomainResource;
import google.registry.model.ofy.Ofy; import google.registry.model.ofy.Ofy;
import google.registry.model.registry.Registry;
import google.registry.testing.AppEngineRule; import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock; import google.registry.testing.FakeClock;
import google.registry.testing.InjectRule; import google.registry.testing.InjectRule;
import javax.inject.Provider;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.Duration; import org.joda.time.Duration;
import org.junit.Before; import org.junit.Before;
@ -58,6 +60,7 @@ public class PublishDnsUpdatesActionTest {
public void setUp() throws Exception { public void setUp() throws Exception {
inject.setStaticField(Ofy.class, "clock", clock); inject.setStaticField(Ofy.class, "clock", clock);
createTld("xn--q9jyb4c"); createTld("xn--q9jyb4c");
persistResource(Registry.get("xn--q9jyb4c").asBuilder().setDnsWriter("mock").build());
DomainResource domain1 = persistActiveDomain("example.xn--q9jyb4c"); DomainResource domain1 = persistActiveDomain("example.xn--q9jyb4c");
persistActiveSubordinateHost("ns1.example.xn--q9jyb4c", domain1); persistActiveSubordinateHost("ns1.example.xn--q9jyb4c", domain1);
persistActiveSubordinateHost("ns2.example.xn--q9jyb4c", domain1); persistActiveSubordinateHost("ns2.example.xn--q9jyb4c", domain1);
@ -66,17 +69,13 @@ public class PublishDnsUpdatesActionTest {
clock.advanceOneMilli(); clock.advanceOneMilli();
} }
private PublishDnsUpdatesAction createAction(String tld) { private PublishDnsUpdatesAction createAction(String tld) throws Exception {
PublishDnsUpdatesAction action = new PublishDnsUpdatesAction(); PublishDnsUpdatesAction action = new PublishDnsUpdatesAction();
action.timeout = Duration.standardSeconds(10); action.timeout = Duration.standardSeconds(10);
action.tld = tld; action.tld = tld;
action.hosts = ImmutableSet.<String>of(); action.hosts = ImmutableSet.<String>of();
action.domains = ImmutableSet.<String>of(); action.domains = ImmutableSet.<String>of();
action.writerProvider = new Provider<DnsWriter>() { action.dnsWriterProxy = new DnsWriterProxy(ImmutableMap.of("mock", dnsWriter));
@Override
public DnsWriter get() {
return dnsWriter;
}};
return action; return action;
} }

View file

@ -675,6 +675,7 @@ class google.registry.model.registry.Registry {
google.registry.model.common.TimedTransitionProperty<org.joda.money.Money, google.registry.model.registry.Registry$BillingCostTransition> eapFeeSchedule; google.registry.model.common.TimedTransitionProperty<org.joda.money.Money, google.registry.model.registry.Registry$BillingCostTransition> eapFeeSchedule;
google.registry.model.common.TimedTransitionProperty<org.joda.money.Money, google.registry.model.registry.Registry$BillingCostTransition> renewBillingCostTransitions; google.registry.model.common.TimedTransitionProperty<org.joda.money.Money, google.registry.model.registry.Registry$BillingCostTransition> renewBillingCostTransitions;
google.registry.model.registry.Registry$TldType tldType; google.registry.model.registry.Registry$TldType tldType;
java.lang.String dnsWriter;
java.lang.String driveFolderId; java.lang.String driveFolderId;
java.lang.String lordnUsername; java.lang.String lordnUsername;
java.lang.String pricingEngineClassName; java.lang.String pricingEngineClassName;

View file

@ -51,6 +51,7 @@ java_library(
"//third_party/java/truth", "//third_party/java/truth",
"//java/google/registry/config", "//java/google/registry/config",
"//java/google/registry/dns:constants", "//java/google/registry/dns:constants",
"//java/google/registry/dns/writer",
"//java/google/registry/flows", "//java/google/registry/flows",
"//java/google/registry/model", "//java/google/registry/model",
"//java/google/registry/pricing", "//java/google/registry/pricing",

View file

@ -53,6 +53,7 @@ import com.googlecode.objectify.VoidWork;
import com.googlecode.objectify.Work; import com.googlecode.objectify.Work;
import com.googlecode.objectify.cmd.Saver; import com.googlecode.objectify.cmd.Saver;
import google.registry.config.RegistryEnvironment; import google.registry.config.RegistryEnvironment;
import google.registry.dns.writer.VoidDnsWriter;
import google.registry.model.Buildable; import google.registry.model.Buildable;
import google.registry.model.EppResource; import google.registry.model.EppResource;
import google.registry.model.EppResource.ForeignKeyedEppResource; import google.registry.model.EppResource.ForeignKeyedEppResource;
@ -222,19 +223,20 @@ public class DatastoreHelper {
public static Registry newRegistry( public static Registry newRegistry(
String tld, String roidSuffix, ImmutableSortedMap<DateTime, TldState> tldStates) { String tld, String roidSuffix, ImmutableSortedMap<DateTime, TldState> tldStates) {
return new Registry.Builder() return new Registry.Builder()
.setTldStr(tld) .setTldStr(tld)
.setRoidSuffix(roidSuffix) .setRoidSuffix(roidSuffix)
.setTldStateTransitions(tldStates) .setTldStateTransitions(tldStates)
// Set billing costs to distinct small primes to avoid masking bugs in tests. // Set billing costs to distinct small primes to avoid masking bugs in tests.
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 11))) .setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 11)))
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.zero(USD))) .setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.zero(USD)))
.setCreateBillingCost(Money.of(USD, 13)) .setCreateBillingCost(Money.of(USD, 13))
.setRestoreBillingCost(Money.of(USD, 17)) .setRestoreBillingCost(Money.of(USD, 17))
.setServerStatusChangeBillingCost(Money.of(USD, 19)) .setServerStatusChangeBillingCost(Money.of(USD, 19))
// Always set a default premium list. Tests that don't want it can delete it. // Always set a default premium list. Tests that don't want it can delete it.
.setPremiumList(persistPremiumList(tld, DEFAULT_PREMIUM_LIST_CONTENTS.get())) .setPremiumList(persistPremiumList(tld, DEFAULT_PREMIUM_LIST_CONTENTS.get()))
.setPremiumPricingEngine(StaticPremiumListPricingEngine.NAME) .setPremiumPricingEngine(StaticPremiumListPricingEngine.NAME)
.build(); .setDnsWriter(VoidDnsWriter.NAME)
.build();
} }
public static ContactResource persistActiveContact(String contactId) { public static ContactResource persistActiveContact(String contactId) {