mirror of
https://github.com/google/nomulus.git
synced 2025-04-30 03:57:51 +02:00
Use ReplaySpecializer to fix DomainBase replays (#991)
* Use ReplaySpecializer to fix DomainBase replays DomainBase currently has a number of ancillary objects that require a cascading delete that doesn't get propagated. Implement beforeSqlDelete() in DomainContent to delete these child entities. * Remove unnecessary Query variable * Fix rebase error
This commit is contained in:
parent
bd0c2a2b21
commit
1d01fabb3c
8 changed files with 85 additions and 19 deletions
|
@ -24,6 +24,7 @@ import static com.google.common.collect.Sets.intersection;
|
|||
import static google.registry.model.EppResourceUtils.projectResourceOntoBuilderAtTime;
|
||||
import static google.registry.model.EppResourceUtils.setAutomaticTransferSuccessProperties;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static google.registry.util.CollectionUtils.forceEmptyToNull;
|
||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
|
@ -378,6 +379,25 @@ public class DomainContent extends EppResource
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to delete grace periods and DelegationSignerData records prior to domain delete.
|
||||
*
|
||||
* <p>See {@link google.registry.schema.replay.ReplaySpecializer}.
|
||||
*/
|
||||
public static void beforeSqlDelete(VKey<DomainBase> key) {
|
||||
// Delete all grace periods associated with the domain.
|
||||
jpaTm()
|
||||
.getEntityManager()
|
||||
.createQuery("DELETE FROM GracePeriod WHERE domain_repo_id = :repo_id")
|
||||
.setParameter("repo_id", key.getSqlKey())
|
||||
.executeUpdate();
|
||||
jpaTm()
|
||||
.getEntityManager()
|
||||
.createQuery("DELETE FROM DelegationSignerData WHERE domain_repo_id = :repo_id")
|
||||
.setParameter("repo_id", key.getSqlKey())
|
||||
.executeUpdate();
|
||||
}
|
||||
|
||||
public static <T> VKey<T> restoreOfyFrom(Key<DomainBase> domainKey, VKey<T> key, Long historyId) {
|
||||
if (historyId == null) {
|
||||
// This is a legacy key (or a null key, in which case this works too)
|
||||
|
|
|
@ -25,6 +25,7 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
|
|||
import static google.registry.testing.DatabaseHelper.assertBillingEventsForResource;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.deleteResource;
|
||||
import static google.registry.testing.DatabaseHelper.getBillingEvents;
|
||||
import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType;
|
||||
import static google.registry.testing.DatabaseHelper.getOnlyPollMessage;
|
||||
import static google.registry.testing.DatabaseHelper.getPollMessages;
|
||||
|
@ -71,18 +72,25 @@ import google.registry.model.transfer.DomainTransferData;
|
|||
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.testing.ReplayExtension;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Duration;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
/** Unit tests for {@link DomainTransferApproveFlow}. */
|
||||
class DomainTransferApproveFlowTest
|
||||
extends DomainTransferFlowTestCase<DomainTransferApproveFlow, DomainBase> {
|
||||
|
||||
@Order(value = Order.DEFAULT - 2)
|
||||
@RegisterExtension
|
||||
final ReplayExtension replayExtension = ReplayExtension.createWithCompare(clock);
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
setEppInput("domain_transfer_approve.xml");
|
||||
|
@ -521,7 +529,24 @@ class DomainTransferApproveFlowTest
|
|||
|
||||
@Test
|
||||
void testFailure_nonexistentDomain() throws Exception {
|
||||
deleteResource(domain);
|
||||
Iterable<BillingEvent> billingEvents = getBillingEvents();
|
||||
Iterable<HistoryEntry> historyEntries = tm().loadAllOf(HistoryEntry.class);
|
||||
Iterable<PollMessage> pollMessages = tm().loadAllOf(PollMessage.class);
|
||||
tm().transact(
|
||||
() -> {
|
||||
deleteResource(domain);
|
||||
for (BillingEvent event : billingEvents) {
|
||||
deleteResource(event);
|
||||
}
|
||||
for (PollMessage pollMessage : pollMessages) {
|
||||
deleteResource(pollMessage);
|
||||
}
|
||||
deleteResource(subordinateHost);
|
||||
for (HistoryEntry hist : historyEntries) {
|
||||
deleteResource(hist);
|
||||
}
|
||||
});
|
||||
|
||||
ResourceDoesNotExistException thrown =
|
||||
assertThrows(
|
||||
ResourceDoesNotExistException.class,
|
||||
|
|
|
@ -766,7 +766,7 @@ public class DatabaseHelper {
|
|||
return newRegistrars.build();
|
||||
}
|
||||
|
||||
private static Iterable<BillingEvent> getBillingEvents() {
|
||||
public static Iterable<BillingEvent> getBillingEvents() {
|
||||
return transactIfJpaTm(
|
||||
() ->
|
||||
Iterables.concat(
|
||||
|
|
|
@ -261,11 +261,11 @@ td.section {
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">generated on</td>
|
||||
<td class="property_value">2021-02-25 19:33:39.25711</td>
|
||||
<td class="property_value">2021-03-04 16:08:40.773463</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">last flyway file</td>
|
||||
<td id="lastFlywayFile" class="property_value">V86__third_poll_message.sql</td>
|
||||
<td id="lastFlywayFile" class="property_value">V87__fix_super_domain_fk.sql</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -274,19 +274,19 @@ td.section {
|
|||
<svg viewbox="0.00 0.00 4221.44 2624.18" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="erDiagram" style="overflow: hidden; width: 100%; height: 800px"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 2620.18)">
|
||||
<title>SchemaCrawler_Diagram</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-2620.18 4217.44,-2620.18 4217.44,4 -4,4" />
|
||||
<text text-anchor="start" x="3952.94" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
<text text-anchor="start" x="3944.94" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
generated by
|
||||
</text>
|
||||
<text text-anchor="start" x="4035.94" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
<text text-anchor="start" x="4027.94" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
SchemaCrawler 16.10.1
|
||||
</text>
|
||||
<text text-anchor="start" x="3951.94" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
<text text-anchor="start" x="3943.94" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
generated on
|
||||
</text>
|
||||
<text text-anchor="start" x="4035.94" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
2021-02-25 19:33:39.25711
|
||||
<text text-anchor="start" x="4027.94" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
2021-03-04 16:08:40.773463
|
||||
</text>
|
||||
<polygon fill="none" stroke="#888888" points="3948.44,-4 3948.44,-44 4205.44,-44 4205.44,-4 3948.44,-4" /> <!-- allocationtoken_a08ccbef -->
|
||||
<polygon fill="none" stroke="#888888" points="3940.44,-4 3940.44,-44 4205.44,-44 4205.44,-4 3940.44,-4" /> <!-- allocationtoken_a08ccbef -->
|
||||
<g id="node1" class="node">
|
||||
<title>allocationtoken_a08ccbef</title>
|
||||
<polygon fill="#ebcef2" stroke="transparent" points="2538.5,-1071.68 2538.5,-1090.68 2691.5,-1090.68 2691.5,-1071.68 2538.5,-1071.68" />
|
||||
|
|
|
@ -261,11 +261,11 @@ td.section {
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">generated on</td>
|
||||
<td class="property_value">2021-02-25 19:33:37.35689</td>
|
||||
<td class="property_value">2021-03-04 16:08:38.771681</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">last flyway file</td>
|
||||
<td id="lastFlywayFile" class="property_value">V86__third_poll_message.sql</td>
|
||||
<td id="lastFlywayFile" class="property_value">V87__fix_super_domain_fk.sql</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -274,19 +274,19 @@ td.section {
|
|||
<svg viewbox="0.00 0.00 4820.18 4862.89" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="erDiagram" style="overflow: hidden; width: 100%; height: 800px"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 4858.89)">
|
||||
<title>SchemaCrawler_Diagram</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-4858.89 4816.18,-4858.89 4816.18,4 -4,4" />
|
||||
<text text-anchor="start" x="4551.68" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
<text text-anchor="start" x="4543.68" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
generated by
|
||||
</text>
|
||||
<text text-anchor="start" x="4634.68" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
<text text-anchor="start" x="4626.68" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
SchemaCrawler 16.10.1
|
||||
</text>
|
||||
<text text-anchor="start" x="4550.68" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
<text text-anchor="start" x="4542.68" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
generated on
|
||||
</text>
|
||||
<text text-anchor="start" x="4634.68" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
2021-02-25 19:33:37.35689
|
||||
<text text-anchor="start" x="4626.68" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||
2021-03-04 16:08:38.771681
|
||||
</text>
|
||||
<polygon fill="none" stroke="#888888" points="4547.18,-4 4547.18,-44 4804.18,-44 4804.18,-4 4547.18,-4" /> <!-- allocationtoken_a08ccbef -->
|
||||
<polygon fill="none" stroke="#888888" points="4539.18,-4 4539.18,-44 4804.18,-44 4804.18,-4 4539.18,-4" /> <!-- allocationtoken_a08ccbef -->
|
||||
<g id="node1" class="node">
|
||||
<title>allocationtoken_a08ccbef</title>
|
||||
<polygon fill="#ebcef2" stroke="transparent" points="2954.5,-2740.89 2954.5,-2759.89 3153.5,-2759.89 3153.5,-2740.89 2954.5,-2740.89" />
|
||||
|
|
|
@ -84,3 +84,4 @@ V83__add_indexes_on_domainhost.sql
|
|||
V84__add_vkey_columns_in_billing_cancellation.sql
|
||||
V85__add_required_columns_in_transfer_data.sql
|
||||
V86__third_poll_message.sql
|
||||
V87__fix_super_domain_fk.sql
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
-- Copyright 2021 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.
|
||||
|
||||
ALTER TABLE "Host" DROP CONSTRAINT fk_host_superordinate_domain;
|
||||
ALTER TABLE if exists "Host"
|
||||
ADD CONSTRAINT fk_host_superordinate_domain
|
||||
FOREIGN KEY (superordinate_domain)
|
||||
REFERENCES "Domain"(repo_id)
|
||||
DEFERRABLE INITIALLY DEFERRED;
|
|
@ -2198,7 +2198,7 @@ ALTER TABLE ONLY public."Host"
|
|||
--
|
||||
|
||||
ALTER TABLE ONLY public."Host"
|
||||
ADD CONSTRAINT fk_host_superordinate_domain FOREIGN KEY (superordinate_domain) REFERENCES public."Domain"(repo_id);
|
||||
ADD CONSTRAINT fk_host_superordinate_domain FOREIGN KEY (superordinate_domain) REFERENCES public."Domain"(repo_id) DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
|
||||
--
|
||||
|
|
Loading…
Add table
Reference in a new issue