Partially convert RDAP ofy calls to tm calls (#964)

* Partially convert RDAP ofy calls to tm calls

This converts the simple retrieval actions but does not touch the more
complicated search actions -- those use some ofy() query searching logic
and will likely end up being significantly more complicated than this
change. Here, though, we are just changing the calls that can be
converted easily to tm() lookups.

To change in future PRs:
- RdapDomainSearchAction
- RdapEntitySearchAction
- RdapNameserverSearchAction
- RdapSearchActionBase
This commit is contained in:
gbrodman 2021-02-23 11:28:10 -05:00 committed by GitHub
parent adb83bea91
commit 61599b0d45
8 changed files with 132 additions and 139 deletions

View file

@ -996,6 +996,13 @@ public class Registrar extends ImmutableObject
return CACHE_BY_CLIENT_ID.get().values(); return CACHE_BY_CLIENT_ID.get().values();
} }
/** Loads all registrar keys using an in-memory cache. */
public static ImmutableSet<VKey<Registrar>> loadAllKeysCached() {
return CACHE_BY_CLIENT_ID.get().keySet().stream()
.map(Registrar::createVKey)
.collect(toImmutableSet());
}
/** Loads and returns a registrar entity by its client id directly from Datastore. */ /** Loads and returns a registrar entity by its client id directly from Datastore. */
public static Optional<Registrar> loadByClientId(String clientId) { public static Optional<Registrar> loadByClientId(String clientId) {
checkArgument(!Strings.isNullOrEmpty(clientId), "clientId must be specified"); checkArgument(!Strings.isNullOrEmpty(clientId), "clientId must be specified");

View file

@ -14,7 +14,8 @@
package google.registry.rdap; package google.registry.rdap;
import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm;
import static google.registry.rdap.RdapUtils.getRegistrarByIanaIdentifier; import static google.registry.rdap.RdapUtils.getRegistrarByIanaIdentifier;
import static google.registry.rdap.RdapUtils.getRegistrarByName; import static google.registry.rdap.RdapUtils.getRegistrarByName;
import static google.registry.request.Action.Method.GET; import static google.registry.request.Action.Method.GET;
@ -23,9 +24,9 @@ import static google.registry.request.Action.Method.HEAD;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Longs; import com.google.common.primitives.Longs;
import com.google.re2j.Pattern; import com.google.re2j.Pattern;
import com.googlecode.objectify.Key;
import google.registry.model.contact.ContactResource; import google.registry.model.contact.ContactResource;
import google.registry.model.registrar.Registrar; import google.registry.model.registrar.Registrar;
import google.registry.persistence.VKey;
import google.registry.rdap.RdapJsonFormatter.OutputDataType; import google.registry.rdap.RdapJsonFormatter.OutputDataType;
import google.registry.rdap.RdapMetrics.EndpointType; import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.rdap.RdapObjectClasses.RdapEntity; import google.registry.rdap.RdapObjectClasses.RdapEntity;
@ -69,13 +70,14 @@ public class RdapEntityAction extends RdapActionBase {
// RDAP Technical Implementation Guide 2.3.1 - MUST support contact entity lookup using the // RDAP Technical Implementation Guide 2.3.1 - MUST support contact entity lookup using the
// handle // handle
if (ROID_PATTERN.matcher(pathSearchString).matches()) { if (ROID_PATTERN.matcher(pathSearchString).matches()) {
Key<ContactResource> contactKey = Key.create(ContactResource.class, pathSearchString); VKey<ContactResource> contactVKey = VKey.create(ContactResource.class, pathSearchString);
ContactResource contactResource = ofy().load().key(contactKey).now(); Optional<ContactResource> contactResource =
transactIfJpaTm(() -> tm().loadByKeyIfPresent(contactVKey));
// As per Andy Newton on the regext mailing list, contacts by themselves have no role, since // As per Andy Newton on the regext mailing list, contacts by themselves have no role, since
// they are global, and might have different roles for different domains. // they are global, and might have different roles for different domains.
if (contactResource != null && isAuthorized(contactResource)) { if (contactResource.isPresent() && isAuthorized(contactResource.get())) {
return rdapJsonFormatter.createRdapContactEntity( return rdapJsonFormatter.createRdapContactEntity(
contactResource, ImmutableSet.of(), OutputDataType.FULL); contactResource.get(), ImmutableSet.of(), OutputDataType.FULL);
} }
} }

View file

@ -20,8 +20,8 @@ import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap; import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
import static google.registry.model.EppResourceUtils.isLinked; import static google.registry.model.EppResourceUtils.isLinked;
import static google.registry.model.ofy.ObjectifyService.ofy;
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.rdap.RdapIcannStandardInformation.CONTACT_REDACTED_VALUE; import static google.registry.rdap.RdapIcannStandardInformation.CONTACT_REDACTED_VALUE;
import static google.registry.util.CollectionUtils.union; import static google.registry.util.CollectionUtils.union;
@ -35,7 +35,6 @@ import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.google.common.net.InetAddresses; import com.google.common.net.InetAddresses;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.googlecode.objectify.Key;
import google.registry.config.RegistryConfig.Config; import google.registry.config.RegistryConfig.Config;
import google.registry.model.EppResource; import google.registry.model.EppResource;
import google.registry.model.contact.ContactAddress; import google.registry.model.contact.ContactAddress;
@ -77,7 +76,6 @@ import java.net.URI;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -343,15 +341,11 @@ public class RdapJsonFormatter {
// Kick off the database loads of the nameservers that we will need, so it can load // Kick off the database loads of the nameservers that we will need, so it can load
// asynchronously while we load and process the contacts. // asynchronously while we load and process the contacts.
ImmutableSet<HostResource> loadedHosts = ImmutableSet<HostResource> loadedHosts =
ImmutableSet.copyOf(tm().loadByKeys(domainBase.getNameservers()).values()); transactIfJpaTm(
() -> ImmutableSet.copyOf(tm().loadByKeys(domainBase.getNameservers()).values()));
// Load the registrant and other contacts and add them to the data. // Load the registrant and other contacts and add them to the data.
Map<Key<ContactResource>, ContactResource> loadedContacts = ImmutableMap<VKey<? extends ContactResource>, ContactResource> loadedContacts =
ofy() transactIfJpaTm(() -> tm().loadByKeysIfPresent(domainBase.getReferencedContacts()));
.load()
.keys(
domainBase.getReferencedContacts().stream()
.map(VKey::getOfyKey)
.collect(toImmutableSet()));
// RDAP Response Profile 2.7.3, A domain MUST have the REGISTRANT, ADMIN, TECH roles and MAY // RDAP Response Profile 2.7.3, A domain MUST have the REGISTRANT, ADMIN, TECH roles and MAY
// have others. We also add the BILLING. // have others. We also add the BILLING.
// //
@ -359,16 +353,16 @@ public class RdapJsonFormatter {
// fields we don't want to show (as opposed to not having contacts at all) because of GDPR etc. // fields we don't want to show (as opposed to not having contacts at all) because of GDPR etc.
// //
// the GDPR redaction is handled in createRdapContactEntity // the GDPR redaction is handled in createRdapContactEntity
ImmutableSetMultimap<Key<ContactResource>, Type> contactsToRoles = ImmutableSetMultimap<VKey<ContactResource>, Type> contactsToRoles =
Streams.concat( Streams.concat(
domainBase.getContacts().stream(), domainBase.getContacts().stream(),
Stream.of(DesignatedContact.create(Type.REGISTRANT, domainBase.getRegistrant()))) Stream.of(DesignatedContact.create(Type.REGISTRANT, domainBase.getRegistrant())))
.sorted(DESIGNATED_CONTACT_ORDERING) .sorted(DESIGNATED_CONTACT_ORDERING)
.collect( .collect(
toImmutableSetMultimap( toImmutableSetMultimap(
contact -> contact.getContactKey().getOfyKey(), DesignatedContact::getType)); DesignatedContact::getContactKey, DesignatedContact::getType));
for (Key<ContactResource> contactKey : contactsToRoles.keySet()) { for (VKey<ContactResource> contactKey : contactsToRoles.keySet()) {
Set<RdapEntity.Role> roles = Set<RdapEntity.Role> roles =
contactsToRoles.get(contactKey).stream() contactsToRoles.get(contactKey).stream()
.map(RdapJsonFormatter::convertContactTypeToRdapRole) .map(RdapJsonFormatter::convertContactTypeToRdapRole)
@ -430,10 +424,12 @@ public class RdapJsonFormatter {
statuses.add(StatusValue.LINKED); statuses.add(StatusValue.LINKED);
} }
if (hostResource.isSubordinate() if (hostResource.isSubordinate()
&& tm().loadByKey(hostResource.getSuperordinateDomain()) && transactIfJpaTm(
() ->
tm().loadByKey(hostResource.getSuperordinateDomain())
.cloneProjectedAtTime(getRequestTime()) .cloneProjectedAtTime(getRequestTime())
.getStatusValues() .getStatusValues()
.contains(StatusValue.PENDING_TRANSFER)) { .contains(StatusValue.PENDING_TRANSFER))) {
statuses.add(StatusValue.PENDING_TRANSFER); statuses.add(StatusValue.PENDING_TRANSFER);
} }
builder builder

View file

@ -392,22 +392,6 @@ public abstract class RdapSearchActionBase extends RdapActionBase {
return setOtherQueryAttributes(query, deletedItemHandling, resultSetMaxSize); return setOtherQueryAttributes(query, deletedItemHandling, resultSetMaxSize);
} }
/** Handles searches by key using a simple string. */
static <T extends EppResource> Query<T> queryItemsByKey(
Class<T> clazz,
String queryString,
DeletedItemHandling deletedItemHandling,
int resultSetMaxSize) {
if (queryString.length() < RdapSearchPattern.MIN_INITIAL_STRING_LENGTH) {
throw new UnprocessableEntityException(
String.format(
"Initial search string must be at least %d characters",
RdapSearchPattern.MIN_INITIAL_STRING_LENGTH));
}
Query<T> query = ofy().load().type(clazz).filterKey("=", Key.create(clazz, queryString));
return setOtherQueryAttributes(query, deletedItemHandling, resultSetMaxSize);
}
static <T extends EppResource> Query<T> setOtherQueryAttributes( static <T extends EppResource> Query<T> setOtherQueryAttributes(
Query<T> query, DeletedItemHandling deletedItemHandling, int resultSetMaxSize) { Query<T> query, DeletedItemHandling deletedItemHandling, int resultSetMaxSize) {
if (deletedItemHandling != DeletedItemHandling.INCLUDE) { if (deletedItemHandling != DeletedItemHandling.INCLUDE) {

View file

@ -16,7 +16,6 @@ package google.registry.rdap;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
@ -34,7 +33,6 @@ import com.google.gson.Gson;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.googlecode.objectify.Key;
import google.registry.keyring.api.KeyModule; import google.registry.keyring.api.KeyModule;
import google.registry.model.registrar.Registrar; import google.registry.model.registrar.Registrar;
import google.registry.model.registry.Registries; import google.registry.model.registry.Registries;
@ -197,14 +195,14 @@ public final class UpdateRegistrarRdapBaseUrlsAction implements Runnable {
@Override @Override
public void run() { public void run() {
ImmutableSetMultimap<String, String> ianaToBaseUrls = getRdapBaseUrlsPerIanaId(); ImmutableSetMultimap<String, String> ianaToBaseUrls = getRdapBaseUrlsPerIanaId();
Registrar.loadAllKeysCached()
for (Key<Registrar> registrarKey : ofy().load().type(Registrar.class).keys()) { .forEach(
tm() (key) ->
.transact( tm().transact(
() -> { () -> {
Registrar registrar = ofy().load().key(registrarKey).now(); Registrar registrar = tm().loadByKey(key);
// Has the registrar been deleted since we loaded the key? (unlikly, especially // Has the registrar been deleted since we loaded the key? (unlikely,
// given we don't delete registrars...) // especially given we don't delete registrars...)
if (registrar == null) { if (registrar == null) {
return; return;
} }
@ -223,11 +221,11 @@ public final class UpdateRegistrarRdapBaseUrlsAction implements Runnable {
} }
logger.atInfo().log( logger.atInfo().log(
"Updating RdapBaseUrls for registrar %s (ianaId %s) from %s to %s", "Updating RdapBaseUrls for registrar %s (ianaId %s) from %s to %s",
registrar.getClientId(), ianaId, registrar.getRdapBaseUrls(), baseUrls); registrar.getClientId(),
ofy() ianaId,
.save() registrar.getRdapBaseUrls(),
.entity(registrar.asBuilder().setRdapBaseUrls(baseUrls).build()); baseUrls);
}); tm().put(registrar.asBuilder().setRdapBaseUrls(baseUrls).build());
} }));
} }
} }

View file

@ -38,12 +38,14 @@ import google.registry.rdap.RdapMetrics.SearchType;
import google.registry.rdap.RdapMetrics.WildcardType; import google.registry.rdap.RdapMetrics.WildcardType;
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType; import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.request.Action; import google.registry.request.Action;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.TestOfyAndSql;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link RdapEntityAction}. */ /** Unit tests for {@link RdapEntityAction}. */
@DualDatabaseTest
class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> { class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
RdapEntityActionTest() { RdapEntityActionTest() {
@ -187,35 +189,35 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
assertThat(response.getStatus()).isEqualTo(404); assertThat(response.getStatus()).isEqualTo(404);
} }
@Test @TestOfyAndSql
void testUnknownEntity_RoidPattern_notFound() { void testUnknownEntity_RoidPattern_notFound() {
runNotFoundTest("_MISSING-ENTITY_"); runNotFoundTest("_MISSING-ENTITY_");
} }
@Test @TestOfyAndSql
void testUnknownEntity_IanaPattern_notFound() { void testUnknownEntity_IanaPattern_notFound() {
runNotFoundTest("123"); runNotFoundTest("123");
} }
@Test @TestOfyAndSql
void testUnknownEntity_notRoidNotIana_notFound() { void testUnknownEntity_notRoidNotIana_notFound() {
// Since we allow search by registrar name, every string is a possible name // Since we allow search by registrar name, every string is a possible name
runNotFoundTest("some,random,string"); runNotFoundTest("some,random,string");
} }
@Test @TestOfyAndSql
void testValidRegistrantContact_works() { void testValidRegistrantContact_works() {
login("evilregistrar"); login("evilregistrar");
runSuccessfulHandleTest(registrant.getRepoId(), "rdap_associated_contact.json"); runSuccessfulHandleTest(registrant.getRepoId(), "rdap_associated_contact.json");
} }
@Test @TestOfyAndSql
void testValidRegistrantContact_found_asAdministrator() { void testValidRegistrantContact_found_asAdministrator() {
loginAsAdmin(); loginAsAdmin();
runSuccessfulHandleTest(registrant.getRepoId(), "rdap_associated_contact.json"); runSuccessfulHandleTest(registrant.getRepoId(), "rdap_associated_contact.json");
} }
@Test @TestOfyAndSql
void testValidRegistrantContact_found_notLoggedIn() { void testValidRegistrantContact_found_notLoggedIn() {
runSuccessfulHandleTest( runSuccessfulHandleTest(
registrant.getRepoId(), registrant.getRepoId(),
@ -225,7 +227,7 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
"rdap_associated_contact_no_personal_data.json"); "rdap_associated_contact_no_personal_data.json");
} }
@Test @TestOfyAndSql
void testValidRegistrantContact_found_loggedInAsOtherRegistrar() { void testValidRegistrantContact_found_loggedInAsOtherRegistrar() {
login("otherregistrar"); login("otherregistrar");
runSuccessfulHandleTest( runSuccessfulHandleTest(
@ -236,49 +238,49 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
"rdap_associated_contact_no_personal_data.json"); "rdap_associated_contact_no_personal_data.json");
} }
@Test @TestOfyAndSql
void testValidAdminContact_works() { void testValidAdminContact_works() {
login("evilregistrar"); login("evilregistrar");
runSuccessfulHandleTest(adminContact.getRepoId(), "rdap_associated_contact.json"); runSuccessfulHandleTest(adminContact.getRepoId(), "rdap_associated_contact.json");
} }
@Test @TestOfyAndSql
void testValidTechContact_works() { void testValidTechContact_works() {
login("evilregistrar"); login("evilregistrar");
runSuccessfulHandleTest(techContact.getRepoId(), "rdap_associated_contact.json"); runSuccessfulHandleTest(techContact.getRepoId(), "rdap_associated_contact.json");
} }
@Test @TestOfyAndSql
void testValidDisconnectedContact_works() { void testValidDisconnectedContact_works() {
login("evilregistrar"); login("evilregistrar");
runSuccessfulHandleTest(disconnectedContact.getRepoId(), "rdap_contact.json"); runSuccessfulHandleTest(disconnectedContact.getRepoId(), "rdap_contact.json");
} }
@Test @TestOfyAndSql
void testDeletedContact_notFound() { void testDeletedContact_notFound() {
runNotFoundTest(deletedContact.getRepoId()); runNotFoundTest(deletedContact.getRepoId());
} }
@Test @TestOfyAndSql
void testDeletedContact_notFound_includeDeletedSetFalse() { void testDeletedContact_notFound_includeDeletedSetFalse() {
action.includeDeletedParam = Optional.of(false); action.includeDeletedParam = Optional.of(false);
runNotFoundTest(deletedContact.getRepoId()); runNotFoundTest(deletedContact.getRepoId());
} }
@Test @TestOfyAndSql
void testDeletedContact_notFound_notLoggedIn() { void testDeletedContact_notFound_notLoggedIn() {
action.includeDeletedParam = Optional.of(true); action.includeDeletedParam = Optional.of(true);
runNotFoundTest(deletedContact.getRepoId()); runNotFoundTest(deletedContact.getRepoId());
} }
@Test @TestOfyAndSql
void testDeletedContact_notFound_loggedInAsDifferentRegistrar() { void testDeletedContact_notFound_loggedInAsDifferentRegistrar() {
login("idnregistrar"); login("idnregistrar");
action.includeDeletedParam = Optional.of(true); action.includeDeletedParam = Optional.of(true);
runNotFoundTest(deletedContact.getRepoId()); runNotFoundTest(deletedContact.getRepoId());
} }
@Test @TestOfyAndSql
void testDeletedContact_found_loggedInAsCorrectRegistrar() { void testDeletedContact_found_loggedInAsCorrectRegistrar() {
login("evilregistrar"); login("evilregistrar");
action.includeDeletedParam = Optional.of(true); action.includeDeletedParam = Optional.of(true);
@ -290,7 +292,7 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
"rdap_contact_deleted.json"); "rdap_contact_deleted.json");
} }
@Test @TestOfyAndSql
void testDeletedContact_found_loggedInAsAdmin() { void testDeletedContact_found_loggedInAsAdmin() {
loginAsAdmin(); loginAsAdmin();
action.includeDeletedParam = Optional.of(true); action.includeDeletedParam = Optional.of(true);
@ -302,12 +304,12 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
"rdap_contact_deleted.json"); "rdap_contact_deleted.json");
} }
@Test @TestOfyAndSql
void testRegistrar_found() { void testRegistrar_found() {
runSuccessfulHandleTest("101", "Yes Virginia <script>", "rdap_registrar.json"); runSuccessfulHandleTest("101", "Yes Virginia <script>", "rdap_registrar.json");
} }
@Test @TestOfyAndSql
void testRegistrarByName_found() { void testRegistrarByName_found() {
assertThat(generateActualJson("IDN%20Registrar")) assertThat(generateActualJson("IDN%20Registrar"))
.isEqualTo( .isEqualTo(
@ -316,28 +318,28 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@Test @TestOfyAndSql
void testRegistrar102_works() { void testRegistrar102_works() {
runSuccessfulHandleTest("102", "IDN Registrar", "rdap_registrar.json"); runSuccessfulHandleTest("102", "IDN Registrar", "rdap_registrar.json");
} }
@Test @TestOfyAndSql
void testRegistrar103_works() { void testRegistrar103_works() {
runSuccessfulHandleTest("103", "Multilevel Registrar", "rdap_registrar.json"); runSuccessfulHandleTest("103", "Multilevel Registrar", "rdap_registrar.json");
} }
@Test @TestOfyAndSql
void testRegistrar104_notFound() { void testRegistrar104_notFound() {
runNotFoundTest("104"); runNotFoundTest("104");
} }
@Test @TestOfyAndSql
void testRegistrar104_notFound_deletedFlagWhenNotLoggedIn() { void testRegistrar104_notFound_deletedFlagWhenNotLoggedIn() {
action.includeDeletedParam = Optional.of(true); action.includeDeletedParam = Optional.of(true);
runNotFoundTest("104"); runNotFoundTest("104");
} }
@Test @TestOfyAndSql
void testRegistrar104_found_deletedFlagWhenLoggedIn() { void testRegistrar104_found_deletedFlagWhenLoggedIn() {
login("deletedregistrar"); login("deletedregistrar");
action.includeDeletedParam = Optional.of(true); action.includeDeletedParam = Optional.of(true);
@ -345,14 +347,14 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
"104", "Yes Virginia <script>", "inactive", null, "rdap_registrar.json"); "104", "Yes Virginia <script>", "inactive", null, "rdap_registrar.json");
} }
@Test @TestOfyAndSql
void testRegistrar104_notFound_deletedFlagWhenLoggedInAsOther() { void testRegistrar104_notFound_deletedFlagWhenLoggedInAsOther() {
login("1tldregistrar"); login("1tldregistrar");
action.includeDeletedParam = Optional.of(true); action.includeDeletedParam = Optional.of(true);
runNotFoundTest("104"); runNotFoundTest("104");
} }
@Test @TestOfyAndSql
void testRegistrar104_found_deletedFlagWhenLoggedInAsAdmin() { void testRegistrar104_found_deletedFlagWhenLoggedInAsAdmin() {
loginAsAdmin(); loginAsAdmin();
action.includeDeletedParam = Optional.of(true); action.includeDeletedParam = Optional.of(true);
@ -360,12 +362,12 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
"104", "Yes Virginia <script>", "inactive", null, "rdap_registrar.json"); "104", "Yes Virginia <script>", "inactive", null, "rdap_registrar.json");
} }
@Test @TestOfyAndSql
void testRegistrar105_doesNotExist() { void testRegistrar105_doesNotExist() {
runNotFoundTest("105"); runNotFoundTest("105");
} }
@Test @TestOfyAndSql
void testQueryParameter_ignored() { void testQueryParameter_ignored() {
login("evilregistrar"); login("evilregistrar");
assertThat(generateActualJson(techContact.getRepoId() + "?key=value")).isEqualTo( assertThat(generateActualJson(techContact.getRepoId() + "?key=value")).isEqualTo(
@ -374,7 +376,7 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@Test @TestOfyAndSql
void testMetrics() { void testMetrics() {
generateActualJson(registrant.getRepoId()); generateActualJson(registrant.getRepoId());
verify(rdapMetrics) verify(rdapMetrics)

View file

@ -47,14 +47,16 @@ import google.registry.rdap.RdapObjectClasses.RdapEntity;
import google.registry.rdap.RdapObjectClasses.ReplyPayloadBase; import google.registry.rdap.RdapObjectClasses.ReplyPayloadBase;
import google.registry.rdap.RdapObjectClasses.TopLevelReplyObject; import google.registry.rdap.RdapObjectClasses.TopLevelReplyObject;
import google.registry.testing.AppEngineExtension; import google.registry.testing.AppEngineExtension;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.FakeClock; import google.registry.testing.FakeClock;
import google.registry.testing.InjectExtension; import google.registry.testing.InjectExtension;
import google.registry.testing.TestOfyAndSql;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link RdapJsonFormatter}. */ /** Unit tests for {@link RdapJsonFormatter}. */
@DualDatabaseTest
class RdapJsonFormatterTest { class RdapJsonFormatterTest {
@RegisterExtension @RegisterExtension
@ -300,41 +302,41 @@ class RdapJsonFormatterTest {
return new Gson().fromJson(loadFile(this.getClass(), expectedFileName), JsonObject.class); return new Gson().fromJson(loadFile(this.getClass(), expectedFileName), JsonObject.class);
} }
@Test @TestOfyAndSql
void testRegistrar() { void testRegistrar() {
assertThat(rdapJsonFormatter.createRdapRegistrarEntity(registrar, OutputDataType.FULL).toJson()) assertThat(rdapJsonFormatter.createRdapRegistrarEntity(registrar, OutputDataType.FULL).toJson())
.isEqualTo(loadJson("rdapjson_registrar.json")); .isEqualTo(loadJson("rdapjson_registrar.json"));
} }
@Test @TestOfyAndSql
void testRegistrar_summary() { void testRegistrar_summary() {
assertThat( assertThat(
rdapJsonFormatter.createRdapRegistrarEntity(registrar, OutputDataType.SUMMARY).toJson()) rdapJsonFormatter.createRdapRegistrarEntity(registrar, OutputDataType.SUMMARY).toJson())
.isEqualTo(loadJson("rdapjson_registrar_summary.json")); .isEqualTo(loadJson("rdapjson_registrar_summary.json"));
} }
@Test @TestOfyAndSql
void testHost_ipv4() { void testHost_ipv4() {
assertThat( assertThat(
rdapJsonFormatter.createRdapNameserver(hostResourceIpv4, OutputDataType.FULL).toJson()) rdapJsonFormatter.createRdapNameserver(hostResourceIpv4, OutputDataType.FULL).toJson())
.isEqualTo(loadJson("rdapjson_host_ipv4.json")); .isEqualTo(loadJson("rdapjson_host_ipv4.json"));
} }
@Test @TestOfyAndSql
void testHost_ipv6() { void testHost_ipv6() {
assertThat( assertThat(
rdapJsonFormatter.createRdapNameserver(hostResourceIpv6, OutputDataType.FULL).toJson()) rdapJsonFormatter.createRdapNameserver(hostResourceIpv6, OutputDataType.FULL).toJson())
.isEqualTo(loadJson("rdapjson_host_ipv6.json")); .isEqualTo(loadJson("rdapjson_host_ipv6.json"));
} }
@Test @TestOfyAndSql
void testHost_both() { void testHost_both() {
assertThat( assertThat(
rdapJsonFormatter.createRdapNameserver(hostResourceBoth, OutputDataType.FULL).toJson()) rdapJsonFormatter.createRdapNameserver(hostResourceBoth, OutputDataType.FULL).toJson())
.isEqualTo(loadJson("rdapjson_host_both.json")); .isEqualTo(loadJson("rdapjson_host_both.json"));
} }
@Test @TestOfyAndSql
void testHost_both_summary() { void testHost_both_summary() {
assertThat( assertThat(
rdapJsonFormatter rdapJsonFormatter
@ -343,7 +345,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_host_both_summary.json")); .isEqualTo(loadJson("rdapjson_host_both_summary.json"));
} }
@Test @TestOfyAndSql
void testHost_noAddresses() { void testHost_noAddresses() {
assertThat( assertThat(
rdapJsonFormatter rdapJsonFormatter
@ -352,7 +354,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_host_no_addresses.json")); .isEqualTo(loadJson("rdapjson_host_no_addresses.json"));
} }
@Test @TestOfyAndSql
void testHost_notLinked() { void testHost_notLinked() {
assertThat( assertThat(
rdapJsonFormatter rdapJsonFormatter
@ -361,7 +363,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_host_not_linked.json")); .isEqualTo(loadJson("rdapjson_host_not_linked.json"));
} }
@Test @TestOfyAndSql
void testHost_superordinateHasPendingTransfer() { void testHost_superordinateHasPendingTransfer() {
assertThat( assertThat(
rdapJsonFormatter rdapJsonFormatter
@ -370,7 +372,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_host_pending_transfer.json")); .isEqualTo(loadJson("rdapjson_host_pending_transfer.json"));
} }
@Test @TestOfyAndSql
void testRegistrant() { void testRegistrant() {
assertThat( assertThat(
rdapJsonFormatter rdapJsonFormatter
@ -382,7 +384,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_registrant.json")); .isEqualTo(loadJson("rdapjson_registrant.json"));
} }
@Test @TestOfyAndSql
void testRegistrant_summary() { void testRegistrant_summary() {
assertThat( assertThat(
rdapJsonFormatter rdapJsonFormatter
@ -394,7 +396,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_registrant_summary.json")); .isEqualTo(loadJson("rdapjson_registrant_summary.json"));
} }
@Test @TestOfyAndSql
void testRegistrant_loggedOut() { void testRegistrant_loggedOut() {
rdapJsonFormatter.rdapAuthorization = RdapAuthorization.PUBLIC_AUTHORIZATION; rdapJsonFormatter.rdapAuthorization = RdapAuthorization.PUBLIC_AUTHORIZATION;
assertThat( assertThat(
@ -407,7 +409,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_registrant_logged_out.json")); .isEqualTo(loadJson("rdapjson_registrant_logged_out.json"));
} }
@Test @TestOfyAndSql
void testRegistrant_baseHasNoTrailingSlash() { void testRegistrant_baseHasNoTrailingSlash() {
// First, make sure we have a trailing slash at the end by default! // First, make sure we have a trailing slash at the end by default!
// This test tries to change the default state, if the default doesn't have a /, then this test // This test tries to change the default state, if the default doesn't have a /, then this test
@ -426,7 +428,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_registrant.json")); .isEqualTo(loadJson("rdapjson_registrant.json"));
} }
@Test @TestOfyAndSql
void testAdmin() { void testAdmin() {
assertThat( assertThat(
rdapJsonFormatter rdapJsonFormatter
@ -438,7 +440,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_admincontact.json")); .isEqualTo(loadJson("rdapjson_admincontact.json"));
} }
@Test @TestOfyAndSql
void testTech() { void testTech() {
assertThat( assertThat(
rdapJsonFormatter rdapJsonFormatter
@ -448,7 +450,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_techcontact.json")); .isEqualTo(loadJson("rdapjson_techcontact.json"));
} }
@Test @TestOfyAndSql
void testRolelessContact() { void testRolelessContact() {
assertThat( assertThat(
rdapJsonFormatter rdapJsonFormatter
@ -458,7 +460,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_rolelesscontact.json")); .isEqualTo(loadJson("rdapjson_rolelesscontact.json"));
} }
@Test @TestOfyAndSql
void testUnlinkedContact() { void testUnlinkedContact() {
assertThat( assertThat(
rdapJsonFormatter rdapJsonFormatter
@ -468,26 +470,26 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_unlinkedcontact.json")); .isEqualTo(loadJson("rdapjson_unlinkedcontact.json"));
} }
@Test @TestOfyAndSql
void testDomain_full() { void testDomain_full() {
assertThat(rdapJsonFormatter.createRdapDomain(domainBaseFull, OutputDataType.FULL).toJson()) assertThat(rdapJsonFormatter.createRdapDomain(domainBaseFull, OutputDataType.FULL).toJson())
.isEqualTo(loadJson("rdapjson_domain_full.json")); .isEqualTo(loadJson("rdapjson_domain_full.json"));
} }
@Test @TestOfyAndSql
void testDomain_summary() { void testDomain_summary() {
assertThat(rdapJsonFormatter.createRdapDomain(domainBaseFull, OutputDataType.SUMMARY).toJson()) assertThat(rdapJsonFormatter.createRdapDomain(domainBaseFull, OutputDataType.SUMMARY).toJson())
.isEqualTo(loadJson("rdapjson_domain_summary.json")); .isEqualTo(loadJson("rdapjson_domain_summary.json"));
} }
@Test @TestOfyAndSql
void testDomain_logged_out() { void testDomain_logged_out() {
rdapJsonFormatter.rdapAuthorization = RdapAuthorization.PUBLIC_AUTHORIZATION; rdapJsonFormatter.rdapAuthorization = RdapAuthorization.PUBLIC_AUTHORIZATION;
assertThat(rdapJsonFormatter.createRdapDomain(domainBaseFull, OutputDataType.FULL).toJson()) assertThat(rdapJsonFormatter.createRdapDomain(domainBaseFull, OutputDataType.FULL).toJson())
.isEqualTo(loadJson("rdapjson_domain_logged_out.json")); .isEqualTo(loadJson("rdapjson_domain_logged_out.json"));
} }
@Test @TestOfyAndSql
void testDomain_noNameserversNoTransfersMultipleRoleContact() { void testDomain_noNameserversNoTransfersMultipleRoleContact() {
assertThat( assertThat(
rdapJsonFormatter rdapJsonFormatter
@ -496,7 +498,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_domain_no_nameservers.json")); .isEqualTo(loadJson("rdapjson_domain_no_nameservers.json"));
} }
@Test @TestOfyAndSql
void testError() { void testError() {
assertThat( assertThat(
RdapObjectClasses.ErrorResponse.create( RdapObjectClasses.ErrorResponse.create(
@ -505,7 +507,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_error.json")); .isEqualTo(loadJson("rdapjson_error.json"));
} }
@Test @TestOfyAndSql
void testTopLevel() { void testTopLevel() {
assertThat( assertThat(
TopLevelReplyObject.create( TopLevelReplyObject.create(
@ -517,7 +519,7 @@ class RdapJsonFormatterTest {
.isEqualTo(loadJson("rdapjson_toplevel.json")); .isEqualTo(loadJson("rdapjson_toplevel.json"));
} }
@Test @TestOfyAndSql
void testTopLevel_domain() { void testTopLevel_domain() {
assertThat( assertThat(
TopLevelReplyObject.create( TopLevelReplyObject.create(

View file

@ -35,13 +35,15 @@ import google.registry.model.registrar.RegistrarAddress;
import google.registry.model.registry.Registry; import google.registry.model.registry.Registry;
import google.registry.model.registry.Registry.TldType; import google.registry.model.registry.Registry.TldType;
import google.registry.testing.AppEngineExtension; import google.registry.testing.AppEngineExtension;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.TestOfyAndSql;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link UpdateRegistrarRdapBaseUrlsAction}. */ /** Unit tests for {@link UpdateRegistrarRdapBaseUrlsAction}. */
@DualDatabaseTest
public final class UpdateRegistrarRdapBaseUrlsActionTest { public final class UpdateRegistrarRdapBaseUrlsActionTest {
/** /**
@ -160,7 +162,7 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
.build()); .build());
} }
@Test @TestOfyAndSql
void testUnknownIana_cleared() { void testUnknownIana_cleared() {
// The IANA ID isn't in the JSON_LIST_REPLY // The IANA ID isn't in the JSON_LIST_REPLY
persistRegistrar("someRegistrar", 4123L, Registrar.Type.REAL, "http://rdap.example/blah"); persistRegistrar("someRegistrar", 4123L, Registrar.Type.REAL, "http://rdap.example/blah");
@ -172,7 +174,7 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
assertThat(loadRegistrar("someRegistrar").getRdapBaseUrls()).isEmpty(); assertThat(loadRegistrar("someRegistrar").getRdapBaseUrls()).isEmpty();
} }
@Test @TestOfyAndSql
void testKnownIana_changed() { void testKnownIana_changed() {
// The IANA ID is in the JSON_LIST_REPLY // The IANA ID is in the JSON_LIST_REPLY
persistRegistrar("someRegistrar", 1448L, Registrar.Type.REAL, "http://rdap.example/blah"); persistRegistrar("someRegistrar", 1448L, Registrar.Type.REAL, "http://rdap.example/blah");
@ -185,7 +187,7 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
.containsExactly("https://rdap.blacknight.com"); .containsExactly("https://rdap.blacknight.com");
} }
@Test @TestOfyAndSql
void testKnownIana_notReal_noChange() { void testKnownIana_notReal_noChange() {
// The IANA ID is in the JSON_LIST_REPLY // The IANA ID is in the JSON_LIST_REPLY
persistRegistrar("someRegistrar", 9999L, Registrar.Type.INTERNAL, "http://rdap.example/blah"); persistRegistrar("someRegistrar", 9999L, Registrar.Type.INTERNAL, "http://rdap.example/blah");
@ -198,7 +200,7 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
.containsExactly("http://rdap.example/blah"); .containsExactly("http://rdap.example/blah");
} }
@Test @TestOfyAndSql
void testKnownIana_notReal_nullIANA_noChange() { void testKnownIana_notReal_nullIANA_noChange() {
persistRegistrar("someRegistrar", null, Registrar.Type.TEST, "http://rdap.example/blah"); persistRegistrar("someRegistrar", null, Registrar.Type.TEST, "http://rdap.example/blah");
@ -210,7 +212,7 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
.containsExactly("http://rdap.example/blah"); .containsExactly("http://rdap.example/blah");
} }
@Test @TestOfyAndSql
void testKnownIana_multipleValues() { void testKnownIana_multipleValues() {
// The IANA ID is in the JSON_LIST_REPLY // The IANA ID is in the JSON_LIST_REPLY
persistRegistrar("registrar4000", 4000L, Registrar.Type.REAL, "http://rdap.example/blah"); persistRegistrar("registrar4000", 4000L, Registrar.Type.REAL, "http://rdap.example/blah");
@ -227,7 +229,7 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
.containsExactly("https://rdap.example.com"); .containsExactly("https://rdap.example.com");
} }
@Test @TestOfyAndSql
void testNoTlds() { void testNoTlds() {
deleteTld("tld"); deleteTld("tld");
assertThat(assertThrows(IllegalArgumentException.class, action::run)) assertThat(assertThrows(IllegalArgumentException.class, action::run))
@ -235,7 +237,7 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
.isEqualTo("There must exist at least one REAL TLD."); .isEqualTo("There must exist at least one REAL TLD.");
} }
@Test @TestOfyAndSql
void testOnlyTestTlds() { void testOnlyTestTlds() {
persistResource(Registry.get("tld").asBuilder().setTldType(TldType.TEST).build()); persistResource(Registry.get("tld").asBuilder().setTldType(TldType.TEST).build());
assertThat(assertThrows(IllegalArgumentException.class, action::run)) assertThat(assertThrows(IllegalArgumentException.class, action::run))
@ -243,7 +245,7 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
.isEqualTo("There must exist at least one REAL TLD."); .isEqualTo("There must exist at least one REAL TLD.");
} }
@Test @TestOfyAndSql
void testSecondTldSucceeds() { void testSecondTldSucceeds() {
createTld("secondtld"); createTld("secondtld");
httpTransport = new TestHttpTransport(); httpTransport = new TestHttpTransport();
@ -261,7 +263,7 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
action.run(); action.run();
} }
@Test @TestOfyAndSql
void testBothFail() { void testBothFail() {
createTld("secondtld"); createTld("secondtld");
httpTransport = new TestHttpTransport(); httpTransport = new TestHttpTransport();
@ -281,7 +283,7 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
.isEqualTo("Error contacting MosAPI server. Tried TLDs [secondtld, tld]"); .isEqualTo("Error contacting MosAPI server. Tried TLDs [secondtld, tld]");
} }
@Test @TestOfyAndSql
void testFailureCause_ignoresLoginFailure() { void testFailureCause_ignoresLoginFailure() {
// Login failures aren't particularly interesting so we should log them, but the final // Login failures aren't particularly interesting so we should log them, but the final
// throwable should be some other failure if one existed // throwable should be some other failure if one existed