diff --git a/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java b/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java index fcfaa91e3..f270127a5 100644 --- a/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java +++ b/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java @@ -14,6 +14,7 @@ package google.registry.model.ofy; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableMap.toImmutableMap; import static com.google.common.collect.ImmutableSet.toImmutableSet; @@ -401,11 +402,13 @@ public class DatastoreTransactionManager implements TransactionManager { } private static class DatastoreQueryComposerImpl extends QueryComposer { + DatastoreQueryComposerImpl(Class entityClass) { super(entityClass); } Query buildQuery() { + checkOnlyOneInequalityField(); Query result = ofy().load().type(entityClass); for (WhereClause pred : predicates) { result = result.filter(pred.fieldName + pred.comparator.getDatastoreString(), pred.value); @@ -420,7 +423,7 @@ public class DatastoreTransactionManager implements TransactionManager { @Override public Optional first() { - return Optional.ofNullable(buildQuery().first().now()); + return Optional.ofNullable(buildQuery().limit(1).first().now()); } @Override @@ -449,5 +452,20 @@ public class DatastoreTransactionManager implements TransactionManager { public List list() { return buildQuery().list(); } + + private void checkOnlyOneInequalityField() { + // Datastore inequality queries are limited to one property, see + // https://cloud.google.com/appengine/docs/standard/go111/datastore/query-restrictions#inequality_filters_are_limited_to_at_most_one_property + long numInequalityFields = + predicates.stream() + .filter(pred -> !pred.comparator.equals(Comparator.EQ)) + .map(pred -> pred.fieldName) + .distinct() + .count(); + checkArgument( + numInequalityFields <= 1, + "Datastore cannot handle inequality queries on multiple fields, we found %s fields.", + numInequalityFields); + } } } diff --git a/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java b/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java index 06fe2d876..e72ac797f 100644 --- a/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java +++ b/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java @@ -69,7 +69,7 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager { // The entity of classes in this set will be simply ignored when passed to modification // operations, i.e. insert, put, update and delete. This is to help maintain a single code path - // when we switch from ofy() to tm() for the database migration as we don't need have a condition + // when we switch from ofy to tm() for the database migration as we don't need have a condition // to exclude the Datastore specific entities when the underlying tm() is jpaTm(). // TODO(b/176108270): Remove this property after database migration. private static final ImmutableSet> IGNORED_ENTITY_CLASSES = diff --git a/core/src/main/java/google/registry/tools/AckPollMessagesCommand.java b/core/src/main/java/google/registry/tools/AckPollMessagesCommand.java index 62f432d39..71a219c98 100644 --- a/core/src/main/java/google/registry/tools/AckPollMessagesCommand.java +++ b/core/src/main/java/google/registry/tools/AckPollMessagesCommand.java @@ -17,7 +17,7 @@ package google.registry.tools; import static com.google.common.base.Strings.isNullOrEmpty; import static google.registry.flows.poll.PollFlowUtils.SQL_POLL_MESSAGE_QUERY; import static google.registry.flows.poll.PollFlowUtils.datastorePollMessageQuery; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.model.poll.PollMessageExternalKeyConverter.makePollMessageExternalId; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; @@ -107,7 +107,7 @@ final class AckPollMessagesCommand implements CommandWithRemoteApi { tm().transact( () -> // Load poll messages and filter to just those of interest. - ofy().load().keys(keys).values().stream() + auditedOfy().load().keys(keys).values().stream() .filter(pm -> isNullOrEmpty(message) || pm.getMsg().contains(message)) .forEach(this::actOnPollMessage)); } diff --git a/core/src/main/java/google/registry/tools/CompareReservedListsCommand.java b/core/src/main/java/google/registry/tools/CompareReservedListsCommand.java index 2449b17e6..27731befc 100644 --- a/core/src/main/java/google/registry/tools/CompareReservedListsCommand.java +++ b/core/src/main/java/google/registry/tools/CompareReservedListsCommand.java @@ -16,7 +16,7 @@ package google.registry.tools; import static com.google.common.collect.ImmutableSet.toImmutableSet; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import com.beust.jcommander.Parameters; @@ -37,7 +37,7 @@ final class CompareReservedListsCommand implements CommandWithRemoteApi { @Override public void run() { ImmutableSet datastoreLists = - ofy().load().type(ReservedList.class).ancestor(getCrossTldKey()).list().stream() + auditedOfy().load().type(ReservedList.class).ancestor(getCrossTldKey()).list().stream() .map(ReservedList::getName) .collect(toImmutableSet()); diff --git a/core/src/main/java/google/registry/tools/DedupeRecurringBillingEventIdsCommand.java b/core/src/main/java/google/registry/tools/DedupeRecurringBillingEventIdsCommand.java index 57b2840b5..e131e4346 100644 --- a/core/src/main/java/google/registry/tools/DedupeRecurringBillingEventIdsCommand.java +++ b/core/src/main/java/google/registry/tools/DedupeRecurringBillingEventIdsCommand.java @@ -15,7 +15,7 @@ package google.registry.tools; import static com.google.common.collect.ImmutableSet.toImmutableSet; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.ofy.ObjectifyService.auditedOfy; import com.beust.jcommander.Parameters; import com.google.common.collect.ImmutableSet; @@ -61,9 +61,9 @@ public class DedupeRecurringBillingEventIdsCommand extends ReadEntityFromKeyPath // Loads the associated DomainBase and BillingEvent.OneTime entities that // may have reference to this BillingEvent.Recurring entity. Key domainKey = getGrandParentAsDomain(Key.create(recurring)); - DomainBase domain = ofy().load().key(domainKey).now(); + DomainBase domain = auditedOfy().load().key(domainKey).now(); List oneTimes = - ofy().load().type(BillingEvent.OneTime.class).ancestor(domainKey).list(); + auditedOfy().load().type(BillingEvent.OneTime.class).ancestor(domainKey).list(); VKey oldRecurringVKey = recurring.createVKey(); // By setting id to 0L, Buildable.build() will assign an application wide unique id to it. diff --git a/core/src/main/java/google/registry/tools/DeleteTldCommand.java b/core/src/main/java/google/registry/tools/DeleteTldCommand.java index 2cabd4528..d7288b3db 100644 --- a/core/src/main/java/google/registry/tools/DeleteTldCommand.java +++ b/core/src/main/java/google/registry/tools/DeleteTldCommand.java @@ -15,9 +15,8 @@ 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 static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -25,6 +24,7 @@ import google.registry.model.domain.DomainBase; import google.registry.model.registrar.Registrar; import google.registry.model.registry.Registry; import google.registry.model.registry.Registry.TldType; +import google.registry.persistence.transaction.QueryComposer.Comparator; /** * Command to delete the {@link Registry} associated with the specified TLD in Datastore. @@ -78,19 +78,11 @@ final class DeleteTldCommand extends ConfirmingCommand implements CommandWithRem } 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()); - } + return transactIfJpaTm( + () -> + tm().createQueryComposer(DomainBase.class) + .where("tld", Comparator.EQ, tld) + .first() + .isPresent()); } } diff --git a/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java b/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java index f761d593a..1c1fbf9f6 100644 --- a/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java +++ b/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java @@ -16,9 +16,7 @@ package google.registry.tools; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.io.BaseEncoding.base16; -import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.registry.Registries.assertTldExists; -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.util.DateTimeUtils.isBeforeOrAt; @@ -30,12 +28,14 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import google.registry.model.domain.DomainBase; import google.registry.model.host.HostResource; +import google.registry.persistence.transaction.QueryComposer.Comparator; import google.registry.tools.params.PathParameter; import google.registry.util.Clock; import java.net.InetAddress; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; import java.util.Map; import javax.inject.Inject; import org.joda.time.DateTime; @@ -74,15 +74,12 @@ final class GenerateDnsReportCommand implements CommandWithRemoteApi { String generate() { result.append("[\n"); - Iterable domains = - tm().isOfy() - ? ofy().load().type(DomainBase.class).filter("tld", tld) - : tm().transact( - () -> - jpaTm() - .query("FROM Domain WHERE tld = :tld", DomainBase.class) - .setParameter("tld", tld) - .getResultList()); + List domains = + transactIfJpaTm( + () -> + tm().createQueryComposer(DomainBase.class) + .where("tld", Comparator.EQ, tld) + .list()); for (DomainBase domain : domains) { // Skip deleted domains and domains that don't get published to DNS. if (isBeforeOrAt(domain.getDeletionTime(), now) || !domain.shouldPublishToDns()) { diff --git a/core/src/main/java/google/registry/tools/GetResourceByKeyCommand.java b/core/src/main/java/google/registry/tools/GetResourceByKeyCommand.java index 235c93b4f..9b345916f 100644 --- a/core/src/main/java/google/registry/tools/GetResourceByKeyCommand.java +++ b/core/src/main/java/google/registry/tools/GetResourceByKeyCommand.java @@ -15,7 +15,7 @@ package google.registry.tools; import static com.google.common.base.Preconditions.checkNotNull; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.ofy.ObjectifyService.auditedOfy; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -47,7 +47,7 @@ final class GetResourceByKeyCommand implements CommandWithRemoteApi { checkNotNull(Key.create(keyString), "Could not parse key string: " + keyString); EppResource resource = checkNotNull( - ofy().load().key(resourceKey).now(), + auditedOfy().load().key(resourceKey).now(), "Could not load resource for key: " + resourceKey); System.out.println(expand ? resource.toHydratedString() : resource.toString()); } diff --git a/core/src/main/java/google/registry/tools/ReadEntityFromKeyPathCommand.java b/core/src/main/java/google/registry/tools/ReadEntityFromKeyPathCommand.java index 6900b1630..37973367d 100644 --- a/core/src/main/java/google/registry/tools/ReadEntityFromKeyPathCommand.java +++ b/core/src/main/java/google/registry/tools/ReadEntityFromKeyPathCommand.java @@ -15,7 +15,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.model.ofy.ObjectifyService.auditedOfy; import static java.nio.charset.StandardCharsets.UTF_8; import com.beust.jcommander.Parameter; @@ -64,7 +64,7 @@ abstract class ReadEntityFromKeyPathCommand extends MutatingCommand { : Files.readLines(keyPathsFile, UTF_8); for (String keyPath : keyPaths) { Key untypedKey = parseKeyPath(keyPath); - Object entity = ofy().load().key(untypedKey).now(); + Object entity = auditedOfy().load().key(untypedKey).now(); if (entity == null) { System.err.printf( "Entity %s read from %s doesn't exist in Datastore! Skipping.%n", diff --git a/core/src/main/java/google/registry/tools/RegistryCli.java b/core/src/main/java/google/registry/tools/RegistryCli.java index bdb5e7ca9..d506f94ef 100644 --- a/core/src/main/java/google/registry/tools/RegistryCli.java +++ b/core/src/main/java/google/registry/tools/RegistryCli.java @@ -15,7 +15,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.tm; import static google.registry.tools.Injector.injectReflectively; import static java.nio.charset.StandardCharsets.UTF_8; @@ -244,7 +244,7 @@ final class RegistryCli implements AutoCloseable, CommandRunner { ObjectifyService.initOfy(); // Make sure we start the command with a clean cache, so that any previous command won't // interfere with this one. - ofy().clearSessionCache(); + tm().clearSessionCache(); // Enable Cloud SQL for command that needs remote API as they will very likely use // Cloud SQL after the database migration. Note that the DB password is stored in Datastore diff --git a/core/src/main/java/google/registry/tools/ResaveEntitiesCommand.java b/core/src/main/java/google/registry/tools/ResaveEntitiesCommand.java index a9b6779dc..44fe17bf3 100644 --- a/core/src/main/java/google/registry/tools/ResaveEntitiesCommand.java +++ b/core/src/main/java/google/registry/tools/ResaveEntitiesCommand.java @@ -15,7 +15,7 @@ package google.registry.tools; import static com.google.common.collect.Lists.partition; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.ofy.ObjectifyService.auditedOfy; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -44,7 +44,8 @@ public final class ResaveEntitiesCommand extends MutatingCommand { protected void init() { for (List batch : partition(mainParameters, BATCH_SIZE)) { for (String websafeKey : batch) { - ImmutableObject entity = ofy().load().key(Key.create(websafeKey)).now(); + ImmutableObject entity = + auditedOfy().load().key(Key.create(websafeKey)).now(); stageEntityChange(entity, entity); } flushTransaction(); diff --git a/core/src/main/java/google/registry/tools/ResaveEnvironmentEntitiesCommand.java b/core/src/main/java/google/registry/tools/ResaveEnvironmentEntitiesCommand.java index 725c475b5..f73dd08b5 100644 --- a/core/src/main/java/google/registry/tools/ResaveEnvironmentEntitiesCommand.java +++ b/core/src/main/java/google/registry/tools/ResaveEnvironmentEntitiesCommand.java @@ -16,7 +16,7 @@ package google.registry.tools; import static com.google.common.collect.Lists.partition; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import com.beust.jcommander.Parameters; @@ -46,8 +46,9 @@ final class ResaveEnvironmentEntitiesCommand implements CommandWithRemoteApi { private static void batchSave(Class clazz) { System.out.printf("Re-saving %s entities.\n", clazz.getSimpleName()); for (final Iterable> batch : - partition(ofy().load().type(clazz).ancestor(getCrossTldKey()).keys().list(), BATCH_SIZE)) { - tm().transact(() -> ofy().save().entities(ofy().load().keys(batch).values())); + partition( + auditedOfy().load().type(clazz).ancestor(getCrossTldKey()).keys().list(), BATCH_SIZE)) { + tm().transact(() -> auditedOfy().save().entities(auditedOfy().load().keys(batch).values())); System.out.printf("Re-saved entities batch: %s.\n", batch); } } diff --git a/core/src/main/java/google/registry/tools/javascrap/BackfillSpec11ThreatMatchesCommand.java b/core/src/main/java/google/registry/tools/javascrap/BackfillSpec11ThreatMatchesCommand.java index 03d1cdd0b..2e77cc5de 100644 --- a/core/src/main/java/google/registry/tools/javascrap/BackfillSpec11ThreatMatchesCommand.java +++ b/core/src/main/java/google/registry/tools/javascrap/BackfillSpec11ThreatMatchesCommand.java @@ -17,9 +17,9 @@ package google.registry.tools.javascrap; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.ImmutableListMultimap.flatteningToImmutableListMultimap; import static com.google.common.collect.ImmutableSet.toImmutableSet; -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 com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -31,6 +31,7 @@ import google.registry.model.domain.DomainBase; import google.registry.model.reporting.Spec11ThreatMatch; import google.registry.model.reporting.Spec11ThreatMatch.ThreatType; import google.registry.model.reporting.Spec11ThreatMatchDao; +import google.registry.persistence.transaction.QueryComposer; import google.registry.reporting.spec11.RegistrarThreatMatches; import google.registry.reporting.spec11.Spec11RegistrarThreatMatchesParser; import google.registry.tools.CommandWithRemoteApi; @@ -148,21 +149,14 @@ public class BackfillSpec11ThreatMatchesCommand extends ConfirmingCommand /** Loads in all {@link DomainBase} objects for a given FQDN. */ private List loadDomainsForFqdn(String fullyQualifiedDomainName) { - if (tm().isOfy()) { - return ofy() - .load() - .type(DomainBase.class) - .filter("fullyQualifiedDomainName", fullyQualifiedDomainName) - .list(); - } else { - return jpaTm() - .transact( - () -> - jpaTm() - .query("FROM Domain WHERE fullyQualifiedDomainName = :fqdn", DomainBase.class) - .setParameter("fqdn", fullyQualifiedDomainName) - .getResultList()); - } + return transactIfJpaTm( + () -> + tm().createQueryComposer(DomainBase.class) + .where( + "fullyQualifiedDomainName", + QueryComposer.Comparator.EQ, + fullyQualifiedDomainName) + .list()); } /** Converts the previous {@link ThreatMatch} object to {@link Spec11ThreatMatch}. */ diff --git a/core/src/main/java/google/registry/tools/javascrap/DeleteContactByRoidCommand.java b/core/src/main/java/google/registry/tools/javascrap/DeleteContactByRoidCommand.java index 652a532c9..ce6dc8cd6 100644 --- a/core/src/main/java/google/registry/tools/javascrap/DeleteContactByRoidCommand.java +++ b/core/src/main/java/google/registry/tools/javascrap/DeleteContactByRoidCommand.java @@ -15,7 +15,7 @@ package google.registry.tools.javascrap; import static com.google.common.base.Verify.verify; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import com.beust.jcommander.Parameter; @@ -52,12 +52,12 @@ public class DeleteContactByRoidCommand extends ConfirmingCommand implements Com ImmutableList> toDelete; @Override - protected void init() throws Exception { + protected void init() { System.out.printf("Deleting %s, which refers to %s.\n", roid, contactId); tm().transact( () -> { Key targetKey = Key.create(ContactResource.class, roid); - ContactResource targetContact = ofy().load().key(targetKey).now(); + ContactResource targetContact = auditedOfy().load().key(targetKey).now(); verify( Objects.equals(targetContact.getContactId(), contactId), "contactId does not match."); @@ -76,7 +76,7 @@ public class DeleteContactByRoidCommand extends ConfirmingCommand implements Com roid, canonicalResource); List ancestors = - ofy().load().ancestor(Key.create(ContactResource.class, roid)).list(); + auditedOfy().load().ancestor(Key.create(ContactResource.class, roid)).list(); System.out.println("Ancestor query returns: "); for (Object entity : ancestors) { @@ -92,7 +92,7 @@ public class DeleteContactByRoidCommand extends ConfirmingCommand implements Com .collect(ImmutableList.toImmutableList()); EppResourceIndex eppResourceIndex = - ofy().load().entity(EppResourceIndex.create(targetKey)).now(); + auditedOfy().load().entity(EppResourceIndex.create(targetKey)).now(); verify(eppResourceIndex.getKey().equals(targetKey), "Wrong EppResource Index loaded"); System.out.printf("\n\nEppResourceIndex found (%s).\n", Key.create(eppResourceIndex)); @@ -103,13 +103,13 @@ public class DeleteContactByRoidCommand extends ConfirmingCommand implements Com .build(); System.out.printf("\n\nAbout to delete %s entities:\n", toDelete.size()); - toDelete.forEach(key -> System.out.println(key)); + toDelete.forEach(System.out::println); }); } @Override protected String execute() { - tm().transact(() -> ofy().delete().keys(toDelete).now()); + tm().transact(() -> auditedOfy().delete().keys(toDelete).now()); return "Done"; } } diff --git a/core/src/main/java/google/registry/tools/server/DeleteEntityAction.java b/core/src/main/java/google/registry/tools/server/DeleteEntityAction.java index 19cfda228..9f8c6807f 100644 --- a/core/src/main/java/google/registry/tools/server/DeleteEntityAction.java +++ b/core/src/main/java/google/registry/tools/server/DeleteEntityAction.java @@ -16,7 +16,7 @@ package google.registry.tools.server; import static com.google.appengine.api.datastore.DatastoreServiceFactory.getDatastoreService; import static com.googlecode.objectify.Key.create; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import com.google.appengine.api.datastore.Entity; @@ -95,7 +95,7 @@ public class DeleteEntityAction implements Runnable { getDatastoreService().delete(rawDeletions); // Delete ofy entities. final ImmutableList ofyDeletions = ofyDeletionsBuilder.build(); - tm().transactNew(() -> ofy().delete().entities(ofyDeletions).now()); + tm().transactNew(() -> auditedOfy().delete().entities(ofyDeletions).now()); String message = String.format( "Deleted %d raw entities and %d registered entities", rawDeletions.size(), @@ -106,8 +106,9 @@ public class DeleteEntityAction implements Runnable { private Optional loadOfyEntity(Key rawKey) { try { - EntityMetadata metadata = ofy().factory().getMetadata(rawKey.getKind()); - return Optional.ofNullable(metadata == null ? null : ofy().load().key(create(rawKey)).now()); + EntityMetadata metadata = auditedOfy().factory().getMetadata(rawKey.getKind()); + return Optional.ofNullable( + metadata == null ? null : auditedOfy().load().key(create(rawKey)).now()); } catch (Throwable e) { logger.atWarning().withCause(e).log( "Could not load entity with key %s using Objectify; falling back to raw Datastore.", diff --git a/core/src/main/java/google/registry/tools/server/KillAllEntitiesReducer.java b/core/src/main/java/google/registry/tools/server/KillAllEntitiesReducer.java index 2a53103cd..566bd35ad 100644 --- a/core/src/main/java/google/registry/tools/server/KillAllEntitiesReducer.java +++ b/core/src/main/java/google/registry/tools/server/KillAllEntitiesReducer.java @@ -15,7 +15,7 @@ package google.registry.tools.server; import static com.google.common.collect.Iterators.partition; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import com.google.appengine.tools.mapreduce.Reducer; @@ -37,7 +37,7 @@ public class KillAllEntitiesReducer extends Reducer, Key, Void> { while (batches.hasNext()) { final List> batch = batches.next(); // Use a transaction to get retrying for free. - tm().transact(() -> ofy().deleteWithoutBackup().keys(batch)); + tm().transact(() -> auditedOfy().deleteWithoutBackup().keys(batch)); getContext().incrementCounter("entities deleted", batch.size()); for (Key key : batch) { getContext().incrementCounter(String.format("%s deleted", key.getKind())); diff --git a/core/src/main/java/google/registry/tools/server/KillAllEppResourcesAction.java b/core/src/main/java/google/registry/tools/server/KillAllEppResourcesAction.java index 5f89b7add..c5ae16010 100644 --- a/core/src/main/java/google/registry/tools/server/KillAllEppResourcesAction.java +++ b/core/src/main/java/google/registry/tools/server/KillAllEppResourcesAction.java @@ -15,7 +15,7 @@ package google.registry.tools.server; import static com.google.common.base.Preconditions.checkArgument; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.request.Action.Method.POST; import com.google.appengine.tools.mapreduce.Mapper; @@ -90,10 +90,10 @@ public class KillAllEppResourcesAction implements Runnable { Key eriKey = Key.create(eri); emitAndIncrementCounter(eriKey, eriKey); Key resourceKey = eri.getKey(); - for (Key key : ofy().load().ancestor(resourceKey).keys()) { + for (Key key : auditedOfy().load().ancestor(resourceKey).keys()) { emitAndIncrementCounter(resourceKey, key); } - EppResource resource = ofy().load().key(eri.getKey()).now(); + EppResource resource = auditedOfy().load().key(eri.getKey()).now(); // TODO(b/28247733): What about FKI's for renamed hosts? Key indexKey = ForeignKeyIndex.createKey(resource); emitAndIncrementCounter(indexKey, indexKey); diff --git a/core/src/main/java/google/registry/tools/server/ListDomainsAction.java b/core/src/main/java/google/registry/tools/server/ListDomainsAction.java index c2f325c07..0d63f93bd 100644 --- a/core/src/main/java/google/registry/tools/server/ListDomainsAction.java +++ b/core/src/main/java/google/registry/tools/server/ListDomainsAction.java @@ -16,7 +16,7 @@ package google.registry.tools.server; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.ImmutableList.toImmutableList; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.model.registry.Registries.assertTldsExist; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; @@ -86,7 +86,7 @@ public final class ListDomainsAction extends ListObjectsAction { // Combine the batches together by sorting all domains together with newest first, applying the // limit, and then reversing for display order. for (List tldsBatch : Lists.partition(tlds.asList(), maxNumSubqueries)) { - ofy() + auditedOfy() .load() .type(DomainBase.class) .filter("tld in", tldsBatch) diff --git a/core/src/main/java/google/registry/tools/server/ResaveAllHistoryEntriesAction.java b/core/src/main/java/google/registry/tools/server/ResaveAllHistoryEntriesAction.java index af151be7d..811e3b2f3 100644 --- a/core/src/main/java/google/registry/tools/server/ResaveAllHistoryEntriesAction.java +++ b/core/src/main/java/google/registry/tools/server/ResaveAllHistoryEntriesAction.java @@ -14,7 +14,7 @@ package google.registry.tools.server; -import static google.registry.model.ofy.ObjectifyService.ofy; +import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import com.google.appengine.tools.mapreduce.Mapper; @@ -69,7 +69,9 @@ public class ResaveAllHistoryEntriesAction implements Runnable { @Override public final void map(final HistoryEntry historyEntry) { - tm().transact(() -> ofy().save().entity(ofy().load().entity(historyEntry).now()).now()); + tm().transact( + () -> + auditedOfy().save().entity(auditedOfy().load().entity(historyEntry).now()).now()); getContext().incrementCounter( String.format( "HistoryEntries parented under %s re-saved", historyEntry.getParent().getKind())); diff --git a/core/src/test/java/google/registry/persistence/transaction/QueryComposerTest.java b/core/src/test/java/google/registry/persistence/transaction/QueryComposerTest.java index 25e895053..eba0aa3e4 100644 --- a/core/src/test/java/google/registry/persistence/transaction/QueryComposerTest.java +++ b/core/src/test/java/google/registry/persistence/transaction/QueryComposerTest.java @@ -30,6 +30,8 @@ import google.registry.testing.AppEngineExtension; import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.TestOfyAndSql; +import google.registry.testing.TestOfyOnly; +import google.registry.testing.TestSqlOnly; import java.util.Optional; import javax.persistence.Column; import javax.persistence.NoResultException; @@ -263,6 +265,33 @@ public class QueryComposerTest { .isEqualTo(ImmutableList.of()); } + @TestOfyOnly + void testMultipleInequalities_failsDatastore() { + assertThat( + assertThrows( + IllegalArgumentException.class, + () -> + tm().createQueryComposer(TestEntity.class) + .where("val", Comparator.GT, 1) + .where("name", Comparator.LT, "b") + .list())) + .hasMessageThat() + .isEqualTo( + "Datastore cannot handle inequality queries on multiple fields, we found 2 fields."); + } + + @TestSqlOnly + void testMultipleInequalities_succeedsSql() { + assertThat( + transactIfJpaTm( + () -> + tm().createQueryComposer(TestEntity.class) + .where("val", Comparator.GT, 1) + .where("name", Comparator.LT, "b") + .list())) + .containsExactly(alpha); + } + @javax.persistence.Entity @Entity(name = "QueryComposerTestEntity") private static class TestEntity extends ImmutableObject {