diff --git a/core/src/main/java/google/registry/flows/domain/token/AllocationTokenFlowUtils.java b/core/src/main/java/google/registry/flows/domain/token/AllocationTokenFlowUtils.java index 5af042884..3fc31d53b 100644 --- a/core/src/main/java/google/registry/flows/domain/token/AllocationTokenFlowUtils.java +++ b/core/src/main/java/google/registry/flows/domain/token/AllocationTokenFlowUtils.java @@ -15,14 +15,13 @@ package google.registry.flows.domain.token; import static com.google.common.base.Preconditions.checkArgument; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.google.common.net.InternetDomainName; -import com.googlecode.objectify.Key; import google.registry.flows.EppException; import google.registry.flows.EppException.AssociationProhibitsOperationException; import google.registry.flows.EppException.AuthorizationErrorException; @@ -153,14 +152,15 @@ public class AllocationTokenFlowUtils { // See https://tools.ietf.org/html/draft-ietf-regext-allocation-token-04#section-2.1 throw new InvalidAllocationTokenException(); } - AllocationToken tokenEntity = ofy().load().key(Key.create(AllocationToken.class, token)).now(); - if (tokenEntity == null) { + Optional maybeTokenEntity = + tm().maybeLoad(VKey.create(AllocationToken.class, token)); + if (maybeTokenEntity.isEmpty()) { throw new InvalidAllocationTokenException(); } - if (tokenEntity.isRedeemed()) { + if (maybeTokenEntity.get().isRedeemed()) { throw new AlreadyRedeemedAllocationTokenException(); } - return tokenEntity; + return maybeTokenEntity.get(); } // Note: exception messages should be <= 32 characters long for domain check results diff --git a/core/src/main/java/google/registry/reporting/spec11/Spec11RegistrarThreatMatchesParser.java b/core/src/main/java/google/registry/reporting/spec11/Spec11RegistrarThreatMatchesParser.java index 474f1a7b2..d3adb241c 100644 --- a/core/src/main/java/google/registry/reporting/spec11/Spec11RegistrarThreatMatchesParser.java +++ b/core/src/main/java/google/registry/reporting/spec11/Spec11RegistrarThreatMatchesParser.java @@ -67,7 +67,6 @@ public class Spec11RegistrarThreatMatchesParser { if (!gcsUtils.existsAndNotEmpty(spec11ReportFilename)) { return ImmutableSet.of(); } - ImmutableSet.Builder builder = ImmutableSet.builder(); try (InputStream in = gcsUtils.openInputStream(spec11ReportFilename); InputStreamReader isr = new InputStreamReader(in, UTF_8)) { // Skip the header at line 0 diff --git a/core/src/main/java/google/registry/tools/DeleteAllocationTokensCommand.java b/core/src/main/java/google/registry/tools/DeleteAllocationTokensCommand.java index 25a88f859..346c027fa 100644 --- a/core/src/main/java/google/registry/tools/DeleteAllocationTokensCommand.java +++ b/core/src/main/java/google/registry/tools/DeleteAllocationTokensCommand.java @@ -14,19 +14,19 @@ package google.registry.tools; +import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.common.collect.Iterables.partition; import static com.google.common.collect.Streams.stream; import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE; -import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableSet; -import com.googlecode.objectify.Key; import google.registry.model.domain.token.AllocationToken; +import google.registry.persistence.VKey; import java.util.List; /** @@ -48,7 +48,7 @@ final class DeleteAllocationTokensCommand extends UpdateOrDeleteAllocationTokens private static final int BATCH_SIZE = 20; private static final Joiner JOINER = Joiner.on(", "); - private ImmutableSet> tokensToDelete; + private ImmutableSet> tokensToDelete; @Override public void init() { @@ -71,26 +71,24 @@ final class DeleteAllocationTokensCommand extends UpdateOrDeleteAllocationTokens } /** Deletes a (filtered) batch of AllocationTokens and returns how many were deleted. */ - private long deleteBatch(List> batch) { + private long deleteBatch(List> batch) { // Load the tokens in the same transaction as they are deleted to verify they weren't redeemed // since the query ran. This also filters out per-domain tokens if they're not to be deleted. - ImmutableSet tokensToDelete = - ofy().load().keys(batch).values().stream() - .filter(t -> withDomains || !t.getDomainName().isPresent()) + ImmutableSet> tokensToDelete = + tm().load(batch).values().stream() + .filter(t -> withDomains || t.getDomainName().isEmpty()) .filter(t -> SINGLE_USE.equals(t.getTokenType())) .filter(t -> !t.isRedeemed()) + .map(AllocationToken::createVKey) .collect(toImmutableSet()); if (!dryRun) { - ofy().delete().entities(tokensToDelete); + tm().delete(tokensToDelete); } System.out.printf( "%s tokens: %s\n", dryRun ? "Would delete" : "Deleted", JOINER.join( - tokensToDelete.stream() - .map(AllocationToken::getToken) - .sorted() - .collect(toImmutableSet()))); + tokensToDelete.stream().map(VKey::getSqlKey).sorted().collect(toImmutableList()))); return tokensToDelete.size(); } } diff --git a/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java b/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java index 4e25d1f41..b738106c3 100644 --- a/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java +++ b/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java @@ -20,8 +20,8 @@ import static com.google.common.collect.Queues.newArrayDeque; import static com.google.common.collect.Sets.difference; import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE; import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE; -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.util.CollectionUtils.nullToEmpty; import static google.registry.util.StringGenerator.DEFAULT_PASSWORD_LENGTH; import static java.nio.charset.StandardCharsets.UTF_8; @@ -38,10 +38,10 @@ import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.Iterables; import com.google.common.collect.Streams; import com.google.common.io.Files; -import com.googlecode.objectify.Key; import google.registry.model.domain.token.AllocationToken; import google.registry.model.domain.token.AllocationToken.TokenStatus; import google.registry.model.domain.token.AllocationToken.TokenType; +import google.registry.persistence.VKey; import google.registry.tools.params.TransitionListParameter.TokenStatusTransitions; import google.registry.util.CollectionUtils; import google.registry.util.NonFinalForTesting; @@ -258,8 +258,13 @@ class GenerateAllocationTokensCommand implements CommandWithRemoteApi { @VisibleForTesting int saveTokens(final ImmutableSet tokens) { - Collection savedTokens = - dryRun ? tokens : tm().transact(() -> ofy().save().entities(tokens).now().values()); + Collection savedTokens; + if (dryRun) { + savedTokens = tokens; + } else { + transactIfJpaTm(() -> tm().transact(() -> tm().putAll(tokens))); + savedTokens = tm().transact(() -> tm().loadAll(tokens)); + } savedTokens.forEach( t -> System.out.println(SKIP_NULLS.join(t.getDomainName().orElse(null), t.getToken()))); return savedTokens.size(); @@ -282,12 +287,14 @@ class GenerateAllocationTokensCommand implements CommandWithRemoteApi { } private ImmutableSet getExistingTokenStrings(ImmutableSet candidates) { - ImmutableSet> existingTokenKeys = + ImmutableSet> existingTokenKeys = candidates.stream() - .map(input -> Key.create(AllocationToken.class, input)) + .map(input -> VKey.create(AllocationToken.class, input)) .collect(toImmutableSet()); - return ofy().load().keys(existingTokenKeys).values().stream() - .map(AllocationToken::getToken) - .collect(toImmutableSet()); + return transactIfJpaTm( + () -> + tm().load(existingTokenKeys).values().stream() + .map(AllocationToken::getToken) + .collect(toImmutableSet())); } } diff --git a/core/src/main/java/google/registry/tools/GetAllocationTokenCommand.java b/core/src/main/java/google/registry/tools/GetAllocationTokenCommand.java index 35777a897..8cdbab0af 100644 --- a/core/src/main/java/google/registry/tools/GetAllocationTokenCommand.java +++ b/core/src/main/java/google/registry/tools/GetAllocationTokenCommand.java @@ -15,7 +15,6 @@ package google.registry.tools; import static com.google.common.collect.ImmutableList.toImmutableList; -import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import com.beust.jcommander.Parameter; @@ -26,6 +25,7 @@ import com.google.common.collect.Lists; import com.googlecode.objectify.Key; import google.registry.model.domain.DomainBase; import google.registry.model.domain.token.AllocationToken; +import google.registry.persistence.VKey; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -45,22 +45,26 @@ final class GetAllocationTokenCommand implements CommandWithRemoteApi { public void run() { ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); for (List tokens : Lists.partition(mainParameters, BATCH_SIZE)) { - ImmutableList> tokenKeys = - tokens.stream().map(t -> Key.create(AllocationToken.class, t)).collect(toImmutableList()); - ofy().load().keys(tokenKeys).forEach((k, v) -> builder.put(k.getName(), v)); + ImmutableList> tokenKeys = + tokens.stream() + .map(t -> VKey.create(AllocationToken.class, t)) + .collect(toImmutableList()); + tm().load(tokenKeys).forEach((k, v) -> builder.put(k.getSqlKey().toString(), v)); } ImmutableMap loadedTokens = builder.build(); - ImmutableMap, DomainBase> domains = loadRedeemedDomains(loadedTokens.values()); + ImmutableMap, DomainBase> domains = loadRedeemedDomains(loadedTokens.values()); for (String token : mainParameters) { if (loadedTokens.containsKey(token)) { AllocationToken loadedToken = loadedTokens.get(token); System.out.println(loadedToken.toString()); - if (!loadedToken.getRedemptionHistoryEntry().isPresent()) { + if (loadedToken.getRedemptionHistoryEntry().isEmpty()) { System.out.printf("Token %s was not redeemed.\n", token); } else { + Key domainOfyKey = + loadedToken.getRedemptionHistoryEntry().get().getOfyKey().getParent(); DomainBase domain = - domains.get(loadedToken.getRedemptionHistoryEntry().get().getOfyKey().getParent()); + domains.get(VKey.create(DomainBase.class, domainOfyKey.getName(), domainOfyKey)); if (domain == null) { System.out.printf("ERROR: Token %s was redeemed but domain can't be loaded.\n", token); } else { @@ -76,19 +80,23 @@ final class GetAllocationTokenCommand implements CommandWithRemoteApi { } } - private static ImmutableMap, DomainBase> loadRedeemedDomains( + @SuppressWarnings("unchecked") + private static ImmutableMap, DomainBase> loadRedeemedDomains( Collection tokens) { - ImmutableList> domainKeys = + ImmutableList> domainKeys = tokens.stream() .map(AllocationToken::getRedemptionHistoryEntry) .filter(Optional::isPresent) .map(Optional::get) .map(key -> tm().load(key)) .map(he -> (Key) he.getParent()) + .map(key -> VKey.create(DomainBase.class, key.getName(), key)) .collect(toImmutableList()); - ImmutableMap.Builder, DomainBase> domainsBuilder = new ImmutableMap.Builder<>(); - for (List> keys : Lists.partition(domainKeys, BATCH_SIZE)) { - domainsBuilder.putAll(ofy().load().keys(keys)); + ImmutableMap.Builder, DomainBase> domainsBuilder = + new ImmutableMap.Builder<>(); + for (List> keys : Lists.partition(domainKeys, BATCH_SIZE)) { + tm().load(ImmutableList.copyOf(keys)) + .forEach((k, v) -> domainsBuilder.put((VKey) k, v)); } return domainsBuilder.build(); } diff --git a/core/src/main/java/google/registry/tools/UpdateAllocationTokensCommand.java b/core/src/main/java/google/registry/tools/UpdateAllocationTokensCommand.java index 345a86549..539b58b5a 100644 --- a/core/src/main/java/google/registry/tools/UpdateAllocationTokensCommand.java +++ b/core/src/main/java/google/registry/tools/UpdateAllocationTokensCommand.java @@ -18,8 +18,8 @@ import static com.google.common.collect.ImmutableMap.toImmutableMap; import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.common.collect.Iterables.partition; import static com.google.common.collect.Streams.stream; -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; @@ -105,13 +105,17 @@ final class UpdateAllocationTokensCommand extends UpdateOrDeleteAllocationTokens } tokensToSave = - ofy().load().keys(getTokenKeys()).values().stream() - .collect(toImmutableMap(Function.identity(), this::updateToken)) - .entrySet() - .stream() - .filter(entry -> !entry.getKey().equals(entry.getValue())) // only update changed tokens - .map(Map.Entry::getValue) - .collect(toImmutableSet()); + transactIfJpaTm( + () -> + tm().load(getTokenKeys()).values().stream() + .collect(toImmutableMap(Function.identity(), this::updateToken)) + .entrySet() + .stream() + .filter( + entry -> + !entry.getKey().equals(entry.getValue())) // only update changed tokens + .map(Map.Entry::getValue) + .collect(toImmutableSet())); } @Override @@ -123,7 +127,7 @@ final class UpdateAllocationTokensCommand extends UpdateOrDeleteAllocationTokens protected String execute() { long numUpdated = stream(partition(tokensToSave, BATCH_SIZE)) - .mapToLong(batch -> tm().transact(() -> saveBatch(batch))) + .mapToLong(batch -> tm().transact(() -> saveBatch(ImmutableList.copyOf(batch)))) .sum(); return String.format("Updated %d tokens in total.", numUpdated); } @@ -141,9 +145,9 @@ final class UpdateAllocationTokensCommand extends UpdateOrDeleteAllocationTokens return builder.build(); } - private long saveBatch(List batch) { + private long saveBatch(ImmutableList batch) { if (!dryRun) { - ofy().save().entities(batch); + tm().putAll(batch); } System.out.printf( "%s tokens: %s\n", diff --git a/core/src/main/java/google/registry/tools/UpdateOrDeleteAllocationTokensCommand.java b/core/src/main/java/google/registry/tools/UpdateOrDeleteAllocationTokensCommand.java index bd400f447..23255f60f 100644 --- a/core/src/main/java/google/registry/tools/UpdateOrDeleteAllocationTokensCommand.java +++ b/core/src/main/java/google/registry/tools/UpdateOrDeleteAllocationTokensCommand.java @@ -15,13 +15,15 @@ package google.registry.tools; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.ImmutableSet.toImmutableSet; -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.google.common.collect.ImmutableSet; -import com.googlecode.objectify.Key; import google.registry.model.domain.token.AllocationToken; +import google.registry.persistence.VKey; import java.util.List; /** Shared base class for commands to update or delete allocation tokens. */ @@ -47,19 +49,28 @@ abstract class UpdateOrDeleteAllocationTokensCommand extends ConfirmingCommand description = "Do not actually update or delete the tokens; defaults to false") protected boolean dryRun; - protected ImmutableSet> getTokenKeys() { + protected ImmutableSet> getTokenKeys() { checkArgument( tokens == null ^ prefix == null, "Must provide one of --tokens or --prefix, not both / neither"); if (tokens != null) { - return tokens.stream() - .map(token -> Key.create(AllocationToken.class, token)) - .collect(toImmutableSet()); + ImmutableSet> keys = + tokens.stream() + .map(token -> VKey.create(AllocationToken.class, token)) + .collect(toImmutableSet()); + ImmutableSet> nonexistentKeys = + transactIfJpaTm( + () -> keys.stream().filter(key -> !tm().exists(key)).collect(toImmutableSet())); + checkState(nonexistentKeys.isEmpty(), "Tokens with keys %s did not exist.", nonexistentKeys); + return keys; } else { checkArgument(!prefix.isEmpty(), "Provided prefix should not be blank"); - return ofy().load().type(AllocationToken.class).keys().list().stream() - .filter(key -> key.getName().startsWith(prefix)) - .collect(toImmutableSet()); + return transactIfJpaTm( + () -> + tm().loadAll(AllocationToken.class).stream() + .filter(token -> token.getToken().startsWith(prefix)) + .map(AllocationToken::createVKey) + .collect(toImmutableSet())); } } } diff --git a/core/src/test/java/google/registry/model/domain/token/AllocationTokenTest.java b/core/src/test/java/google/registry/model/domain/token/AllocationTokenTest.java index 4581780d1..63dc21efa 100644 --- a/core/src/test/java/google/registry/model/domain/token/AllocationTokenTest.java +++ b/core/src/test/java/google/registry/model/domain/token/AllocationTokenTest.java @@ -16,15 +16,14 @@ package google.registry.model.domain.token; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth8.assertThat; -import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects; import static google.registry.model.domain.token.AllocationToken.TokenStatus.CANCELLED; import static google.registry.model.domain.token.AllocationToken.TokenStatus.ENDED; import static google.registry.model.domain.token.AllocationToken.TokenStatus.NOT_STARTED; import static google.registry.model.domain.token.AllocationToken.TokenStatus.VALID; import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE; import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE; -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 static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.persistActiveDomain; import static google.registry.testing.DatabaseHelper.persistResource; @@ -40,12 +39,14 @@ import google.registry.model.domain.DomainBase; import google.registry.model.domain.token.AllocationToken.TokenStatus; import google.registry.model.domain.token.AllocationToken.TokenType; import google.registry.model.reporting.HistoryEntry; -import google.registry.persistence.VKey; +import google.registry.testing.DualDatabaseTest; +import google.registry.testing.TestOfyAndSql; +import google.registry.testing.TestOfyOnly; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; /** Unit tests for {@link AllocationToken}. */ +@DualDatabaseTest public class AllocationTokenTest extends EntityTestCase { public AllocationTokenTest() { @@ -57,7 +58,7 @@ public class AllocationTokenTest extends EntityTestCase { createTld("foo"); } - @Test + @TestOfyAndSql void testPersistence() { AllocationToken unlimitedUseToken = persistResource( @@ -77,7 +78,7 @@ public class AllocationTokenTest extends EntityTestCase { .put(DateTime.now(UTC).plusWeeks(8), TokenStatus.ENDED) .build()) .build()); - assertThat(ofy().load().entity(unlimitedUseToken).now()).isEqualTo(unlimitedUseToken); + assertThat(transactIfJpaTm(() -> tm().load(unlimitedUseToken))).isEqualTo(unlimitedUseToken); DomainBase domain = persistActiveDomain("example.foo"); Key historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1); @@ -90,32 +91,10 @@ public class AllocationTokenTest extends EntityTestCase { .setCreationTimeForTest(DateTime.parse("2010-11-12T05:00:00Z")) .setTokenType(SINGLE_USE) .build()); - assertThat(ofy().load().entity(singleUseToken).now()).isEqualTo(singleUseToken); - - jpaTm() - .transact( - () -> { - jpaTm().insert(unlimitedUseToken); - jpaTm().insert(singleUseToken); - }); - jpaTm() - .transact( - () -> { - assertAboutImmutableObjects() - .that(jpaTm().load(VKey.createSql(AllocationToken.class, "abc123Unlimited"))) - .isEqualExceptFields( - unlimitedUseToken, - "creationTime", - "updateTimestamp", - "redemptionHistoryEntry"); - assertAboutImmutableObjects() - .that(jpaTm().load(VKey.createSql(AllocationToken.class, "abc123Single"))) - .isEqualExceptFields( - singleUseToken, "creationTime", "updateTimestamp", "redemptionHistoryEntry"); - }); + assertThat(transactIfJpaTm(() -> tm().load(singleUseToken))).isEqualTo(singleUseToken); } - @Test + @TestOfyOnly void testIndexing() throws Exception { DomainBase domain = persistActiveDomain("blahdomain.foo"); Key historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1); @@ -133,7 +112,7 @@ public class AllocationTokenTest extends EntityTestCase { "domainName"); } - @Test + @TestOfyAndSql void testCreationTime_autoPopulates() { AllocationToken tokenBeforePersisting = new AllocationToken.Builder().setToken("abc123").setTokenType(SINGLE_USE).build(); @@ -142,7 +121,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(tokenAfterPersisting.getCreationTime()).hasValue(fakeClock.nowUtc()); } - @Test + @TestOfyAndSql void testSetCreationTime_cantCallMoreThanOnce() { AllocationToken.Builder builder = new AllocationToken.Builder() @@ -156,7 +135,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Creation time can only be set once"); } - @Test + @TestOfyAndSql void testSetToken_cantCallMoreThanOnce() { AllocationToken.Builder builder = new AllocationToken.Builder().setToken("foobar"); IllegalStateException thrown = @@ -164,7 +143,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Token can only be set once"); } - @Test + @TestOfyAndSql void testSetTokenType_cantCallMoreThanOnce() { AllocationToken.Builder builder = new AllocationToken.Builder().setTokenType(TokenType.UNLIMITED_USE); @@ -173,7 +152,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Token type can only be set once"); } - @Test + @TestOfyAndSql void testBuild_DomainNameWithLessThanTwoParts() { IllegalArgumentException thrown = assertThrows( @@ -191,7 +170,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Invalid domain name: example"); } - @Test + @TestOfyAndSql void testBuild_invalidTld() { IllegalArgumentException thrown = assertThrows( @@ -209,7 +188,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Invalid domain name: example.nosuchtld"); } - @Test + @TestOfyAndSql void testBuild_domainNameOnlyOnSingleUse() { AllocationToken.Builder builder = new AllocationToken.Builder() @@ -222,7 +201,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Domain name can only be specified for SINGLE_USE tokens"); } - @Test + @TestOfyAndSql void testBuild_redemptionHistoryEntryOnlyInSingleUse() { DomainBase domain = persistActiveDomain("blahdomain.foo"); Key historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1); @@ -237,7 +216,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Redemption history entry can only be specified for SINGLE_USE tokens"); } - @Test + @TestOfyAndSql void testSetTransitions_notStartOfTime() { IllegalArgumentException thrown = assertThrows( @@ -255,7 +234,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("tokenStatusTransitions map must start at START_OF_TIME."); } - @Test + @TestOfyAndSql void testSetTransitions_badInitialValue() { IllegalArgumentException thrown = assertThrows( @@ -272,14 +251,14 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("tokenStatusTransitions must start with NOT_STARTED"); } - @Test + @TestOfyAndSql void testSetTransitions_invalidInitialTransitions() { // NOT_STARTED can only go to VALID or CANCELLED assertBadInitialTransition(NOT_STARTED); assertBadInitialTransition(ENDED); } - @Test + @TestOfyAndSql void testSetTransitions_badTransitionsFromValid() { // VALID can only go to ENDED or CANCELLED assertBadTransition( @@ -300,14 +279,14 @@ public class AllocationTokenTest extends EntityTestCase { NOT_STARTED); } - @Test + @TestOfyAndSql void testSetTransitions_terminalTransitions() { // both ENDED and CANCELLED are terminal assertTerminal(ENDED); assertTerminal(CANCELLED); } - @Test + @TestOfyAndSql void testSetDiscountFractionTooHigh() { IllegalArgumentException thrown = assertThrows( @@ -318,7 +297,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Discount fraction must be between 0 and 1 inclusive"); } - @Test + @TestOfyAndSql void testSetDiscountFractionTooLow() { IllegalArgumentException thrown = assertThrows( @@ -329,7 +308,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Discount fraction must be between 0 and 1 inclusive"); } - @Test + @TestOfyAndSql void testSetDiscountYearsTooHigh() { IllegalArgumentException thrown = assertThrows( @@ -340,7 +319,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Discount years must be between 1 and 10 inclusive"); } - @Test + @TestOfyAndSql void testSetDiscountYearsTooLow() { IllegalArgumentException thrown = assertThrows( @@ -351,7 +330,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Discount years must be between 1 and 10 inclusive"); } - @Test + @TestOfyAndSql void testBuild_noTokenType() { IllegalArgumentException thrown = assertThrows( @@ -360,7 +339,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Token type must be specified"); } - @Test + @TestOfyAndSql void testBuild_noToken() { IllegalArgumentException thrown = assertThrows( @@ -369,7 +348,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Token must not be null or empty"); } - @Test + @TestOfyAndSql void testBuild_emptyToken() { IllegalArgumentException thrown = assertThrows( @@ -378,7 +357,7 @@ public class AllocationTokenTest extends EntityTestCase { assertThat(thrown).hasMessageThat().isEqualTo("Token must not be blank"); } - @Test + @TestOfyAndSql void testBuild_discountPremiumsRequiresDiscountFraction() { IllegalArgumentException thrown = assertThrows( @@ -394,7 +373,7 @@ public class AllocationTokenTest extends EntityTestCase { .isEqualTo("Discount premiums can only be specified along with a discount fraction"); } - @Test + @TestOfyAndSql void testBuild_discountYearsRequiresDiscountFraction() { IllegalArgumentException thrown = assertThrows( diff --git a/core/src/test/java/google/registry/tools/CommandTestCase.java b/core/src/test/java/google/registry/tools/CommandTestCase.java index 3ccb7ef70..d128e0e6d 100644 --- a/core/src/test/java/google/registry/tools/CommandTestCase.java +++ b/core/src/test/java/google/registry/tools/CommandTestCase.java @@ -18,6 +18,8 @@ import static com.google.common.collect.Iterables.concat; import static com.google.common.collect.Iterables.toArray; import static com.google.common.truth.Truth.assertThat; 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 java.nio.charset.StandardCharsets.UTF_8; import static org.joda.time.DateTimeZone.UTC; @@ -185,7 +187,7 @@ public abstract class CommandTestCase { /** Reloads the given resource from Datastore. */ T reloadResource(T resource) { - return ofy().load().entity(resource).now(); + return transactIfJpaTm(() -> tm().load(resource)); } /** Returns count of all poll messages in Datastore. */ diff --git a/core/src/test/java/google/registry/tools/DeleteAllocationTokensCommandTest.java b/core/src/test/java/google/registry/tools/DeleteAllocationTokensCommandTest.java index 889753a70..70fca691e 100644 --- a/core/src/test/java/google/registry/tools/DeleteAllocationTokensCommandTest.java +++ b/core/src/test/java/google/registry/tools/DeleteAllocationTokensCommandTest.java @@ -16,23 +16,28 @@ package google.registry.tools; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE; -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.testing.DatabaseHelper.createTlds; import static google.registry.testing.DatabaseHelper.persistActiveDomain; import static google.registry.testing.DatabaseHelper.persistResource; import static org.junit.jupiter.api.Assertions.assertThrows; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; import google.registry.model.domain.DomainBase; import google.registry.model.domain.token.AllocationToken; import google.registry.model.domain.token.AllocationToken.TokenType; import google.registry.model.reporting.HistoryEntry; -import java.util.Collection; +import google.registry.testing.DualDatabaseTest; +import google.registry.testing.TestOfyAndSql; +import java.util.Arrays; import javax.annotation.Nullable; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; /** Unit tests for {@link DeleteAllocationTokensCommand}. */ +@DualDatabaseTest class DeleteAllocationTokensCommandTest extends CommandTestCase { private AllocationToken preRed1; @@ -53,38 +58,38 @@ class DeleteAllocationTokensCommandTest extends CommandTestCase tm().loadAll(AllocationToken.class).size())).isEqualTo(56); runCommandForced("--prefix", "batch"); - assertThat(ofy().load().type(AllocationToken.class).count()).isEqualTo(56 - 25); + assertThat(transactIfJpaTm(() -> tm().loadAll(AllocationToken.class).size())) + .isEqualTo(56 - 25); } - @Test + @TestOfyAndSql void test_prefixIsRequired() { IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, this::runCommandForced); @@ -143,7 +149,7 @@ class DeleteAllocationTokensCommandTest extends CommandTestCase runCommandForced("--prefix", "")); @@ -177,7 +183,11 @@ class DeleteAllocationTokensCommandTest extends CommandTestCase reloadTokens(AllocationToken... tokens) { - return ofy().load().entities(tokens).values(); + private static ImmutableList reloadTokens(AllocationToken... tokens) { + return transactIfJpaTm(() -> tm().loadAll(ImmutableSet.copyOf(tokens))); + } + + private static void assertNonexistent(AllocationToken... tokens) { + Arrays.stream(tokens).forEach(t -> transactIfJpaTm(() -> assertThat(tm().exists(t)).isFalse())); } } diff --git a/core/src/test/java/google/registry/tools/GenerateAllocationTokensCommandTest.java b/core/src/test/java/google/registry/tools/GenerateAllocationTokensCommandTest.java index 37af7d9d4..1c3232cb3 100644 --- a/core/src/test/java/google/registry/tools/GenerateAllocationTokensCommandTest.java +++ b/core/src/test/java/google/registry/tools/GenerateAllocationTokensCommandTest.java @@ -17,7 +17,8 @@ package google.registry.tools; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE; import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE; -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.testing.DatabaseHelper.assertAllocationTokens; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.persistResource; @@ -43,8 +44,10 @@ import google.registry.model.reporting.HistoryEntry; import google.registry.persistence.VKey; import google.registry.testing.DeterministicStringGenerator; import google.registry.testing.DeterministicStringGenerator.Rule; +import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.FakeSleeper; +import google.registry.testing.TestOfyAndSql; import google.registry.util.Retrier; import google.registry.util.StringGenerator.Alphabets; import java.io.File; @@ -52,10 +55,10 @@ import java.util.Collection; import javax.annotation.Nullable; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatchers; /** Unit tests for {@link GenerateAllocationTokensCommand}. */ +@DualDatabaseTest class GenerateAllocationTokensCommandTest extends CommandTestCase { @BeforeEach @@ -65,14 +68,14 @@ class GenerateAllocationTokensCommandTest extends CommandTestCase tm().loadAll(AllocationToken.class).size())).isEqualTo(100); } - @Test + @TestOfyAndSql void testSuccess_domainNames() throws Exception { createTld("tld"); File domainNamesFile = tmpDir.resolve("domain_names.txt").toFile(); @@ -148,7 +151,7 @@ class GenerateAllocationTokensCommandTest extends CommandTestCase sampleTokens = command.stringGenerator.createStrings(13, 100); runCommand("--tokens", Joiner.on(",").join(sampleTokens)); assertInStdout(Iterables.toArray(sampleTokens, String.class)); - assertThat(ofy().load().type(AllocationToken.class).count()).isEqualTo(100); + assertThat(transactIfJpaTm(() -> tm().loadAll(AllocationToken.class).size())).isEqualTo(100); } - @Test + @TestOfyAndSql void testFailure_mustSpecifyNumberOfTokensOrDomainsFile() { IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> runCommand("--prefix", "FEET")); @@ -208,7 +211,7 @@ class GenerateAllocationTokensCommandTest extends CommandTestCase { - @Test + @TestOfyAndSql void testUpdateTlds_setTlds() throws Exception { AllocationToken token = persistResource(builderWithPromo().setAllowedTlds(ImmutableSet.of("toRemove")).build()); @@ -43,7 +45,7 @@ class UpdateAllocationTokensCommandTest extends CommandTestCase runCommandForced("--prefix", ""));