mirror of
https://github.com/google/nomulus.git
synced 2025-05-28 16:30:12 +02:00
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:
parent
7d3cb3d426
commit
d3364b0387
18 changed files with 349 additions and 502 deletions
|
@ -309,6 +309,14 @@ public class Ofy {
|
|||
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. */
|
||||
public <R> R doTransactionless(Work<R> work) {
|
||||
try {
|
||||
|
|
|
@ -26,7 +26,6 @@ import com.google.common.collect.ImmutableSet;
|
|||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.VoidWork;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
|
@ -156,22 +155,15 @@ public class RegistrarContact extends ImmutableObject implements Jsonifiable {
|
|||
final Registrar registrar, final Set<RegistrarContact> contacts) {
|
||||
ofy()
|
||||
.transact(
|
||||
new VoidWork() {
|
||||
@Override
|
||||
public void vrun() {
|
||||
ofy()
|
||||
.delete()
|
||||
.keys(
|
||||
difference(
|
||||
ImmutableSet.copyOf(
|
||||
ofy()
|
||||
.load()
|
||||
.type(RegistrarContact.class)
|
||||
.ancestor(registrar)
|
||||
.keys()),
|
||||
contacts.stream().map(Key::create).collect(toImmutableSet())));
|
||||
ofy().save().entities(contacts);
|
||||
}
|
||||
() -> {
|
||||
ofy()
|
||||
.delete()
|
||||
.keys(
|
||||
difference(
|
||||
ImmutableSet.copyOf(
|
||||
ofy().load().type(RegistrarContact.class).ancestor(registrar).keys()),
|
||||
contacts.stream().map(Key::create).collect(toImmutableSet())));
|
||||
ofy().save().entities(contacts);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ import com.google.common.collect.ImmutableMap;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.VoidWork;
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.registry.label.DomainLabelMetrics.PremiumListCheckOutcome;
|
||||
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. */
|
||||
public static void deletePremiumList(final PremiumList premiumList) {
|
||||
ofy().transactNew(new VoidWork() {
|
||||
@Override
|
||||
public void vrun() {
|
||||
ofy().delete().entity(premiumList);
|
||||
}});
|
||||
ofy().transactNew(() -> ofy().delete().entity(premiumList));
|
||||
deleteRevisionAndEntriesOfPremiumList(premiumList);
|
||||
cachePremiumLists.invalidate(premiumList.getName());
|
||||
}
|
||||
|
@ -209,20 +204,13 @@ public final class PremiumListUtils {
|
|||
if (premiumList.getRevisionKey() == null) {
|
||||
return;
|
||||
}
|
||||
for (final List<Key<PremiumListEntry>> batch : partition(
|
||||
ofy().load().type(PremiumListEntry.class).ancestor(premiumList.revisionKey).keys(),
|
||||
TRANSACTION_BATCH_SIZE)) {
|
||||
ofy().transactNew(new VoidWork() {
|
||||
@Override
|
||||
public void vrun() {
|
||||
ofy().delete().keys(batch);
|
||||
}});
|
||||
for (final List<Key<PremiumListEntry>> batch :
|
||||
partition(
|
||||
ofy().load().type(PremiumListEntry.class).ancestor(premiumList.revisionKey).keys(),
|
||||
TRANSACTION_BATCH_SIZE)) {
|
||||
ofy().transactNew(() -> ofy().delete().keys(batch));
|
||||
}
|
||||
ofy().transactNew(new VoidWork() {
|
||||
@Override
|
||||
public void vrun() {
|
||||
ofy().delete().key(premiumList.getRevisionKey());
|
||||
}});
|
||||
ofy().transactNew(() -> ofy().delete().key(premiumList.getRevisionKey()));
|
||||
}
|
||||
|
||||
/** Returns whether a PremiumList of the given name exists, bypassing the cache. */
|
||||
|
|
|
@ -22,7 +22,6 @@ import com.google.auto.value.AutoValue;
|
|||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.googlecode.objectify.VoidWork;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
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.
|
||||
ofy()
|
||||
.transact(
|
||||
new VoidWork() {
|
||||
@Override
|
||||
public void vrun() {
|
||||
// To release a lock, check that no one else has already obtained it and if not
|
||||
// delete it. If the lock in Datastore was different then this lock is gone already;
|
||||
// this can happen if release() is called around the expiration time and the lock
|
||||
// expires underneath us.
|
||||
Lock loadedLock = ofy().load().type(Lock.class).id(lockId).now();
|
||||
if (Lock.this.equals(loadedLock)) {
|
||||
// Use noBackupOfy() so that we don't create a commit log entry for deleting the
|
||||
// lock.
|
||||
logger.atInfo().log("Deleting lock: %s", lockId);
|
||||
ofy().deleteWithoutBackup().entity(Lock.this);
|
||||
lockMetrics.recordRelease(
|
||||
resourceName, tld, new Duration(acquiredTime, ofy().getTransactionTime()));
|
||||
} else {
|
||||
logger.atSevere().log(
|
||||
"The lock we acquired was transferred to someone else before we"
|
||||
+ " released it! Did action take longer than lease length?"
|
||||
+ " Our lock: %s, current lock: %s",
|
||||
Lock.this, loadedLock);
|
||||
logger.atInfo().log(
|
||||
"Not deleting lock: %s - someone else has it: %s", lockId, loadedLock);
|
||||
}
|
||||
() -> {
|
||||
// To release a lock, check that no one else has already obtained it and if not
|
||||
// delete it. If the lock in Datastore was different then this lock is gone already;
|
||||
// this can happen if release() is called around the expiration time and the lock
|
||||
// expires underneath us.
|
||||
Lock loadedLock = ofy().load().type(Lock.class).id(lockId).now();
|
||||
if (Lock.this.equals(loadedLock)) {
|
||||
// Use noBackupOfy() so that we don't create a commit log entry for deleting the
|
||||
// lock.
|
||||
logger.atInfo().log("Deleting lock: %s", lockId);
|
||||
ofy().deleteWithoutBackup().entity(Lock.this);
|
||||
lockMetrics.recordRelease(
|
||||
resourceName, tld, new Duration(acquiredTime, ofy().getTransactionTime()));
|
||||
} else {
|
||||
logger.atSevere().log(
|
||||
"The lock we acquired was transferred to someone else before we"
|
||||
+ " released it! Did action take longer than lease length?"
|
||||
+ " Our lock: %s, current lock: %s",
|
||||
Lock.this, loadedLock);
|
||||
logger.atInfo().log(
|
||||
"Not deleting lock: %s - someone else has it: %s", lockId, loadedLock);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import com.google.appengine.tools.cloudstorage.RetryParams;
|
|||
import com.google.appengine.tools.mapreduce.Mapper;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.googlecode.objectify.VoidWork;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.config.RegistryConfig.ConfigModule;
|
||||
import google.registry.gcs.GcsUtils;
|
||||
|
@ -139,14 +138,13 @@ public class RdeContactImportAction implements Runnable {
|
|||
// Record number of attempted map operations
|
||||
getContext().incrementCounter("contact imports attempted");
|
||||
logger.atInfo().log("Saving contact %s", xjcContact.getId());
|
||||
ofy().transact(new VoidWork() {
|
||||
@Override
|
||||
public void vrun() {
|
||||
ContactResource contact =
|
||||
XjcToContactResourceConverter.convertContact(xjcContact);
|
||||
getImportUtils().importEppResource(contact);
|
||||
}
|
||||
});
|
||||
ofy()
|
||||
.transact(
|
||||
() -> {
|
||||
ContactResource contact =
|
||||
XjcToContactResourceConverter.convertContact(xjcContact);
|
||||
getImportUtils().importEppResource(contact);
|
||||
});
|
||||
// Record number of contacts imported
|
||||
getContext().incrementCounter("contacts saved");
|
||||
logger.atInfo().log("Contact %s was imported successfully", xjcContact.getId());
|
||||
|
|
|
@ -35,7 +35,6 @@ import com.google.appengine.tools.mapreduce.Mapper;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.googlecode.objectify.VoidWork;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.config.RegistryConfig.ConfigModule;
|
||||
import google.registry.dns.DnsQueue;
|
||||
|
@ -171,120 +170,10 @@ public class RdeDomainImportAction implements Runnable {
|
|||
try {
|
||||
// Record number of attempted map operations
|
||||
getContext().incrementCounter("domain imports attempted");
|
||||
|
||||
logger.atInfo().log("Saving domain %s", xjcDomain.getName());
|
||||
ofy()
|
||||
.transact(
|
||||
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();
|
||||
}
|
||||
});
|
||||
|
||||
ofy().transact(() -> saveDomain(xjcDomain));
|
||||
|
||||
// Record the number of domains imported
|
||||
getContext().incrementCounter("domains saved");
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import com.google.appengine.tools.cloudstorage.RetryParams;
|
|||
import com.google.appengine.tools.mapreduce.Mapper;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.googlecode.objectify.VoidWork;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.config.RegistryConfig.ConfigModule;
|
||||
import google.registry.gcs.GcsUtils;
|
||||
|
@ -124,14 +123,12 @@ public class RdeHostImportAction implements Runnable {
|
|||
// Record number of attempted map operations
|
||||
getContext().incrementCounter("host imports attempted");
|
||||
logger.atInfo().log("Saving host %s", xjcHost.getName());
|
||||
ofy().transact(new VoidWork() {
|
||||
|
||||
@Override
|
||||
public void vrun() {
|
||||
HostResource host = XjcToHostResourceConverter.convert(xjcHost);
|
||||
getImportUtils().importEppResource(host);
|
||||
}
|
||||
});
|
||||
ofy()
|
||||
.transact(
|
||||
() -> {
|
||||
HostResource host = XjcToHostResourceConverter.convert(xjcHost);
|
||||
getImportUtils().importEppResource(host);
|
||||
});
|
||||
// Record number of hosts imported
|
||||
getContext().incrementCounter("hosts saved");
|
||||
logger.atInfo().log("Host %s was imported successfully", xjcHost.getName());
|
||||
|
|
|
@ -30,10 +30,10 @@ import com.beust.jcommander.Parameter;
|
|||
import com.beust.jcommander.Parameters;
|
||||
import com.google.common.base.Ascii;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.template.soy.data.SoyMapData;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.VoidWork;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.model.domain.DesignatedContact;
|
||||
import google.registry.model.domain.DomainApplication;
|
||||
|
@ -99,98 +99,92 @@ final class AllocateDomainCommand extends MutatingEppToolCommand {
|
|||
protected void initMutatingEppToolCommand() {
|
||||
checkArgument(superuser, "This command MUST be run as --superuser.");
|
||||
setSoyTemplate(DomainAllocateSoyInfo.getInstance(), DomainAllocateSoyInfo.CREATE);
|
||||
ofy()
|
||||
.transactNewReadOnly(
|
||||
new VoidWork() {
|
||||
@Override
|
||||
public void vrun() {
|
||||
Iterable<Key<DomainApplication>> keys =
|
||||
transform(
|
||||
Splitter.on(',').split(ids),
|
||||
applicationId -> Key.create(DomainApplication.class, applicationId));
|
||||
for (DomainApplication application : ofy().load().keys(keys).values()) {
|
||||
// If the application is already allocated print a warning but do not fail.
|
||||
if (application.getApplicationStatus() == ApplicationStatus.ALLOCATED) {
|
||||
System.err.printf(
|
||||
"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.
|
||||
checkState(
|
||||
!application.getApplicationStatus().isFinalStatus(),
|
||||
"Application has final status %s",
|
||||
application.getApplicationStatus());
|
||||
try {
|
||||
HistoryEntry history =
|
||||
checkNotNull(
|
||||
ofy()
|
||||
.load()
|
||||
.type(HistoryEntry.class)
|
||||
.ancestor(checkNotNull(application))
|
||||
.order("modificationTime")
|
||||
.first()
|
||||
.now(),
|
||||
"Could not find any history entries for domain application %s",
|
||||
application.getRepoId());
|
||||
String clientTransactionId =
|
||||
emptyToNull(history.getTrid().getClientTransactionId().orElse(null));
|
||||
Period period = checkNotNull(extractPeriodFromXml(history.getXmlBytes()));
|
||||
checkArgument(period.getUnit() == Period.Unit.YEARS);
|
||||
ImmutableMap.Builder<String, String> contactsMapBuilder =
|
||||
new ImmutableMap.Builder<>();
|
||||
for (DesignatedContact contact : application.getContacts()) {
|
||||
contactsMapBuilder.put(
|
||||
Ascii.toLowerCase(contact.getType().toString()),
|
||||
ofy().load().key(contact.getContactKey()).now().getForeignKey());
|
||||
}
|
||||
LaunchNotice launchNotice = application.getLaunchNotice();
|
||||
addSoyRecord(
|
||||
application.getCurrentSponsorClientId(),
|
||||
new SoyMapData(
|
||||
"name", application.getFullyQualifiedDomainName(),
|
||||
"period", period.getValue(),
|
||||
"nameservers", application.loadNameserverFullyQualifiedHostNames(),
|
||||
"registrant",
|
||||
ofy().load().key(application.getRegistrant()).now().getForeignKey(),
|
||||
"contacts", contactsMapBuilder.build(),
|
||||
"authInfo", application.getAuthInfo().getPw().getValue(),
|
||||
"smdId",
|
||||
application.getEncodedSignedMarks().isEmpty()
|
||||
? null
|
||||
: unmarshal(
|
||||
SignedMark.class,
|
||||
application.getEncodedSignedMarks().get(0).getBytes())
|
||||
.getId(),
|
||||
"applicationRoid", application.getRepoId(),
|
||||
"applicationTime", application.getCreationTime().toString(),
|
||||
"launchNotice",
|
||||
launchNotice == null
|
||||
? null
|
||||
: ImmutableMap.of(
|
||||
"noticeId", launchNotice.getNoticeId().getTcnId(),
|
||||
"expirationTime",
|
||||
launchNotice.getExpirationTime().toString(),
|
||||
"acceptedTime", launchNotice.getAcceptedTime().toString()),
|
||||
"dsRecords",
|
||||
application
|
||||
.getDsData()
|
||||
.stream()
|
||||
.map(
|
||||
dsData ->
|
||||
ImmutableMap.of(
|
||||
"keyTag", dsData.getKeyTag(),
|
||||
"algorithm", dsData.getAlgorithm(),
|
||||
"digestType", dsData.getDigestType(),
|
||||
"digest", base16().encode(dsData.getDigest())))
|
||||
.collect(toImmutableList()),
|
||||
"clTrid", clientTransactionId));
|
||||
applicationKeys.add(Key.create(application));
|
||||
} catch (EppException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
ofy().transactNewReadOnly(this::initAllocateDomainCommand);
|
||||
}
|
||||
|
||||
private void initAllocateDomainCommand() {
|
||||
Iterable<Key<DomainApplication>> keys =
|
||||
transform(
|
||||
Splitter.on(',').split(ids),
|
||||
applicationId -> Key.create(DomainApplication.class, applicationId));
|
||||
for (DomainApplication application : ofy().load().keys(keys).values()) {
|
||||
// If the application is already allocated print a warning but do not fail.
|
||||
if (application.getApplicationStatus() == ApplicationStatus.ALLOCATED) {
|
||||
System.err.printf("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.
|
||||
checkState(
|
||||
!application.getApplicationStatus().isFinalStatus(),
|
||||
"Application has final status %s",
|
||||
application.getApplicationStatus());
|
||||
try {
|
||||
HistoryEntry history =
|
||||
checkNotNull(
|
||||
ofy()
|
||||
.load()
|
||||
.type(HistoryEntry.class)
|
||||
.ancestor(checkNotNull(application))
|
||||
.order("modificationTime")
|
||||
.first()
|
||||
.now(),
|
||||
"Could not find any history entries for domain application %s",
|
||||
application.getRepoId());
|
||||
String clientTransactionId =
|
||||
emptyToNull(history.getTrid().getClientTransactionId().orElse(null));
|
||||
Period period = checkNotNull(extractPeriodFromXml(history.getXmlBytes()));
|
||||
checkArgument(period.getUnit() == Period.Unit.YEARS);
|
||||
ImmutableMap.Builder<String, String> contactsMapBuilder = new ImmutableMap.Builder<>();
|
||||
for (DesignatedContact contact : application.getContacts()) {
|
||||
contactsMapBuilder.put(
|
||||
Ascii.toLowerCase(contact.getType().toString()),
|
||||
ofy().load().key(contact.getContactKey()).now().getForeignKey());
|
||||
}
|
||||
LaunchNotice launchNotice = application.getLaunchNotice();
|
||||
String smdId =
|
||||
application.getEncodedSignedMarks().isEmpty()
|
||||
? null
|
||||
: unmarshal(SignedMark.class, application.getEncodedSignedMarks().get(0).getBytes())
|
||||
.getId();
|
||||
ImmutableMap<String, String> launchNoticeMap =
|
||||
(launchNotice == null)
|
||||
? null
|
||||
: ImmutableMap.of(
|
||||
"noticeId", launchNotice.getNoticeId().getTcnId(),
|
||||
"expirationTime", launchNotice.getExpirationTime().toString(),
|
||||
"acceptedTime", launchNotice.getAcceptedTime().toString());
|
||||
ImmutableList<ImmutableMap<String, ?>> dsRecords =
|
||||
application
|
||||
.getDsData()
|
||||
.stream()
|
||||
.map(
|
||||
dsData ->
|
||||
ImmutableMap.of(
|
||||
"keyTag", dsData.getKeyTag(),
|
||||
"algorithm", dsData.getAlgorithm(),
|
||||
"digestType", dsData.getDigestType(),
|
||||
"digest", base16().encode(dsData.getDigest())))
|
||||
.collect(toImmutableList());
|
||||
addSoyRecord(
|
||||
application.getCurrentSponsorClientId(),
|
||||
new SoyMapData(
|
||||
"name", application.getFullyQualifiedDomainName(),
|
||||
"period", period.getValue(),
|
||||
"nameservers", application.loadNameserverFullyQualifiedHostNames(),
|
||||
"registrant", ofy().load().key(application.getRegistrant()).now().getForeignKey(),
|
||||
"contacts", contactsMapBuilder.build(),
|
||||
"authInfo", application.getAuthInfo().getPw().getValue(),
|
||||
"smdId", smdId,
|
||||
"applicationRoid", application.getRepoId(),
|
||||
"applicationTime", application.getCreationTime().toString(),
|
||||
"launchNotice", launchNoticeMap,
|
||||
"dsRecords", dsRecords,
|
||||
"clTrid", clientTransactionId));
|
||||
applicationKeys.add(Key.create(application));
|
||||
} catch (EppException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import static google.registry.model.ofy.ObjectifyService.ofy;
|
|||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.Parameters;
|
||||
import com.googlecode.objectify.VoidWork;
|
||||
import google.registry.model.domain.DomainResource;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.registry.Registry;
|
||||
|
@ -78,11 +77,7 @@ final class DeleteTldCommand extends ConfirmingCommand implements RemoteApiComma
|
|||
|
||||
@Override
|
||||
protected String execute() {
|
||||
ofy().transactNew(new VoidWork() {
|
||||
@Override
|
||||
public void vrun() {
|
||||
ofy().delete().entity(registry).now();
|
||||
}});
|
||||
ofy().transactNew(() -> ofy().delete().entity(registry).now());
|
||||
registry.invalidateInCache();
|
||||
return String.format("Deleted TLD '%s'.\n", tld);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ import com.google.common.collect.ImmutableList;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.VoidWork;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.tools.Command.RemoteApiCommand;
|
||||
import java.util.ArrayList;
|
||||
|
@ -142,39 +141,33 @@ public abstract class MutatingCommand extends ConfirmingCommand implements Remot
|
|||
@Override
|
||||
protected String execute() throws Exception {
|
||||
for (final List<EntityChange> batch : getCollatedEntityChangeBatches()) {
|
||||
ofy().transact(new VoidWork() {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}});
|
||||
ofy().transact(() -> batch.forEach(this::executeChange));
|
||||
}
|
||||
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
|
||||
* order inside a single transaction.
|
||||
|
|
|
@ -25,7 +25,6 @@ import com.google.appengine.api.datastore.KeyFactory;
|
|||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.googlecode.objectify.VoidWork;
|
||||
import com.googlecode.objectify.impl.EntityMetadata;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.HttpException.BadRequestException;
|
||||
|
@ -90,11 +89,7 @@ public class DeleteEntityAction implements Runnable {
|
|||
getDatastoreService().delete(rawDeletions);
|
||||
// Delete ofy entities.
|
||||
final ImmutableList<Object> ofyDeletions = ofyDeletionsBuilder.build();
|
||||
ofy().transactNew(new VoidWork() {
|
||||
@Override
|
||||
public void vrun() {
|
||||
ofy().delete().entities(ofyDeletions).now();
|
||||
}});
|
||||
ofy().transactNew(() -> ofy().delete().entities(ofyDeletions).now());
|
||||
String message = String.format(
|
||||
"Deleted %d raw entities and %d registered entities",
|
||||
rawDeletions.size(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue