Migrate away from VoidWorks

This is one last hanging piece of work left over from last year's Java 8
migration. There's no functionality changes in this CL, just refactoring.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=201947600
This commit is contained in:
mcilwain 2018-06-25 07:04:26 -07:00 committed by Ben McIlwain
parent 7d3cb3d426
commit d3364b0387
18 changed files with 349 additions and 502 deletions

View file

@ -309,6 +309,14 @@ public class Ofy {
throw new AssertionError(); // How on earth did we get here? throw new AssertionError(); // How on earth did we get here?
} }
public void transactNewReadOnly(Runnable work) {
transactNewReadOnly(
() -> {
work.run();
return null;
});
}
/** Execute some work in a transactionless context. */ /** Execute some work in a transactionless context. */
public <R> R doTransactionless(Work<R> work) { public <R> R doTransactionless(Work<R> work) {
try { try {

View file

@ -26,7 +26,6 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Streams; import com.google.common.collect.Streams;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.VoidWork;
import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Index; import com.googlecode.objectify.annotation.Index;
@ -156,22 +155,15 @@ public class RegistrarContact extends ImmutableObject implements Jsonifiable {
final Registrar registrar, final Set<RegistrarContact> contacts) { final Registrar registrar, final Set<RegistrarContact> contacts) {
ofy() ofy()
.transact( .transact(
new VoidWork() { () -> {
@Override ofy()
public void vrun() { .delete()
ofy() .keys(
.delete() difference(
.keys( ImmutableSet.copyOf(
difference( ofy().load().type(RegistrarContact.class).ancestor(registrar).keys()),
ImmutableSet.copyOf( contacts.stream().map(Key::create).collect(toImmutableSet())));
ofy() ofy().save().entities(contacts);
.load()
.type(RegistrarContact.class)
.ancestor(registrar)
.keys()),
contacts.stream().map(Key::create).collect(toImmutableSet())));
ofy().save().entities(contacts);
}
}); });
} }

View file

@ -36,7 +36,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Streams; import com.google.common.collect.Streams;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.VoidWork;
import google.registry.model.registry.Registry; import google.registry.model.registry.Registry;
import google.registry.model.registry.label.DomainLabelMetrics.PremiumListCheckOutcome; import google.registry.model.registry.label.DomainLabelMetrics.PremiumListCheckOutcome;
import google.registry.model.registry.label.PremiumList.PremiumListEntry; import google.registry.model.registry.label.PremiumList.PremiumListEntry;
@ -196,11 +195,7 @@ public final class PremiumListUtils {
/** Deletes the PremiumList and all of its child entities. */ /** Deletes the PremiumList and all of its child entities. */
public static void deletePremiumList(final PremiumList premiumList) { public static void deletePremiumList(final PremiumList premiumList) {
ofy().transactNew(new VoidWork() { ofy().transactNew(() -> ofy().delete().entity(premiumList));
@Override
public void vrun() {
ofy().delete().entity(premiumList);
}});
deleteRevisionAndEntriesOfPremiumList(premiumList); deleteRevisionAndEntriesOfPremiumList(premiumList);
cachePremiumLists.invalidate(premiumList.getName()); cachePremiumLists.invalidate(premiumList.getName());
} }
@ -209,20 +204,13 @@ public final class PremiumListUtils {
if (premiumList.getRevisionKey() == null) { if (premiumList.getRevisionKey() == null) {
return; return;
} }
for (final List<Key<PremiumListEntry>> batch : partition( for (final List<Key<PremiumListEntry>> batch :
ofy().load().type(PremiumListEntry.class).ancestor(premiumList.revisionKey).keys(), partition(
TRANSACTION_BATCH_SIZE)) { ofy().load().type(PremiumListEntry.class).ancestor(premiumList.revisionKey).keys(),
ofy().transactNew(new VoidWork() { TRANSACTION_BATCH_SIZE)) {
@Override ofy().transactNew(() -> ofy().delete().keys(batch));
public void vrun() {
ofy().delete().keys(batch);
}});
} }
ofy().transactNew(new VoidWork() { ofy().transactNew(() -> ofy().delete().key(premiumList.getRevisionKey()));
@Override
public void vrun() {
ofy().delete().key(premiumList.getRevisionKey());
}});
} }
/** Returns whether a PremiumList of the given name exists, bypassing the cache. */ /** Returns whether a PremiumList of the given name exists, bypassing the cache. */

View file

@ -22,7 +22,6 @@ import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.googlecode.objectify.VoidWork;
import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Id;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
@ -216,30 +215,27 @@ public class Lock extends ImmutableObject {
// Just use the default clock because we aren't actually doing anything that will use the clock. // Just use the default clock because we aren't actually doing anything that will use the clock.
ofy() ofy()
.transact( .transact(
new VoidWork() { () -> {
@Override // To release a lock, check that no one else has already obtained it and if not
public void vrun() { // delete it. If the lock in Datastore was different then this lock is gone already;
// To release a lock, check that no one else has already obtained it and if not // this can happen if release() is called around the expiration time and the lock
// delete it. If the lock in Datastore was different then this lock is gone already; // expires underneath us.
// this can happen if release() is called around the expiration time and the lock Lock loadedLock = ofy().load().type(Lock.class).id(lockId).now();
// expires underneath us. if (Lock.this.equals(loadedLock)) {
Lock loadedLock = ofy().load().type(Lock.class).id(lockId).now(); // Use noBackupOfy() so that we don't create a commit log entry for deleting the
if (Lock.this.equals(loadedLock)) { // lock.
// Use noBackupOfy() so that we don't create a commit log entry for deleting the logger.atInfo().log("Deleting lock: %s", lockId);
// lock. ofy().deleteWithoutBackup().entity(Lock.this);
logger.atInfo().log("Deleting lock: %s", lockId); lockMetrics.recordRelease(
ofy().deleteWithoutBackup().entity(Lock.this); resourceName, tld, new Duration(acquiredTime, ofy().getTransactionTime()));
lockMetrics.recordRelease( } else {
resourceName, tld, new Duration(acquiredTime, ofy().getTransactionTime())); logger.atSevere().log(
} else { "The lock we acquired was transferred to someone else before we"
logger.atSevere().log( + " released it! Did action take longer than lease length?"
"The lock we acquired was transferred to someone else before we" + " Our lock: %s, current lock: %s",
+ " released it! Did action take longer than lease length?" Lock.this, loadedLock);
+ " Our lock: %s, current lock: %s", logger.atInfo().log(
Lock.this, loadedLock); "Not deleting lock: %s - someone else has it: %s", lockId, loadedLock);
logger.atInfo().log(
"Not deleting lock: %s - someone else has it: %s", lockId, loadedLock);
}
} }
}); });
} }

View file

@ -24,7 +24,6 @@ import com.google.appengine.tools.cloudstorage.RetryParams;
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;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.googlecode.objectify.VoidWork;
import google.registry.config.RegistryConfig.Config; import google.registry.config.RegistryConfig.Config;
import google.registry.config.RegistryConfig.ConfigModule; import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils; import google.registry.gcs.GcsUtils;
@ -139,14 +138,13 @@ public class RdeContactImportAction implements Runnable {
// Record number of attempted map operations // Record number of attempted map operations
getContext().incrementCounter("contact imports attempted"); getContext().incrementCounter("contact imports attempted");
logger.atInfo().log("Saving contact %s", xjcContact.getId()); logger.atInfo().log("Saving contact %s", xjcContact.getId());
ofy().transact(new VoidWork() { ofy()
@Override .transact(
public void vrun() { () -> {
ContactResource contact = ContactResource contact =
XjcToContactResourceConverter.convertContact(xjcContact); XjcToContactResourceConverter.convertContact(xjcContact);
getImportUtils().importEppResource(contact); getImportUtils().importEppResource(contact);
} });
});
// Record number of contacts imported // Record number of contacts imported
getContext().incrementCounter("contacts saved"); getContext().incrementCounter("contacts saved");
logger.atInfo().log("Contact %s was imported successfully", xjcContact.getId()); logger.atInfo().log("Contact %s was imported successfully", xjcContact.getId());

View file

@ -35,7 +35,6 @@ import com.google.appengine.tools.mapreduce.Mapper;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.googlecode.objectify.VoidWork;
import google.registry.config.RegistryConfig.Config; import google.registry.config.RegistryConfig.Config;
import google.registry.config.RegistryConfig.ConfigModule; import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.dns.DnsQueue; import google.registry.dns.DnsQueue;
@ -171,120 +170,10 @@ public class RdeDomainImportAction implements Runnable {
try { try {
// Record number of attempted map operations // Record number of attempted map operations
getContext().incrementCounter("domain imports attempted"); getContext().incrementCounter("domain imports attempted");
logger.atInfo().log("Saving domain %s", xjcDomain.getName()); logger.atInfo().log("Saving domain %s", xjcDomain.getName());
ofy()
.transact( ofy().transact(() -> saveDomain(xjcDomain));
new VoidWork() {
@Override
public void vrun() {
HistoryEntry historyEntry = createHistoryEntryForDomainImport(xjcDomain);
BillingEvent.Recurring autorenewBillingEvent =
createAutoRenewBillingEventForDomainImport(xjcDomain, historyEntry);
PollMessage.Autorenew autorenewPollMessage =
createAutoRenewPollMessageForDomainImport(xjcDomain, historyEntry);
DomainResource domain =
XjcToDomainResourceConverter.convertDomain(
xjcDomain, autorenewBillingEvent, autorenewPollMessage);
getDnsQueue().addDomainRefreshTask(domain.getFullyQualifiedDomainName());
// Keep a list of "extra objects" that need to be saved along with the domain
// and add to it if necessary.
ImmutableSet<Object> extraEntitiesToSave =
getImportUtils().createIndexesForEppResource(domain);
// Create speculative server approval entities for pending transfers
if (domain.getTransferData().getTransferStatus() == TransferStatus.PENDING) {
TransferData transferData = domain.getTransferData();
checkArgumentNotNull(
transferData,
"Domain %s is in pending transfer but has no transfer data",
domain.getFullyQualifiedDomainName());
Money transferCost =
getDomainRenewCost(
domain.getFullyQualifiedDomainName(),
transferData.getPendingTransferExpirationTime(),
1);
DateTime automaticTransferTime =
transferData.getPendingTransferExpirationTime();
// If the transfer will occur within the autorenew grace period, it should
// subsume the autorenew, so we don't add the normal extra year. See the
// original logic in DomainTransferRequestFlow (which is very similar) for
// more information. That said, note that here we stop 1 millisecond before
// the actual transfer time to avoid hitting the transfer-handling part of
// cloneProjectedAtTime(), since unlike in the DomainTransferRequestFlow case,
// this domain already has a pending transfer.
DomainResource domainAtTransferTime =
domain.cloneProjectedAtTime(automaticTransferTime.minusMillis(1));
boolean inAutorenewGraceAtTransfer =
!domainAtTransferTime
.getGracePeriodsOfType(GracePeriodStatus.AUTO_RENEW)
.isEmpty();
int extraYears = inAutorenewGraceAtTransfer ? 0 : 1;
// Construct the capped new expiration time.
DateTime serverApproveNewExpirationTime =
extendRegistrationWithCap(
automaticTransferTime,
domainAtTransferTime.getRegistrationExpirationTime(),
extraYears);
// Create speculative entities in anticipation of an automatic server
// approval.
ImmutableSet<TransferServerApproveEntity> serverApproveEntities =
createTransferServerApproveEntities(
automaticTransferTime,
serverApproveNewExpirationTime,
historyEntry,
domain,
historyEntry.getTrid(),
transferData.getGainingClientId(),
Optional.of(transferCost),
transferData.getTransferRequestTime());
transferData =
createPendingTransferData(
transferData.asBuilder(),
serverApproveEntities,
Period.create(1, Unit.YEARS));
// Create a poll message to notify the losing registrar that a transfer was
// requested.
PollMessage requestPollMessage =
createLosingTransferPollMessage(
domain.getRepoId(),
transferData,
serverApproveNewExpirationTime,
historyEntry)
.asBuilder()
.setEventTime(transferData.getTransferRequestTime())
.build();
domain = domain.asBuilder().setTransferData(transferData).build();
autorenewBillingEvent =
autorenewBillingEvent
.asBuilder()
.setRecurrenceEndTime(transferData.getPendingTransferExpirationTime())
.build();
autorenewPollMessage =
autorenewPollMessage
.asBuilder()
.setAutorenewEndTime(transferData.getPendingTransferExpirationTime())
.build();
extraEntitiesToSave =
new ImmutableSet.Builder<>()
.add(requestPollMessage)
.addAll(extraEntitiesToSave)
.addAll(serverApproveEntities)
.build();
} // End pending transfer check
ofy()
.save()
.entities(
new ImmutableSet.Builder<>()
.add(
domain,
historyEntry,
autorenewBillingEvent,
autorenewPollMessage)
.addAll(extraEntitiesToSave)
.build())
.now();
}
});
// Record the number of domains imported // Record the number of domains imported
getContext().incrementCounter("domains saved"); getContext().incrementCounter("domains saved");
logger.atInfo().log("Domain %s was imported successfully", xjcDomain.getName()); logger.atInfo().log("Domain %s was imported successfully", xjcDomain.getName());
@ -298,5 +187,101 @@ public class RdeDomainImportAction implements Runnable {
"Error processing domain %s; xml=%s", xjcDomain.getName(), xjcDomain); "Error processing domain %s; xml=%s", xjcDomain.getName(), xjcDomain);
} }
} }
private void saveDomain(XjcRdeDomain xjcDomain) {
HistoryEntry historyEntry = createHistoryEntryForDomainImport(xjcDomain);
BillingEvent.Recurring autorenewBillingEvent =
createAutoRenewBillingEventForDomainImport(xjcDomain, historyEntry);
PollMessage.Autorenew autorenewPollMessage =
createAutoRenewPollMessageForDomainImport(xjcDomain, historyEntry);
DomainResource domain =
XjcToDomainResourceConverter.convertDomain(
xjcDomain, autorenewBillingEvent, autorenewPollMessage);
getDnsQueue().addDomainRefreshTask(domain.getFullyQualifiedDomainName());
// Keep a list of "extra objects" that need to be saved along with the domain
// and add to it if necessary.
ImmutableSet<Object> extraEntitiesToSave =
getImportUtils().createIndexesForEppResource(domain);
// Create speculative server approval entities for pending transfers
if (domain.getTransferData().getTransferStatus() == TransferStatus.PENDING) {
TransferData transferData = domain.getTransferData();
checkArgumentNotNull(
transferData,
"Domain %s is in pending transfer but has no transfer data",
domain.getFullyQualifiedDomainName());
Money transferCost =
getDomainRenewCost(
domain.getFullyQualifiedDomainName(),
transferData.getPendingTransferExpirationTime(),
1);
DateTime automaticTransferTime = transferData.getPendingTransferExpirationTime();
// If the transfer will occur within the autorenew grace period, it should
// subsume the autorenew, so we don't add the normal extra year. See the
// original logic in DomainTransferRequestFlow (which is very similar) for
// more information. That said, note that here we stop 1 millisecond before
// the actual transfer time to avoid hitting the transfer-handling part of
// cloneProjectedAtTime(), since unlike in the DomainTransferRequestFlow case,
// this domain already has a pending transfer.
DomainResource domainAtTransferTime =
domain.cloneProjectedAtTime(automaticTransferTime.minusMillis(1));
boolean inAutorenewGraceAtTransfer =
!domainAtTransferTime.getGracePeriodsOfType(GracePeriodStatus.AUTO_RENEW).isEmpty();
int extraYears = inAutorenewGraceAtTransfer ? 0 : 1;
// Construct the capped new expiration time.
DateTime serverApproveNewExpirationTime =
extendRegistrationWithCap(
automaticTransferTime,
domainAtTransferTime.getRegistrationExpirationTime(),
extraYears);
// Create speculative entities in anticipation of an automatic server
// approval.
ImmutableSet<TransferServerApproveEntity> serverApproveEntities =
createTransferServerApproveEntities(
automaticTransferTime,
serverApproveNewExpirationTime,
historyEntry,
domain,
historyEntry.getTrid(),
transferData.getGainingClientId(),
Optional.of(transferCost),
transferData.getTransferRequestTime());
transferData =
createPendingTransferData(
transferData.asBuilder(), serverApproveEntities, Period.create(1, Unit.YEARS));
// Create a poll message to notify the losing registrar that a transfer was
// requested.
PollMessage requestPollMessage =
createLosingTransferPollMessage(
domain.getRepoId(), transferData, serverApproveNewExpirationTime, historyEntry)
.asBuilder()
.setEventTime(transferData.getTransferRequestTime())
.build();
domain = domain.asBuilder().setTransferData(transferData).build();
autorenewBillingEvent =
autorenewBillingEvent
.asBuilder()
.setRecurrenceEndTime(transferData.getPendingTransferExpirationTime())
.build();
autorenewPollMessage =
autorenewPollMessage
.asBuilder()
.setAutorenewEndTime(transferData.getPendingTransferExpirationTime())
.build();
extraEntitiesToSave =
new ImmutableSet.Builder<>()
.add(requestPollMessage)
.addAll(extraEntitiesToSave)
.addAll(serverApproveEntities)
.build();
} // End pending transfer check
ofy()
.save()
.entities(
new ImmutableSet.Builder<>()
.add(domain, historyEntry, autorenewBillingEvent, autorenewPollMessage)
.addAll(extraEntitiesToSave)
.build())
.now();
}
} }
} }

View file

@ -24,7 +24,6 @@ import com.google.appengine.tools.cloudstorage.RetryParams;
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;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.googlecode.objectify.VoidWork;
import google.registry.config.RegistryConfig.Config; import google.registry.config.RegistryConfig.Config;
import google.registry.config.RegistryConfig.ConfigModule; import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.gcs.GcsUtils; import google.registry.gcs.GcsUtils;
@ -124,14 +123,12 @@ public class RdeHostImportAction implements Runnable {
// Record number of attempted map operations // Record number of attempted map operations
getContext().incrementCounter("host imports attempted"); getContext().incrementCounter("host imports attempted");
logger.atInfo().log("Saving host %s", xjcHost.getName()); logger.atInfo().log("Saving host %s", xjcHost.getName());
ofy().transact(new VoidWork() { ofy()
.transact(
@Override () -> {
public void vrun() { HostResource host = XjcToHostResourceConverter.convert(xjcHost);
HostResource host = XjcToHostResourceConverter.convert(xjcHost); getImportUtils().importEppResource(host);
getImportUtils().importEppResource(host); });
}
});
// Record number of hosts imported // Record number of hosts imported
getContext().incrementCounter("hosts saved"); getContext().incrementCounter("hosts saved");
logger.atInfo().log("Host %s was imported successfully", xjcHost.getName()); logger.atInfo().log("Host %s was imported successfully", xjcHost.getName());

View file

@ -30,10 +30,10 @@ import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters; import com.beust.jcommander.Parameters;
import com.google.common.base.Ascii; import com.google.common.base.Ascii;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.template.soy.data.SoyMapData; import com.google.template.soy.data.SoyMapData;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.VoidWork;
import google.registry.flows.EppException; import google.registry.flows.EppException;
import google.registry.model.domain.DesignatedContact; import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.DomainApplication; import google.registry.model.domain.DomainApplication;
@ -99,98 +99,92 @@ final class AllocateDomainCommand extends MutatingEppToolCommand {
protected void initMutatingEppToolCommand() { protected void initMutatingEppToolCommand() {
checkArgument(superuser, "This command MUST be run as --superuser."); checkArgument(superuser, "This command MUST be run as --superuser.");
setSoyTemplate(DomainAllocateSoyInfo.getInstance(), DomainAllocateSoyInfo.CREATE); setSoyTemplate(DomainAllocateSoyInfo.getInstance(), DomainAllocateSoyInfo.CREATE);
ofy() ofy().transactNewReadOnly(this::initAllocateDomainCommand);
.transactNewReadOnly( }
new VoidWork() {
@Override private void initAllocateDomainCommand() {
public void vrun() { Iterable<Key<DomainApplication>> keys =
Iterable<Key<DomainApplication>> keys = transform(
transform( Splitter.on(',').split(ids),
Splitter.on(',').split(ids), applicationId -> Key.create(DomainApplication.class, applicationId));
applicationId -> Key.create(DomainApplication.class, applicationId)); for (DomainApplication application : ofy().load().keys(keys).values()) {
for (DomainApplication application : ofy().load().keys(keys).values()) { // If the application is already allocated print a warning but do not fail.
// If the application is already allocated print a warning but do not fail. if (application.getApplicationStatus() == ApplicationStatus.ALLOCATED) {
if (application.getApplicationStatus() == ApplicationStatus.ALLOCATED) { System.err.printf("Application %s has already been allocated\n", application.getRepoId());
System.err.printf( continue;
"Application %s has already been allocated\n", application.getRepoId()); }
continue; // Ensure domain doesn't already have a final status which it shouldn't be updated
} // from.
// Ensure domain doesn't already have a final status which it shouldn't be updated checkState(
// from. !application.getApplicationStatus().isFinalStatus(),
checkState( "Application has final status %s",
!application.getApplicationStatus().isFinalStatus(), application.getApplicationStatus());
"Application has final status %s", try {
application.getApplicationStatus()); HistoryEntry history =
try { checkNotNull(
HistoryEntry history = ofy()
checkNotNull( .load()
ofy() .type(HistoryEntry.class)
.load() .ancestor(checkNotNull(application))
.type(HistoryEntry.class) .order("modificationTime")
.ancestor(checkNotNull(application)) .first()
.order("modificationTime") .now(),
.first() "Could not find any history entries for domain application %s",
.now(), application.getRepoId());
"Could not find any history entries for domain application %s", String clientTransactionId =
application.getRepoId()); emptyToNull(history.getTrid().getClientTransactionId().orElse(null));
String clientTransactionId = Period period = checkNotNull(extractPeriodFromXml(history.getXmlBytes()));
emptyToNull(history.getTrid().getClientTransactionId().orElse(null)); checkArgument(period.getUnit() == Period.Unit.YEARS);
Period period = checkNotNull(extractPeriodFromXml(history.getXmlBytes())); ImmutableMap.Builder<String, String> contactsMapBuilder = new ImmutableMap.Builder<>();
checkArgument(period.getUnit() == Period.Unit.YEARS); for (DesignatedContact contact : application.getContacts()) {
ImmutableMap.Builder<String, String> contactsMapBuilder = contactsMapBuilder.put(
new ImmutableMap.Builder<>(); Ascii.toLowerCase(contact.getType().toString()),
for (DesignatedContact contact : application.getContacts()) { ofy().load().key(contact.getContactKey()).now().getForeignKey());
contactsMapBuilder.put( }
Ascii.toLowerCase(contact.getType().toString()), LaunchNotice launchNotice = application.getLaunchNotice();
ofy().load().key(contact.getContactKey()).now().getForeignKey()); String smdId =
} application.getEncodedSignedMarks().isEmpty()
LaunchNotice launchNotice = application.getLaunchNotice(); ? null
addSoyRecord( : unmarshal(SignedMark.class, application.getEncodedSignedMarks().get(0).getBytes())
application.getCurrentSponsorClientId(), .getId();
new SoyMapData( ImmutableMap<String, String> launchNoticeMap =
"name", application.getFullyQualifiedDomainName(), (launchNotice == null)
"period", period.getValue(), ? null
"nameservers", application.loadNameserverFullyQualifiedHostNames(), : ImmutableMap.of(
"registrant", "noticeId", launchNotice.getNoticeId().getTcnId(),
ofy().load().key(application.getRegistrant()).now().getForeignKey(), "expirationTime", launchNotice.getExpirationTime().toString(),
"contacts", contactsMapBuilder.build(), "acceptedTime", launchNotice.getAcceptedTime().toString());
"authInfo", application.getAuthInfo().getPw().getValue(), ImmutableList<ImmutableMap<String, ?>> dsRecords =
"smdId", application
application.getEncodedSignedMarks().isEmpty() .getDsData()
? null .stream()
: unmarshal( .map(
SignedMark.class, dsData ->
application.getEncodedSignedMarks().get(0).getBytes()) ImmutableMap.of(
.getId(), "keyTag", dsData.getKeyTag(),
"applicationRoid", application.getRepoId(), "algorithm", dsData.getAlgorithm(),
"applicationTime", application.getCreationTime().toString(), "digestType", dsData.getDigestType(),
"launchNotice", "digest", base16().encode(dsData.getDigest())))
launchNotice == null .collect(toImmutableList());
? null addSoyRecord(
: ImmutableMap.of( application.getCurrentSponsorClientId(),
"noticeId", launchNotice.getNoticeId().getTcnId(), new SoyMapData(
"expirationTime", "name", application.getFullyQualifiedDomainName(),
launchNotice.getExpirationTime().toString(), "period", period.getValue(),
"acceptedTime", launchNotice.getAcceptedTime().toString()), "nameservers", application.loadNameserverFullyQualifiedHostNames(),
"dsRecords", "registrant", ofy().load().key(application.getRegistrant()).now().getForeignKey(),
application "contacts", contactsMapBuilder.build(),
.getDsData() "authInfo", application.getAuthInfo().getPw().getValue(),
.stream() "smdId", smdId,
.map( "applicationRoid", application.getRepoId(),
dsData -> "applicationTime", application.getCreationTime().toString(),
ImmutableMap.of( "launchNotice", launchNoticeMap,
"keyTag", dsData.getKeyTag(), "dsRecords", dsRecords,
"algorithm", dsData.getAlgorithm(), "clTrid", clientTransactionId));
"digestType", dsData.getDigestType(), applicationKeys.add(Key.create(application));
"digest", base16().encode(dsData.getDigest()))) } catch (EppException e) {
.collect(toImmutableList()), throw new RuntimeException(e);
"clTrid", clientTransactionId)); }
applicationKeys.add(Key.create(application)); }
} catch (EppException e) {
throw new RuntimeException(e);
}
}
}
});
} }
} }

View file

@ -19,7 +19,6 @@ import static google.registry.model.ofy.ObjectifyService.ofy;
import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters; import com.beust.jcommander.Parameters;
import com.googlecode.objectify.VoidWork;
import google.registry.model.domain.DomainResource; import google.registry.model.domain.DomainResource;
import google.registry.model.registrar.Registrar; import google.registry.model.registrar.Registrar;
import google.registry.model.registry.Registry; import google.registry.model.registry.Registry;
@ -78,11 +77,7 @@ final class DeleteTldCommand extends ConfirmingCommand implements RemoteApiComma
@Override @Override
protected String execute() { protected String execute() {
ofy().transactNew(new VoidWork() { ofy().transactNew(() -> ofy().delete().entity(registry).now());
@Override
public void vrun() {
ofy().delete().entity(registry).now();
}});
registry.invalidateInCache(); registry.invalidateInCache();
return String.format("Deleted TLD '%s'.\n", tld); return String.format("Deleted TLD '%s'.\n", tld);
} }

View file

@ -30,7 +30,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.VoidWork;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.tools.Command.RemoteApiCommand; import google.registry.tools.Command.RemoteApiCommand;
import java.util.ArrayList; import java.util.ArrayList;
@ -142,39 +141,33 @@ public abstract class MutatingCommand extends ConfirmingCommand implements Remot
@Override @Override
protected String execute() throws Exception { protected String execute() throws Exception {
for (final List<EntityChange> batch : getCollatedEntityChangeBatches()) { for (final List<EntityChange> batch : getCollatedEntityChangeBatches()) {
ofy().transact(new VoidWork() { ofy().transact(() -> batch.forEach(this::executeChange));
@Override
public void vrun() {
for (EntityChange change : batch) {
// Load the key of the entity to mutate and double-check that it hasn't been
// modified from the version that existed when the change was prepared.
ImmutableObject existingEntity = ofy().load().key(change.key).now();
checkState(
Objects.equals(change.oldEntity, existingEntity),
"Entity changed since init() was called.\n%s",
prettyPrintEntityDeepDiff(
change.oldEntity == null ? ImmutableMap.of()
: change.oldEntity.toDiffableFieldMap(),
existingEntity == null ? ImmutableMap.of()
: existingEntity.toDiffableFieldMap()));
switch (change.type) {
case CREATE: // Fall through.
case UPDATE:
ofy().save().entity(change.newEntity).now();
break;
case DELETE:
ofy().delete().key(change.key).now();
break;
default:
throw new UnsupportedOperationException(
"Unknown entity change type: " + change.type);
}
}
}});
} }
return String.format("Updated %d entities.\n", changedEntitiesMap.size()); return String.format("Updated %d entities.\n", changedEntitiesMap.size());
} }
private void executeChange(EntityChange change) {
// Load the key of the entity to mutate and double-check that it hasn't been
// modified from the version that existed when the change was prepared.
ImmutableObject existingEntity = ofy().load().key(change.key).now();
checkState(
Objects.equals(change.oldEntity, existingEntity),
"Entity changed since init() was called.\n%s",
prettyPrintEntityDeepDiff(
(change.oldEntity == null) ? ImmutableMap.of() : change.oldEntity.toDiffableFieldMap(),
(existingEntity == null) ? ImmutableMap.of() : existingEntity.toDiffableFieldMap()));
switch (change.type) {
case CREATE: // Fall through.
case UPDATE:
ofy().save().entity(change.newEntity).now();
return;
case DELETE:
ofy().delete().key(change.key).now();
return;
}
throw new UnsupportedOperationException("Unknown entity change type: " + change.type);
}
/** /**
* Returns a set of lists of EntityChange actions to commit. Each list should be executed in * Returns a set of lists of EntityChange actions to commit. Each list should be executed in
* order inside a single transaction. * order inside a single transaction.

View file

@ -25,7 +25,6 @@ import com.google.appengine.api.datastore.KeyFactory;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.googlecode.objectify.VoidWork;
import com.googlecode.objectify.impl.EntityMetadata; import com.googlecode.objectify.impl.EntityMetadata;
import google.registry.request.Action; import google.registry.request.Action;
import google.registry.request.HttpException.BadRequestException; import google.registry.request.HttpException.BadRequestException;
@ -90,11 +89,7 @@ public class DeleteEntityAction implements Runnable {
getDatastoreService().delete(rawDeletions); getDatastoreService().delete(rawDeletions);
// Delete ofy entities. // Delete ofy entities.
final ImmutableList<Object> ofyDeletions = ofyDeletionsBuilder.build(); final ImmutableList<Object> ofyDeletions = ofyDeletionsBuilder.build();
ofy().transactNew(new VoidWork() { ofy().transactNew(() -> ofy().delete().entities(ofyDeletions).now());
@Override
public void vrun() {
ofy().delete().entities(ofyDeletions).now();
}});
String message = String.format( String message = String.format(
"Deleted %d raw entities and %d registered entities", "Deleted %d raw entities and %d registered entities",
rawDeletions.size(), rawDeletions.size(),

View file

@ -17,7 +17,6 @@ package google.registry.model.common;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.ofy.ObjectifyService.ofy;
import com.googlecode.objectify.VoidWork;
import google.registry.testing.AppEngineRule; import google.registry.testing.AppEngineRule;
import org.junit.After; import org.junit.After;
import org.junit.Rule; import org.junit.Rule;
@ -47,11 +46,10 @@ public class GaeUserIdConverterTest {
@Test @Test
public void testSuccess_inTransaction() { public void testSuccess_inTransaction() {
ofy().transactNew(new VoidWork() { ofy()
@Override .transactNew(
public void vrun() { () ->
assertThat(GaeUserIdConverter.convertEmailAddressToGaeUserId("example@example.com")) assertThat(GaeUserIdConverter.convertEmailAddressToGaeUserId("example@example.com"))
.matches("[0-9]+"); .matches("[0-9]+"));
}});
} }
} }

View file

@ -83,13 +83,13 @@ public class OfyTest {
// This can't be initialized earlier because namespaces need the AppEngineRule to work. // This can't be initialized earlier because namespaces need the AppEngineRule to work.
} }
private void doBackupGroupRootTimestampInversionTest(VoidWork work) { private void doBackupGroupRootTimestampInversionTest(Runnable runnable) {
DateTime groupTimestamp = ofy().load().key(someObject.getParent()).now() DateTime groupTimestamp = ofy().load().key(someObject.getParent()).now()
.getUpdateAutoTimestamp().getTimestamp(); .getUpdateAutoTimestamp().getTimestamp();
// Set the clock in Ofy to the same time as the backup group root's save time. // Set the clock in Ofy to the same time as the backup group root's save time.
Ofy ofy = new Ofy(new FakeClock(groupTimestamp)); Ofy ofy = new Ofy(new FakeClock(groupTimestamp));
TimestampInversionException thrown = TimestampInversionException thrown =
assertThrows(TimestampInversionException.class, () -> ofy.transact(work)); assertThrows(TimestampInversionException.class, () -> ofy.transact(runnable));
assertThat(thrown) assertThat(thrown)
.hasMessageThat() .hasMessageThat()
.contains( .contains(
@ -101,20 +101,12 @@ public class OfyTest {
@Test @Test
public void testBackupGroupRootTimestampsMustIncreaseOnSave() { public void testBackupGroupRootTimestampsMustIncreaseOnSave() {
doBackupGroupRootTimestampInversionTest(new VoidWork() { doBackupGroupRootTimestampInversionTest(() -> ofy().save().entity(someObject));
@Override
public void vrun() {
ofy().save().entity(someObject);
}});
} }
@Test @Test
public void testBackupGroupRootTimestampsMustIncreaseOnDelete() { public void testBackupGroupRootTimestampsMustIncreaseOnDelete() {
doBackupGroupRootTimestampInversionTest(new VoidWork() { doBackupGroupRootTimestampInversionTest(() -> ofy().delete().entity(someObject));
@Override
public void vrun() {
ofy().delete().entity(someObject);
}});
} }
@Test @Test
@ -125,12 +117,9 @@ public class OfyTest {
() -> () ->
ofy() ofy()
.transact( .transact(
new VoidWork() { () -> {
@Override ofy().save().entity(someObject);
public void vrun() { ofy().save().entity(someObject);
ofy().save().entity(someObject);
ofy().save().entity(someObject);
}
})); }));
assertThat(thrown).hasMessageThat().contains("Multiple entries with same key"); assertThat(thrown).hasMessageThat().contains("Multiple entries with same key");
} }
@ -143,12 +132,9 @@ public class OfyTest {
() -> () ->
ofy() ofy()
.transact( .transact(
new VoidWork() { () -> {
@Override ofy().delete().entity(someObject);
public void vrun() { ofy().delete().entity(someObject);
ofy().delete().entity(someObject);
ofy().delete().entity(someObject);
}
})); }));
assertThat(thrown).hasMessageThat().contains("Multiple entries with same key"); assertThat(thrown).hasMessageThat().contains("Multiple entries with same key");
} }
@ -161,12 +147,9 @@ public class OfyTest {
() -> () ->
ofy() ofy()
.transact( .transact(
new VoidWork() { () -> {
@Override ofy().save().entity(someObject);
public void vrun() { ofy().delete().entity(someObject);
ofy().save().entity(someObject);
ofy().delete().entity(someObject);
}
})); }));
assertThat(thrown).hasMessageThat().contains("Multiple entries with same key"); assertThat(thrown).hasMessageThat().contains("Multiple entries with same key");
} }
@ -179,12 +162,9 @@ public class OfyTest {
() -> () ->
ofy() ofy()
.transact( .transact(
new VoidWork() { () -> {
@Override ofy().delete().entity(someObject);
public void vrun() { ofy().save().entity(someObject);
ofy().delete().entity(someObject);
ofy().save().entity(someObject);
}
})); }));
assertThat(thrown).hasMessageThat().contains("Multiple entries with same key"); assertThat(thrown).hasMessageThat().contains("Multiple entries with same key");
} }
@ -193,15 +173,7 @@ public class OfyTest {
public void testSavingKeyTwiceInOneCall() { public void testSavingKeyTwiceInOneCall() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
() -> () -> ofy().transact(() -> ofy().save().entities(someObject, someObject)));
ofy()
.transact(
new VoidWork() {
@Override
public void vrun() {
ofy().save().entities(someObject, someObject);
}
}));
} }
/** Simple entity class with lifecycle callbacks. */ /** Simple entity class with lifecycle callbacks. */
@ -241,11 +213,7 @@ public class OfyTest {
public void testLifecycleCallbacks_loadFromDatastore() { public void testLifecycleCallbacks_loadFromDatastore() {
ofy().factory().register(LifecycleObject.class); ofy().factory().register(LifecycleObject.class);
final LifecycleObject object = new LifecycleObject(); final LifecycleObject object = new LifecycleObject();
ofy().transact(new VoidWork() { ofy().transact(() -> ofy().save().entity(object).now());
@Override
public void vrun() {
ofy().save().entity(object).now();
}});
assertThat(object.onSaveCalled).isTrue(); assertThat(object.onSaveCalled).isTrue();
ofy().clearSessionCache(); ofy().clearSessionCache();
assertThat(ofy().load().entity(object).now().onLoadCalled).isTrue(); assertThat(ofy().load().entity(object).now().onLoadCalled).isTrue();

View file

@ -22,7 +22,6 @@ import static google.registry.model.rde.RdeRevision.saveRevision;
import static google.registry.testing.JUnitBackports.assertThrows; import static google.registry.testing.JUnitBackports.assertThrows;
import com.google.common.base.VerifyException; import com.google.common.base.VerifyException;
import com.googlecode.objectify.VoidWork;
import google.registry.testing.AppEngineRule; import google.registry.testing.AppEngineRule;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.junit.Rule; import org.junit.Rule;
@ -51,17 +50,12 @@ public class RdeRevisionTest {
@Test @Test
public void testSaveRevision_objectDoesntExist_newRevisionIsZero_nextRevIsOne() { public void testSaveRevision_objectDoesntExist_newRevisionIsZero_nextRevIsOne() {
ofy().transact(new VoidWork() { ofy().transact(() -> saveRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL, 0));
@Override ofy()
public void vrun() { .transact(
saveRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL, 0); () ->
}}); assertThat(getNextRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL))
ofy().transact(new VoidWork() { .isEqualTo(1));
@Override
public void vrun() {
assertThat(getNextRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL))
.isEqualTo(1);
}});
} }
@Test @Test
@ -72,12 +66,8 @@ public class RdeRevisionTest {
() -> () ->
ofy() ofy()
.transact( .transact(
new VoidWork() { () ->
@Override saveRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL, 1)));
public void vrun() {
saveRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL, 1);
}
}));
assertThat(thrown).hasMessageThat().contains("object missing"); assertThat(thrown).hasMessageThat().contains("object missing");
} }
@ -90,29 +80,19 @@ public class RdeRevisionTest {
() -> () ->
ofy() ofy()
.transact( .transact(
new VoidWork() { () -> saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 0)));
@Override
public void vrun() {
saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 0);
}
}));
assertThat(thrown).hasMessageThat().contains("object already created"); assertThat(thrown).hasMessageThat().contains("object already created");
} }
@Test @Test
public void testSaveRevision_objectExistsAtZero_newRevisionIsOne_nextRevIsTwo() { public void testSaveRevision_objectExistsAtZero_newRevisionIsOne_nextRevIsTwo() {
save("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 0); save("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 0);
ofy().transact(new VoidWork() { ofy().transact(() -> saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 1));
@Override ofy()
public void vrun() { .transact(
saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 1); () ->
}}); assertThat(getNextRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL))
ofy().transact(new VoidWork() { .isEqualTo(2));
@Override
public void vrun() {
assertThat(getNextRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL))
.isEqualTo(2);
}});
} }
@Test @Test
@ -124,12 +104,7 @@ public class RdeRevisionTest {
() -> () ->
ofy() ofy()
.transact( .transact(
new VoidWork() { () -> saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 2)));
@Override
public void vrun() {
saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 2);
}
}));
assertThat(thrown).hasMessageThat().contains("should be at 1 "); assertThat(thrown).hasMessageThat().contains("should be at 1 ");
} }
@ -141,12 +116,8 @@ public class RdeRevisionTest {
() -> () ->
ofy() ofy()
.transact( .transact(
new VoidWork() { () ->
@Override saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, -1)));
public void vrun() {
saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, -1);
}
}));
assertThat(thrown).hasMessageThat().contains("Negative revision"); assertThat(thrown).hasMessageThat().contains("Negative revision");
} }

View file

@ -33,7 +33,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.ImmutableSortedSet;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.VoidWork;
import google.registry.model.EntityTestCase; import google.registry.model.EntityTestCase;
import google.registry.model.common.EntityGroupRoot; import google.registry.model.common.EntityGroupRoot;
import google.registry.model.registrar.Registrar.State; import google.registry.model.registrar.Registrar.State;
@ -418,15 +417,16 @@ public class RegistrarTest extends EntityTestCase {
@Test @Test
public void testLoadByClientIdCached_isTransactionless() { public void testLoadByClientIdCached_isTransactionless() {
ofy().transact(new VoidWork() { ofy()
@Override .transact(
public void vrun() { () -> {
assertThat(Registrar.loadByClientIdCached("registrar")).isPresent(); assertThat(Registrar.loadByClientIdCached("registrar")).isPresent();
// Load something as a control to make sure we are seeing loaded keys in the session cache. // Load something as a control to make sure we are seeing loaded keys in the session
ofy().load().entity(abuseAdminContact).now(); // cache.
assertThat(ofy().getSessionKeys()).contains(Key.create(abuseAdminContact)); ofy().load().entity(abuseAdminContact).now();
assertThat(ofy().getSessionKeys()).doesNotContain(Key.create(registrar)); assertThat(ofy().getSessionKeys()).contains(Key.create(abuseAdminContact));
}}); assertThat(ofy().getSessionKeys()).doesNotContain(Key.create(registrar));
});
ofy().clearSessionCache(); ofy().clearSessionCache();
// Conversely, loads outside of a transaction should end up in the session cache. // Conversely, loads outside of a transaction should end up in the session cache.
assertThat(Registrar.loadByClientIdCached("registrar")).isPresent(); assertThat(Registrar.loadByClientIdCached("registrar")).isPresent();

View file

@ -41,7 +41,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.VoidWork;
import google.registry.dns.writer.VoidDnsWriter; import google.registry.dns.writer.VoidDnsWriter;
import google.registry.model.pricing.StaticPremiumListPricingEngine; import google.registry.model.pricing.StaticPremiumListPricingEngine;
import google.registry.model.registry.Registry; import google.registry.model.registry.Registry;
@ -193,18 +192,14 @@ public class PremiumListUtilsTest {
// Remove one of the premium list entries from behind the Bloom filter's back. // Remove one of the premium list entries from behind the Bloom filter's back.
ofy() ofy()
.transactNew( .transactNew(
new VoidWork() { () ->
@Override
public void vrun() {
ofy() ofy()
.delete() .delete()
.keys( .keys(
Key.create( Key.create(
PremiumList.getCached("tld").get().getRevisionKey(), PremiumList.getCached("tld").get().getRevisionKey(),
PremiumListEntry.class, PremiumListEntry.class,
"rich")); "rich")));
}
});
ofy().clearSessionCache(); ofy().clearSessionCache();
assertThat(getPremiumPrice("rich", Registry.get("tld"))).isEmpty(); assertThat(getPremiumPrice("rich", Registry.get("tld"))).isEmpty();

View file

@ -53,7 +53,6 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Streams; import com.google.common.collect.Streams;
import com.google.common.net.InetAddresses; import com.google.common.net.InetAddresses;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.VoidWork;
import com.googlecode.objectify.cmd.Saver; import com.googlecode.objectify.cmd.Saver;
import google.registry.dns.writer.VoidDnsWriter; import google.registry.dns.writer.VoidDnsWriter;
import google.registry.model.Buildable; import google.registry.model.Buildable;
@ -366,11 +365,7 @@ public class DatastoreHelper {
final DomainResource persistedDomain = persistResource(domain); final DomainResource persistedDomain = persistResource(domain);
// Calls {@link LordnTask#enqueueDomainResourceTask} wrapped in an ofy transaction so that the // Calls {@link LordnTask#enqueueDomainResourceTask} wrapped in an ofy transaction so that the
// transaction time is set correctly. // transaction time is set correctly.
ofy().transactNew(new VoidWork() { ofy().transactNew(() -> LordnTask.enqueueDomainResourceTask(persistedDomain));
@Override
public void vrun() {
LordnTask.enqueueDomainResourceTask(persistedDomain);
}});
return persistedDomain; return persistedDomain;
} }
@ -947,11 +942,7 @@ public class DatastoreHelper {
assertWithMessage("Attempting to persist a Builder is almost certainly an error in test code") assertWithMessage("Attempting to persist a Builder is almost certainly an error in test code")
.that(resource) .that(resource)
.isNotInstanceOf(Buildable.Builder.class); .isNotInstanceOf(Buildable.Builder.class);
ofy().transact(new VoidWork() { ofy().transact(() -> saveResource(resource, wantBackup));
@Override
public void vrun() {
saveResource(resource, wantBackup);
}});
// Force the session cache to be cleared so that when we read the resource back, we read from // Force the session cache to be cleared so that when we read the resource back, we read from
// Datastore and not from the session cache. This is needed to trigger Objectify's load process // Datastore and not from the session cache. This is needed to trigger Objectify's load process
// (unmarshalling entity protos to POJOs, nulling out empty collections, calling @OnLoad // (unmarshalling entity protos to POJOs, nulling out empty collections, calling @OnLoad
@ -964,13 +955,13 @@ public class DatastoreHelper {
public static <R extends EppResource> R persistEppResourceInFirstBucket(final R resource) { public static <R extends EppResource> R persistEppResourceInFirstBucket(final R resource) {
final EppResourceIndex eppResourceIndex = final EppResourceIndex eppResourceIndex =
EppResourceIndex.create(Key.create(EppResourceIndexBucket.class, 1), Key.create(resource)); EppResourceIndex.create(Key.create(EppResourceIndexBucket.class, 1), Key.create(resource));
ofy().transact(new VoidWork() { ofy()
@Override .transact(
public void vrun() { () -> {
Saver saver = ofy().save(); Saver saver = ofy().save();
saver.entity(resource); saver.entity(resource);
persistEppResourceExtras(resource, eppResourceIndex, saver); persistEppResourceExtras(resource, eppResourceIndex, saver);
}}); });
ofy().clearSessionCache(); ofy().clearSessionCache();
return ofy().load().entity(resource).now(); return ofy().load().entity(resource).now();
} }
@ -987,13 +978,7 @@ public class DatastoreHelper {
} }
// Persist domains ten at a time, to avoid exceeding the entity group limit. // Persist domains ten at a time, to avoid exceeding the entity group limit.
for (final List<R> chunk : Iterables.partition(resources, 10)) { for (final List<R> chunk : Iterables.partition(resources, 10)) {
ofy().transact(new VoidWork() { ofy().transact(() -> chunk.forEach(resource -> saveResource(resource, wantBackup)));
@Override
public void vrun() {
for (R resource : chunk) {
saveResource(resource, wantBackup);
}
}});
} }
// Force the session to be cleared so that when we read it back, we read from Datastore // Force the session to be cleared so that when we read it back, we read from Datastore
// and not from the transaction's session cache. // and not from the transaction's session cache.
@ -1015,18 +1000,20 @@ public class DatastoreHelper {
*/ */
public static <R extends EppResource> R persistEppResource(final R resource) { public static <R extends EppResource> R persistEppResource(final R resource) {
checkState(!ofy().inTransaction()); checkState(!ofy().inTransaction());
ofy().transact(new VoidWork() { ofy()
@Override .transact(
public void vrun() { () -> {
ofy().save().<ImmutableObject>entities( ofy()
resource, .save()
new HistoryEntry.Builder() .<ImmutableObject>entities(
.setParent(resource) resource,
.setType(getHistoryEntryType(resource)) new HistoryEntry.Builder()
.setModificationTime(ofy().getTransactionTime()) .setParent(resource)
.build()); .setType(getHistoryEntryType(resource))
ofy().save().entity(ForeignKeyIndex.create(resource, resource.getDeletionTime())); .setModificationTime(ofy().getTransactionTime())
}}); .build());
ofy().save().entity(ForeignKeyIndex.create(resource, resource.getDeletionTime()));
});
ofy().clearSessionCache(); ofy().clearSessionCache();
return ofy().load().entity(resource).safe(); return ofy().load().entity(resource).safe();
} }
@ -1099,11 +1086,7 @@ public class DatastoreHelper {
* ForeignKeyedEppResources. * ForeignKeyedEppResources.
*/ */
public static <R> ImmutableList<R> persistSimpleResources(final Iterable<R> resources) { public static <R> ImmutableList<R> persistSimpleResources(final Iterable<R> resources) {
ofy().transact(new VoidWork(){ ofy().transact(() -> ofy().saveWithoutBackup().entities(resources));
@Override
public void vrun() {
ofy().saveWithoutBackup().entities(resources);
}});
// Force the session to be cleared so that when we read it back, we read from Datastore // Force the session to be cleared so that when we read it back, we read from Datastore
// and not from the transaction's session cache. // and not from the transaction's session cache.
ofy().clearSessionCache(); ofy().clearSessionCache();

View file

@ -35,7 +35,6 @@ import com.google.appengine.api.taskqueue.TransientFailureException;
import com.google.apphosting.api.DeadlineExceededException; import com.google.apphosting.api.DeadlineExceededException;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.VoidWork;
import google.registry.model.domain.DomainResource; import google.registry.model.domain.DomainResource;
import google.registry.model.domain.launch.LaunchNotice; import google.registry.model.domain.launch.LaunchNotice;
import google.registry.model.ofy.Ofy; import google.registry.model.ofy.Ofy;
@ -174,15 +173,7 @@ public class LordnTaskTest {
public void test_enqueueDomainResourceTask_throwsNpeOnNullDomain() { public void test_enqueueDomainResourceTask_throwsNpeOnNullDomain() {
assertThrows( assertThrows(
NullPointerException.class, NullPointerException.class,
() -> () -> ofy().transactNew(() -> LordnTask.enqueueDomainResourceTask(null)));
ofy()
.transactNew(
new VoidWork() {
@Override
public void vrun() {
LordnTask.enqueueDomainResourceTask(null);
}
}));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")