google-nomulus/java/google/registry/rde/imports/XjcToDomainResourceConverter.java
mcilwain 646dcecd7e Create GenerateAllocationTokens nomulus tool command
This creates a specified number of tokens of a given schema, with a dryrun option
to not persist them.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=181403775
2018-01-19 14:26:56 -05:00

271 lines
12 KiB
Java

// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.rde.imports;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.util.DomainNameUtils.canonicalizeDomainName;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import static org.joda.time.DateTimeZone.UTC;
import com.google.common.base.Ascii;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InternetDomainName;
import com.googlecode.objectify.Key;
import google.registry.model.billing.BillingEvent;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.DomainAuthInfo;
import google.registry.model.domain.DomainResource;
import google.registry.model.domain.GracePeriod;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.model.index.ForeignKeyIndex;
import google.registry.model.poll.PollMessage;
import google.registry.model.registry.Registries;
import google.registry.model.registry.Registry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.util.NonFinalForTesting;
import google.registry.util.RandomStringGenerator;
import google.registry.util.StringGenerator;
import google.registry.util.XmlToEnumMapper;
import google.registry.xjc.domain.XjcDomainContactType;
import google.registry.xjc.domain.XjcDomainNsType;
import google.registry.xjc.domain.XjcDomainStatusType;
import google.registry.xjc.rdedomain.XjcRdeDomain;
import google.registry.xjc.rdedomain.XjcRdeDomainElement;
import google.registry.xjc.rdedomain.XjcRdeDomainTransferDataType;
import google.registry.xjc.rgp.XjcRgpStatusType;
import google.registry.xjc.secdns.XjcSecdnsDsDataType;
import java.security.NoSuchAlgorithmException;
import java.security.ProviderException;
import java.security.SecureRandom;
import java.util.function.Function;
import org.joda.time.DateTime;
/** Utility class that converts an {@link XjcRdeDomainElement} into a {@link DomainResource}. */
final class XjcToDomainResourceConverter extends XjcToEppResourceConverter {
@NonFinalForTesting
static StringGenerator stringGenerator =
new RandomStringGenerator(StringGenerator.Alphabets.BASE_64, getRandom());
static SecureRandom getRandom() {
try {
return SecureRandom.getInstance("NativePRNG");
} catch (NoSuchAlgorithmException e) {
throw new ProviderException(e);
}
}
private static final XmlToEnumMapper<TransferStatus> TRANSFER_STATUS_MAPPER =
XmlToEnumMapper.create(TransferStatus.values());
private static final Function<String, Key<HostResource>> HOST_OBJ_CONVERTER =
fullyQualifiedHostName -> {
// host names are always lower case
fullyQualifiedHostName = canonicalizeDomainName(fullyQualifiedHostName);
Key<HostResource> key =
ForeignKeyIndex.loadAndGetKey(
HostResource.class, fullyQualifiedHostName, DateTime.now(UTC));
checkState(
key != null,
String.format("HostResource not found with name '%s'", fullyQualifiedHostName));
return key;
};
/** Converts {@link XjcRgpStatusType} to {@link GracePeriod} */
private static class GracePeriodConverter implements Function<XjcRgpStatusType, GracePeriod> {
private final XjcRdeDomain domain;
private final Key<BillingEvent.Recurring> autoRenewBillingEvent;
private final Registry tld;
GracePeriodConverter(XjcRdeDomain domain, Key<BillingEvent.Recurring> autoRenewBillingEvent) {
this.domain = domain;
this.autoRenewBillingEvent = autoRenewBillingEvent;
this.tld =
Registry.get(
Registries.findTldForNameOrThrow(InternetDomainName.from(domain.getName()))
.toString());
}
@Override
public GracePeriod apply(XjcRgpStatusType gracePeriodStatus) {
switch (gracePeriodStatus.getS()) {
case ADD_PERIOD:
return GracePeriod.createWithoutBillingEvent(
GracePeriodStatus.ADD,
domain.getCrDate().plus(this.tld.getAddGracePeriodLength()),
domain.getCrRr().getValue());
case AUTO_RENEW_PERIOD:
return GracePeriod.createForRecurring(
GracePeriodStatus.AUTO_RENEW,
domain.getUpDate().plus(this.tld.getAutoRenewGracePeriodLength()),
domain.getClID(),
autoRenewBillingEvent);
case PENDING_DELETE:
return GracePeriod.createWithoutBillingEvent(
GracePeriodStatus.PENDING_DELETE,
domain.getUpDate().plus(this.tld.getPendingDeleteLength()),
domain.getClID());
case REDEMPTION_PERIOD:
return GracePeriod.createWithoutBillingEvent(
GracePeriodStatus.REDEMPTION,
domain.getUpDate().plus(this.tld.getRedemptionGracePeriodLength()),
domain.getClID());
case RENEW_PERIOD:
return GracePeriod.createWithoutBillingEvent(
GracePeriodStatus.RENEW,
domain.getUpDate().plus(this.tld.getRenewGracePeriodLength()),
domain.getClID());
case TRANSFER_PERIOD:
return GracePeriod.createWithoutBillingEvent(
GracePeriodStatus.TRANSFER,
domain.getUpDate().plus(this.tld.getTransferGracePeriodLength()),
domain.getTrnData().getReRr().getValue());
default:
throw new IllegalArgumentException(
"Unsupported grace period status: " + gracePeriodStatus.getS());
}
}
}
/** Converts {@link XjcRdeDomain} to {@link DomainResource}. */
static DomainResource convertDomain(
XjcRdeDomain domain,
BillingEvent.Recurring autoRenewBillingEvent,
PollMessage.Autorenew autoRenewPollMessage) {
GracePeriodConverter gracePeriodConverter =
new GracePeriodConverter(domain, Key.create(autoRenewBillingEvent));
DomainResource.Builder builder =
new DomainResource.Builder()
.setFullyQualifiedDomainName(canonicalizeDomainName(domain.getName()))
.setRepoId(domain.getRoid())
.setIdnTableName(domain.getIdnTableId())
.setPersistedCurrentSponsorClientId(domain.getClID())
.setCreationClientId(domain.getCrRr().getValue())
.setCreationTime(domain.getCrDate())
.setAutorenewPollMessage(Key.create(autoRenewPollMessage))
.setAutorenewBillingEvent(Key.create(autoRenewBillingEvent))
.setRegistrationExpirationTime(domain.getExDate())
.setLastEppUpdateTime(domain.getUpDate())
.setLastEppUpdateClientId(domain.getUpRr() == null ? null : domain.getUpRr().getValue())
.setLastTransferTime(domain.getTrDate())
.setStatusValues(
domain
.getStatuses()
.stream()
.map(XjcToDomainResourceConverter::convertStatusType)
.collect(toImmutableSet()))
.setNameservers(convertNameservers(domain.getNs()))
.setGracePeriods(
domain
.getRgpStatuses()
.stream()
.map(gracePeriodConverter)
.collect(toImmutableSet()))
.setContacts(
domain
.getContacts()
.stream()
.map(XjcToDomainResourceConverter::convertContactType)
.collect(toImmutableSet()))
.setDsData(
domain.getSecDNS() == null
? ImmutableSet.of()
: domain
.getSecDNS()
.getDsDatas()
.stream()
.map(XjcToDomainResourceConverter::convertSecdnsDsDataType)
.collect(toImmutableSet()))
.setTransferData(convertDomainTransferData(domain.getTrnData()))
// authInfo pw must be a token between 6 and 16 characters in length
// generate a token of 16 characters as the default authInfo pw
.setAuthInfo(
DomainAuthInfo.create(
PasswordAuth.create(stringGenerator.createString(16), domain.getRoid())));
checkArgumentNotNull(
domain.getRegistrant(), "Registrant is missing for domain '%s'", domain.getName());
builder = builder.setRegistrant(convertRegistrant(domain.getRegistrant()));
return builder.build();
}
/** Returns {@link Key} for registrant from foreign key */
private static Key<ContactResource> convertRegistrant(String contactId) {
Key<ContactResource> key =
ForeignKeyIndex.loadAndGetKey(ContactResource.class, contactId, DateTime.now(UTC));
checkState(key != null, "Registrant not found: '%s'", contactId);
return key;
}
/** Converts {@link XjcDomainNsType} to <code>ImmutableSet<Key<HostResource>></code>. */
private static ImmutableSet<Key<HostResource>> convertNameservers(XjcDomainNsType ns) {
// If no hosts are specified, return an empty set
if (ns == null || (ns.getHostAttrs() == null && ns.getHostObjs() == null)) {
return ImmutableSet.of();
}
// Domain linked hosts must be specified by host object, not host attributes.
checkArgument(
ns.getHostAttrs() == null || ns.getHostAttrs().isEmpty(),
"Host attributes are not yet supported");
return ns.getHostObjs().stream().map(HOST_OBJ_CONVERTER).collect(toImmutableSet());
}
/** Converts {@link XjcRdeDomainTransferDataType} to {@link TransferData}. */
private static TransferData convertDomainTransferData(XjcRdeDomainTransferDataType data) {
if (data == null) {
return TransferData.EMPTY;
}
return new TransferData.Builder()
.setTransferStatus(TRANSFER_STATUS_MAPPER.xmlToEnum(data.getTrStatus().value()))
.setGainingClientId(data.getReRr().getValue())
.setLosingClientId(data.getAcRr().getValue())
.setTransferRequestTime(data.getReDate())
.setPendingTransferExpirationTime(data.getAcDate())
.setTransferredRegistrationExpirationTime(data.getExDate())
.build();
}
/** Converts {@link XjcDomainStatusType} to {@link StatusValue}. */
private static StatusValue convertStatusType(XjcDomainStatusType type) {
return StatusValue.fromXmlName(type.getS().value());
}
/** Converts {@link XjcSecdnsDsDataType} to {@link DelegationSignerData}. */
private static DelegationSignerData convertSecdnsDsDataType(XjcSecdnsDsDataType secdns) {
return DelegationSignerData.create(
secdns.getKeyTag(), secdns.getAlg(), secdns.getDigestType(), secdns.getDigest());
}
/** Converts {@link XjcDomainContactType} to {@link DesignatedContact}. */
private static DesignatedContact convertContactType(XjcDomainContactType contact) {
String contactId = contact.getValue();
Key<ContactResource> key =
ForeignKeyIndex.loadAndGetKey(ContactResource.class, contactId, DateTime.now(UTC));
checkState(key != null, "Contact not found: '%s'", contactId);
DesignatedContact.Type type =
DesignatedContact.Type.valueOf(Ascii.toUpperCase(contact.getType().toString()));
return DesignatedContact.create(type, key);
}
private XjcToDomainResourceConverter() {}
}