mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 16:07:15 +02:00
mv com/google/domain/registry google/registry
This change renames directories in preparation for the great package rename. The repository is now in a broken state because the code itself hasn't been updated. However this should ensure that git correctly preserves history for each file.
This commit is contained in:
parent
a41677aea1
commit
5012893c1d
2396 changed files with 0 additions and 0 deletions
414
java/google/registry/model/domain/DomainResource.java
Normal file
414
java/google/registry/model/domain/DomainResource.java
Normal file
|
@ -0,0 +1,414 @@
|
|||
// 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 com.google.domain.registry.model.domain;
|
||||
|
||||
import static com.google.common.collect.Sets.intersection;
|
||||
import static com.google.domain.registry.model.EppResourceUtils.projectResourceOntoBuilderAtTime;
|
||||
import static com.google.domain.registry.model.EppResourceUtils.setAutomaticTransferSuccessProperties;
|
||||
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
|
||||
import static com.google.domain.registry.util.CollectionUtils.difference;
|
||||
import static com.google.domain.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
import static com.google.domain.registry.util.CollectionUtils.union;
|
||||
import static com.google.domain.registry.util.DateTimeUtils.earliestOf;
|
||||
import static com.google.domain.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||
import static com.google.domain.registry.util.DateTimeUtils.leapSafeAddYears;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.domain.registry.model.EppResource.ForeignKeyedEppResource;
|
||||
import com.google.domain.registry.model.annotations.ExternalMessagingName;
|
||||
import com.google.domain.registry.model.billing.BillingEvent;
|
||||
import com.google.domain.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import com.google.domain.registry.model.eppcommon.StatusValue;
|
||||
import com.google.domain.registry.model.poll.PollMessage;
|
||||
import com.google.domain.registry.model.registry.Registry;
|
||||
import com.google.domain.registry.model.transfer.TransferData;
|
||||
import com.google.domain.registry.model.transfer.TransferStatus;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.Ref;
|
||||
import com.googlecode.objectify.annotation.Cache;
|
||||
import com.googlecode.objectify.annotation.EntitySubclass;
|
||||
import com.googlecode.objectify.annotation.IgnoreSave;
|
||||
import com.googlecode.objectify.condition.IfNull;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Interval;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
/** A persistable domain resource including mutable and non-mutable fields. */
|
||||
@XmlRootElement(name = "infData")
|
||||
@XmlType(propOrder = {
|
||||
"fullyQualifiedDomainName",
|
||||
"repoId",
|
||||
"status",
|
||||
"registrant",
|
||||
"contacts",
|
||||
"nameservers",
|
||||
"subordinateHosts",
|
||||
"currentSponsorClientId",
|
||||
"creationClientId",
|
||||
"creationTime",
|
||||
"lastEppUpdateClientId",
|
||||
"lastEppUpdateTime",
|
||||
"registrationExpirationTime",
|
||||
"lastTransferTime",
|
||||
"authInfo"})
|
||||
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
|
||||
@EntitySubclass(index = true)
|
||||
@ExternalMessagingName("domain")
|
||||
public class DomainResource extends DomainBase implements ForeignKeyedEppResource {
|
||||
|
||||
/** The max number of years that a domain can be registered for, as set by ICANN policy. */
|
||||
public static final int MAX_REGISTRATION_YEARS = 10;
|
||||
|
||||
/** Status values which prohibit DNS information from being published. */
|
||||
private static final ImmutableSet<StatusValue> DNS_PUBLISHING_PROHIBITED_STATUSES =
|
||||
ImmutableSet.of(
|
||||
StatusValue.CLIENT_HOLD,
|
||||
StatusValue.INACTIVE,
|
||||
StatusValue.PENDING_DELETE,
|
||||
StatusValue.SERVER_HOLD);
|
||||
|
||||
/** Fully qualified host names of this domain's active subordinate hosts. */
|
||||
@XmlElement(name = "host")
|
||||
Set<String> subordinateHosts;
|
||||
|
||||
/** When this domain's registration will expire. */
|
||||
@XmlElement(name = "exDate")
|
||||
DateTime registrationExpirationTime;
|
||||
|
||||
/**
|
||||
* The poll message associated with this domain being deleted.
|
||||
* <p>
|
||||
* This field should be null if the domain is not in pending delete. If it is, the field should
|
||||
* refer to a {@link PollMessage} timed to when the domain is fully deleted. If the domain is
|
||||
* restored, the message should be deleted.
|
||||
*/
|
||||
@XmlTransient
|
||||
Key<PollMessage.OneTime> deletePollMessage;
|
||||
|
||||
/**
|
||||
* The recurring billing event associated with this domain's autorenewals.
|
||||
* <p>
|
||||
* The recurrence should be open ended unless the domain is in pending delete or fully deleted, in
|
||||
* which case it should be closed at the time the delete was requested. Whenever the domain's
|
||||
* {@link #registrationExpirationTime} is changed the recurrence should be closed, a new one
|
||||
* should be created, and this field should be updated to point to the new one.
|
||||
*/
|
||||
@XmlTransient
|
||||
Ref<BillingEvent.Recurring> autorenewBillingEvent;
|
||||
|
||||
/**
|
||||
* The recurring poll message associated with this domain's autorenewals.
|
||||
* <p>
|
||||
* The recurrence should be open ended unless the domain is in pending delete or fully deleted, in
|
||||
* which case it should be closed at the time the delete was requested. Whenever the domain's
|
||||
* {@link #registrationExpirationTime} is changed the recurrence should be closed, a new one
|
||||
* should be created, and this field should be updated to point to the new one.
|
||||
*/
|
||||
@XmlTransient
|
||||
Ref<PollMessage.Autorenew> autorenewPollMessage;
|
||||
|
||||
/** The unexpired grace periods for this domain (some of which may not be active yet). */
|
||||
@XmlTransient
|
||||
Set<GracePeriod> gracePeriods;
|
||||
|
||||
/**
|
||||
* The id of the signed mark that was used to create the sunrise application for this domain.
|
||||
* Will only be populated for domains allocated from a sunrise application.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
@XmlTransient
|
||||
String smdId;
|
||||
|
||||
/**
|
||||
* The time that the application used to allocate this domain was created. Will only be populated
|
||||
* for domains allocated from an application.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
@XmlTransient
|
||||
DateTime applicationTime;
|
||||
|
||||
/**
|
||||
* A reference to the application used to allocate this domain. Will only be populated for domains
|
||||
* allocated from an application.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
@XmlTransient
|
||||
Ref<DomainApplication> application;
|
||||
|
||||
public ImmutableSet<String> getSubordinateHosts() {
|
||||
return nullToEmptyImmutableCopy(subordinateHosts);
|
||||
}
|
||||
|
||||
public DateTime getRegistrationExpirationTime() {
|
||||
return registrationExpirationTime;
|
||||
}
|
||||
|
||||
public Key<PollMessage.OneTime> getDeletePollMessage() {
|
||||
return deletePollMessage;
|
||||
}
|
||||
|
||||
public Ref<BillingEvent.Recurring> getAutorenewBillingEvent() {
|
||||
return autorenewBillingEvent;
|
||||
}
|
||||
|
||||
public Ref<PollMessage.Autorenew> getAutorenewPollMessage() {
|
||||
return autorenewPollMessage;
|
||||
}
|
||||
|
||||
public ImmutableSet<GracePeriod> getGracePeriods() {
|
||||
return nullToEmptyImmutableCopy(gracePeriods);
|
||||
}
|
||||
|
||||
public String getSmdId() {
|
||||
return smdId;
|
||||
}
|
||||
|
||||
public DateTime getApplicationTime() {
|
||||
return applicationTime;
|
||||
}
|
||||
|
||||
public Ref<DomainApplication> getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForeignKey() {
|
||||
return fullyQualifiedDomainName;
|
||||
}
|
||||
|
||||
/** Returns true if DNS information should be published for the given domain. */
|
||||
public boolean shouldPublishToDns() {
|
||||
return intersection(getStatusValues(), DNS_PUBLISHING_PROHIBITED_STATUSES).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Registry Grace Period Statuses for this domain.
|
||||
* <p>
|
||||
* This collects all statuses from the domain's {@link GracePeriod}s and also adds the
|
||||
* PENDING_DELETE status if needed.
|
||||
*/
|
||||
public ImmutableSet<GracePeriodStatus> getGracePeriodStatuses() {
|
||||
Set<GracePeriodStatus> gracePeriodStatuses = new HashSet<>();
|
||||
for (GracePeriod gracePeriod : getGracePeriods()) {
|
||||
gracePeriodStatuses.add(gracePeriod.getType());
|
||||
}
|
||||
if (getStatusValues().contains(StatusValue.PENDING_DELETE)
|
||||
&& !gracePeriodStatuses.contains(GracePeriodStatus.REDEMPTION)) {
|
||||
gracePeriodStatuses.add(GracePeriodStatus.PENDING_DELETE);
|
||||
}
|
||||
return ImmutableSet.copyOf(gracePeriodStatuses);
|
||||
}
|
||||
|
||||
/**
|
||||
* The logic in this method, which handles implicit server approval of transfers, very closely
|
||||
* parallels the logic in {@code DomainTransferApproveFlow} which handles explicit client
|
||||
* approvals.
|
||||
*/
|
||||
@Override
|
||||
public DomainResource cloneProjectedAtTime(final DateTime now) {
|
||||
|
||||
TransferData transferData = getTransferData();
|
||||
DateTime transferExpirationTime = transferData.getPendingTransferExpirationTime();
|
||||
|
||||
// If there's a pending transfer that has expired, handle it.
|
||||
if (TransferStatus.PENDING.equals(transferData.getTransferStatus())
|
||||
&& isBeforeOrAt(transferExpirationTime, now)) {
|
||||
// Project until just before the transfer time. This will handle the case of an autorenew
|
||||
// before the transfer was even requested or during the request period.
|
||||
// If the transfer time is precisely the moment that the domain expires, there will not be an
|
||||
// autorenew billing event (since we end the recurrence at transfer time and recurrences are
|
||||
// exclusive of their ending), and we can just proceed with the transfer.
|
||||
DomainResource domainAtTransferTime =
|
||||
cloneProjectedAtTime(transferExpirationTime.minusMillis(1));
|
||||
// If we are within an autorenew grace period, the transfer will subsume the autorenew. There
|
||||
// will already be a cancellation written in advance by the transfer request flow, so we don't
|
||||
// need to worry about billing, but we do need to reduce the number of years added to the
|
||||
// expiration time by one to account for the year added by the autorenew.
|
||||
int extraYears = transferData.getExtendedRegistrationYears();
|
||||
if (domainAtTransferTime.getGracePeriodStatuses().contains(GracePeriodStatus.AUTO_RENEW)) {
|
||||
extraYears--;
|
||||
}
|
||||
// Set the expiration, autorenew events, and grace period for the transfer. (Transfer ends
|
||||
// all other graces).
|
||||
Builder builder = domainAtTransferTime.asBuilder()
|
||||
// Extend the registration by the correct number of years from the expiration time that
|
||||
// was current on the domain right before the transfer, capped at 10 years from the
|
||||
// moment of the transfer.
|
||||
.setRegistrationExpirationTime(extendRegistrationWithCap(
|
||||
transferExpirationTime,
|
||||
domainAtTransferTime.getRegistrationExpirationTime(),
|
||||
extraYears))
|
||||
// Set the speculatively-written new autorenew events as the domain's autorenew events.
|
||||
.setAutorenewBillingEvent(transferData.getServerApproveAutorenewEvent())
|
||||
.setAutorenewPollMessage(transferData.getServerApproveAutorenewPollMessage())
|
||||
// Set the grace period using a ref to the prescheduled transfer billing event. Not using
|
||||
// GracePeriod.forBillingEvent() here in order to avoid the actual datastore fetch.
|
||||
.setGracePeriods(ImmutableSet.of(GracePeriod.create(
|
||||
GracePeriodStatus.TRANSFER,
|
||||
transferExpirationTime.plus(Registry.get(getTld()).getTransferGracePeriodLength()),
|
||||
transferData.getGainingClientId(),
|
||||
Ref.create(transferData.getServerApproveBillingEvent().key()))));
|
||||
// Set all remaining transfer properties.
|
||||
setAutomaticTransferSuccessProperties(builder, transferData);
|
||||
// Finish projecting to now.
|
||||
return builder.build().cloneProjectedAtTime(now);
|
||||
}
|
||||
|
||||
// There is no transfer. Do any necessary autorenews.
|
||||
|
||||
Builder builder = asBuilder();
|
||||
if (isBeforeOrAt(registrationExpirationTime, now)) {
|
||||
// Autorenew by the number of years between the old expiration time and now.
|
||||
DateTime lastAutorenewTime = leapSafeAddYears(
|
||||
registrationExpirationTime,
|
||||
new Interval(registrationExpirationTime, now).toPeriod().getYears());
|
||||
DateTime newExpirationTime = lastAutorenewTime.plusYears(1);
|
||||
builder
|
||||
.setRegistrationExpirationTime(newExpirationTime)
|
||||
.addGracePeriod(GracePeriod.createForRecurring(
|
||||
GracePeriodStatus.AUTO_RENEW,
|
||||
lastAutorenewTime.plus(Registry.get(getTld()).getAutoRenewGracePeriodLength()),
|
||||
getCurrentSponsorClientId(),
|
||||
Ref.create(autorenewBillingEvent.key())));
|
||||
}
|
||||
|
||||
// Remove any grace periods that have expired.
|
||||
DomainResource almostBuilt = builder.build();
|
||||
builder = almostBuilt.asBuilder();
|
||||
for (GracePeriod gracePeriod : almostBuilt.getGracePeriods()) {
|
||||
if (isBeforeOrAt(gracePeriod.getExpirationTime(), now)) {
|
||||
builder.removeGracePeriod(gracePeriod);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle common properties like setting or unsetting linked status. This also handles the
|
||||
// general case of pending transfers for other resource types, but since we've always handled
|
||||
// a pending transfer by this point that's a no-op for domains.
|
||||
projectResourceOntoBuilderAtTime(almostBuilt, builder, now);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/** Return what the expiration time would be if the given number of years were added to it. */
|
||||
public static DateTime extendRegistrationWithCap(
|
||||
DateTime now, DateTime currentExpirationTime, Integer extendedRegistrationYears) {
|
||||
// We must cap registration at the max years (aka 10), even if that truncates the last year.
|
||||
return earliestOf(
|
||||
leapSafeAddYears(
|
||||
currentExpirationTime, Optional.fromNullable(extendedRegistrationYears).or(0)),
|
||||
leapSafeAddYears(now, MAX_REGISTRATION_YEARS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
}
|
||||
|
||||
/** A builder for constructing {@link DomainResource}, since it is immutable. */
|
||||
public static class Builder extends DomainBase.Builder<DomainResource, Builder> {
|
||||
|
||||
public Builder() {}
|
||||
|
||||
private Builder(DomainResource instance) {
|
||||
super(instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResource build() {
|
||||
// A DomainResource has status INACTIVE if there are no nameservers.
|
||||
if (getInstance().getNameservers().isEmpty()) {
|
||||
addStatusValue(StatusValue.INACTIVE);
|
||||
} else { // There are nameservers, so make sure INACTIVE isn't there.
|
||||
removeStatusValue(StatusValue.INACTIVE);
|
||||
}
|
||||
// This must be called after we add or remove INACTIVE, since that affects whether we get OK.
|
||||
return super.build();
|
||||
}
|
||||
|
||||
public Builder setSubordinateHosts(ImmutableSet<String> subordinateHosts) {
|
||||
getInstance().subordinateHosts = subordinateHosts;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public Builder addSubordinateHost(String hostToAdd) {
|
||||
return setSubordinateHosts(ImmutableSet.copyOf(
|
||||
union(getInstance().getSubordinateHosts(), hostToAdd)));
|
||||
}
|
||||
|
||||
public Builder removeSubordinateHost(String hostToRemove) {
|
||||
return setSubordinateHosts(ImmutableSet.copyOf(
|
||||
difference(getInstance().getSubordinateHosts(), hostToRemove)));
|
||||
}
|
||||
|
||||
public Builder setRegistrationExpirationTime(DateTime registrationExpirationTime) {
|
||||
getInstance().registrationExpirationTime = registrationExpirationTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDeletePollMessage(Key<PollMessage.OneTime> deletePollMessage) {
|
||||
getInstance().deletePollMessage = deletePollMessage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAutorenewBillingEvent(Ref<BillingEvent.Recurring> autorenewBillingEvent) {
|
||||
getInstance().autorenewBillingEvent = autorenewBillingEvent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAutorenewPollMessage(Ref<PollMessage.Autorenew> autorenewPollMessage) {
|
||||
getInstance().autorenewPollMessage = autorenewPollMessage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSmdId(String smdId) {
|
||||
getInstance().smdId = smdId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setApplicationTime(DateTime applicationTime) {
|
||||
getInstance().applicationTime = applicationTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setApplication(Ref<DomainApplication> application) {
|
||||
getInstance().application = application;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setGracePeriods(ImmutableSet<GracePeriod> gracePeriods) {
|
||||
getInstance().gracePeriods = gracePeriods;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addGracePeriod(GracePeriod gracePeriod) {
|
||||
getInstance().gracePeriods = union(getInstance().getGracePeriods(), gracePeriod);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder removeGracePeriod(GracePeriod gracePeriod) {
|
||||
getInstance().gracePeriods = difference(getInstance().getGracePeriods(), gracePeriod);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue