Add javadoc to contact/host flows and mark them final

Also make minor javadoc tweaks to domain transfer flows
to match what we are changing in contact/host flows.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=133955677
This commit is contained in:
cgoldfeder 2016-09-22 08:21:09 -07:00 committed by Ben McIlwain
parent a69fc769af
commit 0564bcdbc9
20 changed files with 120 additions and 44 deletions

View file

@ -35,9 +35,11 @@ import javax.inject.Inject;
/** /**
* An EPP flow that checks whether a contact can be provisioned. * An EPP flow that checks whether a contact can be provisioned.
* *
* <p>This flows can check the existence of multiple contacts simultaneously.
*
* @error {@link google.registry.flows.exceptions.TooManyResourceChecksException} * @error {@link google.registry.flows.exceptions.TooManyResourceChecksException}
*/ */
public class ContactCheckFlow extends LoggedInFlow { public final class ContactCheckFlow extends LoggedInFlow {
@Inject ResourceCommand resourceCommand; @Inject ResourceCommand resourceCommand;
@Inject @Config("maxChecks") int maxChecks; @Inject @Config("maxChecks") int maxChecks;

View file

@ -41,13 +41,13 @@ import google.registry.model.reporting.HistoryEntry;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that creates a new contact resource. * An EPP flow that creates a new contact.
* *
* @error {@link google.registry.flows.exceptions.ResourceAlreadyExistsException} * @error {@link google.registry.flows.exceptions.ResourceAlreadyExistsException}
* @error {@link ContactFlowUtils.BadInternationalizedPostalInfoException} * @error {@link ContactFlowUtils.BadInternationalizedPostalInfoException}
* @error {@link ContactFlowUtils.DeclineContactDisclosureFieldDisallowedPolicyException} * @error {@link ContactFlowUtils.DeclineContactDisclosureFieldDisallowedPolicyException}
*/ */
public class ContactCreateFlow extends LoggedInFlow implements TransactionalFlow { public final class ContactCreateFlow extends LoggedInFlow implements TransactionalFlow {
@Inject ResourceCommand resourceCommand; @Inject ResourceCommand resourceCommand;
@Inject @ClientId String clientId; @Inject @ClientId String clientId;

View file

@ -44,14 +44,21 @@ import javax.inject.Inject;
import org.joda.time.Duration; import org.joda.time.Duration;
/** /**
* An EPP flow that deletes a contact resource. /**
* An EPP flow that deletes a contact.
*
* <p>Contacts that are in use by any domain cannot be deleted. The flow may return immediately if a
* quick smoke check determines that deletion is impossible due to an existing reference. However, a
* successful delete will always be asynchronous, as all existing domains must be checked for
* references to the host before the deletion is allowed to proceed. A poll message will be written
* with the success or failure message when the process is complete.
* *
* @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException} * @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException}
* @error {@link google.registry.flows.exceptions.ResourceStatusProhibitsOperationException} * @error {@link google.registry.flows.exceptions.ResourceStatusProhibitsOperationException}
* @error {@link google.registry.flows.exceptions.ResourceToDeleteIsReferencedException} * @error {@link google.registry.flows.exceptions.ResourceToDeleteIsReferencedException}
* @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException} * @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException}
*/ */
public class ContactDeleteFlow extends LoggedInFlow implements TransactionalFlow { public final class ContactDeleteFlow extends LoggedInFlow implements TransactionalFlow {
private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES = ImmutableSet.of( private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES = ImmutableSet.of(
StatusValue.LINKED, StatusValue.LINKED,

View file

@ -29,11 +29,15 @@ import google.registry.model.eppoutput.EppOutput;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that reads a contact. * An EPP flow that returns information about a contact.
*
* <p>The response includes the contact's postal info, phone numbers, emails, the authInfo which can
* be used to request a transfer and the details of the contact's most recent transfer if it has
* ever been transferred. Any registrar can see any contact's information.
* *
* @error {@link google.registry.flows.exceptions.ResourceToQueryDoesNotExistException} * @error {@link google.registry.flows.exceptions.ResourceToQueryDoesNotExistException}
*/ */
public class ContactInfoFlow extends LoggedInFlow { public final class ContactInfoFlow extends LoggedInFlow {
@Inject @TargetId String targetId; @Inject @TargetId String targetId;
@Inject Optional<AuthInfo> authInfo; @Inject Optional<AuthInfo> authInfo;

View file

@ -43,14 +43,20 @@ import google.registry.model.transfer.TransferStatus;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that approves a pending transfer on a {@link ContactResource}. /**
* An EPP flow that approves a pending transfer on a contact.
*
* <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The
* losing registrar has a "transfer" time period to respond (by default five days) after which the
* transfer is automatically approved. Within that window, this flow allows the losing client to
* explicitly approve the transfer request, which then becomes effective immediately.
* *
* @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException} * @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException}
* @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException} * @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException}
* @error {@link google.registry.flows.exceptions.NotPendingTransferException} * @error {@link google.registry.flows.exceptions.NotPendingTransferException}
* @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException} * @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException}
*/ */
public class ContactTransferApproveFlow extends LoggedInFlow implements TransactionalFlow { public final class ContactTransferApproveFlow extends LoggedInFlow implements TransactionalFlow {
@Inject ResourceCommand resourceCommand; @Inject ResourceCommand resourceCommand;
@Inject @ClientId String clientId; @Inject @ClientId String clientId;
@ -64,6 +70,10 @@ public class ContactTransferApproveFlow extends LoggedInFlow implements Transact
registerExtensions(MetadataExtension.class); registerExtensions(MetadataExtension.class);
} }
/**
* <p>The logic in this flow, which handles client approvals, very closely parallels the logic in
* {@link ContactResource#cloneProjectedAtTime} which handles implicit server approvals.
*/
@Override @Override
public final EppOutput run() throws EppException { public final EppOutput run() throws EppException {
ContactResource existingContact = loadResourceToMutate(ContactResource.class, targetId, now); ContactResource existingContact = loadResourceToMutate(ContactResource.class, targetId, now);

View file

@ -43,14 +43,20 @@ import google.registry.model.transfer.TransferStatus;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that cancels a pending transfer on a {@link ContactResource}. /**
* An EPP flow that cancels a pending transfer on a contact.
*
* <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The
* losing registrar has a "transfer" time period to respond (by default five days) after which the
* transfer is automatically approved. Within that window, this flow allows the gaining client to
* withdraw the transfer request.
* *
* @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException} * @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException}
* @error {@link google.registry.flows.exceptions.NotPendingTransferException} * @error {@link google.registry.flows.exceptions.NotPendingTransferException}
* @error {@link google.registry.flows.exceptions.NotTransferInitiatorException} * @error {@link google.registry.flows.exceptions.NotTransferInitiatorException}
* @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException} * @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException}
*/ */
public class ContactTransferCancelFlow extends LoggedInFlow implements TransactionalFlow { public final class ContactTransferCancelFlow extends LoggedInFlow implements TransactionalFlow {
@Inject ResourceCommand resourceCommand; @Inject ResourceCommand resourceCommand;
@Inject Optional<AuthInfo> authInfo; @Inject Optional<AuthInfo> authInfo;

View file

@ -32,14 +32,21 @@ import google.registry.model.eppoutput.EppOutput;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that queries a pending transfer on a {@link ContactResource}. * An EPP flow that queries a pending transfer on a contact.
*
* <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The
* losing registrar has a "transfer" time period to respond (by default five days) after which the
* transfer is automatically approved. This flow can be used by the gaining or losing registrars
* (or anyone with the correct authId) to see the status of a transfer, which may still be pending
* or may have been approved, rejected, cancelled or implicitly approved by virtue of the transfer
* period expiring.
* *
* @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException} * @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException}
* @error {@link google.registry.flows.exceptions.NoTransferHistoryToQueryException} * @error {@link google.registry.flows.exceptions.NoTransferHistoryToQueryException}
* @error {@link google.registry.flows.exceptions.NotAuthorizedToViewTransferException} * @error {@link google.registry.flows.exceptions.NotAuthorizedToViewTransferException}
* @error {@link google.registry.flows.exceptions.ResourceToQueryDoesNotExistException} * @error {@link google.registry.flows.exceptions.ResourceToQueryDoesNotExistException}
*/ */
public class ContactTransferQueryFlow extends LoggedInFlow { public final class ContactTransferQueryFlow extends LoggedInFlow {
@Inject Optional<AuthInfo> authInfo; @Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId; @Inject @ClientId String clientId;

View file

@ -42,14 +42,19 @@ import google.registry.model.transfer.TransferStatus;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that rejects a pending transfer on a {@link ContactResource}. * An EPP flow that rejects a pending transfer on a contact.
*
* <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The
* losing registrar has a "transfer" time period to respond (by default five days) after which the
* transfer is automatically approved. Within that window, this flow allows the losing client to
* reject the transfer request.
* *
* @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException} * @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException}
* @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException} * @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException}
* @error {@link google.registry.flows.exceptions.NotPendingTransferException} * @error {@link google.registry.flows.exceptions.NotPendingTransferException}
* @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException} * @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException}
*/ */
public class ContactTransferRejectFlow extends LoggedInFlow implements TransactionalFlow { public final class ContactTransferRejectFlow extends LoggedInFlow implements TransactionalFlow {
@Inject Optional<AuthInfo> authInfo; @Inject Optional<AuthInfo> authInfo;
@Inject @ClientId String clientId; @Inject @ClientId String clientId;

View file

@ -48,7 +48,14 @@ import org.joda.time.DateTime;
import org.joda.time.Duration; import org.joda.time.Duration;
/** /**
* An EPP flow that requests a transfer on a {@link ContactResource}. /**
* An EPP flow that requests a transfer on a contact.
*
* <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The
* losing registrar has a "transfer" time period to respond (by default five days) after which the
* transfer is automatically approved. Within that window, the transfer might be approved explicitly
* by the losing registrar or rejected, and the gaining registrar can also cancel the transfer
* request.
* *
* @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException} * @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException}
* @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException} * @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException}
@ -56,7 +63,7 @@ import org.joda.time.Duration;
* @error {@link google.registry.flows.exceptions.MissingTransferRequestAuthInfoException} * @error {@link google.registry.flows.exceptions.MissingTransferRequestAuthInfoException}
* @error {@link google.registry.flows.exceptions.ObjectAlreadySponsoredException} * @error {@link google.registry.flows.exceptions.ObjectAlreadySponsoredException}
*/ */
public class ContactTransferRequestFlow extends LoggedInFlow implements TransactionalFlow { public final class ContactTransferRequestFlow extends LoggedInFlow implements TransactionalFlow {
private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES = ImmutableSet.of( private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES = ImmutableSet.of(
StatusValue.CLIENT_TRANSFER_PROHIBITED, StatusValue.CLIENT_TRANSFER_PROHIBITED,

View file

@ -48,7 +48,7 @@ import google.registry.model.reporting.HistoryEntry;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that updates a contact resource. * An EPP flow that updates a contact.
* *
* @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException} * @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException}
* @error {@link google.registry.flows.exceptions.AddRemoveSameValueEppException} * @error {@link google.registry.flows.exceptions.AddRemoveSameValueEppException}
@ -59,7 +59,7 @@ import javax.inject.Inject;
* @error {@link ContactFlowUtils.BadInternationalizedPostalInfoException} * @error {@link ContactFlowUtils.BadInternationalizedPostalInfoException}
* @error {@link ContactFlowUtils.DeclineContactDisclosureFieldDisallowedPolicyException} * @error {@link ContactFlowUtils.DeclineContactDisclosureFieldDisallowedPolicyException}
*/ */
public class ContactUpdateFlow extends LoggedInFlow implements TransactionalFlow { public final class ContactUpdateFlow extends LoggedInFlow implements TransactionalFlow {
/** /**
* Note that CLIENT_UPDATE_PROHIBITED is intentionally not in this list. This is because it * Note that CLIENT_UPDATE_PROHIBITED is intentionally not in this list. This is because it

View file

@ -59,7 +59,7 @@ import javax.inject.Inject;
import org.joda.time.DateTime; import org.joda.time.DateTime;
/** /**
* An EPP flow that approves a pending transfer on a {@link DomainResource}. * An EPP flow that approves a pending transfer on a domain.
* *
* <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The * <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The
* losing registrar has a "transfer" time period to respond (by default five days) after which the * losing registrar has a "transfer" time period to respond (by default five days) after which the
@ -70,9 +70,6 @@ import org.joda.time.DateTime;
* timestamps such that they only would become active when the transfer period passed. In this flow, * timestamps such that they only would become active when the transfer period passed. In this flow,
* those speculative objects are deleted and replaced with new ones with the correct approval time. * those speculative objects are deleted and replaced with new ones with the correct approval time.
* *
* <p>The logic in this flow, which handles client approvals, very closely parallels the logic in
* {@link DomainResource#cloneProjectedAtTime} which handles implicit server approvals.
*
* @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException} * @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException}
* @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException} * @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException}
* @error {@link google.registry.flows.exceptions.NotPendingTransferException} * @error {@link google.registry.flows.exceptions.NotPendingTransferException}
@ -92,6 +89,10 @@ public final class DomainTransferApproveFlow extends LoggedInFlow implements Tra
registerExtensions(MetadataExtension.class); registerExtensions(MetadataExtension.class);
} }
/**
* <p>The logic in this flow, which handles client approvals, very closely parallels the logic in
* {@link DomainResource#cloneProjectedAtTime} which handles implicit server approvals.
*/
@Override @Override
public final EppOutput run() throws EppException { public final EppOutput run() throws EppException {
DomainResource existingDomain = loadResourceToMutate(DomainResource.class, targetId, now); DomainResource existingDomain = loadResourceToMutate(DomainResource.class, targetId, now);

View file

@ -44,7 +44,7 @@ import google.registry.model.transfer.TransferStatus;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that cancels a pending transfer on a {@link DomainResource}. * An EPP flow that cancels a pending transfer on a domain.
* *
* <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The * <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The
* losing registrar has a "transfer" time period to respond (by default five days) after which the * losing registrar has a "transfer" time period to respond (by default five days) after which the

View file

@ -36,7 +36,7 @@ import javax.inject.Inject;
import org.joda.time.DateTime; import org.joda.time.DateTime;
/** /**
* An EPP flow that queries a pending transfer on a {@link DomainResource}. * An EPP flow that queries a pending transfer on a domain.
* *
* <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The * <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The
* losing registrar has a "transfer" time period to respond (by default five days) after which the * losing registrar has a "transfer" time period to respond (by default five days) after which the

View file

@ -44,7 +44,7 @@ import google.registry.model.transfer.TransferStatus;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that rejects a pending transfer on a {@link DomainResource}. * An EPP flow that rejects a pending transfer on a domain.
* *
* <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The * <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The
* losing registrar has a "transfer" time period to respond (by default five days) after which the * losing registrar has a "transfer" time period to respond (by default five days) after which the

View file

@ -76,7 +76,7 @@ import org.joda.money.Money;
import org.joda.time.DateTime; import org.joda.time.DateTime;
/** /**
* An EPP flow that requests a transfer on a {@link DomainResource}. * An EPP flow that requests a transfer on a domain.
* *
* <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The * <p>The "gaining" registrar requests a transfer from the "losing" (aka current) registrar. The
* losing registrar has a "transfer" time period to respond (by default five days) after which the * losing registrar has a "transfer" time period to respond (by default five days) after which the

View file

@ -35,9 +35,11 @@ import javax.inject.Inject;
/** /**
* An EPP flow that checks whether a host can be provisioned. * An EPP flow that checks whether a host can be provisioned.
* *
* <p>This flows can check the existence of multiple hosts simultaneously.
*
* @error {@link google.registry.flows.exceptions.TooManyResourceChecksException} * @error {@link google.registry.flows.exceptions.TooManyResourceChecksException}
*/ */
public class HostCheckFlow extends LoggedInFlow { public final class HostCheckFlow extends LoggedInFlow {
@Inject ResourceCommand resourceCommand; @Inject ResourceCommand resourceCommand;
@Inject @Config("maxChecks") int maxChecks; @Inject @Config("maxChecks") int maxChecks;

View file

@ -51,7 +51,13 @@ import google.registry.model.reporting.HistoryEntry;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that creates a new host resource. * An EPP flow that creates a new host.
*
* <p>Hosts can be "external", or "internal" (also known as "in bailiwick"). Internal hosts are
* those that are under a top level domain within this registry, and external hosts are all other
* hosts. Internal hosts must have at least one ip address associated with them, whereas external
* hosts cannot have any. This flow allows creating a host name, and if necessary enqueues tasks to
* update DNS.
* *
* @error {@link google.registry.flows.EppXmlTransformer.IpAddressVersionMismatchException} * @error {@link google.registry.flows.EppXmlTransformer.IpAddressVersionMismatchException}
* @error {@link google.registry.flows.exceptions.ResourceAlreadyExistsException} * @error {@link google.registry.flows.exceptions.ResourceAlreadyExistsException}
@ -62,7 +68,7 @@ import javax.inject.Inject;
* @error {@link SubordinateHostMustHaveIpException} * @error {@link SubordinateHostMustHaveIpException}
* @error {@link UnexpectedExternalHostIpException} * @error {@link UnexpectedExternalHostIpException}
*/ */
public class HostCreateFlow extends LoggedInFlow implements TransactionalFlow { public final class HostCreateFlow extends LoggedInFlow implements TransactionalFlow {
@Inject ResourceCommand resourceCommand; @Inject ResourceCommand resourceCommand;
@Inject @ClientId String clientId; @Inject @ClientId String clientId;

View file

@ -42,14 +42,20 @@ import google.registry.model.reporting.HistoryEntry;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that deletes a host resource. * An EPP flow that deletes a host.
*
* <p>Hosts that are in use by any domain cannot be deleted. The flow may return immediately if a
* quick smoke check determines that deletion is impossible due to an existing reference. However, a
* successful delete will always be asynchronous, as all existing domains must be checked for
* references to the host before the deletion is allowed to proceed. A poll message will be written
* with the success or failure message when the process is complete.
* *
* @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException} * @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException}
* @error {@link google.registry.flows.exceptions.ResourceStatusProhibitsOperationException} * @error {@link google.registry.flows.exceptions.ResourceStatusProhibitsOperationException}
* @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException} * @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException}
* @error {@link google.registry.flows.exceptions.ResourceToDeleteIsReferencedException} * @error {@link google.registry.flows.exceptions.ResourceToDeleteIsReferencedException}
*/ */
public class HostDeleteFlow extends LoggedInFlow implements TransactionalFlow { public final class HostDeleteFlow extends LoggedInFlow implements TransactionalFlow {
private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES = ImmutableSet.of( private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES = ImmutableSet.of(
StatusValue.LINKED, StatusValue.LINKED,

View file

@ -29,11 +29,14 @@ import google.registry.model.host.HostResource;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that reads a host. * An EPP flow that returns information about a host.
*
* <p>The returned information included IP addresses, if any, and details of the host's most recent
* transfer if it has ever been transferred. Any registrar can see the information for any host.
* *
* @error {@link google.registry.flows.exceptions.ResourceToQueryDoesNotExistException} * @error {@link google.registry.flows.exceptions.ResourceToQueryDoesNotExistException}
*/ */
public class HostInfoFlow extends LoggedInFlow { public final class HostInfoFlow extends LoggedInFlow {
@Inject @TargetId String targetId; @Inject @TargetId String targetId;
@Inject Optional<AuthInfo> authInfo; @Inject Optional<AuthInfo> authInfo;

View file

@ -62,7 +62,17 @@ import java.util.Objects;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow that updates a host resource. * An EPP flow that updates a host.
*
* <p>Hosts can be "external", or "internal" (also known as "in bailiwick"). Internal hosts are
* those that are under a top level domain within this registry, and external hosts are all other
* hosts. Internal hosts must have at least one IP address associated with them, whereas external
* hosts cannot have any.
*
* <p>This flow allows changing a host name, and adding or removing IP addresses to hosts. When
* a host is renamed from internal to external all IP addresses must be simultaneously removed, and
* when it is renamed from external to internal at least one must be added. If the host is renamed
* or IP addresses are added, tasks are enqueued to update DNS accordingly.
* *
* @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException} * @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException}
* @error {@link google.registry.flows.exceptions.ResourceHasClientUpdateProhibitedException} * @error {@link google.registry.flows.exceptions.ResourceHasClientUpdateProhibitedException}
@ -78,7 +88,7 @@ import javax.inject.Inject;
* @error {@link RenameHostToExternalRemoveIpException} * @error {@link RenameHostToExternalRemoveIpException}
* @error {@link RenameHostToSubordinateRequiresIpException} * @error {@link RenameHostToSubordinateRequiresIpException}
*/ */
public class HostUpdateFlow extends LoggedInFlow implements TransactionalFlow { public final class HostUpdateFlow extends LoggedInFlow implements TransactionalFlow {
/** /**
* Note that CLIENT_UPDATE_PROHIBITED is intentionally not in this list. This is because it * Note that CLIENT_UPDATE_PROHIBITED is intentionally not in this list. This is because it
@ -260,33 +270,33 @@ public class HostUpdateFlow extends LoggedInFlow implements TransactionalFlow {
} }
} }
/** Cannot add ip addresses to an external host. */ /** Cannot add IP addresses to an external host. */
static class CannotAddIpToExternalHostException extends ParameterValueRangeErrorException { static class CannotAddIpToExternalHostException extends ParameterValueRangeErrorException {
public CannotAddIpToExternalHostException() { public CannotAddIpToExternalHostException() {
super("Cannot add ip addresses to external hosts"); super("Cannot add IP addresses to external hosts");
} }
} }
/** Cannot remove all ip addresses from a subordinate host. */ /** Cannot remove all IP addresses from a subordinate host. */
static class CannotRemoveSubordinateHostLastIpException static class CannotRemoveSubordinateHostLastIpException
extends StatusProhibitsOperationException { extends StatusProhibitsOperationException {
public CannotRemoveSubordinateHostLastIpException() { public CannotRemoveSubordinateHostLastIpException() {
super("Cannot remove all ip addresses from a subordinate host"); super("Cannot remove all IP addresses from a subordinate host");
} }
} }
/** Host rename from external to subordinate must also add an ip addresses. */ /** Host rename from external to subordinate must also add an IP addresses. */
static class RenameHostToSubordinateRequiresIpException static class RenameHostToSubordinateRequiresIpException
extends RequiredParameterMissingException { extends RequiredParameterMissingException {
public RenameHostToSubordinateRequiresIpException() { public RenameHostToSubordinateRequiresIpException() {
super("Host rename from external to subordinate must also add an ip address"); super("Host rename from external to subordinate must also add an IP address");
} }
} }
/** Host rename from subordinate to external must also remove all ip addresses. */ /** Host rename from subordinate to external must also remove all IP addresses. */
static class RenameHostToExternalRemoveIpException extends ParameterValueRangeErrorException { static class RenameHostToExternalRemoveIpException extends ParameterValueRangeErrorException {
public RenameHostToExternalRemoveIpException() { public RenameHostToExternalRemoveIpException() {
super("Host rename from subordinate to external must also remove all ip addresses"); super("Host rename from subordinate to external must also remove all IP addresses");
} }
} }
} }