diff --git a/java/google/registry/flows/contact/ContactCheckFlow.java b/java/google/registry/flows/contact/ContactCheckFlow.java index ea4d672c3..00358eef1 100644 --- a/java/google/registry/flows/contact/ContactCheckFlow.java +++ b/java/google/registry/flows/contact/ContactCheckFlow.java @@ -35,9 +35,11 @@ import javax.inject.Inject; /** * An EPP flow that checks whether a contact can be provisioned. * + *
This flows can check the existence of multiple contacts simultaneously. + * * @error {@link google.registry.flows.exceptions.TooManyResourceChecksException} */ -public class ContactCheckFlow extends LoggedInFlow { +public final class ContactCheckFlow extends LoggedInFlow { @Inject ResourceCommand resourceCommand; @Inject @Config("maxChecks") int maxChecks; diff --git a/java/google/registry/flows/contact/ContactCreateFlow.java b/java/google/registry/flows/contact/ContactCreateFlow.java index f6d8ac553..ebe636b98 100644 --- a/java/google/registry/flows/contact/ContactCreateFlow.java +++ b/java/google/registry/flows/contact/ContactCreateFlow.java @@ -41,13 +41,13 @@ import google.registry.model.reporting.HistoryEntry; 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 ContactFlowUtils.BadInternationalizedPostalInfoException} * @error {@link ContactFlowUtils.DeclineContactDisclosureFieldDisallowedPolicyException} */ -public class ContactCreateFlow extends LoggedInFlow implements TransactionalFlow { +public final class ContactCreateFlow extends LoggedInFlow implements TransactionalFlow { @Inject ResourceCommand resourceCommand; @Inject @ClientId String clientId; diff --git a/java/google/registry/flows/contact/ContactDeleteFlow.java b/java/google/registry/flows/contact/ContactDeleteFlow.java index d1e5003b7..be6da8644 100644 --- a/java/google/registry/flows/contact/ContactDeleteFlow.java +++ b/java/google/registry/flows/contact/ContactDeleteFlow.java @@ -44,14 +44,21 @@ import javax.inject.Inject; import org.joda.time.Duration; /** - * An EPP flow that deletes a contact resource. +/** + * An EPP flow that deletes a contact. + * + *
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.exceptions.ResourceStatusProhibitsOperationException}
* @error {@link google.registry.flows.exceptions.ResourceToDeleteIsReferencedException}
* @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 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}
*/
-public class ContactInfoFlow extends LoggedInFlow {
+public final class ContactInfoFlow extends LoggedInFlow {
@Inject @TargetId String targetId;
@Inject Optional 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.ResourceNotOwnedException}
* @error {@link google.registry.flows.exceptions.NotPendingTransferException}
* @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 @ClientId String clientId;
@@ -64,6 +70,10 @@ public class ContactTransferApproveFlow extends LoggedInFlow implements Transact
registerExtensions(MetadataExtension.class);
}
+ /**
+ * The logic in this flow, which handles client approvals, very closely parallels the logic in
+ * {@link ContactResource#cloneProjectedAtTime} which handles implicit server approvals.
+ */
@Override
public final EppOutput run() throws EppException {
ContactResource existingContact = loadResourceToMutate(ContactResource.class, targetId, now);
diff --git a/java/google/registry/flows/contact/ContactTransferCancelFlow.java b/java/google/registry/flows/contact/ContactTransferCancelFlow.java
index edb9b08d5..8c761f7a7 100644
--- a/java/google/registry/flows/contact/ContactTransferCancelFlow.java
+++ b/java/google/registry/flows/contact/ContactTransferCancelFlow.java
@@ -43,14 +43,20 @@ import google.registry.model.transfer.TransferStatus;
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.
+ *
+ * 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.exceptions.NotPendingTransferException}
* @error {@link google.registry.flows.exceptions.NotTransferInitiatorException}
* @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 Optional 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.exceptions.NoTransferHistoryToQueryException}
* @error {@link google.registry.flows.exceptions.NotAuthorizedToViewTransferException}
* @error {@link google.registry.flows.exceptions.ResourceToQueryDoesNotExistException}
*/
-public class ContactTransferQueryFlow extends LoggedInFlow {
+public final class ContactTransferQueryFlow extends LoggedInFlow {
@Inject Optional 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.ResourceNotOwnedException}
* @error {@link google.registry.flows.exceptions.NotPendingTransferException}
* @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException}
*/
-public class ContactTransferRejectFlow extends LoggedInFlow implements TransactionalFlow {
+public final class ContactTransferRejectFlow extends LoggedInFlow implements TransactionalFlow {
@Inject Optional 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.exceptions.ResourceToMutateDoesNotExistException}
@@ -56,7 +63,7 @@ import org.joda.time.Duration;
* @error {@link google.registry.flows.exceptions.MissingTransferRequestAuthInfoException}
* @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 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
@@ -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,
* those speculative objects are deleted and replaced with new ones with the correct approval time.
*
- * 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.ResourceNotOwnedException}
* @error {@link google.registry.flows.exceptions.NotPendingTransferException}
@@ -92,6 +89,10 @@ public final class DomainTransferApproveFlow extends LoggedInFlow implements Tra
registerExtensions(MetadataExtension.class);
}
+ /**
+ * The logic in this flow, which handles client approvals, very closely parallels the logic in
+ * {@link DomainResource#cloneProjectedAtTime} which handles implicit server approvals.
+ */
@Override
public final EppOutput run() throws EppException {
DomainResource existingDomain = loadResourceToMutate(DomainResource.class, targetId, now);
diff --git a/java/google/registry/flows/domain/DomainTransferCancelFlow.java b/java/google/registry/flows/domain/DomainTransferCancelFlow.java
index 6471eb6a5..11c6c2b3e 100644
--- a/java/google/registry/flows/domain/DomainTransferCancelFlow.java
+++ b/java/google/registry/flows/domain/DomainTransferCancelFlow.java
@@ -44,7 +44,7 @@ import google.registry.model.transfer.TransferStatus;
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.
*
* 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
diff --git a/java/google/registry/flows/domain/DomainTransferQueryFlow.java b/java/google/registry/flows/domain/DomainTransferQueryFlow.java
index e016eca23..854058f8f 100644
--- a/java/google/registry/flows/domain/DomainTransferQueryFlow.java
+++ b/java/google/registry/flows/domain/DomainTransferQueryFlow.java
@@ -36,7 +36,7 @@ import javax.inject.Inject;
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.
*
* 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
diff --git a/java/google/registry/flows/domain/DomainTransferRejectFlow.java b/java/google/registry/flows/domain/DomainTransferRejectFlow.java
index 0b921b7c5..b792e13c5 100644
--- a/java/google/registry/flows/domain/DomainTransferRejectFlow.java
+++ b/java/google/registry/flows/domain/DomainTransferRejectFlow.java
@@ -44,7 +44,7 @@ import google.registry.model.transfer.TransferStatus;
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.
*
* 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
diff --git a/java/google/registry/flows/domain/DomainTransferRequestFlow.java b/java/google/registry/flows/domain/DomainTransferRequestFlow.java
index ca1bcd022..2d7545ee6 100644
--- a/java/google/registry/flows/domain/DomainTransferRequestFlow.java
+++ b/java/google/registry/flows/domain/DomainTransferRequestFlow.java
@@ -76,7 +76,7 @@ import org.joda.money.Money;
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.
*
* 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
diff --git a/java/google/registry/flows/host/HostCheckFlow.java b/java/google/registry/flows/host/HostCheckFlow.java
index 21e15ab28..8d4ccca97 100644
--- a/java/google/registry/flows/host/HostCheckFlow.java
+++ b/java/google/registry/flows/host/HostCheckFlow.java
@@ -35,9 +35,11 @@ import javax.inject.Inject;
/**
* An EPP flow that checks whether a host can be provisioned.
*
+ * This flows can check the existence of multiple hosts simultaneously.
+ *
* @error {@link google.registry.flows.exceptions.TooManyResourceChecksException}
*/
-public class HostCheckFlow extends LoggedInFlow {
+public final class HostCheckFlow extends LoggedInFlow {
@Inject ResourceCommand resourceCommand;
@Inject @Config("maxChecks") int maxChecks;
diff --git a/java/google/registry/flows/host/HostCreateFlow.java b/java/google/registry/flows/host/HostCreateFlow.java
index eaf3946f5..43a4ff2ee 100644
--- a/java/google/registry/flows/host/HostCreateFlow.java
+++ b/java/google/registry/flows/host/HostCreateFlow.java
@@ -51,7 +51,13 @@ import google.registry.model.reporting.HistoryEntry;
import javax.inject.Inject;
/**
- * An EPP flow that creates a new host resource.
+ * An EPP flow that creates a new host.
+ *
+ * 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.exceptions.ResourceAlreadyExistsException}
@@ -62,7 +68,7 @@ import javax.inject.Inject;
* @error {@link SubordinateHostMustHaveIpException}
* @error {@link UnexpectedExternalHostIpException}
*/
-public class HostCreateFlow extends LoggedInFlow implements TransactionalFlow {
+public final class HostCreateFlow extends LoggedInFlow implements TransactionalFlow {
@Inject ResourceCommand resourceCommand;
@Inject @ClientId String clientId;
diff --git a/java/google/registry/flows/host/HostDeleteFlow.java b/java/google/registry/flows/host/HostDeleteFlow.java
index b16093312..7ce15e35c 100644
--- a/java/google/registry/flows/host/HostDeleteFlow.java
+++ b/java/google/registry/flows/host/HostDeleteFlow.java
@@ -42,14 +42,20 @@ import google.registry.model.reporting.HistoryEntry;
import javax.inject.Inject;
/**
- * An EPP flow that deletes a host resource.
+ * An EPP flow that deletes a host.
+ *
+ * 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.exceptions.ResourceStatusProhibitsOperationException}
* @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException}
* @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 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}
*/
-public class HostInfoFlow extends LoggedInFlow {
+public final class HostInfoFlow extends LoggedInFlow {
@Inject @TargetId String targetId;
@Inject Optional 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 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.exceptions.ResourceHasClientUpdateProhibitedException}
@@ -78,7 +88,7 @@ import javax.inject.Inject;
* @error {@link RenameHostToExternalRemoveIpException}
* @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
@@ -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 {
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
extends StatusProhibitsOperationException {
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
extends RequiredParameterMissingException {
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 {
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");
}
}
}