mirror of
https://github.com/google/nomulus.git
synced 2025-07-22 18:55:58 +02:00
Use a more efficient query to find resources in histories (#1354)
This commit is contained in:
parent
c8e51b0e53
commit
1e6287372d
2 changed files with 24 additions and 22 deletions
|
@ -213,6 +213,7 @@ PRESUBMITS = {
|
||||||
{"src/test", "ActivityReportingQueryBuilder.java",
|
{"src/test", "ActivityReportingQueryBuilder.java",
|
||||||
# This class contains helper method to make queries in Beam.
|
# This class contains helper method to make queries in Beam.
|
||||||
"RegistryJpaIO.java",
|
"RegistryJpaIO.java",
|
||||||
|
"CreateSyntheticHistoryEntriesAction.java",
|
||||||
# TODO(b/179158393): Remove everything below, which should be done
|
# TODO(b/179158393): Remove everything below, which should be done
|
||||||
# using Criteria
|
# using Criteria
|
||||||
"JpaTransactionManager.java",
|
"JpaTransactionManager.java",
|
||||||
|
|
|
@ -21,6 +21,7 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.ofyTm;
|
import static google.registry.persistence.transaction.TransactionManagerFactory.ofyTm;
|
||||||
|
|
||||||
import com.google.appengine.tools.mapreduce.Mapper;
|
import com.google.appengine.tools.mapreduce.Mapper;
|
||||||
|
import com.google.common.base.CaseFormat;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import google.registry.config.RegistryConfig.Config;
|
import google.registry.config.RegistryConfig.Config;
|
||||||
|
@ -29,16 +30,12 @@ import google.registry.mapreduce.inputs.EppResourceInputs;
|
||||||
import google.registry.model.EppResource;
|
import google.registry.model.EppResource;
|
||||||
import google.registry.model.domain.DomainHistory;
|
import google.registry.model.domain.DomainHistory;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
import google.registry.persistence.transaction.CriteriaQueryBuilder;
|
|
||||||
import google.registry.rde.RdeStagingAction;
|
import google.registry.rde.RdeStagingAction;
|
||||||
import google.registry.request.Action;
|
import google.registry.request.Action;
|
||||||
import google.registry.request.Response;
|
import google.registry.request.Response;
|
||||||
import google.registry.request.auth.Auth;
|
import google.registry.request.auth.Auth;
|
||||||
import google.registry.tools.server.GenerateZoneFilesAction;
|
import google.registry.tools.server.GenerateZoneFilesAction;
|
||||||
import java.util.Optional;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mapreduce that creates synthetic history objects in SQL for all {@link EppResource} objects.
|
* A mapreduce that creates synthetic history objects in SQL for all {@link EppResource} objects.
|
||||||
|
@ -105,8 +102,9 @@ public class CreateSyntheticHistoryEntriesAction implements Runnable {
|
||||||
.sendLinkToMapreduceConsole(response);
|
.sendLinkToMapreduceConsole(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lifted from HistoryEntryDao
|
// Returns true iff any of the *History objects in SQL contain a representation of this resource
|
||||||
private static Optional<? extends HistoryEntry> mostRecentHistoryFromSql(EppResource resource) {
|
// at the point in time that the *History object was created.
|
||||||
|
private static boolean hasHistoryContainingResource(EppResource resource) {
|
||||||
return jpaTm()
|
return jpaTm()
|
||||||
.transact(
|
.transact(
|
||||||
() -> {
|
() -> {
|
||||||
|
@ -114,18 +112,24 @@ public class CreateSyntheticHistoryEntriesAction implements Runnable {
|
||||||
Class<? extends HistoryEntry> historyClass =
|
Class<? extends HistoryEntry> historyClass =
|
||||||
getHistoryClassFromParent(resource.getClass());
|
getHistoryClassFromParent(resource.getClass());
|
||||||
// The field representing repo ID unfortunately varies by history class
|
// The field representing repo ID unfortunately varies by history class
|
||||||
String repoIdFieldName = getRepoIdFieldNameFromHistoryClass(historyClass);
|
String repoIdFieldName =
|
||||||
CriteriaBuilder criteriaBuilder = jpaTm().getEntityManager().getCriteriaBuilder();
|
CaseFormat.LOWER_CAMEL.to(
|
||||||
CriteriaQuery<? extends HistoryEntry> criteriaQuery =
|
CaseFormat.LOWER_UNDERSCORE,
|
||||||
CriteriaQueryBuilder.create(historyClass)
|
getRepoIdFieldNameFromHistoryClass(historyClass));
|
||||||
.where(repoIdFieldName, criteriaBuilder::equal, resource.getRepoId())
|
// The "history" fields in the *History objects are all prefixed with "history_". If
|
||||||
.orderByDesc("modificationTime")
|
// any of the non-"history_" fields are non-null, that means that that row contains
|
||||||
.build();
|
// a representation of that EppResource at that point in time. We use creation_time as
|
||||||
return jpaTm()
|
// a marker since it's the simplest field and all EppResources will have it.
|
||||||
.criteriaQuery(criteriaQuery)
|
return (boolean)
|
||||||
.setMaxResults(1)
|
jpaTm()
|
||||||
.getResultStream()
|
.getEntityManager()
|
||||||
.findFirst();
|
.createNativeQuery(
|
||||||
|
String.format(
|
||||||
|
"SELECT EXISTS (SELECT 1 FROM \"%s\" WHERE %s = :repoId AND"
|
||||||
|
+ " creation_time IS NOT NULL)",
|
||||||
|
historyClass.getSimpleName(), repoIdFieldName))
|
||||||
|
.setParameter("repoId", resource.getRepoId())
|
||||||
|
.getSingleResult();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,10 +168,7 @@ public class CreateSyntheticHistoryEntriesAction implements Runnable {
|
||||||
EppResource eppResource = auditedOfy().load().key(resourceKey).now();
|
EppResource eppResource = auditedOfy().load().key(resourceKey).now();
|
||||||
// Only save new history entries if the most recent history for this object in SQL does not
|
// Only save new history entries if the most recent history for this object in SQL does not
|
||||||
// have the resource at that point in time already
|
// have the resource at that point in time already
|
||||||
Optional<? extends HistoryEntry> maybeHistory = mostRecentHistoryFromSql(eppResource);
|
if (!hasHistoryContainingResource(eppResource)) {
|
||||||
if (maybeHistory
|
|
||||||
.map(history -> !history.getResourceAtPointInTime().isPresent())
|
|
||||||
.orElse(true)) {
|
|
||||||
ofyTm()
|
ofyTm()
|
||||||
.transact(
|
.transact(
|
||||||
() ->
|
() ->
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue