Add documentation on poll messages and an outline of Code structure

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=133713736
This commit is contained in:
mcilwain 2016-09-20 09:19:42 -07:00 committed by Ben McIlwain
parent 5c9e34ea55
commit 65ff6b45d1
5 changed files with 107 additions and 9 deletions

View file

@ -1,3 +1,58 @@
# Code structure # Code structure
An overall look at the structure of the Domain Registry code. This document contains information on the overall structure of the code, and how
particularly important pieces of the system are implemented.
## Dagger dependency injection
## Bazel build system
## Flows
## Commit logs and backups
## Cursors
## Mapreduces
## Actions and servlets
## Foreign key indexes
## Point-in-time accuracy
## Guava
## EPP resource hierarchy
## Poll messages
Poll messages are the mechanism by which EPP handles asynchronous communication
between the registry and registrars. Refer to
[RFC 5730 Section 2.9.2.3](https://tools.ietf.org/html/rfc5730#section-2.9.2.3)
for their protocol specification.
Poll messages are stored by the system as entities in Datastore. All poll
messages have an event time at which they become active; any poll request before
that time will not return the poll message. For example, every domain when
created speculatively enqueues a poll message for the automatic renewal of the
domain a year later. This poll message won't be delivered until that year
elapses, and if some change to the domain occurs prior to that point, such as it
being deleted, then the speculative poll message will be deleted and thus never
delivered. Other poll messages are effective immediately, e.g. the poll message
generated for the owning registrar when another registrar requests the transfer
of a domain. These messages are written out with an event time of when they were
created, and will thus be delivered whenever the registrar next polls for
messages.
`PollMessage` is the abstract base class for the two different types of poll
messages that extend it:
* **`Autorenew`** - A poll message corresponding to an automatic renewal of
a domain. It recurs annually.
* **`OneTime`** - A one-time poll message used for everything else.
Queries for poll messages by the registrar are handled in `PollRequestFlow`, and
poll messages are ACKed (and thus deleted) in `PollAckFlow`.
## Security

View file

@ -35,12 +35,18 @@ import google.registry.flows.TransactionalFlow;
import google.registry.model.eppoutput.EppOutput; import google.registry.model.eppoutput.EppOutput;
import google.registry.model.poll.MessageQueueInfo; import google.registry.model.poll.MessageQueueInfo;
import google.registry.model.poll.PollMessage; import google.registry.model.poll.PollMessage;
import google.registry.model.poll.PollMessageExternalKeyConverter;
import google.registry.model.poll.PollMessageExternalKeyConverter.PollMessageExternalKeyParseException; import google.registry.model.poll.PollMessageExternalKeyConverter.PollMessageExternalKeyParseException;
import javax.inject.Inject; import javax.inject.Inject;
import org.joda.time.DateTime; import org.joda.time.DateTime;
/** /**
* An EPP flow for acknowledging poll messages. * An EPP flow for acknowledging {@link PollMessage}s.
*
* <p>Registrars refer to poll messages using an externally visible id generated by
* {@link PollMessageExternalKeyConverter}. One-time poll messages are deleted from Datastore once
* they are ACKed, whereas autorenew poll messages are simply marked as read, and won't be delivered
* again until the next year of their recurrence.
* *
* @error {@link PollAckFlow.InvalidMessageIdException} * @error {@link PollAckFlow.InvalidMessageIdException}
* @error {@link PollAckFlow.MessageDoesNotExistException} * @error {@link PollAckFlow.MessageDoesNotExistException}

View file

@ -28,10 +28,17 @@ import google.registry.flows.LoggedInFlow;
import google.registry.model.eppoutput.EppOutput; import google.registry.model.eppoutput.EppOutput;
import google.registry.model.poll.MessageQueueInfo; import google.registry.model.poll.MessageQueueInfo;
import google.registry.model.poll.PollMessage; import google.registry.model.poll.PollMessage;
import google.registry.model.poll.PollMessageExternalKeyConverter;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* An EPP flow for requesting poll messages. * An EPP flow for requesting {@link PollMessage}s.
*
* <p>This flow uses an eventually consistent Datastore query to return the oldest poll message for
* the registrar, as well as the total number of pending messages. Note that poll messages whose
* event time is in the future (i.e. they are speculative and could still be changed or rescinded)
* are ignored. The externally visible id for the poll message that the registrar sees is generated
* by {@link PollMessageExternalKeyConverter}.
* *
* @error {@link PollRequestFlow.UnexpectedMessageIdException} * @error {@link PollRequestFlow.UnexpectedMessageIdException}
*/ */

View file

@ -50,11 +50,30 @@ import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
import java.util.List; import java.util.List;
import org.joda.time.DateTime; import org.joda.time.DateTime;
/** A poll message that is pending for a registrar. */ /**
* A poll message that is pending for a registrar.
*
* <p>Poll messages are not delivered until their {@link #eventTime} has passed. Poll messages can
* be speculatively enqueued for future delivery, and then modified or deleted before that date has
* passed. Unlike most other entities in Datastore, which are marked as deleted but otherwise
* retained for historical purposes, poll messages are truly deleted once they have been delivered
* and ACKed.
*
* <p>Poll messages are parented off of the {@link HistoryEntry} that resulted in their creation.
* This means that poll messages are contained in the Datastore entity group of the parent {@link
* EppResource} (which can be a domain, application, contact, or host). It is thus possible to
* perform a strongly consistent query to find all poll messages associated with a given EPP
* resource.
*
* <p>Poll messages are identified externally by registrars using the format defined in {@link
* PollMessageExternalKeyConverter}.
*
* @see "https://tools.ietf.org/html/rfc5730#section-2.9.2.3"
*/
@Entity @Entity
@ExternalMessagingName("message") @ExternalMessagingName("message")
public abstract class PollMessage public abstract class PollMessage extends ImmutableObject
extends ImmutableObject implements Buildable, TransferServerApproveEntity { implements Buildable, TransferServerApproveEntity {
public static final Converter<Key<PollMessage>, String> EXTERNAL_KEY_CONVERTER = public static final Converter<Key<PollMessage>, String> EXTERNAL_KEY_CONVERTER =
@ -158,7 +177,11 @@ public abstract class PollMessage
} }
} }
/** A one-time poll message. */ /**
* A one-time poll message.
*
* <p>One-time poll messages are deleted from Datastore once they have been delivered and ACKed.
*/
@EntitySubclass(index = false) @EntitySubclass(index = false)
public static class OneTime extends PollMessage { public static class OneTime extends PollMessage {
@ -252,7 +275,13 @@ public abstract class PollMessage
} }
} }
/** An autorenew poll message which recurs annually. */ /**
* An auto-renew poll message which recurs annually.
*
* <p>Auto-renew poll messages are not deleted until the registration of their parent domain has
* been canceled, because there will always be a speculative renewal for next year until that
* happens.
*/
@EntitySubclass(index = false) @EntitySubclass(index = false)
public static class Autorenew extends PollMessage { public static class Autorenew extends PollMessage {

View file

@ -28,7 +28,8 @@ import google.registry.model.reporting.HistoryEntry;
import java.util.List; import java.util.List;
/** /**
* A converter between external key strings for PollMessages and Objectify Keys to the resource. * A converter between external key strings for {@link PollMessage}s (i.e. what registrars use to
* identify and ACK them) and Datastore keys to the resource.
* *
* <p>The format of the key string is A-B-C-D-E as follows: * <p>The format of the key string is A-B-C-D-E as follows:
* *