diff --git a/core/src/main/java/google/registry/tools/DeleteTldCommand.java b/core/src/main/java/google/registry/tools/DeleteTldCommand.java index ec9ac4eea..2cabd4528 100644 --- a/core/src/main/java/google/registry/tools/DeleteTldCommand.java +++ b/core/src/main/java/google/registry/tools/DeleteTldCommand.java @@ -16,6 +16,7 @@ package google.registry.tools; import static com.google.common.base.Preconditions.checkState; import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import com.beust.jcommander.Parameter; @@ -61,13 +62,7 @@ final class DeleteTldCommand extends ConfirmingCommand implements CommandWithRem "Cannot delete TLD because registrar %s lists it as an allowed TLD", registrar.getClientId()); } - - int count = ofy().load() - .type(DomainBase.class) - .filter("tld", tld) - .limit(1) - .count(); - checkState(count == 0, "Cannot delete TLD because a domain is defined on it"); + checkState(!tldContainsDomains(tld), "Cannot delete TLD because a domain is defined on it"); } @Override @@ -77,8 +72,25 @@ final class DeleteTldCommand extends ConfirmingCommand implements CommandWithRem @Override protected String execute() { - tm().transactNew(() -> ofy().delete().entity(registry).now()); + tm().transactNew(() -> tm().delete(registry)); registry.invalidateInCache(); return String.format("Deleted TLD '%s'.\n", tld); } + + private boolean tldContainsDomains(String tld) { + if (tm().isOfy()) { + return ofy().load().type(DomainBase.class).filter("tld", tld).limit(1).count() > 0; + } else { + return jpaTm() + .transact( + () -> + jpaTm() + .query("FROM Domain WHERE tld = :tld", DomainBase.class) + .setParameter("tld", tld) + .setMaxResults(1) + .getResultStream() + .findFirst() + .isPresent()); + } + } } diff --git a/core/src/main/java/google/registry/tools/ListCursorsCommand.java b/core/src/main/java/google/registry/tools/ListCursorsCommand.java index eacd5e1b5..0dcc38b46 100644 --- a/core/src/main/java/google/registry/tools/ListCursorsCommand.java +++ b/core/src/main/java/google/registry/tools/ListCursorsCommand.java @@ -15,17 +15,19 @@ package google.registry.tools; import static com.google.common.collect.ImmutableMap.toImmutableMap; -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 com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; import com.google.common.base.Strings; -import com.googlecode.objectify.Key; +import com.google.common.collect.ImmutableMap; import google.registry.model.common.Cursor; import google.registry.model.common.Cursor.CursorType; import google.registry.model.registry.Registries; import google.registry.model.registry.Registry; import google.registry.model.registry.Registry.TldType; +import google.registry.persistence.VKey; import java.util.Map; import java.util.Optional; @@ -50,20 +52,18 @@ final class ListCursorsCommand implements CommandWithRemoteApi { @Override public void run() { - Map> registries = - Registries.getTlds() - .stream() + Map> registries = + Registries.getTlds().stream() .map(Registry::get) .filter(r -> r.getTldType() == filterTldType) .filter(r -> !filterEscrowEnabled || r.getEscrowEnabled()) - .collect(toImmutableMap(r -> r, r -> Cursor.createKey(cursorType, r))); - Map, Cursor> cursors = ofy().load().keys(registries.values()); + .collect(toImmutableMap(r -> r, r -> Cursor.createVKey(cursorType, r.getTldStr()))); + ImmutableMap, Cursor> cursors = + transactIfJpaTm(() -> tm().loadByKeysIfPresent(registries.values())); if (!registries.isEmpty()) { String header = String.format(OUTPUT_FMT, "TLD", "Cursor Time", "Last Update Time"); System.out.printf("%s\n%s\n", header, Strings.repeat("-", header.length())); - registries - .entrySet() - .stream() + registries.entrySet().stream() .map( e -> renderLine( diff --git a/core/src/main/java/google/registry/tools/server/ListHostsAction.java b/core/src/main/java/google/registry/tools/server/ListHostsAction.java index cab007ca1..27451be2b 100644 --- a/core/src/main/java/google/registry/tools/server/ListHostsAction.java +++ b/core/src/main/java/google/registry/tools/server/ListHostsAction.java @@ -15,13 +15,13 @@ package google.registry.tools.server; import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet; -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.request.Action.Method.GET; import static google.registry.request.Action.Method.POST; import static java.util.Comparator.comparing; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Streams; import google.registry.model.EppResourceUtils; import google.registry.model.host.HostResource; import google.registry.request.Action; @@ -51,7 +51,7 @@ public final class ListHostsAction extends ListObjectsAction { @Override public ImmutableSet loadObjects() { final DateTime now = clock.nowUtc(); - return Streams.stream(ofy().load().type(HostResource.class)) + return transactIfJpaTm(() -> tm().loadAllOf(HostResource.class)).stream() .filter(host -> EppResourceUtils.isActive(host, now)) .collect(toImmutableSortedSet(comparing(HostResource::getHostName))); } diff --git a/core/src/main/java/google/registry/tools/server/ListPremiumListsAction.java b/core/src/main/java/google/registry/tools/server/ListPremiumListsAction.java index 346755c79..662355c84 100644 --- a/core/src/main/java/google/registry/tools/server/ListPremiumListsAction.java +++ b/core/src/main/java/google/registry/tools/server/ListPremiumListsAction.java @@ -14,16 +14,21 @@ package google.registry.tools.server; -import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet; +import static google.registry.persistence.transaction.TransactionManagerFactory.tm; +import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.request.Action.Method.GET; import static google.registry.request.Action.Method.POST; import com.google.common.collect.ImmutableSet; import google.registry.model.registry.label.PremiumList; +import google.registry.model.registry.label.PremiumListDualDao; import google.registry.request.Action; import google.registry.request.auth.Auth; +import java.util.Comparator; +import java.util.Optional; import javax.inject.Inject; +import org.hibernate.Hibernate; /** * An action that lists premium lists, for use by the {@code nomulus list_premium_lists} command. @@ -46,7 +51,14 @@ public final class ListPremiumListsAction extends ListObjectsAction @Override public ImmutableSet loadObjects() { - return ImmutableSet.copyOf( - ofy().load().type(PremiumList.class).ancestor(getCrossTldKey()).list()); + return transactIfJpaTm( + () -> + tm().loadAllOf(PremiumList.class).stream() + .map(PremiumList::getName) + .map(PremiumListDualDao::getLatestRevision) + .filter(Optional::isPresent) + .map(Optional::get) + .peek(list -> Hibernate.initialize(list.getLabelsToPrices())) + .collect(toImmutableSortedSet(Comparator.comparing(PremiumList::getName)))); } } diff --git a/core/src/main/java/google/registry/tools/server/ListReservedListsAction.java b/core/src/main/java/google/registry/tools/server/ListReservedListsAction.java index c94d53e9d..4125ec253 100644 --- a/core/src/main/java/google/registry/tools/server/ListReservedListsAction.java +++ b/core/src/main/java/google/registry/tools/server/ListReservedListsAction.java @@ -14,15 +14,19 @@ package google.registry.tools.server; -import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet; +import static google.registry.persistence.transaction.TransactionManagerFactory.tm; +import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.request.Action.Method.GET; import static google.registry.request.Action.Method.POST; import com.google.common.collect.ImmutableSet; import google.registry.model.registry.label.ReservedList; +import google.registry.model.registry.label.ReservedListDualDatabaseDao; import google.registry.request.Action; import google.registry.request.auth.Auth; +import java.util.Comparator; +import java.util.Optional; import javax.inject.Inject; /** A that lists reserved lists, for use by the {@code nomulus list_reserved_lists} command. */ @@ -44,7 +48,13 @@ public final class ListReservedListsAction extends ListObjectsAction loadObjects() { - return ImmutableSet.copyOf( - ofy().load().type(ReservedList.class).ancestor(getCrossTldKey()).list()); + return transactIfJpaTm( + () -> + tm().loadAllOf(ReservedList.class).stream() + .map(ReservedList::getName) + .map(ReservedListDualDatabaseDao::getLatestRevision) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(toImmutableSortedSet(Comparator.comparing(ReservedList::getName)))); } } diff --git a/core/src/test/java/google/registry/tools/DeleteTldCommandTest.java b/core/src/test/java/google/registry/tools/DeleteTldCommandTest.java index 790efe03f..7d73ca891 100644 --- a/core/src/test/java/google/registry/tools/DeleteTldCommandTest.java +++ b/core/src/test/java/google/registry/tools/DeleteTldCommandTest.java @@ -27,11 +27,13 @@ import com.google.common.collect.ImmutableSortedMap; import google.registry.model.registry.Registry; import google.registry.model.registry.Registry.RegistryNotFoundException; import google.registry.model.registry.Registry.TldType; +import google.registry.testing.DualDatabaseTest; +import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; /** Unit tests for {@link DeleteTldCommand}. */ +@DualDatabaseTest class DeleteTldCommandTest extends CommandTestCase { private static final String TLD_REAL = "tldreal"; @@ -53,7 +55,7 @@ class DeleteTldCommandTest extends CommandTestCase { TldType.TEST)); } - @Test + @TestOfyAndSql void testSuccess_otherTldUnaffected() throws Exception { runCommandForced("--tld=" + TLD_TEST); @@ -61,24 +63,24 @@ class DeleteTldCommandTest extends CommandTestCase { assertThrows(RegistryNotFoundException.class, () -> Registry.get(TLD_TEST)); } - @Test + @TestOfyAndSql void testFailure_whenTldDoesNotExist() { assertThrows(RegistryNotFoundException.class, () -> runCommandForced("--tld=nonexistenttld")); } - @Test + @TestOfyAndSql void testFailure_whenTldIsReal() { assertThrows(IllegalStateException.class, () -> runCommandForced("--tld=" + TLD_REAL)); } - @Test + @TestOfyAndSql void testFailure_whenDomainsArePresent() { persistDeletedDomain("domain." + TLD_TEST, DateTime.parse("2000-01-01TZ")); assertThrows(IllegalStateException.class, () -> runCommandForced("--tld=" + TLD_TEST)); } - @Test + @TestOfyAndSql void testFailure_whenRegistrarLinksToTld() { allowRegistrarAccess("TheRegistrar", TLD_TEST); diff --git a/core/src/test/java/google/registry/tools/ListCursorsCommandTest.java b/core/src/test/java/google/registry/tools/ListCursorsCommandTest.java index d835c7940..982ac4ee1 100644 --- a/core/src/test/java/google/registry/tools/ListCursorsCommandTest.java +++ b/core/src/test/java/google/registry/tools/ListCursorsCommandTest.java @@ -24,14 +24,15 @@ import google.registry.model.common.Cursor; import google.registry.model.common.Cursor.CursorType; import google.registry.model.ofy.Ofy; import google.registry.model.registry.Registry; -import google.registry.testing.FakeClock; +import google.registry.testing.DualDatabaseTest; import google.registry.testing.InjectExtension; +import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link ListCursorsCommand}. */ +@DualDatabaseTest public class ListCursorsCommandTest extends CommandTestCase { private static final String HEADER_ONE = @@ -44,17 +45,17 @@ public class ListCursorsCommandTest extends CommandTestCase @BeforeEach void beforeEach() { - inject.setStaticField( - Ofy.class, "clock", new FakeClock(DateTime.parse("1984-12-21T06:07:08.789Z"))); + fakeClock.setTo(DateTime.parse("1984-12-21T06:07:08.789Z")); + inject.setStaticField(Ofy.class, "clock", fakeClock); } - @Test + @TestOfyAndSql void testListCursors_noTlds_printsNothing() throws Exception { runCommand("--type=BRDA"); assertThat(getStdoutAsString()).isEmpty(); } - @Test + @TestOfyAndSql void testListCursors_twoTldsOneAbsent_printsAbsentAndTimestampSorted() throws Exception { createTlds("foo", "bar"); persistResource( @@ -69,19 +70,19 @@ public class ListCursorsCommandTest extends CommandTestCase .inOrder(); } - @Test + @TestOfyAndSql void testListCursors_badCursor_throwsIae() { ParameterException thrown = assertThrows(ParameterException.class, () -> runCommand("--type=love")); assertThat(thrown).hasMessageThat().contains("Invalid value for --type parameter."); } - @Test + @TestOfyAndSql void testListCursors_lowercaseCursor_isAllowed() throws Exception { runCommand("--type=brda"); } - @Test + @TestOfyAndSql void testListCursors_filterEscrowEnabled_doesWhatItSays() throws Exception { createTlds("foo", "bar"); persistResource(Registry.get("bar").asBuilder().setEscrowEnabled(true).build()); diff --git a/core/src/test/java/google/registry/tools/server/ListHostsActionTest.java b/core/src/test/java/google/registry/tools/server/ListHostsActionTest.java index 29c9c7b49..6f5f5b614 100644 --- a/core/src/test/java/google/registry/tools/server/ListHostsActionTest.java +++ b/core/src/test/java/google/registry/tools/server/ListHostsActionTest.java @@ -17,13 +17,15 @@ package google.registry.tools.server; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.persistActiveHost; +import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; +import google.registry.testing.TestOfyAndSql; import java.util.Optional; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; /** Unit tests for {@link ListHostsAction}. */ +@DualDatabaseTest class ListHostsActionTest extends ListActionTestCase { private ListHostsAction action; @@ -35,7 +37,7 @@ class ListHostsActionTest extends ListActionTestCase { action.clock = new FakeClock(DateTime.parse("2000-01-01TZ")); } - @Test + @TestOfyAndSql void testRun_noParameters() { testRunSuccess( action, @@ -44,7 +46,7 @@ class ListHostsActionTest extends ListActionTestCase { null); } - @Test + @TestOfyAndSql void testRun_twoLinesWithRepoId() { persistActiveHost("example2.foo"); persistActiveHost("example1.foo"); @@ -59,7 +61,7 @@ class ListHostsActionTest extends ListActionTestCase { "^example2.foo\\s+2-ROID\\s*$"); } - @Test + @TestOfyAndSql void testRun_twoLinesWithWildcard() { persistActiveHost("example2.foo"); persistActiveHost("example1.foo"); @@ -74,7 +76,7 @@ class ListHostsActionTest extends ListActionTestCase { "^example2.foo\\s+.*1"); } - @Test + @TestOfyAndSql void testRun_twoLinesWithWildcardAndAnotherField() { persistActiveHost("example2.foo"); persistActiveHost("example1.foo"); @@ -89,7 +91,7 @@ class ListHostsActionTest extends ListActionTestCase { "^example2.foo\\s+.*1"); } - @Test + @TestOfyAndSql void testRun_withBadField_returnsError() { persistActiveHost("example2.foo"); persistActiveHost("example1.foo"); diff --git a/core/src/test/java/google/registry/tools/server/ListPremiumListsActionTest.java b/core/src/test/java/google/registry/tools/server/ListPremiumListsActionTest.java index a26500bd8..eda8ade0f 100644 --- a/core/src/test/java/google/registry/tools/server/ListPremiumListsActionTest.java +++ b/core/src/test/java/google/registry/tools/server/ListPremiumListsActionTest.java @@ -16,11 +16,15 @@ package google.registry.tools.server; import static google.registry.testing.DatabaseHelper.persistPremiumList; +import google.registry.testing.DualDatabaseTest; +import google.registry.testing.TestOfyAndSql; +import google.registry.testing.TestOfyOnly; +import google.registry.testing.TestSqlOnly; import java.util.Optional; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; /** Unit tests for {@link ListPremiumListsAction}. */ +@DualDatabaseTest class ListPremiumListsActionTest extends ListActionTestCase { private ListPremiumListsAction action; @@ -32,7 +36,7 @@ class ListPremiumListsActionTest extends ListActionTestCase { action = new ListPremiumListsAction(); } - @Test + @TestOfyAndSql void testRun_noParameters() { testRunSuccess( action, @@ -43,7 +47,7 @@ class ListPremiumListsActionTest extends ListActionTestCase { "^xn--q9jyb4c$"); } - @Test + @TestOfyOnly // only ofy has revisionKey void testRun_withParameters() { testRunSuccess( action, @@ -56,7 +60,20 @@ class ListPremiumListsActionTest extends ListActionTestCase { "^xn--q9jyb4c\\s+.*PremiumList.*$"); } - @Test + @TestSqlOnly + void testRun_withLabelsToPrices() { + testRunSuccess( + action, + Optional.of("labelsToPrices"), + Optional.empty(), + Optional.empty(), + "^name\\s+labelsToPrices\\s*$", + "^-+\\s+-+\\s*$", + "^how\\s+\\{richer=5000\\.00\\}$", + "^xn--q9jyb4c\\s+\\{rich=100\\.00\\}\\s+$"); + } + + @TestOfyOnly void testRun_withWildcard() { testRunSuccess( action, @@ -69,7 +86,7 @@ class ListPremiumListsActionTest extends ListActionTestCase { "^xn--q9jyb4c\\s+.*PremiumList"); } - @Test + @TestOfyAndSql void testRun_withBadField_returnsError() { testRunError( action, diff --git a/core/src/test/java/google/registry/tools/server/ListReservedListsActionTest.java b/core/src/test/java/google/registry/tools/server/ListReservedListsActionTest.java index c34e84b0f..6f56d4cc7 100644 --- a/core/src/test/java/google/registry/tools/server/ListReservedListsActionTest.java +++ b/core/src/test/java/google/registry/tools/server/ListReservedListsActionTest.java @@ -20,11 +20,13 @@ import static google.registry.testing.DatabaseHelper.persistResource; import google.registry.model.registry.Registry; import google.registry.model.registry.label.ReservedList; +import google.registry.testing.DualDatabaseTest; +import google.registry.testing.TestOfyAndSql; import java.util.Optional; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; /** Unit tests for {@link ListReservedListsAction}. */ +@DualDatabaseTest class ListReservedListsActionTest extends ListActionTestCase { private ListReservedListsAction action; @@ -38,7 +40,7 @@ class ListReservedListsActionTest extends ListActionTestCase { action = new ListReservedListsAction(); } - @Test + @TestOfyAndSql void testRun_noParameters() { testRunSuccess( action, @@ -49,7 +51,7 @@ class ListReservedListsActionTest extends ListActionTestCase { "^xn--q9jyb4c-published\\s*$"); } - @Test + @TestOfyAndSql void testRun_withParameters() { testRunSuccess( action, @@ -62,7 +64,7 @@ class ListReservedListsActionTest extends ListActionTestCase { "^xn--q9jyb4c-published\\s+true\\s*$"); } - @Test + @TestOfyAndSql void testRun_withWildcard() { testRunSuccess( action, @@ -75,7 +77,7 @@ class ListReservedListsActionTest extends ListActionTestCase { "^xn--q9jyb4c-published\\s+.*true"); } - @Test + @TestOfyAndSql void testRun_withBadField_returnsError() { testRunError( action,