mirror of
https://github.com/google/nomulus.git
synced 2025-05-05 06:27:51 +02:00
Skip synthetic history entries for resources that don't need them (#1320)
* Skip synthetic history entries for resources that don't need them The reason for creating synthetic history entries is so that we can guarantee that each EppResource's most recent *History object contains that resource at that point in time. If the most recent *History object in SQL contains that resource already, there is no need to create a synthetic *History object for that resource.
This commit is contained in:
parent
93b4b03322
commit
742eff0b0a
11 changed files with 161 additions and 48 deletions
|
@ -206,15 +206,12 @@ PRESUBMITS = {
|
||||||
"RegistryJpaIO.java",
|
"RegistryJpaIO.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
|
||||||
"ForeignKeyIndex.java",
|
|
||||||
"HistoryEntryDao.java",
|
|
||||||
"JpaTransactionManager.java",
|
"JpaTransactionManager.java",
|
||||||
"JpaTransactionManagerImpl.java",
|
"JpaTransactionManagerImpl.java",
|
||||||
# CriteriaQueryBuilder is a false positive
|
# CriteriaQueryBuilder is a false positive
|
||||||
"CriteriaQueryBuilder.java",
|
"CriteriaQueryBuilder.java",
|
||||||
"RdapDomainSearchAction.java",
|
"RdapDomainSearchAction.java",
|
||||||
"RdapNameserverSearchAction.java",
|
"RdapNameserverSearchAction.java",
|
||||||
"RdapSearchActionBase.java",
|
|
||||||
"ReadOnlyCheckingEntityManager.java",
|
"ReadOnlyCheckingEntityManager.java",
|
||||||
"RegistryQuery",
|
"RegistryQuery",
|
||||||
},
|
},
|
||||||
|
|
|
@ -228,7 +228,7 @@ public abstract class ForeignKeyIndex<E extends EppResource> extends BackupGroup
|
||||||
tm().transact(
|
tm().transact(
|
||||||
() ->
|
() ->
|
||||||
jpaTm()
|
jpaTm()
|
||||||
.query(
|
.criteriaQuery(
|
||||||
CriteriaQueryBuilder.create(clazz)
|
CriteriaQueryBuilder.create(clazz)
|
||||||
.whereFieldIsIn(property, foreignKeys)
|
.whereFieldIsIn(property, foreignKeys)
|
||||||
.build())
|
.build())
|
||||||
|
|
|
@ -24,6 +24,7 @@ import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableCollection;
|
import com.google.common.collect.ImmutableCollection;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Streams;
|
import com.google.common.collect.Streams;
|
||||||
import google.registry.model.EppResource;
|
import google.registry.model.EppResource;
|
||||||
import google.registry.model.contact.ContactHistory;
|
import google.registry.model.contact.ContactHistory;
|
||||||
|
@ -49,6 +50,25 @@ import org.joda.time.DateTime;
|
||||||
*/
|
*/
|
||||||
public class HistoryEntryDao {
|
public class HistoryEntryDao {
|
||||||
|
|
||||||
|
public static ImmutableMap<Class<? extends EppResource>, Class<? extends HistoryEntry>>
|
||||||
|
RESOURCE_TYPES_TO_HISTORY_TYPES =
|
||||||
|
ImmutableMap.of(
|
||||||
|
ContactResource.class,
|
||||||
|
ContactHistory.class,
|
||||||
|
DomainBase.class,
|
||||||
|
DomainHistory.class,
|
||||||
|
HostResource.class,
|
||||||
|
HostHistory.class);
|
||||||
|
|
||||||
|
public static ImmutableMap<Class<? extends HistoryEntry>, String> REPO_ID_FIELD_NAMES =
|
||||||
|
ImmutableMap.of(
|
||||||
|
ContactHistory.class,
|
||||||
|
"contactRepoId",
|
||||||
|
DomainHistory.class,
|
||||||
|
"domainRepoId",
|
||||||
|
HostHistory.class,
|
||||||
|
"hostRepoId");
|
||||||
|
|
||||||
/** Loads all history objects in the times specified, including all types. */
|
/** Loads all history objects in the times specified, including all types. */
|
||||||
public static ImmutableList<HistoryEntry> loadAllHistoryObjects(
|
public static ImmutableList<HistoryEntry> loadAllHistoryObjects(
|
||||||
DateTime afterTime, DateTime beforeTime) {
|
DateTime afterTime, DateTime beforeTime) {
|
||||||
|
@ -164,7 +184,7 @@ public class HistoryEntryDao {
|
||||||
private static <T extends HistoryEntry> Stream<T> loadHistoryObjectFromSqlByRegistrars(
|
private static <T extends HistoryEntry> Stream<T> loadHistoryObjectFromSqlByRegistrars(
|
||||||
Class<T> historyClass, ImmutableCollection<String> registrarIds) {
|
Class<T> historyClass, ImmutableCollection<String> registrarIds) {
|
||||||
return jpaTm()
|
return jpaTm()
|
||||||
.query(
|
.criteriaQuery(
|
||||||
CriteriaQueryBuilder.create(historyClass)
|
CriteriaQueryBuilder.create(historyClass)
|
||||||
.whereFieldIsIn("clientId", registrarIds)
|
.whereFieldIsIn("clientId", registrarIds)
|
||||||
.build())
|
.build())
|
||||||
|
@ -188,34 +208,32 @@ public class HistoryEntryDao {
|
||||||
|
|
||||||
return ImmutableList.sortedCopyOf(
|
return ImmutableList.sortedCopyOf(
|
||||||
Comparator.comparing(HistoryEntry::getModificationTime),
|
Comparator.comparing(HistoryEntry::getModificationTime),
|
||||||
jpaTm().query(criteriaQuery).getResultList());
|
jpaTm().criteriaQuery(criteriaQuery).getResultList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Class<? extends HistoryEntry> getHistoryClassFromParent(
|
private static Class<? extends HistoryEntry> getHistoryClassFromParent(
|
||||||
Class<? extends EppResource> parent) {
|
Class<? extends EppResource> parent) {
|
||||||
if (parent.equals(ContactResource.class)) {
|
if (!RESOURCE_TYPES_TO_HISTORY_TYPES.containsKey(parent)) {
|
||||||
return ContactHistory.class;
|
throw new IllegalArgumentException(
|
||||||
} else if (parent.equals(DomainBase.class)) {
|
String.format("Unknown history type for parent %s", parent.getName()));
|
||||||
return DomainHistory.class;
|
|
||||||
} else if (parent.equals(HostResource.class)) {
|
|
||||||
return HostHistory.class;
|
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException(
|
return RESOURCE_TYPES_TO_HISTORY_TYPES.get(parent);
|
||||||
String.format("Unknown history type for parent %s", parent.getName()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getRepoIdFieldNameFromHistoryClass(
|
private static String getRepoIdFieldNameFromHistoryClass(
|
||||||
Class<? extends HistoryEntry> historyClass) {
|
Class<? extends HistoryEntry> historyClass) {
|
||||||
return historyClass.equals(ContactHistory.class)
|
if (!REPO_ID_FIELD_NAMES.containsKey(historyClass)) {
|
||||||
? "contactRepoId"
|
throw new IllegalArgumentException(
|
||||||
: historyClass.equals(DomainHistory.class) ? "domainRepoId" : "hostRepoId";
|
String.format("Unknown history type %s", historyClass.getName()));
|
||||||
|
}
|
||||||
|
return REPO_ID_FIELD_NAMES.get(historyClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T extends HistoryEntry> List<T> loadAllHistoryObjectsFromSql(
|
private static <T extends HistoryEntry> List<T> loadAllHistoryObjectsFromSql(
|
||||||
Class<T> historyClass, DateTime afterTime, DateTime beforeTime) {
|
Class<T> historyClass, DateTime afterTime, DateTime beforeTime) {
|
||||||
CriteriaBuilder criteriaBuilder = jpaTm().getEntityManager().getCriteriaBuilder();
|
CriteriaBuilder criteriaBuilder = jpaTm().getEntityManager().getCriteriaBuilder();
|
||||||
return jpaTm()
|
return jpaTm()
|
||||||
.query(
|
.criteriaQuery(
|
||||||
CriteriaQueryBuilder.create(historyClass)
|
CriteriaQueryBuilder.create(historyClass)
|
||||||
.where("modificationTime", criteriaBuilder::greaterThanOrEqualTo, afterTime)
|
.where("modificationTime", criteriaBuilder::greaterThanOrEqualTo, afterTime)
|
||||||
.where("modificationTime", criteriaBuilder::lessThanOrEqualTo, beforeTime)
|
.where("modificationTime", criteriaBuilder::lessThanOrEqualTo, beforeTime)
|
||||||
|
|
|
@ -36,7 +36,7 @@ public interface JpaTransactionManager extends TransactionManager {
|
||||||
<T> TypedQuery<T> query(String sqlString, Class<T> resultClass);
|
<T> TypedQuery<T> query(String sqlString, Class<T> resultClass);
|
||||||
|
|
||||||
/** Creates a JPA SQU query for the given criteria query. */
|
/** Creates a JPA SQU query for the given criteria query. */
|
||||||
<T> TypedQuery<T> query(CriteriaQuery<T> criteriaQuery);
|
<T> TypedQuery<T> criteriaQuery(CriteriaQuery<T> criteriaQuery);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a JPA SQL query for the given query string.
|
* Creates a JPA SQL query for the given query string.
|
||||||
|
|
|
@ -135,7 +135,7 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> TypedQuery<T> query(CriteriaQuery<T> criteriaQuery) {
|
public <T> TypedQuery<T> criteriaQuery(CriteriaQuery<T> criteriaQuery) {
|
||||||
return new DetachingTypedQuery<>(getEntityManager().createQuery(criteriaQuery));
|
return new DetachingTypedQuery<>(getEntityManager().createQuery(criteriaQuery));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -591,7 +591,7 @@ public class RdapDomainSearchAction extends RdapSearchActionBase {
|
||||||
cursorString.get());
|
cursorString.get());
|
||||||
}
|
}
|
||||||
jpaTm()
|
jpaTm()
|
||||||
.query(queryBuilder.build())
|
.criteriaQuery(queryBuilder.build())
|
||||||
.getResultStream()
|
.getResultStream()
|
||||||
.filter(this::isAuthorized)
|
.filter(this::isAuthorized)
|
||||||
.forEach(
|
.forEach(
|
||||||
|
|
|
@ -202,7 +202,7 @@ public abstract class RdapSearchActionBase extends RdapActionBase {
|
||||||
desiredRegistrar.get());
|
desiredRegistrar.get());
|
||||||
}
|
}
|
||||||
List<T> queryResult =
|
List<T> queryResult =
|
||||||
jpaTm().query(builder.build()).setMaxResults(querySizeLimit).getResultList();
|
jpaTm().criteriaQuery(builder.build()).setMaxResults(querySizeLimit).getResultList();
|
||||||
if (checkForVisibility) {
|
if (checkForVisibility) {
|
||||||
return filterResourcesByVisibility(queryResult, querySizeLimit);
|
return filterResourcesByVisibility(queryResult, querySizeLimit);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,7 +15,10 @@
|
||||||
package google.registry.tools.javascrap;
|
package google.registry.tools.javascrap;
|
||||||
|
|
||||||
import static google.registry.model.ofy.ObjectifyService.auditedOfy;
|
import static google.registry.model.ofy.ObjectifyService.auditedOfy;
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
import static google.registry.model.reporting.HistoryEntryDao.REPO_ID_FIELD_NAMES;
|
||||||
|
import static google.registry.model.reporting.HistoryEntryDao.RESOURCE_TYPES_TO_HISTORY_TYPES;
|
||||||
|
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||||
|
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.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
@ -26,12 +29,16 @@ 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.
|
||||||
|
@ -61,6 +68,9 @@ import javax.inject.Inject;
|
||||||
auth = Auth.AUTH_INTERNAL_OR_ADMIN)
|
auth = Auth.AUTH_INTERNAL_OR_ADMIN)
|
||||||
public class CreateSyntheticHistoryEntriesAction implements Runnable {
|
public class CreateSyntheticHistoryEntriesAction implements Runnable {
|
||||||
|
|
||||||
|
private static final String HISTORY_REASON =
|
||||||
|
"Backfill EppResource history objects during Cloud SQL migration";
|
||||||
|
|
||||||
private final MapreduceRunner mrRunner;
|
private final MapreduceRunner mrRunner;
|
||||||
private final Response response;
|
private final Response response;
|
||||||
private final String registryAdminRegistrarId;
|
private final String registryAdminRegistrarId;
|
||||||
|
@ -97,6 +107,50 @@ public class CreateSyntheticHistoryEntriesAction implements Runnable {
|
||||||
.sendLinkToMapreduceConsole(response);
|
.sendLinkToMapreduceConsole(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lifted from HistoryEntryDao
|
||||||
|
private static Optional<? extends HistoryEntry> mostRecentHistoryFromSql(EppResource resource) {
|
||||||
|
return jpaTm()
|
||||||
|
.transact(
|
||||||
|
() -> {
|
||||||
|
// The class we're searching from is based on which parent type (e.g. Domain) we have
|
||||||
|
Class<? extends HistoryEntry> historyClass =
|
||||||
|
getHistoryClassFromParent(resource.getClass());
|
||||||
|
// The field representing repo ID unfortunately varies by history class
|
||||||
|
String repoIdFieldName = getRepoIdFieldNameFromHistoryClass(historyClass);
|
||||||
|
CriteriaBuilder criteriaBuilder = jpaTm().getEntityManager().getCriteriaBuilder();
|
||||||
|
CriteriaQuery<? extends HistoryEntry> criteriaQuery =
|
||||||
|
CriteriaQueryBuilder.create(historyClass)
|
||||||
|
.where(repoIdFieldName, criteriaBuilder::equal, resource.getRepoId())
|
||||||
|
.orderByDesc("modificationTime")
|
||||||
|
.build();
|
||||||
|
return jpaTm()
|
||||||
|
.criteriaQuery(criteriaQuery)
|
||||||
|
.setMaxResults(1)
|
||||||
|
.getResultStream()
|
||||||
|
.findFirst();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lifted from HistoryEntryDao
|
||||||
|
private static Class<? extends HistoryEntry> getHistoryClassFromParent(
|
||||||
|
Class<? extends EppResource> parent) {
|
||||||
|
if (!RESOURCE_TYPES_TO_HISTORY_TYPES.containsKey(parent)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format("Unknown history type for parent %s", parent.getName()));
|
||||||
|
}
|
||||||
|
return RESOURCE_TYPES_TO_HISTORY_TYPES.get(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lifted from HistoryEntryDao
|
||||||
|
private static String getRepoIdFieldNameFromHistoryClass(
|
||||||
|
Class<? extends HistoryEntry> historyClass) {
|
||||||
|
if (!REPO_ID_FIELD_NAMES.containsKey(historyClass)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format("Unknown history type %s", historyClass.getName()));
|
||||||
|
}
|
||||||
|
return REPO_ID_FIELD_NAMES.get(historyClass);
|
||||||
|
}
|
||||||
|
|
||||||
/** Mapper to re-save all EPP resources. */
|
/** Mapper to re-save all EPP resources. */
|
||||||
public static class CreateSyntheticHistoryEntriesMapper
|
public static class CreateSyntheticHistoryEntriesMapper
|
||||||
extends Mapper<Key<EppResource>, Void, Void> {
|
extends Mapper<Key<EppResource>, Void, Void> {
|
||||||
|
@ -109,20 +163,27 @@ public class CreateSyntheticHistoryEntriesAction implements Runnable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void map(final Key<EppResource> resourceKey) {
|
public final void map(final Key<EppResource> resourceKey) {
|
||||||
tm().transact(
|
EppResource eppResource = auditedOfy().load().key(resourceKey).now();
|
||||||
() -> {
|
// Only save new history entries if the most recent history for this object in SQL does not
|
||||||
EppResource eppResource = auditedOfy().load().key(resourceKey).now();
|
// have the resource at that point in time already
|
||||||
tm().put(
|
Optional<? extends HistoryEntry> maybeHistory = mostRecentHistoryFromSql(eppResource);
|
||||||
HistoryEntry.createBuilderForResource(eppResource)
|
if (maybeHistory
|
||||||
.setRegistrarId(registryAdminRegistrarId)
|
.map(history -> !history.getResourceAtPointInTime().isPresent())
|
||||||
.setBySuperuser(true)
|
.orElse(true)) {
|
||||||
.setRequestedByRegistrar(false)
|
ofyTm()
|
||||||
.setModificationTime(tm().getTransactionTime())
|
.transact(
|
||||||
.setReason(
|
() ->
|
||||||
"Backfill EppResource history objects during Cloud SQL migration")
|
ofyTm()
|
||||||
.setType(HistoryEntry.Type.SYNTHETIC)
|
.put(
|
||||||
.build());
|
HistoryEntry.createBuilderForResource(eppResource)
|
||||||
});
|
.setRegistrarId(registryAdminRegistrarId)
|
||||||
|
.setBySuperuser(true)
|
||||||
|
.setRequestedByRegistrar(false)
|
||||||
|
.setModificationTime(ofyTm().getTransactionTime())
|
||||||
|
.setReason(HISTORY_REASON)
|
||||||
|
.setType(HistoryEntry.Type.SYNTHETIC)
|
||||||
|
.build()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ class CriteriaQueryBuilderTest {
|
||||||
.transact(
|
.transact(
|
||||||
() ->
|
() ->
|
||||||
jpaTm()
|
jpaTm()
|
||||||
.query(
|
.criteriaQuery(
|
||||||
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
|
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
|
||||||
.build())
|
.build())
|
||||||
.getResultList()))
|
.getResultList()))
|
||||||
|
@ -80,7 +80,7 @@ class CriteriaQueryBuilderTest {
|
||||||
jpaTm().getEntityManager().getCriteriaBuilder()::equal,
|
jpaTm().getEntityManager().getCriteriaBuilder()::equal,
|
||||||
"zztz")
|
"zztz")
|
||||||
.build();
|
.build();
|
||||||
return jpaTm().query(query).getResultList();
|
return jpaTm().criteriaQuery(query).getResultList();
|
||||||
});
|
});
|
||||||
assertThat(result).containsExactly(entity2);
|
assertThat(result).containsExactly(entity2);
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ class CriteriaQueryBuilderTest {
|
||||||
.where(
|
.where(
|
||||||
"data", jpaTm().getEntityManager().getCriteriaBuilder()::like, "a%")
|
"data", jpaTm().getEntityManager().getCriteriaBuilder()::like, "a%")
|
||||||
.build();
|
.build();
|
||||||
return jpaTm().query(query).getResultList();
|
return jpaTm().criteriaQuery(query).getResultList();
|
||||||
});
|
});
|
||||||
assertThat(result).containsExactly(entity3);
|
assertThat(result).containsExactly(entity3);
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ class CriteriaQueryBuilderTest {
|
||||||
.where(
|
.where(
|
||||||
"data", jpaTm().getEntityManager().getCriteriaBuilder()::like, "%a%")
|
"data", jpaTm().getEntityManager().getCriteriaBuilder()::like, "%a%")
|
||||||
.build();
|
.build();
|
||||||
return jpaTm().query(query).getResultList();
|
return jpaTm().criteriaQuery(query).getResultList();
|
||||||
});
|
});
|
||||||
assertThat(result).containsExactly(entity1, entity3).inOrder();
|
assertThat(result).containsExactly(entity1, entity3).inOrder();
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ class CriteriaQueryBuilderTest {
|
||||||
.where(
|
.where(
|
||||||
"data", jpaTm().getEntityManager().getCriteriaBuilder()::like, "%t%")
|
"data", jpaTm().getEntityManager().getCriteriaBuilder()::like, "%t%")
|
||||||
.build();
|
.build();
|
||||||
return jpaTm().query(query).getResultList();
|
return jpaTm().criteriaQuery(query).getResultList();
|
||||||
});
|
});
|
||||||
assertThat(result).containsExactly(entity1);
|
assertThat(result).containsExactly(entity1);
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ class CriteriaQueryBuilderTest {
|
||||||
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
|
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
|
||||||
.whereFieldIsIn("data", ImmutableList.of("aaa", "bbb"))
|
.whereFieldIsIn("data", ImmutableList.of("aaa", "bbb"))
|
||||||
.build();
|
.build();
|
||||||
return jpaTm().query(query).getResultList();
|
return jpaTm().criteriaQuery(query).getResultList();
|
||||||
});
|
});
|
||||||
assertThat(result).containsExactly(entity3).inOrder();
|
assertThat(result).containsExactly(entity3).inOrder();
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ class CriteriaQueryBuilderTest {
|
||||||
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
|
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
|
||||||
.whereFieldIsNotIn("data", ImmutableList.of("aaa", "bbb"))
|
.whereFieldIsNotIn("data", ImmutableList.of("aaa", "bbb"))
|
||||||
.build();
|
.build();
|
||||||
return jpaTm().query(query).getResultList();
|
return jpaTm().criteriaQuery(query).getResultList();
|
||||||
});
|
});
|
||||||
assertThat(result).containsExactly(entity1, entity2).inOrder();
|
assertThat(result).containsExactly(entity1, entity2).inOrder();
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ class CriteriaQueryBuilderTest {
|
||||||
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
|
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
|
||||||
.whereFieldIsIn("data", ImmutableList.of("aaa", "bbb", "data"))
|
.whereFieldIsIn("data", ImmutableList.of("aaa", "bbb", "data"))
|
||||||
.build();
|
.build();
|
||||||
return jpaTm().query(query).getResultList();
|
return jpaTm().criteriaQuery(query).getResultList();
|
||||||
});
|
});
|
||||||
assertThat(result).containsExactly(entity1, entity3).inOrder();
|
assertThat(result).containsExactly(entity1, entity3).inOrder();
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ class CriteriaQueryBuilderTest {
|
||||||
.where(
|
.where(
|
||||||
"data", jpaTm().getEntityManager().getCriteriaBuilder()::like, "%a%")
|
"data", jpaTm().getEntityManager().getCriteriaBuilder()::like, "%a%")
|
||||||
.build();
|
.build();
|
||||||
return jpaTm().query(query).getResultList();
|
return jpaTm().criteriaQuery(query).getResultList();
|
||||||
});
|
});
|
||||||
assertThat(result).containsExactly(entity3, entity1).inOrder();
|
assertThat(result).containsExactly(entity3, entity1).inOrder();
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ class CriteriaQueryBuilderTest {
|
||||||
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
|
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
|
||||||
.orderByDesc("data")
|
.orderByDesc("data")
|
||||||
.build();
|
.build();
|
||||||
return jpaTm().query(query).getResultList();
|
return jpaTm().criteriaQuery(query).getResultList();
|
||||||
});
|
});
|
||||||
assertThat(result).containsExactly(entity2, entity1, entity3).inOrder();
|
assertThat(result).containsExactly(entity2, entity1, entity3).inOrder();
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,7 +623,7 @@ class JpaTransactionManagerImplTest {
|
||||||
.getEntityManager()
|
.getEntityManager()
|
||||||
.contains(
|
.contains(
|
||||||
jpaTm()
|
jpaTm()
|
||||||
.query(
|
.criteriaQuery(
|
||||||
CriteriaQueryBuilder.create(TestEntity.class)
|
CriteriaQueryBuilder.create(TestEntity.class)
|
||||||
.where(
|
.where(
|
||||||
"name",
|
"name",
|
||||||
|
|
|
@ -15,12 +15,15 @@
|
||||||
package google.registry.tools.javascrap;
|
package google.registry.tools.javascrap;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||||
import static google.registry.testing.DatabaseHelper.createTld;
|
import static google.registry.testing.DatabaseHelper.createTld;
|
||||||
import static google.registry.testing.DatabaseHelper.loadByKey;
|
import static google.registry.testing.DatabaseHelper.loadByKey;
|
||||||
|
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||||
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||||
import static google.registry.testing.DatabaseHelper.persistActiveHost;
|
import static google.registry.testing.DatabaseHelper.persistActiveHost;
|
||||||
import static google.registry.testing.DatabaseHelper.persistDomainAsDeleted;
|
import static google.registry.testing.DatabaseHelper.persistDomainAsDeleted;
|
||||||
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
|
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
|
||||||
|
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
|
|
||||||
|
@ -30,9 +33,11 @@ import com.googlecode.objectify.Key;
|
||||||
import google.registry.model.EppResource;
|
import google.registry.model.EppResource;
|
||||||
import google.registry.model.contact.ContactResource;
|
import google.registry.model.contact.ContactResource;
|
||||||
import google.registry.model.domain.DomainBase;
|
import google.registry.model.domain.DomainBase;
|
||||||
|
import google.registry.model.domain.DomainHistory;
|
||||||
import google.registry.model.host.HostResource;
|
import google.registry.model.host.HostResource;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
import google.registry.model.reporting.HistoryEntryDao;
|
import google.registry.model.reporting.HistoryEntryDao;
|
||||||
|
import google.registry.model.tld.Registry;
|
||||||
import google.registry.testing.FakeResponse;
|
import google.registry.testing.FakeResponse;
|
||||||
import google.registry.testing.mapreduce.MapreduceTestCase;
|
import google.registry.testing.mapreduce.MapreduceTestCase;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
@ -96,6 +101,38 @@ public class CreateSyntheticHistoryEntriesActionTest
|
||||||
assertThat(Iterables.getLast(historyEntries).getType()).isEqualTo(HistoryEntry.Type.SYNTHETIC);
|
assertThat(Iterables.getLast(historyEntries).getType()).isEqualTo(HistoryEntry.Type.SYNTHETIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDoesntSave_ifAlreadyReplayed() throws Exception {
|
||||||
|
DateTime now = DateTime.parse("1999-04-03T22:00:00.0Z");
|
||||||
|
DomainHistory domainHistoryWithoutDomain =
|
||||||
|
persistResource(
|
||||||
|
new DomainHistory.Builder()
|
||||||
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
|
.setModificationTime(now)
|
||||||
|
.setDomain(domain)
|
||||||
|
.setRegistrarId(domain.getCreationRegistrarId())
|
||||||
|
.build());
|
||||||
|
DomainHistory domainHistoryWithDomain =
|
||||||
|
domainHistoryWithoutDomain.asBuilder().setDomain(domain).build();
|
||||||
|
// Simulate having replayed the domain and history to SQL
|
||||||
|
jpaTm()
|
||||||
|
.transact(
|
||||||
|
() ->
|
||||||
|
jpaTm()
|
||||||
|
.putAll(
|
||||||
|
Registry.get("tld"),
|
||||||
|
loadRegistrar("TheRegistrar"),
|
||||||
|
contact,
|
||||||
|
domain,
|
||||||
|
domainHistoryWithDomain));
|
||||||
|
runMapreduce();
|
||||||
|
|
||||||
|
// Since we already had a DomainHistory with the domain in SQL, we shouldn't create a synthetic
|
||||||
|
// history entry
|
||||||
|
assertThat(HistoryEntryDao.loadHistoryObjectsForResource(domain.createVKey()))
|
||||||
|
.containsExactly(domainHistoryWithoutDomain);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreation_forDeletedResource() throws Exception {
|
void testCreation_forDeletedResource() throws Exception {
|
||||||
persistDomainAsDeleted(domain, domain.getCreationTime().plusMonths(6));
|
persistDomainAsDeleted(domain, domain.getCreationTime().plusMonths(6));
|
||||||
|
|
Loading…
Add table
Reference in a new issue