mirror of
https://github.com/google/nomulus.git
synced 2025-07-01 16:53:35 +02:00
Canonicalize domain/host names in async DS->SQL replay (#1350)
This commit is contained in:
parent
1b4b217588
commit
30c23efba9
8 changed files with 160 additions and 2 deletions
|
@ -24,6 +24,7 @@ import google.registry.model.host.HostResource;
|
|||
import google.registry.model.replay.DatastoreAndSqlEntity;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.WithStringVKey;
|
||||
import google.registry.util.DomainNameUtils;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
|
@ -164,6 +165,11 @@ public class DomainBase extends DomainContent
|
|||
return cloneDomainProjectedAtTime(this, now);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeSqlSaveOnReplay() {
|
||||
fullyQualifiedDomainName = DomainNameUtils.canonicalizeDomainName(fullyQualifiedDomainName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeDatastoreSaveOnReplay() {
|
||||
saveIndexesToDatastore();
|
||||
|
|
|
@ -33,6 +33,7 @@ import google.registry.model.replay.SqlEntity;
|
|||
import google.registry.model.reporting.DomainTransactionRecord;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.util.DomainNameUtils;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
|
@ -303,6 +304,8 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
|
|||
public void beforeSqlSaveOnReplay() {
|
||||
if (domainContent == null) {
|
||||
domainContent = jpaTm().getEntityManager().find(DomainBase.class, getDomainRepoId());
|
||||
domainContent.fullyQualifiedDomainName =
|
||||
DomainNameUtils.canonicalizeDomainName(domainContent.fullyQualifiedDomainName);
|
||||
fillAuxiliaryFieldsFromDomain(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import google.registry.model.replay.DatastoreEntity;
|
|||
import google.registry.model.replay.SqlEntity;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.util.DomainNameUtils;
|
||||
import java.io.Serializable;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -141,6 +142,8 @@ public class HostHistory extends HistoryEntry implements SqlEntity, UnsafeSerial
|
|||
public void beforeSqlSaveOnReplay() {
|
||||
if (hostBase == null) {
|
||||
hostBase = jpaTm().getEntityManager().find(HostResource.class, getHostRepoId());
|
||||
hostBase.fullyQualifiedHostName =
|
||||
DomainNameUtils.canonicalizeDomainName(hostBase.fullyQualifiedHostName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import google.registry.model.annotations.ReportedOn;
|
|||
import google.registry.model.replay.DatastoreAndSqlEntity;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.WithStringVKey;
|
||||
import google.registry.util.DomainNameUtils;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
|
||||
|
@ -51,6 +52,11 @@ public class HostResource extends HostBase
|
|||
return VKey.create(HostResource.class, getRepoId(), Key.create(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeSqlSaveOnReplay() {
|
||||
fullyQualifiedHostName = DomainNameUtils.canonicalizeDomainName(fullyQualifiedHostName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeDatastoreSaveOnReplay() {
|
||||
saveIndexesToDatastore();
|
||||
|
|
|
@ -921,6 +921,19 @@ public class DomainBaseTest extends EntityTestCase {
|
|||
.containsExactly(EppResourceIndex.create(Key.create(domain)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBeforeSqlSaveOnReplay_canonicalName() {
|
||||
domain.fullyQualifiedDomainName = "EXAMPLE.COM";
|
||||
assertThat(domain.getDomainName()).isEqualTo("EXAMPLE.COM");
|
||||
domain.beforeSqlSaveOnReplay();
|
||||
assertThat(domain.getDomainName()).isEqualTo("example.com");
|
||||
|
||||
domain.fullyQualifiedDomainName = "kittyçat.com";
|
||||
assertThat(domain.getDomainName()).isEqualTo("kittyçat.com");
|
||||
domain.beforeSqlSaveOnReplay();
|
||||
assertThat(domain.getDomainName()).isEqualTo("xn--kittyat-yxa.com");
|
||||
}
|
||||
|
||||
static class BillEventInfo extends ImmutableObject {
|
||||
VKey<BillingEvent.Recurring> billingEventRecurring;
|
||||
Long billingEventRecurringHistoryId;
|
||||
|
|
|
@ -56,6 +56,7 @@ import google.registry.testing.DualDatabaseTest;
|
|||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Optional;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@ -136,8 +137,7 @@ public class DomainHistoryTest extends EntityTestCase {
|
|||
DomainHistory domainHistory = createDomainHistory(domain);
|
||||
tm().transact(() -> tm().insert(domainHistory));
|
||||
|
||||
// retrieving a HistoryEntry or a DomainHistory with the same key should return the same
|
||||
// object
|
||||
// retrieving a HistoryEntry or a DomainHistory with the same key should return the same object
|
||||
// note: due to the @EntitySubclass annotation. all Keys for DomainHistory objects will have
|
||||
// type HistoryEntry
|
||||
VKey<DomainHistory> domainHistoryVKey = domainHistory.createVKey();
|
||||
|
@ -232,6 +232,66 @@ public class DomainHistoryTest extends EntityTestCase {
|
|||
jpaTm().loadByEntity(historyWithoutResource).getDomainContent().get()));
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testBeforeSqlSave_canonicalNameUncapitalized() throws Exception {
|
||||
Field domainNameField = DomainContent.class.getDeclaredField("fullyQualifiedDomainName");
|
||||
// reflection hacks to get around visibility issues
|
||||
domainNameField.setAccessible(true);
|
||||
DomainBase domain = createDomainWithContactsAndHosts();
|
||||
domainNameField.set(domain, "EXAMPLE.TLD");
|
||||
|
||||
DomainHistory historyWithoutResource =
|
||||
new DomainHistory.Builder()
|
||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
|
||||
.setModificationTime(fakeClock.nowUtc())
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setTrid(Trid.create("ABC-123", "server-trid"))
|
||||
.setBySuperuser(false)
|
||||
.setReason("reason")
|
||||
.setRequestedByRegistrar(true)
|
||||
.setDomainRepoId(domain.getRepoId())
|
||||
.setOtherRegistrarId("otherClient")
|
||||
.setPeriod(Period.create(1, Period.Unit.YEARS))
|
||||
.build();
|
||||
|
||||
DatabaseHelper.putInDb(domain, historyWithoutResource);
|
||||
jpaTm().transact(historyWithoutResource::beforeSqlSaveOnReplay);
|
||||
|
||||
assertThat(historyWithoutResource.getDomainContent().get().getDomainName())
|
||||
.isEqualTo("example.tld");
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testBeforeSqlSave_canonicalNameUtf8() throws Exception {
|
||||
Field domainNameField = DomainContent.class.getDeclaredField("fullyQualifiedDomainName");
|
||||
// reflection hacks to get around visibility issues
|
||||
domainNameField.setAccessible(true);
|
||||
DomainBase domain = createDomainWithContactsAndHosts();
|
||||
domainNameField.set(domain, "kittyçat.tld");
|
||||
|
||||
DomainHistory historyWithoutResource =
|
||||
new DomainHistory.Builder()
|
||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
|
||||
.setModificationTime(fakeClock.nowUtc())
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setTrid(Trid.create("ABC-123", "server-trid"))
|
||||
.setBySuperuser(false)
|
||||
.setReason("reason")
|
||||
.setRequestedByRegistrar(true)
|
||||
.setDomainRepoId(domain.getRepoId())
|
||||
.setOtherRegistrarId("otherClient")
|
||||
.setPeriod(Period.create(1, Period.Unit.YEARS))
|
||||
.build();
|
||||
|
||||
DatabaseHelper.putInDb(domain, historyWithoutResource);
|
||||
jpaTm().transact(historyWithoutResource::beforeSqlSaveOnReplay);
|
||||
|
||||
assertThat(historyWithoutResource.getDomainContent().get().getDomainName())
|
||||
.isEqualTo("xn--kittyat-yxa.tld");
|
||||
}
|
||||
|
||||
static DomainBase createDomainWithContactsAndHosts() {
|
||||
createTld("tld");
|
||||
HostResource host = newHostResourceWithRoid("ns1.example.com", "host1");
|
||||
|
|
|
@ -33,10 +33,12 @@ import google.registry.model.host.HostHistory;
|
|||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/** Tests for {@link HostHistory}. */
|
||||
@DualDatabaseTest
|
||||
|
@ -146,6 +148,58 @@ public class HostHistoryTest extends EntityTestCase {
|
|||
.hasFieldsEqualTo(jpaTm().loadByEntity(hostHistory).getHostBase().get()));
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testBeforeSqlSave_canonicalNameUncapitalized() throws Exception {
|
||||
Field hostNameField = HostBase.class.getDeclaredField("fullyQualifiedHostName");
|
||||
// reflection hacks to get around visibility issues
|
||||
hostNameField.setAccessible(true);
|
||||
HostResource hostResource = newHostResource("ns1.example.tld");
|
||||
hostNameField.set(hostResource, "NS1.EXAMPLE.TLD");
|
||||
HostHistory hostHistory =
|
||||
new HostHistory.Builder()
|
||||
.setType(HistoryEntry.Type.HOST_CREATE)
|
||||
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
|
||||
.setModificationTime(fakeClock.nowUtc())
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setTrid(Trid.create("ABC-123", "server-trid"))
|
||||
.setBySuperuser(false)
|
||||
.setReason("reason")
|
||||
.setRequestedByRegistrar(true)
|
||||
.setHostRepoId(hostResource.getRepoId())
|
||||
.build();
|
||||
|
||||
DatabaseHelper.putInDb(hostResource, hostHistory);
|
||||
jpaTm().transact(hostHistory::beforeSqlSaveOnReplay);
|
||||
|
||||
assertThat(hostHistory.getHostBase().get().getHostName()).isEqualTo("ns1.example.tld");
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testBeforeSqlSave_canonicalNameUtf8() throws Exception {
|
||||
Field hostNameField = HostBase.class.getDeclaredField("fullyQualifiedHostName");
|
||||
// reflection hacks to get around visibility issues
|
||||
hostNameField.setAccessible(true);
|
||||
HostResource hostResource = newHostResource("ns1.example.tld");
|
||||
hostNameField.set(hostResource, "ns1.kittyçat.tld");
|
||||
HostHistory hostHistory =
|
||||
new HostHistory.Builder()
|
||||
.setType(HistoryEntry.Type.HOST_CREATE)
|
||||
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
|
||||
.setModificationTime(fakeClock.nowUtc())
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setTrid(Trid.create("ABC-123", "server-trid"))
|
||||
.setBySuperuser(false)
|
||||
.setReason("reason")
|
||||
.setRequestedByRegistrar(true)
|
||||
.setHostRepoId(hostResource.getRepoId())
|
||||
.build();
|
||||
|
||||
DatabaseHelper.putInDb(hostResource, hostHistory);
|
||||
jpaTm().transact(hostHistory::beforeSqlSaveOnReplay);
|
||||
|
||||
assertThat(hostHistory.getHostBase().get().getHostName()).isEqualTo("ns1.xn--kittyat-yxa.tld");
|
||||
}
|
||||
|
||||
private void assertHostHistoriesEqual(HostHistory one, HostHistory two) {
|
||||
assertAboutImmutableObjects().that(one).isEqualExceptFields(two, "hostBase");
|
||||
assertAboutImmutableObjects()
|
||||
|
|
|
@ -319,4 +319,17 @@ class HostResourceTest extends EntityTestCase {
|
|||
assertThat(ofyTm().loadAllOf(EppResourceIndex.class))
|
||||
.containsExactly(EppResourceIndex.create(Key.create(host)));
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testBeforeSqlSaveOnReplay_canonicalName() {
|
||||
host.fullyQualifiedHostName = "NS1.EXAMPLE.COM";
|
||||
assertThat(host.getHostName()).isEqualTo("NS1.EXAMPLE.COM");
|
||||
host.beforeSqlSaveOnReplay();
|
||||
assertThat(host.getHostName()).isEqualTo("ns1.example.com");
|
||||
|
||||
host.fullyQualifiedHostName = "ns1.kittyçat.com";
|
||||
assertThat(host.getHostName()).isEqualTo("ns1.kittyçat.com");
|
||||
host.beforeSqlSaveOnReplay();
|
||||
assertThat(host.getHostName()).isEqualTo("ns1.xn--kittyat-yxa.com");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue