This CL changes the domain and contact transfer flows to check the entire
TransferData on the post-transfer resource, rather than just spot-checking
certain fields. This approach provides much better code coverage - in
particular, it checks that the non-request flows (approve, cancel, reject)
don't modify the fields that they shouldn't be modifying, and that they do
actually clear out the transfer server-approve entities fields written by
the transfer request flow. It's slightly orthogonal, but I also added
testing that the server-approve entities fields are actually set in the
request flows, which was previously untested.
This is pre-work for introducing an exDate-storing field into TransferData,
by making it easier to test everywhere that exDate is set *and* unset only
in the correct places.
As part of this CL, I've introduced a TransferData.copyConstantFieldsToBuilder()
method that is like asBuilder() but instead of copying all the fields to the new
builder, it only copies the logically constant ones: losing/gaining client IDs,
the request time and TRID, and transferPeriod. This is useful both in tests but
is also used in the resolvingPendingTransfer() helper that centralizes the core
transfer resolution logic (as of [] That method has its own tests,
and in the process I removed a bunch of crufty defunct TransferData tests.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=171053454
Normally, if a domain is in the auto-renew grace period, a transfer will cancel the auto-renew billing event. In the event of a transfer with no change to registration end date, the auto-renew billing event should not be cancelled and the gaining registrar should not be charged for the transfer.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=170576726
This CL deduplicates these two methods in DomainTransferRequestFlowTest:
- assertHistoryEntriesContainTransferBillingEventsOrGracePeriods()
- assertHistoryEntriesDoNotContainTransferBillingEventsOrGracePeriods()
Instead, we have one method with an extra parameter dictating whether or not
we should expect a transfer billing event (yes normally, no in the case of a
superuser transfer w/ 0 period). This is less code overall and avoids drift
between the normal vs special case assertions (if people make changes in one
but forget to do so in the other).
Also, the methods as named were a little confusing because the "Contain" vs
"DoNotContain" naming suggests that the methods are asserting opposite things,
but actually they assert some things in common (like the existence of autorenew
billing events, and that pre-transfer grace periods are cleared).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=170540417
Allow superusers to change the transfer period to zero years and allow
superusers to change the automatic transfer length.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=167598314
This is the last of many cls adding explicit logging in all our domain
mutation flows to facilitate transaction reporting.
The transfer process is as follows:
GAINING sends a TransferRequest to LOSING
LOSING either acks (TransferApprove), nacks (TransferReject) or does nothing
(auto approve). For acks and autoapproves, we produce a +1 counter for GAINING
and LOSING for domain-gaining/losing-successful for each registrar, to be
reported on the approve date + the transfer grace period. For nacks, we produce
a +1 counter for domain-gaining/losing-nacked for each registrar.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=166535579
This makes the code more understandable from callsites, and also forces
users of this function to deal with the situation where the registrar
with a given client ID might not be present (it was previously silently
NPEing from some of the callsites).
This also adds a test helper method loadRegistrar(clientId) that retains
the old functionality for terseness in tests. It also fixes some instances
of using the load method with the wrong cachedness -- some uses in high-
traffic situations (WHOIS) that should have caching, but also low-traffic
reporting that don't benefit from caching so might as well always be
current.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=162990468
The --superuser command in the nomulus command-line tool should be
bypassing checks on whether the passed-in registrar client ID has access
to the TLD in question, but currently it is not.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=158974462
As part of b/36599833, this makes FlowReporter log the tld(s) of every domain
flow it executes, so we can provide ICANN reporting totals on a per-TLD basis.
It also adds several other fields that we're computing anyway and which seem
useful, particularly for debugging any issues we see in production with the data
that we're attempting to record for ICANN reporting. The full set of fields is:
- commandType (e.g. "create", "info", "transfer")
- resourceType* (e.g. "domain", "contact", "host")
- flowClassName (e.g. "ContactCreateFlow", "DomainRestoreRequestFlow")
- targetId* (e.g. "ns1.foo.com", "bar.org", "contact-1234")
- targetIds* - plural of the above, for multi-resource checks
- tld** (e.g. "com", "co.uk") - extracted from targetId, lowercased
- tlds** - plural of the above, deduplicated, for multi-resource checks
* = only non-empty for resource flows (not e.g. login, logout, poll)
** = only non-empty for domain flows
Note that TLD extraction is deliberately very lenient to avoid the complexity
overhead of double-validation of the domain names in the common case.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=154070794
As part of b/36599833, this makes FlowRunner log the appropriate ICANN activity
report field name for each flow it runs as part of a structured JSON log
statement which can be parsed to generate ICANN activity reports (under the key
"icannActivityReportField").
In order to support this, we introduce an annotation for Flow classes called
@ReportingSpec and a corresponding enum of values for this annotation, which is
IcannReportingTypes.ActivityReportField, that stores the mapping of constant
enum values to field names.
The mapping from flows to fields is fairly obvious, with three exceptions:
- Application flows are all accounted under domains, since applications are
technically just deferred domain creates within the EPP protocol
- ClaimsCheckFlow is counted as a domain check
- DomainAllocateFlow is counted as a domain create
In addition, I've added tests to all the corresponding flows that we are
indeed logging what we expect.
We'll also need to log the TLD for this to be useful, but I'm doing that in a
follow-up CL.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=151283411
Now that transfers are always restricted to 1 year, it's unnecessary to store
extendedRegistrationYears on TransferData - it will always be equal to 1. This
simplifies logic in a few other places, e.g. RdeDomainImportAction.
I verified in BigQuery that no DomainBases exist with extendedRegistrationYears
values that aren't either null or equal to 1. At some point we should remove
the persisted fields from datastore via e.g. resaving all those domains, but
it's low priority and can wait until we have some more pressing migration.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=150373897
This changes ResourceStatusProhibitsOperationException so that we print out the list of StatusValues using their XML names rather than the literal enum name, i.e. we use "pendingDelete" rather than "PENDING_DELETE".
This seems more correct given that EPP clients will be used to seeing the status values in the XML representation, and it also matches the existing ResourceHasClientUpdateProhibitedException that hardcodes "clientUpdateProhibited":
http://[]/third_party/java_src/gtld/java/google/registry/flows/exceptions/ResourceHasClientUpdateProhibitedException.java?l=22&rcl=146111211
Also reorganized related test methods and added some missing tests, including for ContactTransferRequestFlow which previously had none. I also renamed the "clientProhibitedStatusValue" tests to instead say "statusValueNotClientSettable" to be clearer about what's being tested, and that it's not related to the "clientXXProhibited" statuses.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=150248562
It turns out that this ICANN policy appears to prohibit transfers with
registration extensions other than 1 year (section A.8):
https://www.icann.org/resources/pages/policy-2012-03-07-en
This is backed up by the practical fact that we've never seen a registrar
request a transfer for any period other than one year.
And removing the support for multi-year transfers vastly simplifies
transfer logic and eliminates a bunch of annoying corner cases. Users
still can achieve the same thing by doing a 1-year transfer plus a
manual renewal afterwards for the remainder of the desired extension.
This change leaves in place lots of infrastructure to support multi-year
transfers that is now obsolete (e.g. TransferData.extendedRegistrationYears).
This should all be cleaned up, but it's a lower priority than fixing the
gap itself and insulating ourselves against needing to handle any real
multi-year transfer case. Once this CL goes in, we can start ignoring
extendedRegistrationYears entirely because it'll always be 1 year, which
makes the cleanup process easier.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=150212864
In fact, completely eviscerate cloneProjectedAtTime (to be removed in
a followup CL) in favor of doing the projection of transfers and the
loading of values from the superordinate domain at call sites. This
is one of the issues that blocked the memcache audit work, since the
load inside of cloneProjectedAtTime could not be controlled by the
caller.
Note: fixed a minor bug where a subordinate host created after its superordinate domain was last transferred should have lastTransferTime==null but was previously reporting the domain's lastTransferTime.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=149769125
This fixes longstanding bug b/19430703 in which domain transfers that were
server-approved would only handle the autorenew grace period correctly if
the autorenew grace period was going to start within the transfer window.
If the autorenew grace period was already active (e.g. the domain had
recently autorenewed, before the transfer was requested), the logic would
miss it, even if it was going to be active throughout the transfer window
(i.e. it would still be active at the server-approval time).
When the autorenew grace period is active at the time a transfer is approved
(whether by the server or explicitly via DomainTransferApproveFlow), the
correct behavior is to essentially "cancel" the autorenew - the losing registrar
receives a refund for the autorenew charge, and the gaining registrar's transfer
extended registration years are applied to the expiration time as it was prior
to that autorenew. The way we implement this is that we just have the transfer
essentially "subsume" the autorenew - we deduct 1 year from the transfer's
extended registration years before extending the registration period from what
the expiration time is post-autorenew at the moment of transfer approval.
See b/19430703#comment17 for details on the policy justification; the only real
ICANN document about this is https://www.icann.org/news/advisory-2002-06-06-en,
but registrars informally document in many places that transfers will trigger
autorenew grace, e.g. see https://support.google.com/domains/answer/3251236
There are still a few parts of this bug that remain unfixed:
1) RdeDomainImportAction repeats a lot of logic when handling imported domains
that are in pending transfer, so it will also need to address this case in
some way, but the policy choices there are unclear so I'm waiting until we
know more about RDE import goals to figure out how to fix that.
2) Behavior at the millisecond edge cases is inconsistent - specifically, for
the case where a transfer is requested such that the automatic transfer
time is exactly the domain's expiration time (down to the millisecond),
the correct behavior is a little unclear and this CL for now ignores this
issue in favor of getting a fix for 99.999% of the issue into prod. See
newly created b/35881941 for the gory details.
Also, there are parts of this bug that will be fixed as parts of either
b/25084229 (transfer exDate computations) or b/35110537 (disallowing transfers
with extended registration years other than 1), both of which are less pressing.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=149024269
This CL adds an otherClientId field to be populated on domain transfers with client ID of the other end of the transaction (losing registrar for requests and cancels, gaining registrar for approves and rejects). This will be used for reporting in compliance with specification 3 of the ICANN registry agreement.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=143775945
Also adds a mechanism to ensure that fee extensions are included when custom
pricing logic adds a custom fee, and fixes up the domain restore flow to
properly use the restore price.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=142715136
This also adds a domain update pricing hook to DomainPricingCustomLogic.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=142286755
and HostResource.
DomainApplication is not transferable and has no need for this
field. HostResource needs it because it can be transferred with
a domain.
This is all in service of removing the ofy().load() inside of
host's cloneProjectedAtTime.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=139346925
HostResource and DomainApplication are not transferable, (or at
least, not directly in the case of hosts) and have no need for
the TransferData field. In a flat-flow world, we can push it down
to where it's actually used.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=139201423
aka regexing for fun and profit.
This also makes sure that there are no statements after the
throwing statement, since these would be dead code. There
were a surprising number of places with assertions after
the throw, and none of these are actually triggered in tests
ever. When I found these, I replaced them with try/catch/rethrow
which makes the assertions actually happen:
before:
// This is the ExceptionRule that checks EppException marshaling
thrown.expect(FooException.class);
doThrowingThing();
assertSomething(); // Dead code!
after:
try {
doThrowingThing();
assertWithMessage("...").fail();
} catch (FooException e) {
assertSomething();
// For EppExceptions:
assertAboutEppExceptins().that(e).marshalsToXml();
}
To make this work, I added EppExceptionSubject.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=135793407
TestExtraLogicManager is pretty kludgy, and should be replaced with injection, mocking, etc. But in the meantime, using a dedicated error to signal its success, rather than IllegalArgumentException as was done before, at least makes things a little easier to follow.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=134832315
These were historically separate due to the old flow
structure, but now they should be one exception.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=133984858
It is replaced by loadByForeignKey(), which does the same thing that
loadByUniqueId() did for contacts, hosts, and domains, and also
loadDomainApplication(), which loads domain application by ROID. This eliminates
the ugly mode-switching of attemping to load by other foreign key or ROID.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=133980156
This CL enhances various domain flows (check, create, delete, renew, restore, transfer, update) so that they invoke the appropriate methods on the object implementing the TLD's RegistryExtraFlowLogic (if any). TldSpecificLogicProxy is also updated to invoke RegistryExtraFlowLogic proxy (if any) to fetch the appropriate price. The tests use a made-up extra flow logic object which can be attached to a test TLD to make sure that the proper routines are being invoked.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=132486734
This change replaces all Ref objects in the code with Key objects. These are
stored in datastore as the same object (raw datastore keys), so this is not
a model change.
Our best practices doc says to use Keys not Refs because:
* The .get() method obscures what's actually going on
- Much harder to visually audit the code for datastore loads
- Hard to distinguish Ref<T> get()'s from Optional get()'s and Supplier get()'s
* Implicit ofy().load() offers much less control
- Antipattern for ultimate goal of making Ofy injectable
- Can't control cache use or batch loading without making ofy() explicit anyway
* Serialization behavior is surprising and could be quite dangerous/incorrect
- Can lead to serialization errors. If it actually worked "as intended",
it would lead to a Ref<> on a serialized object being replaced upon
deserialization with a stale copy of the old value, which could potentially
break all kinds of transactional expectations
* Having both Ref<T> and Key<T> introduces extra boilerplate everywhere
- E.g. helper methods all need to have Ref and Key overloads, or you need to
call .key() to get the Key<T> for every Ref<T> you want to pass in
- Creating a Ref<T> is more cumbersome, since it doesn't have all the create()
overloads that Key<T> has, only create(Key<T>) and create(Entity) - no way to
create directly from kind+ID/name, raw Key, websafe key string, etc.
(Note that Refs are treated specially by Objectify's @Load method and Keys are not;
we don't use that feature, but it is the one advantage Refs have over Keys.)
The direct impetus for this change is that I am trying to audit our use of memcache,
and the implicit .get() calls to datastore were making that very hard.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=131965491
We want to support multiple versions of the fee extension, to allow new features while maintaining backward compatibility. This CL extends the framework and adds one new version, 0.11 (spec version 7), to the existing version 0.6 (spec version 3). A follow-on CL will add version 0.12 (spec version 8).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=127849044
Daggerizes all of the EPP flows. This does not change anything yet
about the flows themselves, just how they are invoked, but after
this CL it's safe to @Inject things into flow classes.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=125382478
The dark lord Gosling designed the Java package naming system so that
ownership flows from the DNS system. Since we own the domain name
registry.google, it seems only appropriate that we should use
google.registry as our package name.
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.
2016-05-13 18:55:08 -04:00
Renamed from javatests/com/google/domain/registry/flows/domain/DomainTransferRequestFlowTest.java (Browse further)