mirror of
https://github.com/google/nomulus.git
synced 2025-04-29 19:47:51 +02:00
Add sanity checks to history entry construction (#1156)
* Add sanity checks to history entry construction * Add more missing setClientId() calls and delete scrap tool * Merge branch 'master' into synthetic-requestedby * Set more client IDs * Merge branch 'master' into synthetic-requestedby
This commit is contained in:
parent
8293e1e807
commit
4e312f2482
31 changed files with 276 additions and 523 deletions
|
@ -14,8 +14,10 @@
|
||||||
|
|
||||||
package google.registry.model.reporting;
|
package google.registry.model.reporting;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.googlecode.objectify.Key.getKind;
|
import static com.googlecode.objectify.Key.getKind;
|
||||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||||
|
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
@ -383,6 +385,13 @@ public class HistoryEntry extends ImmutableObject implements Buildable, Datastor
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T build() {
|
public T build() {
|
||||||
|
// TODO(mcilwain): Add null checking for id/parent once DB migration is complete.
|
||||||
|
checkArgumentNotNull(getInstance().type, "History entry type must be specified");
|
||||||
|
checkArgumentNotNull(getInstance().modificationTime, "Modification time must be specified");
|
||||||
|
checkArgumentNotNull(getInstance().clientId, "Registrar ID must be specified");
|
||||||
|
checkArgument(
|
||||||
|
!getInstance().type.equals(Type.SYNTHETIC) || !getInstance().requestedByRegistrar,
|
||||||
|
"Synthetic history entries cannot be requested by a registrar");
|
||||||
return super.build();
|
return super.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,191 +0,0 @@
|
||||||
// Copyright 2020 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.tools;
|
|
||||||
|
|
||||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
|
||||||
import static google.registry.model.ofy.ObjectifyService.auditedOfy;
|
|
||||||
|
|
||||||
import com.beust.jcommander.Parameters;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import google.registry.model.billing.BillingEvent;
|
|
||||||
import google.registry.model.billing.BillingEvent.OneTime;
|
|
||||||
import google.registry.model.billing.BillingEvent.Recurring;
|
|
||||||
import google.registry.model.domain.DomainBase;
|
|
||||||
import google.registry.model.domain.GracePeriod;
|
|
||||||
import google.registry.model.transfer.DomainTransferData;
|
|
||||||
import google.registry.model.transfer.TransferData.TransferServerApproveEntity;
|
|
||||||
import google.registry.persistence.VKey;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A command that re-saves the problematic {@link BillingEvent.Recurring} entities with unique IDs.
|
|
||||||
*
|
|
||||||
* <p>This command is used to address the duplicate id issue we found for certain {@link
|
|
||||||
* BillingEvent.Recurring} entities. The command reassigns an application wide unique id to the
|
|
||||||
* problematic entity and resaves it, it also resaves the entity having reference to the problematic
|
|
||||||
* entity with the updated id.
|
|
||||||
*
|
|
||||||
* <p>To use this command, you will need to provide the path to a file containing a list of strings
|
|
||||||
* representing the literal of Objectify key for the problematic entities. An example key literal
|
|
||||||
* is:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* "DomainBase", "111111-TEST", "HistoryEntry", 2222222, "Recurring", 3333333
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* <p>Note that the double quotes are part of the key literal. The key literal can be retrieved from
|
|
||||||
* the column <code>__key__.path</code> in BigQuery.
|
|
||||||
*/
|
|
||||||
@Parameters(
|
|
||||||
separators = " =",
|
|
||||||
commandDescription = "Dedupe BillingEvent.Recurring entities with duplicate IDs.")
|
|
||||||
public class DedupeRecurringBillingEventIdsCommand extends ReadEntityFromKeyPathCommand<Recurring> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void process(Recurring recurring) {
|
|
||||||
// Loads the associated DomainBase and BillingEvent.OneTime entities that
|
|
||||||
// may have reference to this BillingEvent.Recurring entity.
|
|
||||||
Key<DomainBase> domainKey = getGrandParentAsDomain(Key.create(recurring));
|
|
||||||
DomainBase domain = auditedOfy().load().key(domainKey).now();
|
|
||||||
List<BillingEvent.OneTime> oneTimes =
|
|
||||||
auditedOfy().load().type(BillingEvent.OneTime.class).ancestor(domainKey).list();
|
|
||||||
|
|
||||||
VKey<Recurring> oldRecurringVKey = recurring.createVKey();
|
|
||||||
// By setting id to 0L, Buildable.build() will assign an application wide unique id to it.
|
|
||||||
Recurring uniqIdRecurring = recurring.asBuilder().setId(0L).build();
|
|
||||||
VKey<Recurring> newRecurringVKey = uniqIdRecurring.createVKey();
|
|
||||||
|
|
||||||
// After having the unique id for the BillingEvent.Recurring entity, we also need to
|
|
||||||
// update the references in other entities to point to the new BillingEvent.Recurring
|
|
||||||
// entity.
|
|
||||||
updateReferenceInOneTimeBillingEvent(oneTimes, oldRecurringVKey, newRecurringVKey);
|
|
||||||
updateReferenceInDomain(domain, oldRecurringVKey, newRecurringVKey);
|
|
||||||
|
|
||||||
stageEntityKeyChange(recurring, uniqIdRecurring);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resaves {@link BillingEvent.OneTime} entities with updated {@link
|
|
||||||
* BillingEvent.OneTime#cancellationMatchingBillingEvent}.
|
|
||||||
*
|
|
||||||
* <p>{@link BillingEvent.OneTime#cancellationMatchingBillingEvent} is a {@link VKey} to a {@link
|
|
||||||
* BillingEvent.Recurring} entity. So, if the {@link BillingEvent.Recurring} entity gets a new key
|
|
||||||
* by changing its id, we need to update {@link
|
|
||||||
* BillingEvent.OneTime#cancellationMatchingBillingEvent} as well.
|
|
||||||
*/
|
|
||||||
private void updateReferenceInOneTimeBillingEvent(
|
|
||||||
List<OneTime> oneTimes, VKey<Recurring> oldRecurringVKey, VKey<Recurring> newRecurringVKey) {
|
|
||||||
oneTimes.forEach(
|
|
||||||
oneTime -> {
|
|
||||||
if (oneTime.getCancellationMatchingBillingEvent() != null
|
|
||||||
&& oneTime.getCancellationMatchingBillingEvent().equals(oldRecurringVKey)) {
|
|
||||||
BillingEvent.OneTime updatedOneTime =
|
|
||||||
oneTime.asBuilder().setCancellationMatchingBillingEvent(newRecurringVKey).build();
|
|
||||||
stageEntityChange(oneTime, updatedOneTime);
|
|
||||||
appendChangeMessage(
|
|
||||||
String.format(
|
|
||||||
"Changed cancellationMatchingBillingEvent in entity %s from %s to %s\n",
|
|
||||||
oneTime.createVKey().getOfyKey(),
|
|
||||||
oneTime.getCancellationMatchingBillingEvent().getOfyKey(),
|
|
||||||
updatedOneTime.getCancellationMatchingBillingEvent().getOfyKey()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resaves {@link DomainBase} entity with updated references to {@link BillingEvent.Recurring}
|
|
||||||
* entity.
|
|
||||||
*
|
|
||||||
* <p>The following 4 fields in the domain entity can be or have a reference to this
|
|
||||||
* BillingEvent.Recurring entity, so we need to check them and replace them with the new entity
|
|
||||||
* when necessary:
|
|
||||||
*
|
|
||||||
* <ol>
|
|
||||||
* <li>domain.autorenewBillingEvent, see {@link DomainBase#autorenewBillingEvent}
|
|
||||||
* <li>domain.transferData.serverApproveAutorenewEvent, see {@link
|
|
||||||
* DomainTransferData#serverApproveAutorenewEvent}
|
|
||||||
* <li>domain.transferData.serverApproveEntities, see {@link
|
|
||||||
* DomainTransferData#serverApproveEntities}
|
|
||||||
* <li>domain.gracePeriods.billingEventRecurring, see {@link GracePeriod#billingEventRecurring}
|
|
||||||
* </ol>
|
|
||||||
*/
|
|
||||||
private void updateReferenceInDomain(
|
|
||||||
DomainBase domain, VKey<Recurring> oldRecurringVKey, VKey<Recurring> newRecurringVKey) {
|
|
||||||
DomainBase.Builder domainBuilder = domain.asBuilder();
|
|
||||||
StringBuilder domainChange =
|
|
||||||
new StringBuilder(
|
|
||||||
String.format(
|
|
||||||
"Resaved domain %s with following changes:\n", domain.createVKey().getOfyKey()));
|
|
||||||
|
|
||||||
if (domain.getAutorenewBillingEvent() != null
|
|
||||||
&& domain.getAutorenewBillingEvent().equals(oldRecurringVKey)) {
|
|
||||||
domainBuilder.setAutorenewBillingEvent(newRecurringVKey);
|
|
||||||
domainChange.append(
|
|
||||||
String.format(
|
|
||||||
" Changed autorenewBillingEvent from %s to %s.\n",
|
|
||||||
oldRecurringVKey, newRecurringVKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (domain.getTransferData().getServerApproveAutorenewEvent() != null
|
|
||||||
&& domain.getTransferData().getServerApproveAutorenewEvent().equals(oldRecurringVKey)) {
|
|
||||||
Set<VKey<? extends TransferServerApproveEntity>> serverApproveEntities =
|
|
||||||
Sets.union(
|
|
||||||
Sets.difference(
|
|
||||||
domain.getTransferData().getServerApproveEntities(),
|
|
||||||
ImmutableSet.of(oldRecurringVKey)),
|
|
||||||
ImmutableSet.of(newRecurringVKey));
|
|
||||||
domainBuilder.setTransferData(
|
|
||||||
domain
|
|
||||||
.getTransferData()
|
|
||||||
.asBuilder()
|
|
||||||
.setServerApproveEntities(ImmutableSet.copyOf(serverApproveEntities))
|
|
||||||
.setServerApproveAutorenewEvent(newRecurringVKey)
|
|
||||||
.build());
|
|
||||||
domainChange.append(
|
|
||||||
String.format(
|
|
||||||
" Changed transferData.serverApproveAutoRenewEvent from %s to %s.\n",
|
|
||||||
oldRecurringVKey, newRecurringVKey));
|
|
||||||
domainChange.append(
|
|
||||||
String.format(
|
|
||||||
" Changed transferData.serverApproveEntities to remove %s and add %s.\n",
|
|
||||||
oldRecurringVKey, newRecurringVKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
ImmutableSet<GracePeriod> updatedGracePeriod =
|
|
||||||
domain.getGracePeriods().stream()
|
|
||||||
.map(
|
|
||||||
gracePeriod ->
|
|
||||||
gracePeriod.getRecurringBillingEvent().equals(oldRecurringVKey)
|
|
||||||
? gracePeriod.cloneWithRecurringBillingEvent(newRecurringVKey)
|
|
||||||
: gracePeriod)
|
|
||||||
.collect(toImmutableSet());
|
|
||||||
if (!updatedGracePeriod.equals(domain.getGracePeriods())) {
|
|
||||||
domainBuilder.setGracePeriods(updatedGracePeriod);
|
|
||||||
domainChange.append(
|
|
||||||
String.format(
|
|
||||||
" Changed gracePeriods to remove %s and add %s.\n",
|
|
||||||
oldRecurringVKey, newRecurringVKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
DomainBase updatedDomain = domainBuilder.build();
|
|
||||||
if (!updatedDomain.equals(domain)) {
|
|
||||||
stageEntityChange(domain, updatedDomain);
|
|
||||||
appendChangeMessage(domainChange.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -53,7 +53,6 @@ public final class RegistryTool {
|
||||||
.put("create_tld", CreateTldCommand.class)
|
.put("create_tld", CreateTldCommand.class)
|
||||||
.put("curl", CurlCommand.class)
|
.put("curl", CurlCommand.class)
|
||||||
.put("dedupe_one_time_billing_event_ids", DedupeOneTimeBillingEventIdsCommand.class)
|
.put("dedupe_one_time_billing_event_ids", DedupeOneTimeBillingEventIdsCommand.class)
|
||||||
.put("dedupe_recurring_billing_event_ids", DedupeRecurringBillingEventIdsCommand.class)
|
|
||||||
.put("delete_allocation_tokens", DeleteAllocationTokensCommand.class)
|
.put("delete_allocation_tokens", DeleteAllocationTokensCommand.class)
|
||||||
.put("delete_contact_by_roid", DeleteContactByRoidCommand.class)
|
.put("delete_contact_by_roid", DeleteContactByRoidCommand.class)
|
||||||
.put("delete_domain", DeleteDomainCommand.class)
|
.put("delete_domain", DeleteDomainCommand.class)
|
||||||
|
|
|
@ -170,6 +170,7 @@ class DeleteExpiredDomainsActionTest {
|
||||||
.setType(DOMAIN_CREATE)
|
.setType(DOMAIN_CREATE)
|
||||||
.setParent(pendingExpirationDomain)
|
.setParent(pendingExpirationDomain)
|
||||||
.setModificationTime(clock.nowUtc().minusMonths(9))
|
.setModificationTime(clock.nowUtc().minusMonths(9))
|
||||||
|
.setClientId(pendingExpirationDomain.getCreationClientId())
|
||||||
.build());
|
.build());
|
||||||
BillingEvent.Recurring autorenewBillingEvent =
|
BillingEvent.Recurring autorenewBillingEvent =
|
||||||
persistResource(createAutorenewBillingEvent(createHistoryEntry).build());
|
persistResource(createAutorenewBillingEvent(createHistoryEntry).build());
|
||||||
|
|
|
@ -279,11 +279,14 @@ class DeleteProberDataActionTest extends MapreduceTestCase<DeleteProberDataActio
|
||||||
*/
|
*/
|
||||||
private static Set<ImmutableObject> persistDomainAndDescendants(String fqdn) {
|
private static Set<ImmutableObject> persistDomainAndDescendants(String fqdn) {
|
||||||
DomainBase domain = persistDeletedDomain(fqdn, DELETION_TIME);
|
DomainBase domain = persistDeletedDomain(fqdn, DELETION_TIME);
|
||||||
HistoryEntry historyEntry = persistSimpleResource(
|
HistoryEntry historyEntry =
|
||||||
new HistoryEntry.Builder()
|
persistSimpleResource(
|
||||||
.setParent(domain)
|
new HistoryEntry.Builder()
|
||||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
.setParent(domain)
|
||||||
.build());
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
|
.setModificationTime(DELETION_TIME.minusYears(3))
|
||||||
|
.build());
|
||||||
BillingEvent.OneTime billingEvent = persistSimpleResource(
|
BillingEvent.OneTime billingEvent = persistSimpleResource(
|
||||||
new BillingEvent.OneTime.Builder()
|
new BillingEvent.OneTime.Builder()
|
||||||
.setParent(historyEntry)
|
.setParent(historyEntry)
|
||||||
|
|
|
@ -19,6 +19,7 @@ import static google.registry.model.common.Cursor.CursorType.RECURRING_BILLING;
|
||||||
import static google.registry.model.domain.Period.Unit.YEARS;
|
import static google.registry.model.domain.Period.Unit.YEARS;
|
||||||
import static google.registry.model.ofy.ObjectifyService.auditedOfy;
|
import static google.registry.model.ofy.ObjectifyService.auditedOfy;
|
||||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_AUTORENEW;
|
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_AUTORENEW;
|
||||||
|
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_CREATE;
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||||
import static google.registry.testing.DatabaseHelper.assertBillingEvents;
|
import static google.registry.testing.DatabaseHelper.assertBillingEvents;
|
||||||
import static google.registry.testing.DatabaseHelper.assertBillingEventsForResource;
|
import static google.registry.testing.DatabaseHelper.assertBillingEventsForResource;
|
||||||
|
@ -84,9 +85,20 @@ public class ExpandRecurringBillingEventsActionTest
|
||||||
action.clock = clock;
|
action.clock = clock;
|
||||||
action.cursorTimeParam = Optional.empty();
|
action.cursorTimeParam = Optional.empty();
|
||||||
createTld("tld");
|
createTld("tld");
|
||||||
domain = persistResource(newDomainBase("example.tld").asBuilder()
|
domain =
|
||||||
.setCreationTimeForTest(DateTime.parse("1999-01-05T00:00:00Z")).build());
|
persistResource(
|
||||||
historyEntry = persistResource(new HistoryEntry.Builder().setParent(domain).build());
|
newDomainBase("example.tld")
|
||||||
|
.asBuilder()
|
||||||
|
.setCreationTimeForTest(DateTime.parse("1999-01-05T00:00:00Z"))
|
||||||
|
.build());
|
||||||
|
historyEntry =
|
||||||
|
persistResource(
|
||||||
|
new HistoryEntry.Builder()
|
||||||
|
.setClientId(domain.getCreationClientId())
|
||||||
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
|
.setModificationTime(DateTime.parse("1999-01-05T00:00:00Z"))
|
||||||
|
.setParent(domain)
|
||||||
|
.build());
|
||||||
recurring =
|
recurring =
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(historyEntry)
|
.setParent(historyEntry)
|
||||||
|
@ -174,7 +186,14 @@ public class ExpandRecurringBillingEventsActionTest
|
||||||
void testSuccess_expandSingleEvent_deletedDomain() throws Exception {
|
void testSuccess_expandSingleEvent_deletedDomain() throws Exception {
|
||||||
DateTime deletionTime = DateTime.parse("2000-08-01T00:00:00Z");
|
DateTime deletionTime = DateTime.parse("2000-08-01T00:00:00Z");
|
||||||
DomainBase deletedDomain = persistDeletedDomain("deleted.tld", deletionTime);
|
DomainBase deletedDomain = persistDeletedDomain("deleted.tld", deletionTime);
|
||||||
historyEntry = persistResource(new HistoryEntry.Builder().setParent(deletedDomain).build());
|
historyEntry =
|
||||||
|
persistResource(
|
||||||
|
new HistoryEntry.Builder()
|
||||||
|
.setParent(deletedDomain)
|
||||||
|
.setClientId(deletedDomain.getCreationClientId())
|
||||||
|
.setModificationTime(deletedDomain.getCreationTime())
|
||||||
|
.setType(DOMAIN_CREATE)
|
||||||
|
.build());
|
||||||
recurring =
|
recurring =
|
||||||
persistResource(
|
persistResource(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
|
|
|
@ -100,7 +100,14 @@ public class DomainBaseUtilTest {
|
||||||
.build())
|
.build())
|
||||||
.createVKey();
|
.createVKey();
|
||||||
Key<HistoryEntry> historyEntryKey =
|
Key<HistoryEntry> historyEntryKey =
|
||||||
Key.create(persistResource(new HistoryEntry.Builder().setParent(domainKey).build()));
|
Key.create(
|
||||||
|
persistResource(
|
||||||
|
new HistoryEntry.Builder()
|
||||||
|
.setParent(domainKey)
|
||||||
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
|
.setModificationTime(fakeClock.nowUtc().minusYears(1))
|
||||||
|
.build()));
|
||||||
oneTimeBillKey = Key.create(historyEntryKey, BillingEvent.OneTime.class, 1);
|
oneTimeBillKey = Key.create(historyEntryKey, BillingEvent.OneTime.class, 1);
|
||||||
recurringBillKey = VKey.from(Key.create(historyEntryKey, BillingEvent.Recurring.class, 2));
|
recurringBillKey = VKey.from(Key.create(historyEntryKey, BillingEvent.Recurring.class, 2));
|
||||||
VKey<PollMessage.Autorenew> autorenewPollKey =
|
VKey<PollMessage.Autorenew> autorenewPollKey =
|
||||||
|
|
|
@ -181,6 +181,7 @@ class InitSqlPipelineTest {
|
||||||
new HistoryEntry.Builder()
|
new HistoryEntry.Builder()
|
||||||
.setParent(domainKey)
|
.setParent(domainKey)
|
||||||
.setModificationTime(fakeClock.nowUtc())
|
.setModificationTime(fakeClock.nowUtc())
|
||||||
|
.setClientId(registrar1.getClientId())
|
||||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
.build());
|
.build());
|
||||||
persistResource(
|
persistResource(
|
||||||
|
|
|
@ -179,6 +179,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||||
.setType(DOMAIN_CREATE)
|
.setType(DOMAIN_CREATE)
|
||||||
.setParent(domain)
|
.setParent(domain)
|
||||||
.setModificationTime(clock.nowUtc())
|
.setModificationTime(clock.nowUtc())
|
||||||
|
.setClientId(domain.getCreationClientId())
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1114,6 +1115,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||||
.setType(DOMAIN_CREATE)
|
.setType(DOMAIN_CREATE)
|
||||||
.setParent(domain)
|
.setParent(domain)
|
||||||
.setModificationTime(TIME_BEFORE_FLOW.minusDays(1))
|
.setModificationTime(TIME_BEFORE_FLOW.minusDays(1))
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
.setDomainTransactionRecords(ImmutableSet.of(existingRecord))
|
.setDomainTransactionRecords(ImmutableSet.of(existingRecord))
|
||||||
.build());
|
.build());
|
||||||
runFlow();
|
runFlow();
|
||||||
|
|
|
@ -366,6 +366,7 @@ class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, DomainBase
|
||||||
.setParent(domain)
|
.setParent(domain)
|
||||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
.setModificationTime(clock.nowUtc())
|
.setModificationTime(clock.nowUtc())
|
||||||
|
.setClientId(domain.getCreationClientId())
|
||||||
.build());
|
.build());
|
||||||
BillingEvent.Recurring renewEvent =
|
BillingEvent.Recurring renewEvent =
|
||||||
persistResource(
|
persistResource(
|
||||||
|
|
|
@ -130,6 +130,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
|
||||||
.setParent(domain)
|
.setParent(domain)
|
||||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
.setModificationTime(clock.nowUtc())
|
.setModificationTime(clock.nowUtc())
|
||||||
|
.setClientId(domain.getCreationClientId())
|
||||||
.build();
|
.build();
|
||||||
BillingEvent.Recurring autorenewEvent =
|
BillingEvent.Recurring autorenewEvent =
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
|
|
|
@ -116,6 +116,7 @@ class DomainRestoreRequestFlowTest
|
||||||
new HistoryEntry.Builder()
|
new HistoryEntry.Builder()
|
||||||
.setType(HistoryEntry.Type.DOMAIN_DELETE)
|
.setType(HistoryEntry.Type.DOMAIN_DELETE)
|
||||||
.setModificationTime(clock.nowUtc())
|
.setModificationTime(clock.nowUtc())
|
||||||
|
.setClientId(domain.getCurrentSponsorClientId())
|
||||||
.setParent(domain)
|
.setParent(domain)
|
||||||
.build());
|
.build());
|
||||||
persistResource(
|
persistResource(
|
||||||
|
|
|
@ -607,6 +607,7 @@ class DomainTransferApproveFlowTest
|
||||||
.setType(DOMAIN_TRANSFER_REQUEST)
|
.setType(DOMAIN_TRANSFER_REQUEST)
|
||||||
.setParent(domain)
|
.setParent(domain)
|
||||||
.setModificationTime(clock.nowUtc().minusDays(4))
|
.setModificationTime(clock.nowUtc().minusDays(4))
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
.setDomainTransactionRecords(
|
.setDomainTransactionRecords(
|
||||||
ImmutableSet.of(previousSuccessRecord, notCancellableRecord))
|
ImmutableSet.of(previousSuccessRecord, notCancellableRecord))
|
||||||
.build());
|
.build());
|
||||||
|
|
|
@ -406,6 +406,7 @@ class DomainTransferCancelFlowTest
|
||||||
.setType(DOMAIN_TRANSFER_REQUEST)
|
.setType(DOMAIN_TRANSFER_REQUEST)
|
||||||
.setDomain(domain)
|
.setDomain(domain)
|
||||||
.setModificationTime(clock.nowUtc().minusDays(4))
|
.setModificationTime(clock.nowUtc().minusDays(4))
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
.setDomainTransactionRecords(
|
.setDomainTransactionRecords(
|
||||||
ImmutableSet.of(previousSuccessRecord, notCancellableRecord))
|
ImmutableSet.of(previousSuccessRecord, notCancellableRecord))
|
||||||
.build());
|
.build());
|
||||||
|
|
|
@ -371,6 +371,7 @@ class DomainTransferRejectFlowTest
|
||||||
.setType(DOMAIN_TRANSFER_REQUEST)
|
.setType(DOMAIN_TRANSFER_REQUEST)
|
||||||
.setParent(domain)
|
.setParent(domain)
|
||||||
.setModificationTime(clock.nowUtc().minusDays(4))
|
.setModificationTime(clock.nowUtc().minusDays(4))
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
.setDomainTransactionRecords(
|
.setDomainTransactionRecords(
|
||||||
ImmutableSet.of(previousSuccessRecord, notCancellableRecord))
|
ImmutableSet.of(previousSuccessRecord, notCancellableRecord))
|
||||||
.build());
|
.build());
|
||||||
|
|
|
@ -156,6 +156,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||||
new HistoryEntry.Builder()
|
new HistoryEntry.Builder()
|
||||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
.setModificationTime(clock.nowUtc())
|
.setModificationTime(clock.nowUtc())
|
||||||
|
.setClientId(domain.getCreationClientId())
|
||||||
.setParent(domain)
|
.setParent(domain)
|
||||||
.build());
|
.build());
|
||||||
clock.advanceOneMilli();
|
clock.advanceOneMilli();
|
||||||
|
@ -179,6 +180,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||||
new HistoryEntry.Builder()
|
new HistoryEntry.Builder()
|
||||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
.setModificationTime(clock.nowUtc())
|
.setModificationTime(clock.nowUtc())
|
||||||
|
.setClientId(domain.getCreationClientId())
|
||||||
.setParent(domain)
|
.setParent(domain)
|
||||||
.build());
|
.build());
|
||||||
clock.advanceOneMilli();
|
clock.advanceOneMilli();
|
||||||
|
|
|
@ -208,12 +208,14 @@ class PollRequestFlowTest extends FlowTestCase<PollRequestFlow> {
|
||||||
void testSuccess_contactDelete() throws Exception {
|
void testSuccess_contactDelete() throws Exception {
|
||||||
// Contact delete poll messages do not have any response data, so ensure that no
|
// Contact delete poll messages do not have any response data, so ensure that no
|
||||||
// response data block is produced in the poll message.
|
// response data block is produced in the poll message.
|
||||||
HistoryEntry historyEntry = persistResource(new HistoryEntry.Builder()
|
HistoryEntry historyEntry =
|
||||||
.setClientId("NewRegistrar")
|
persistResource(
|
||||||
.setModificationTime(clock.nowUtc().minusDays(1))
|
new HistoryEntry.Builder()
|
||||||
.setType(HistoryEntry.Type.CONTACT_DELETE)
|
.setClientId("NewRegistrar")
|
||||||
.setParent(contact)
|
.setModificationTime(clock.nowUtc().minusDays(1))
|
||||||
.build());
|
.setType(HistoryEntry.Type.CONTACT_DELETE)
|
||||||
|
.setParent(contact)
|
||||||
|
.build());
|
||||||
persistResource(
|
persistResource(
|
||||||
new PollMessage.OneTime.Builder()
|
new PollMessage.OneTime.Builder()
|
||||||
.setClientId("NewRegistrar")
|
.setClientId("NewRegistrar")
|
||||||
|
@ -229,12 +231,14 @@ class PollRequestFlowTest extends FlowTestCase<PollRequestFlow> {
|
||||||
void testSuccess_hostDelete() throws Exception {
|
void testSuccess_hostDelete() throws Exception {
|
||||||
// Host delete poll messages do not have any response data, so ensure that no
|
// Host delete poll messages do not have any response data, so ensure that no
|
||||||
// response data block is produced in the poll message.
|
// response data block is produced in the poll message.
|
||||||
HistoryEntry historyEntry = persistResource(new HistoryEntry.Builder()
|
HistoryEntry historyEntry =
|
||||||
.setClientId("NewRegistrar")
|
persistResource(
|
||||||
.setModificationTime(clock.nowUtc().minusDays(1))
|
new HistoryEntry.Builder()
|
||||||
.setType(HistoryEntry.Type.HOST_DELETE)
|
.setClientId("NewRegistrar")
|
||||||
.setParent(host)
|
.setModificationTime(clock.nowUtc().minusDays(1))
|
||||||
.build());
|
.setType(HistoryEntry.Type.HOST_DELETE)
|
||||||
|
.setParent(host)
|
||||||
|
.build());
|
||||||
persistResource(
|
persistResource(
|
||||||
new PollMessage.OneTime.Builder()
|
new PollMessage.OneTime.Builder()
|
||||||
.setClientId("NewRegistrar")
|
.setClientId("NewRegistrar")
|
||||||
|
|
|
@ -80,10 +80,22 @@ class ChildEntityInputTest {
|
||||||
domainA = persistEppResourceInFirstBucket(newDomainBase("a.tld", contact));
|
domainA = persistEppResourceInFirstBucket(newDomainBase("a.tld", contact));
|
||||||
domainHistoryEntryA =
|
domainHistoryEntryA =
|
||||||
persistResource(
|
persistResource(
|
||||||
new DomainHistory.Builder().setDomain(domainA).setModificationTime(now).build());
|
new DomainHistory.Builder()
|
||||||
|
.setDomain(domainA)
|
||||||
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
|
.setDomain(domainA)
|
||||||
|
.setModificationTime(now)
|
||||||
|
.setClientId(domainA.getCreationClientId())
|
||||||
|
.build());
|
||||||
contactHistoryEntry =
|
contactHistoryEntry =
|
||||||
persistResource(
|
persistResource(
|
||||||
new ContactHistory.Builder().setContact(contact).setModificationTime(now).build());
|
new ContactHistory.Builder()
|
||||||
|
.setContact(contact)
|
||||||
|
.setType(HistoryEntry.Type.CONTACT_CREATE)
|
||||||
|
.setContact(contact)
|
||||||
|
.setModificationTime(now)
|
||||||
|
.setClientId(contact.getCreationClientId())
|
||||||
|
.build());
|
||||||
oneTimeA =
|
oneTimeA =
|
||||||
persistResource(
|
persistResource(
|
||||||
new BillingEvent.OneTime.Builder()
|
new BillingEvent.OneTime.Builder()
|
||||||
|
@ -113,7 +125,13 @@ class ChildEntityInputTest {
|
||||||
domainB = persistEppResourceInFirstBucket(newDomainBase("b.tld"));
|
domainB = persistEppResourceInFirstBucket(newDomainBase("b.tld"));
|
||||||
domainHistoryEntryB =
|
domainHistoryEntryB =
|
||||||
persistResource(
|
persistResource(
|
||||||
new DomainHistory.Builder().setDomain(domainB).setModificationTime(now).build());
|
new DomainHistory.Builder()
|
||||||
|
.setDomain(domainB)
|
||||||
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
|
.setDomain(domainB)
|
||||||
|
.setModificationTime(now)
|
||||||
|
.setClientId(domainB.getCreationClientId())
|
||||||
|
.build());
|
||||||
oneTimeB =
|
oneTimeB =
|
||||||
persistResource(
|
persistResource(
|
||||||
new BillingEvent.OneTime.Builder()
|
new BillingEvent.OneTime.Builder()
|
||||||
|
@ -295,8 +313,9 @@ class ChildEntityInputTest {
|
||||||
persistResource(
|
persistResource(
|
||||||
new DomainHistory.Builder()
|
new DomainHistory.Builder()
|
||||||
.setDomain(domain)
|
.setDomain(domain)
|
||||||
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
.setModificationTime(now)
|
.setModificationTime(now)
|
||||||
.setClientId(i + ".tld")
|
.setClientId(domain.getCreationClientId())
|
||||||
.build())
|
.build())
|
||||||
.asHistoryEntry());
|
.asHistoryEntry());
|
||||||
persistResource(EppResourceIndex.create(getBucketKey(i), Key.create(domain)));
|
persistResource(EppResourceIndex.create(getBucketKey(i), Key.create(domain)));
|
||||||
|
|
|
@ -80,6 +80,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
.setDomain(domain)
|
.setDomain(domain)
|
||||||
.setModificationTime(now)
|
.setModificationTime(now)
|
||||||
.setRequestedByRegistrar(false)
|
.setRequestedByRegistrar(false)
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
.setXmlBytes(new byte[0])
|
.setXmlBytes(new byte[0])
|
||||||
.build());
|
.build());
|
||||||
|
@ -89,6 +90,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
.setDomain(domain)
|
.setDomain(domain)
|
||||||
.setModificationTime(now.plusDays(1))
|
.setModificationTime(now.plusDays(1))
|
||||||
.setRequestedByRegistrar(false)
|
.setRequestedByRegistrar(false)
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
.setXmlBytes(new byte[0])
|
.setXmlBytes(new byte[0])
|
||||||
.build());
|
.build());
|
||||||
|
|
|
@ -443,7 +443,7 @@ public class DomainBaseSqlTest {
|
||||||
.setModificationTime(DateTime.now(UTC))
|
.setModificationTime(DateTime.now(UTC))
|
||||||
.setParent(Key.create(DomainBase.class, "4-COM"))
|
.setParent(Key.create(DomainBase.class, "4-COM"))
|
||||||
.setDomainRepoId("4-COM")
|
.setDomainRepoId("4-COM")
|
||||||
|
.setClientId("registrar1")
|
||||||
// These are non-null, but I don't think some tests set them.
|
// These are non-null, but I don't think some tests set them.
|
||||||
.setReason("felt like it")
|
.setReason("felt like it")
|
||||||
.setRequestedByRegistrar(false)
|
.setRequestedByRegistrar(false)
|
||||||
|
@ -574,7 +574,7 @@ public class DomainBaseSqlTest {
|
||||||
.setModificationTime(DateTime.now(UTC))
|
.setModificationTime(DateTime.now(UTC))
|
||||||
.setParent(Key.create(DomainBase.class, "4-COM"))
|
.setParent(Key.create(DomainBase.class, "4-COM"))
|
||||||
.setDomainRepoId("4-COM")
|
.setDomainRepoId("4-COM")
|
||||||
|
.setClientId("registrar1")
|
||||||
// These are non-null, but I don't think some tests set them.
|
// These are non-null, but I don't think some tests set them.
|
||||||
.setReason("felt like it")
|
.setReason("felt like it")
|
||||||
.setRequestedByRegistrar(false)
|
.setRequestedByRegistrar(false)
|
||||||
|
|
|
@ -63,6 +63,7 @@ import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/** Unit tests for {@link DomainBase}. */
|
/** Unit tests for {@link DomainBase}. */
|
||||||
|
@SuppressWarnings("WeakerAccess") // Referred to by EppInputTest.
|
||||||
public class DomainBaseTest extends EntityTestCase {
|
public class DomainBaseTest extends EntityTestCase {
|
||||||
|
|
||||||
private DomainBase domain;
|
private DomainBase domain;
|
||||||
|
@ -98,7 +99,13 @@ public class DomainBaseTest extends EntityTestCase {
|
||||||
.createVKey();
|
.createVKey();
|
||||||
historyEntryKey =
|
historyEntryKey =
|
||||||
Key.create(
|
Key.create(
|
||||||
persistResource(new HistoryEntry.Builder().setParent(domainKey.getOfyKey()).build()));
|
persistResource(
|
||||||
|
new HistoryEntry.Builder()
|
||||||
|
.setParent(domainKey.getOfyKey())
|
||||||
|
.setModificationTime(fakeClock.nowUtc())
|
||||||
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
|
.setClientId("aregistrar")
|
||||||
|
.build()));
|
||||||
oneTimeBillKey = VKey.from(Key.create(historyEntryKey, BillingEvent.OneTime.class, 1));
|
oneTimeBillKey = VKey.from(Key.create(historyEntryKey, BillingEvent.OneTime.class, 1));
|
||||||
recurringBillKey = VKey.from(Key.create(historyEntryKey, BillingEvent.Recurring.class, 2));
|
recurringBillKey = VKey.from(Key.create(historyEntryKey, BillingEvent.Recurring.class, 2));
|
||||||
VKey<PollMessage.Autorenew> autorenewPollKey =
|
VKey<PollMessage.Autorenew> autorenewPollKey =
|
||||||
|
@ -112,7 +119,7 @@ public class DomainBaseTest extends EntityTestCase {
|
||||||
new DomainBase.Builder()
|
new DomainBase.Builder()
|
||||||
.setDomainName("example.com")
|
.setDomainName("example.com")
|
||||||
.setRepoId("4-COM")
|
.setRepoId("4-COM")
|
||||||
.setCreationClientId("a registrar")
|
.setCreationClientId("aregistrar")
|
||||||
.setLastEppUpdateTime(fakeClock.nowUtc())
|
.setLastEppUpdateTime(fakeClock.nowUtc())
|
||||||
.setLastEppUpdateClientId("AnotherRegistrar")
|
.setLastEppUpdateClientId("AnotherRegistrar")
|
||||||
.setLastTransferTime(fakeClock.nowUtc())
|
.setLastTransferTime(fakeClock.nowUtc())
|
||||||
|
@ -356,7 +363,13 @@ public class DomainBaseTest extends EntityTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doExpiredTransferTest(DateTime oldExpirationTime) {
|
private void doExpiredTransferTest(DateTime oldExpirationTime) {
|
||||||
HistoryEntry historyEntry = new HistoryEntry.Builder().setParent(domain).build();
|
HistoryEntry historyEntry =
|
||||||
|
new HistoryEntry.Builder()
|
||||||
|
.setParent(domain)
|
||||||
|
.setModificationTime(fakeClock.nowUtc())
|
||||||
|
.setClientId(domain.getCurrentSponsorClientId())
|
||||||
|
.setType(HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST)
|
||||||
|
.build();
|
||||||
BillingEvent.OneTime transferBillingEvent =
|
BillingEvent.OneTime transferBillingEvent =
|
||||||
persistResource(
|
persistResource(
|
||||||
new BillingEvent.OneTime.Builder()
|
new BillingEvent.OneTime.Builder()
|
||||||
|
|
|
@ -71,8 +71,9 @@ public class OfyTest {
|
||||||
createTld("tld");
|
createTld("tld");
|
||||||
someObject =
|
someObject =
|
||||||
new HistoryEntry.Builder()
|
new HistoryEntry.Builder()
|
||||||
.setClientId("client id")
|
.setClientId("clientid")
|
||||||
.setModificationTime(START_OF_TIME)
|
.setModificationTime(START_OF_TIME)
|
||||||
|
.setType(HistoryEntry.Type.CONTACT_CREATE)
|
||||||
.setParent(persistActiveContact("parentContact"))
|
.setParent(persistActiveContact("parentContact"))
|
||||||
.setTrid(Trid.create("client", "server"))
|
.setTrid(Trid.create("client", "server"))
|
||||||
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
|
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
package google.registry.model.reporting;
|
package google.registry.model.reporting;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||||
import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm;
|
import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm;
|
||||||
|
@ -21,6 +22,7 @@ import static google.registry.testing.DatabaseHelper.createTld;
|
||||||
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
import static org.junit.Assert.assertThrows;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
@ -33,6 +35,7 @@ import google.registry.model.reporting.DomainTransactionRecord.TransactionReport
|
||||||
import google.registry.testing.DualDatabaseTest;
|
import google.registry.testing.DualDatabaseTest;
|
||||||
import google.registry.testing.TestOfyAndSql;
|
import google.registry.testing.TestOfyAndSql;
|
||||||
import google.registry.testing.TestOfyOnly;
|
import google.registry.testing.TestOfyOnly;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
|
||||||
/** Unit tests for {@link HistoryEntry}. */
|
/** Unit tests for {@link HistoryEntry}. */
|
||||||
|
@ -87,6 +90,70 @@ class HistoryEntryTest extends EntityTestCase {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestOfyAndSql
|
||||||
|
void testBuilder_typeMustBeSpecified() {
|
||||||
|
IllegalArgumentException thrown =
|
||||||
|
assertThrows(
|
||||||
|
IllegalArgumentException.class,
|
||||||
|
() ->
|
||||||
|
new HistoryEntry.Builder()
|
||||||
|
.setId(5L)
|
||||||
|
.setModificationTime(DateTime.parse("1985-07-12T22:30:00Z"))
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
|
.setReason("Reason")
|
||||||
|
.build());
|
||||||
|
assertThat(thrown).hasMessageThat().isEqualTo("History entry type must be specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestOfyAndSql
|
||||||
|
void testBuilder_modificationTimeMustBeSpecified() {
|
||||||
|
IllegalArgumentException thrown =
|
||||||
|
assertThrows(
|
||||||
|
IllegalArgumentException.class,
|
||||||
|
() ->
|
||||||
|
new HistoryEntry.Builder()
|
||||||
|
.setId(5L)
|
||||||
|
.setType(HistoryEntry.Type.CONTACT_CREATE)
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
|
.setReason("Reason")
|
||||||
|
.build());
|
||||||
|
assertThat(thrown).hasMessageThat().isEqualTo("Modification time must be specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestOfyAndSql
|
||||||
|
void testBuilder_registrarIdMustBeSpecified() {
|
||||||
|
IllegalArgumentException thrown =
|
||||||
|
assertThrows(
|
||||||
|
IllegalArgumentException.class,
|
||||||
|
() ->
|
||||||
|
new HistoryEntry.Builder()
|
||||||
|
.setId(5L)
|
||||||
|
.setType(HistoryEntry.Type.CONTACT_CREATE)
|
||||||
|
.setModificationTime(DateTime.parse("1985-07-12T22:30:00Z"))
|
||||||
|
.setReason("Reason")
|
||||||
|
.build());
|
||||||
|
assertThat(thrown).hasMessageThat().isEqualTo("Registrar ID must be specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestOfyAndSql
|
||||||
|
void testBuilder_syntheticHistoryEntries_mustNotBeRequestedByRegistrar() {
|
||||||
|
IllegalArgumentException thrown =
|
||||||
|
assertThrows(
|
||||||
|
IllegalArgumentException.class,
|
||||||
|
() ->
|
||||||
|
new HistoryEntry.Builder()
|
||||||
|
.setId(5L)
|
||||||
|
.setType(HistoryEntry.Type.SYNTHETIC)
|
||||||
|
.setModificationTime(DateTime.parse("1985-07-12T22:30:00Z"))
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
|
.setReason("Reason")
|
||||||
|
.setRequestedByRegistrar(true)
|
||||||
|
.build());
|
||||||
|
assertThat(thrown)
|
||||||
|
.hasMessageThat()
|
||||||
|
.isEqualTo("Synthetic history entries cannot be requested by a registrar");
|
||||||
|
}
|
||||||
|
|
||||||
@TestOfyOnly
|
@TestOfyOnly
|
||||||
void testIndexing() throws Exception {
|
void testIndexing() throws Exception {
|
||||||
verifyIndexing(domainHistory.asHistoryEntry(), "modificationTime", "clientId");
|
verifyIndexing(domainHistory.asHistoryEntry(), "modificationTime", "clientId");
|
||||||
|
|
|
@ -225,6 +225,7 @@ public class DomainBaseToXjcConverterTest {
|
||||||
.setModificationTime(clock.nowUtc())
|
.setModificationTime(clock.nowUtc())
|
||||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
.setDomain(domain)
|
.setDomain(domain)
|
||||||
|
.setClientId(domain.getCreationClientId())
|
||||||
.build());
|
.build());
|
||||||
BillingEvent.OneTime billingEvent =
|
BillingEvent.OneTime billingEvent =
|
||||||
persistResource(
|
persistResource(
|
||||||
|
|
|
@ -66,7 +66,13 @@ final class RdeFixtures {
|
||||||
.createVKey())
|
.createVKey())
|
||||||
.build();
|
.build();
|
||||||
HistoryEntry historyEntry =
|
HistoryEntry historyEntry =
|
||||||
persistResource(new HistoryEntry.Builder().setParent(domain).build());
|
persistResource(
|
||||||
|
new HistoryEntry.Builder()
|
||||||
|
.setParent(domain)
|
||||||
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
|
.setModificationTime(clock.nowUtc())
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
|
.build());
|
||||||
clock.advanceOneMilli();
|
clock.advanceOneMilli();
|
||||||
BillingEvent.OneTime billingEvent =
|
BillingEvent.OneTime billingEvent =
|
||||||
persistResourceWithCommitLog(
|
persistResourceWithCommitLog(
|
||||||
|
|
|
@ -545,6 +545,7 @@ public class DatabaseHelper {
|
||||||
.setType(HistoryEntry.Type.CONTACT_TRANSFER_REQUEST)
|
.setType(HistoryEntry.Type.CONTACT_TRANSFER_REQUEST)
|
||||||
.setParent(persistResource(contact))
|
.setParent(persistResource(contact))
|
||||||
.setModificationTime(now)
|
.setModificationTime(now)
|
||||||
|
.setClientId(contact.getCurrentSponsorClientId())
|
||||||
.build()
|
.build()
|
||||||
.toChildHistoryEntity());
|
.toChildHistoryEntity());
|
||||||
return persistResource(
|
return persistResource(
|
||||||
|
@ -616,6 +617,7 @@ public class DatabaseHelper {
|
||||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
.setModificationTime(now)
|
.setModificationTime(now)
|
||||||
.setDomain(domain)
|
.setDomain(domain)
|
||||||
|
.setClientId(domain.getCreationClientId())
|
||||||
.build());
|
.build());
|
||||||
BillingEvent.Recurring autorenewEvent =
|
BillingEvent.Recurring autorenewEvent =
|
||||||
persistResource(
|
persistResource(
|
||||||
|
@ -657,6 +659,7 @@ public class DatabaseHelper {
|
||||||
.setType(HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST)
|
.setType(HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST)
|
||||||
.setModificationTime(tm().transact(() -> tm().getTransactionTime()))
|
.setModificationTime(tm().transact(() -> tm().getTransactionTime()))
|
||||||
.setDomain(domain)
|
.setDomain(domain)
|
||||||
|
.setClientId("TheRegistrar")
|
||||||
.build());
|
.build());
|
||||||
BillingEvent.OneTime transferBillingEvent =
|
BillingEvent.OneTime transferBillingEvent =
|
||||||
persistResource(
|
persistResource(
|
||||||
|
@ -1085,7 +1088,7 @@ public class DatabaseHelper {
|
||||||
tm().put(
|
tm().put(
|
||||||
new HistoryEntry.Builder()
|
new HistoryEntry.Builder()
|
||||||
.setParent(resource)
|
.setParent(resource)
|
||||||
.setClientId(resource.getPersistedCurrentSponsorClientId())
|
.setClientId(resource.getCreationClientId())
|
||||||
.setType(getHistoryEntryType(resource))
|
.setType(getHistoryEntryType(resource))
|
||||||
.setModificationTime(tm().getTransactionTime())
|
.setModificationTime(tm().getTransactionTime())
|
||||||
.build()
|
.build()
|
||||||
|
|
|
@ -62,6 +62,7 @@ public class AckPollMessagesCommandTest extends CommandTestCase<AckPollMessagesC
|
||||||
new DomainHistory.Builder()
|
new DomainHistory.Builder()
|
||||||
.setModificationTime(clock.nowUtc())
|
.setModificationTime(clock.nowUtc())
|
||||||
.setDomainRepoId(domain.getRepoId())
|
.setDomainRepoId(domain.getRepoId())
|
||||||
|
.setClientId(domain.getCreationClientId())
|
||||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
.setId(2406L)
|
.setId(2406L)
|
||||||
.build());
|
.build());
|
||||||
|
|
|
@ -1,258 +0,0 @@
|
||||||
// Copyright 2020 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.tools;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
|
||||||
import static google.registry.model.ofy.ObjectifyService.auditedOfy;
|
|
||||||
import static google.registry.testing.DatabaseHelper.createTld;
|
|
||||||
import static google.registry.testing.DatabaseHelper.loadByEntity;
|
|
||||||
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
|
||||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
|
||||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
|
||||||
import static org.joda.money.CurrencyUnit.USD;
|
|
||||||
import static org.joda.time.DateTimeZone.UTC;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import google.registry.model.ImmutableObject;
|
|
||||||
import google.registry.model.billing.BillingEvent;
|
|
||||||
import google.registry.model.billing.BillingEvent.Flag;
|
|
||||||
import google.registry.model.billing.BillingEvent.Reason;
|
|
||||||
import google.registry.model.domain.DomainBase;
|
|
||||||
import google.registry.model.domain.GracePeriod;
|
|
||||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
|
||||||
import google.registry.model.transfer.DomainTransferData;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import org.joda.money.Money;
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
/** Unit tests for {@link DedupeRecurringBillingEventIdsCommand}. */
|
|
||||||
class DedupeRecurringBillingEventIdsCommandTest
|
|
||||||
extends CommandTestCase<DedupeRecurringBillingEventIdsCommand> {
|
|
||||||
|
|
||||||
private final DateTime now = DateTime.now(UTC);
|
|
||||||
private DomainBase domain1;
|
|
||||||
private DomainBase domain2;
|
|
||||||
private HistoryEntry historyEntry1;
|
|
||||||
private HistoryEntry historyEntry2;
|
|
||||||
private BillingEvent.Recurring recurring1;
|
|
||||||
private BillingEvent.Recurring recurring2;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void beforeEach() {
|
|
||||||
createTld("tld");
|
|
||||||
domain1 = persistActiveDomain("foo.tld");
|
|
||||||
domain2 = persistActiveDomain("bar.tld");
|
|
||||||
historyEntry1 =
|
|
||||||
persistResource(
|
|
||||||
new HistoryEntry.Builder().setParent(domain1).setModificationTime(now).build());
|
|
||||||
historyEntry2 =
|
|
||||||
persistResource(
|
|
||||||
new HistoryEntry.Builder()
|
|
||||||
.setParent(domain2)
|
|
||||||
.setModificationTime(now.plusDays(1))
|
|
||||||
.build());
|
|
||||||
recurring1 =
|
|
||||||
persistResource(
|
|
||||||
new BillingEvent.Recurring.Builder()
|
|
||||||
.setParent(historyEntry1)
|
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
|
||||||
.setReason(Reason.RENEW)
|
|
||||||
.setEventTime(now.plusYears(1))
|
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
|
||||||
.setClientId("a registrar")
|
|
||||||
.setTargetId("foo.tld")
|
|
||||||
.build());
|
|
||||||
recurring2 =
|
|
||||||
persistResource(
|
|
||||||
new BillingEvent.Recurring.Builder()
|
|
||||||
.setId(recurring1.getId())
|
|
||||||
.setParent(historyEntry2)
|
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
|
||||||
.setReason(Reason.RENEW)
|
|
||||||
.setEventTime(now.plusYears(1))
|
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
|
||||||
.setClientId("a registrar")
|
|
||||||
.setTargetId("bar.tld")
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOnlyResaveBillingEventsCorrectly() throws Exception {
|
|
||||||
assertThat(recurring1.getId()).isEqualTo(recurring2.getId());
|
|
||||||
|
|
||||||
runCommand(
|
|
||||||
"--force",
|
|
||||||
"--key_paths_file",
|
|
||||||
writeToNamedTmpFile("keypath.txt", getKeyPathLiteral(recurring1, recurring2)));
|
|
||||||
|
|
||||||
assertNotChangeExceptUpdateTime(domain1, domain2, historyEntry1, historyEntry2);
|
|
||||||
assertNotInDatastore(recurring1, recurring2);
|
|
||||||
|
|
||||||
ImmutableList<BillingEvent.Recurring> recurrings = loadAllRecurrings();
|
|
||||||
assertThat(recurrings.size()).isEqualTo(2);
|
|
||||||
|
|
||||||
recurrings.forEach(
|
|
||||||
newRecurring -> {
|
|
||||||
if (newRecurring.getTargetId().equals("foo.tld")) {
|
|
||||||
assertSameRecurringEntityExceptId(newRecurring, recurring1);
|
|
||||||
} else if (newRecurring.getTargetId().equals("bar.tld")) {
|
|
||||||
assertSameRecurringEntityExceptId(newRecurring, recurring2);
|
|
||||||
} else {
|
|
||||||
fail("Unknown BillingEvent.Recurring entity: " + newRecurring.createVKey());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testResaveAssociatedDomainAndOneTimeBillingEventCorrectly() throws Exception {
|
|
||||||
assertThat(recurring1.getId()).isEqualTo(recurring2.getId());
|
|
||||||
GracePeriod gracePeriod =
|
|
||||||
GracePeriod.createForRecurring(
|
|
||||||
GracePeriodStatus.AUTO_RENEW,
|
|
||||||
domain1.getRepoId(),
|
|
||||||
now.plusDays(45),
|
|
||||||
"a registrar",
|
|
||||||
recurring1.createVKey());
|
|
||||||
domain1 =
|
|
||||||
persistResource(
|
|
||||||
domain1
|
|
||||||
.asBuilder()
|
|
||||||
.setAutorenewBillingEvent(recurring1.createVKey())
|
|
||||||
.setGracePeriods(ImmutableSet.of(gracePeriod))
|
|
||||||
.setTransferData(
|
|
||||||
new DomainTransferData.Builder()
|
|
||||||
.setServerApproveAutorenewEvent(recurring1.createVKey())
|
|
||||||
.setServerApproveEntities(ImmutableSet.of(recurring1.createVKey()))
|
|
||||||
.build())
|
|
||||||
.build());
|
|
||||||
|
|
||||||
BillingEvent.OneTime oneTime =
|
|
||||||
persistResource(
|
|
||||||
new BillingEvent.OneTime.Builder()
|
|
||||||
.setClientId("a registrar")
|
|
||||||
.setTargetId("foo.tld")
|
|
||||||
.setParent(historyEntry1)
|
|
||||||
.setReason(Reason.CREATE)
|
|
||||||
.setFlags(ImmutableSet.of(Flag.SYNTHETIC))
|
|
||||||
.setSyntheticCreationTime(now)
|
|
||||||
.setPeriodYears(2)
|
|
||||||
.setCost(Money.of(USD, 1))
|
|
||||||
.setEventTime(now)
|
|
||||||
.setBillingTime(now.plusDays(5))
|
|
||||||
.setCancellationMatchingBillingEvent(recurring1.createVKey())
|
|
||||||
.build());
|
|
||||||
|
|
||||||
runCommand(
|
|
||||||
"--force",
|
|
||||||
"--key_paths_file",
|
|
||||||
writeToNamedTmpFile("keypath.txt", getKeyPathLiteral(recurring1, recurring2)));
|
|
||||||
|
|
||||||
assertNotChangeExceptUpdateTime(domain2, historyEntry1, historyEntry2);
|
|
||||||
assertNotInDatastore(recurring1, recurring2);
|
|
||||||
ImmutableList<BillingEvent.Recurring> recurrings = loadAllRecurrings();
|
|
||||||
assertThat(recurrings.size()).isEqualTo(2);
|
|
||||||
|
|
||||||
recurrings.forEach(
|
|
||||||
newRecurring -> {
|
|
||||||
if (newRecurring.getTargetId().equals("foo.tld")) {
|
|
||||||
assertSameRecurringEntityExceptId(newRecurring, recurring1);
|
|
||||||
|
|
||||||
BillingEvent.OneTime persistedOneTime = auditedOfy().load().entity(oneTime).now();
|
|
||||||
assertAboutImmutableObjects()
|
|
||||||
.that(persistedOneTime)
|
|
||||||
.isEqualExceptFields(oneTime, "cancellationMatchingBillingEvent");
|
|
||||||
assertThat(persistedOneTime.getCancellationMatchingBillingEvent())
|
|
||||||
.isEqualTo(newRecurring.createVKey());
|
|
||||||
|
|
||||||
DomainBase persistedDomain = auditedOfy().load().entity(domain1).now();
|
|
||||||
assertAboutImmutableObjects()
|
|
||||||
.that(persistedDomain)
|
|
||||||
.isEqualExceptFields(
|
|
||||||
domain1,
|
|
||||||
"updateTimestamp",
|
|
||||||
"revisions",
|
|
||||||
"gracePeriods",
|
|
||||||
"transferData",
|
|
||||||
"autorenewBillingEvent");
|
|
||||||
assertThat(persistedDomain.getAutorenewBillingEvent())
|
|
||||||
.isEqualTo(newRecurring.createVKey());
|
|
||||||
assertThat(persistedDomain.getGracePeriods())
|
|
||||||
.containsExactly(
|
|
||||||
GracePeriod.createForRecurring(
|
|
||||||
GracePeriodStatus.AUTO_RENEW,
|
|
||||||
domain1.getRepoId(),
|
|
||||||
now.plusDays(45),
|
|
||||||
"a registrar",
|
|
||||||
newRecurring.createVKey(),
|
|
||||||
gracePeriod.getGracePeriodId()));
|
|
||||||
assertThat(persistedDomain.getTransferData().getServerApproveAutorenewEvent())
|
|
||||||
.isEqualTo(newRecurring.createVKey());
|
|
||||||
assertThat(persistedDomain.getTransferData().getServerApproveEntities())
|
|
||||||
.containsExactly(newRecurring.createVKey());
|
|
||||||
|
|
||||||
} else if (newRecurring.getTargetId().equals("bar.tld")) {
|
|
||||||
assertSameRecurringEntityExceptId(newRecurring, recurring2);
|
|
||||||
} else {
|
|
||||||
fail("Unknown BillingEvent.Recurring entity: " + newRecurring.createVKey());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void assertNotInDatastore(ImmutableObject... entities) {
|
|
||||||
for (ImmutableObject entity : entities) {
|
|
||||||
assertThat(auditedOfy().load().entity(entity).now()).isNull();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void assertNotChangeExceptUpdateTime(ImmutableObject... entities) {
|
|
||||||
for (ImmutableObject entity : entities) {
|
|
||||||
assertAboutImmutableObjects()
|
|
||||||
.that(loadByEntity(entity))
|
|
||||||
.isEqualExceptFields(entity, "updateTimestamp", "revisions");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void assertSameRecurringEntityExceptId(
|
|
||||||
BillingEvent.Recurring recurring1, BillingEvent.Recurring recurring2) {
|
|
||||||
assertAboutImmutableObjects().that(recurring1).isEqualExceptFields(recurring2, "id");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ImmutableList<BillingEvent.Recurring> loadAllRecurrings() {
|
|
||||||
return ImmutableList.copyOf(auditedOfy().load().type(BillingEvent.Recurring.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getKeyPathLiteral(Object... entities) {
|
|
||||||
return Arrays.stream(entities)
|
|
||||||
.map(
|
|
||||||
entity -> {
|
|
||||||
Key<?> key = Key.create(entity);
|
|
||||||
return String.format(
|
|
||||||
"\"DomainBase\", \"%s\", \"HistoryEntry\", %s, \"%s\", %s",
|
|
||||||
key.getParent().getParent().getName(),
|
|
||||||
key.getParent().getId(),
|
|
||||||
key.getKind(),
|
|
||||||
key.getId());
|
|
||||||
})
|
|
||||||
.reduce((k1, k2) -> k1 + "\n" + k2)
|
|
||||||
.get();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -299,6 +299,7 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
|
||||||
.setModificationTime(fakeClock.nowUtc())
|
.setModificationTime(fakeClock.nowUtc())
|
||||||
.setType(DOMAIN_CREATE)
|
.setType(DOMAIN_CREATE)
|
||||||
.setDomain(domain)
|
.setDomain(domain)
|
||||||
|
.setClientId(domain.getCreationClientId())
|
||||||
.build());
|
.build());
|
||||||
BillingEvent.Recurring autorenewBillingEvent =
|
BillingEvent.Recurring autorenewBillingEvent =
|
||||||
persistResource(
|
persistResource(
|
||||||
|
|
|
@ -31,6 +31,7 @@ import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
import com.google.appengine.api.datastore.Entity;
|
import com.google.appengine.api.datastore.Entity;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
@ -82,47 +83,65 @@ class KillAllEppResourcesActionTest extends MapreduceTestCase<KillAllEppResource
|
||||||
executeTasksUntilEmpty("mapreduce");
|
executeTasksUntilEmpty("mapreduce");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final ImmutableMap<Class<? extends EppResource>, HistoryEntry.Type>
|
||||||
|
HISTORY_ENTRY_CREATE_TYPES =
|
||||||
|
ImmutableMap.of(
|
||||||
|
DomainBase.class,
|
||||||
|
HistoryEntry.Type.DOMAIN_CREATE,
|
||||||
|
ContactResource.class,
|
||||||
|
HistoryEntry.Type.CONTACT_CREATE,
|
||||||
|
HostResource.class,
|
||||||
|
HistoryEntry.Type.HOST_CREATE);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testKill() throws Exception {
|
void testKill() throws Exception {
|
||||||
createTld("tld1");
|
createTld("tld1");
|
||||||
createTld("tld2");
|
createTld("tld2");
|
||||||
for (EppResource resource : asList(
|
for (EppResource resource :
|
||||||
persistActiveDomain("foo.tld1"),
|
asList(
|
||||||
persistActiveDomain("foo.tld2"),
|
persistActiveDomain("foo.tld1"),
|
||||||
persistActiveContact("foo"),
|
persistActiveDomain("foo.tld2"),
|
||||||
persistActiveContact("foo"),
|
persistActiveContact("foo"),
|
||||||
persistActiveHost("ns.foo.tld1"),
|
persistActiveContact("foo"),
|
||||||
persistActiveHost("ns.foo.tld2"))) {
|
persistActiveHost("ns.foo.tld1"),
|
||||||
HistoryEntry history = new HistoryEntry.Builder().setParent(resource).build();
|
persistActiveHost("ns.foo.tld2"))) {
|
||||||
for (ImmutableObject descendant : asList(
|
HistoryEntry history =
|
||||||
history,
|
new HistoryEntry.Builder()
|
||||||
new PollMessage.OneTime.Builder()
|
.setParent(resource)
|
||||||
.setParent(history)
|
.setClientId(resource.getCreationClientId())
|
||||||
.setClientId("")
|
.setModificationTime(resource.getCreationTime())
|
||||||
.setEventTime(START_OF_TIME)
|
.setType(HISTORY_ENTRY_CREATE_TYPES.get(resource.getClass()))
|
||||||
.build(),
|
.build();
|
||||||
new PollMessage.Autorenew.Builder()
|
for (ImmutableObject descendant :
|
||||||
.setParent(history)
|
asList(
|
||||||
.setClientId("")
|
history,
|
||||||
.setEventTime(START_OF_TIME)
|
new PollMessage.OneTime.Builder()
|
||||||
.build(),
|
.setParent(history)
|
||||||
new BillingEvent.OneTime.Builder()
|
.setClientId("")
|
||||||
.setParent(history)
|
.setEventTime(START_OF_TIME)
|
||||||
.setBillingTime(START_OF_TIME)
|
.build(),
|
||||||
.setEventTime(START_OF_TIME)
|
new PollMessage.Autorenew.Builder()
|
||||||
.setClientId("")
|
.setParent(history)
|
||||||
.setTargetId("")
|
.setClientId("")
|
||||||
.setReason(Reason.CREATE)
|
.setEventTime(START_OF_TIME)
|
||||||
.setPeriodYears(1)
|
.build(),
|
||||||
.setCost(Money.of(CurrencyUnit.USD, 1))
|
new BillingEvent.OneTime.Builder()
|
||||||
.build(),
|
.setParent(history)
|
||||||
new BillingEvent.Recurring.Builder()
|
.setBillingTime(START_OF_TIME)
|
||||||
.setParent(history)
|
.setEventTime(START_OF_TIME)
|
||||||
.setEventTime(START_OF_TIME)
|
.setClientId("")
|
||||||
.setClientId("")
|
.setTargetId("")
|
||||||
.setTargetId("")
|
.setReason(Reason.CREATE)
|
||||||
.setReason(Reason.RENEW)
|
.setPeriodYears(1)
|
||||||
.build())) {
|
.setCost(Money.of(CurrencyUnit.USD, 1))
|
||||||
|
.build(),
|
||||||
|
new BillingEvent.Recurring.Builder()
|
||||||
|
.setParent(history)
|
||||||
|
.setEventTime(START_OF_TIME)
|
||||||
|
.setClientId("")
|
||||||
|
.setTargetId("")
|
||||||
|
.setReason(Reason.RENEW)
|
||||||
|
.build())) {
|
||||||
persistResource(descendant);
|
persistResource(descendant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,9 +55,25 @@ class ResaveAllHistoryEntriesActionTest extends MapreduceTestCase<ResaveAllHisto
|
||||||
DomainBase domain = persistActiveDomain("test.tld");
|
DomainBase domain = persistActiveDomain("test.tld");
|
||||||
ContactResource contact = persistActiveContact("humanBeing");
|
ContactResource contact = persistActiveContact("humanBeing");
|
||||||
Entity domainEntry =
|
Entity domainEntry =
|
||||||
auditedOfy().save().toEntity(new HistoryEntry.Builder().setParent(domain).build());
|
auditedOfy()
|
||||||
|
.save()
|
||||||
|
.toEntity(
|
||||||
|
new HistoryEntry.Builder()
|
||||||
|
.setParent(domain)
|
||||||
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
|
.setModificationTime(domain.getCreationTime())
|
||||||
|
.setClientId(domain.getCreationClientId())
|
||||||
|
.build());
|
||||||
Entity contactEntry =
|
Entity contactEntry =
|
||||||
auditedOfy().save().toEntity(new HistoryEntry.Builder().setParent(contact).build());
|
auditedOfy()
|
||||||
|
.save()
|
||||||
|
.toEntity(
|
||||||
|
new HistoryEntry.Builder()
|
||||||
|
.setParent(contact)
|
||||||
|
.setType(HistoryEntry.Type.CONTACT_CREATE)
|
||||||
|
.setClientId(contact.getCreationClientId())
|
||||||
|
.setModificationTime(contact.getCreationTime())
|
||||||
|
.build());
|
||||||
|
|
||||||
// Set raw properties outside the Objectify schema, which will be deleted upon re-save.
|
// Set raw properties outside the Objectify schema, which will be deleted upon re-save.
|
||||||
domainEntry.setProperty("clientId", "validId");
|
domainEntry.setProperty("clientId", "validId");
|
||||||
|
|
Loading…
Add table
Reference in a new issue