// 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.model.host; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Sets.difference; import static com.google.common.collect.Sets.union; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.DateTimeUtils.START_OF_TIME; import static google.registry.util.DomainNameUtils.canonicalizeDomainName; import com.google.common.base.Optional; import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.IgnoreSave; import com.googlecode.objectify.annotation.Index; import com.googlecode.objectify.condition.IfNull; import google.registry.model.EppResource; import google.registry.model.EppResource.ForeignKeyedEppResource; import google.registry.model.annotations.ExternalMessagingName; import google.registry.model.annotations.ReportedOn; import google.registry.model.domain.DomainResource; import google.registry.model.transfer.TransferData; import java.net.InetAddress; import java.util.Set; import javax.annotation.Nullable; import org.joda.time.DateTime; /** * A persistable Host resource including mutable and non-mutable fields. * *
A host's {@link TransferData} is stored on the superordinate domain. Non-subordinate hosts * don't carry a full set of TransferData; all they have is lastTransferTime. * * @see RFC 5732 */ @ReportedOn @Entity @ExternalMessagingName("host") public class HostResource extends EppResource implements ForeignKeyedEppResource { /** * Fully qualified hostname, which is a unique identifier for this host. * *
This is only unique in the sense that for any given lifetime specified as the time range
* from (creationTime, deletionTime) there can only be one host in Datastore with this name.
* However, there can be many hosts with the same name and non-overlapping lifetimes.
*/
@Index
String fullyQualifiedHostName;
/** IP Addresses for this host. Can be null if this is an external host. */
@Index
Set Can be null if the resource has never been transferred.
*/
DateTime lastTransferTime;
/**
* The most recent time that the {@link #superordinateDomain} field was changed.
*
* This should be updated whenever the superordinate domain changes, including when it is set
* to null. This field will be null for new hosts that have never experienced a change of
* superordinate domain.
*/
DateTime lastSuperordinateChange;
public String getFullyQualifiedHostName() {
return fullyQualifiedHostName;
}
public Key Hosts can move between superordinate domains, so to know which lastTransferTime is correct
* we need to know if the host was attached to this superordinate the last time that the
* superordinate was transferred. If the last superordinate change was before this time, then the
* host was attached to this superordinate domain during that transfer.
*
* If the host is not subordinate the domain can be null and we just return last transfer time.
*
* @param superordinateDomain the loaded superordinate domain, which must match the key in
* the {@link #superordinateDomain} field. Passing it as a parameter allows the caller to
* control the degree of consistency used to load it.
*/
public DateTime computeLastTransferTime(@Nullable DomainResource superordinateDomain) {
if (!isSubordinate()) {
checkArgument(superordinateDomain == null);
return getLastTransferTime();
}
checkArgument(
superordinateDomain != null
&& Key.create(superordinateDomain).equals(getSuperordinateDomain()));
DateTime lastSuperordinateChange =
Optional.fromNullable(getLastSuperordinateChange()).or(getCreationTime());
DateTime lastTransferOfCurrentSuperordinate =
Optional.fromNullable(superordinateDomain.getLastTransferTime()).or(START_OF_TIME);
return (lastSuperordinateChange.isBefore(lastTransferOfCurrentSuperordinate))
? superordinateDomain.getLastTransferTime()
: getLastTransferTime();
}
@Override
public Builder asBuilder() {
return new Builder(clone(this));
}
/** A builder for constructing {@link HostResource}, since it is immutable. */
public static class Builder extends EppResource.Builder