mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 07:57:13 +02:00
Refactor Guava functional methods to use lambdas
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=177027488
This commit is contained in:
parent
2ae496bfce
commit
bbe2584da4
47 changed files with 478 additions and 647 deletions
|
@ -23,7 +23,6 @@ import static google.registry.util.DateTimeUtils.earliestOf;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import google.registry.model.ofy.CommitLogBucket;
|
import google.registry.model.ofy.CommitLogBucket;
|
||||||
import google.registry.model.ofy.CommitLogCheckpoint;
|
import google.registry.model.ofy.CommitLogCheckpoint;
|
||||||
import google.registry.model.ofy.CommitLogManifest;
|
import google.registry.model.ofy.CommitLogManifest;
|
||||||
|
@ -116,15 +115,14 @@ class CommitLogCheckpointStrategy {
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
ImmutableMap<Integer, DateTime> readBucketTimestamps() {
|
ImmutableMap<Integer, DateTime> readBucketTimestamps() {
|
||||||
// Use a fresh session cache so that we get the latest data from Datastore.
|
// Use a fresh session cache so that we get the latest data from Datastore.
|
||||||
return ofy.doWithFreshSessionCache(new Work<ImmutableMap<Integer, DateTime>>() {
|
return ofy.doWithFreshSessionCache(
|
||||||
@Override
|
() -> {
|
||||||
public ImmutableMap<Integer, DateTime> run() {
|
ImmutableMap.Builder<Integer, DateTime> results = new ImmutableMap.Builder<>();
|
||||||
ImmutableMap.Builder<Integer, DateTime> results = new ImmutableMap.Builder<>();
|
for (CommitLogBucket bucket : CommitLogBucket.loadAllBuckets()) {
|
||||||
for (CommitLogBucket bucket : CommitLogBucket.loadAllBuckets()) {
|
results.put(bucket.getBucketNum(), bucket.getLastWrittenTime());
|
||||||
results.put(bucket.getBucketNum(), bucket.getLastWrittenTime());
|
}
|
||||||
}
|
return results.build();
|
||||||
return results.build();
|
});
|
||||||
}});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -30,7 +30,6 @@ import com.google.auto.value.AutoValue;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMultiset;
|
import com.google.common.collect.ImmutableMultiset;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import google.registry.config.RegistryConfig.Config;
|
import google.registry.config.RegistryConfig.Config;
|
||||||
import google.registry.mapreduce.MapreduceRunner;
|
import google.registry.mapreduce.MapreduceRunner;
|
||||||
import google.registry.mapreduce.inputs.CommitLogManifestInput;
|
import google.registry.mapreduce.inputs.CommitLogManifestInput;
|
||||||
|
@ -282,39 +281,36 @@ public final class DeleteOldCommitLogsAction implements Runnable {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeletionResult deletionResult = ofy().transactNew(new Work<DeletionResult>() {
|
DeletionResult deletionResult = ofy().transactNew(() -> {
|
||||||
@Override
|
CommitLogManifest manifest = ofy().load().key(manifestKey).now();
|
||||||
public DeletionResult run() {
|
// It is possible that the same manifestKey was run twice, if a shard had to be restarted
|
||||||
CommitLogManifest manifest = ofy().load().key(manifestKey).now();
|
// or some weird failure. If this happens, we want to exit immediately.
|
||||||
// It is possible that the same manifestKey was run twice, if a shard had to be restarted
|
// Note that this can never happen in dryRun.
|
||||||
// or some weird failure. If this happens, we want to exit immediately.
|
if (manifest == null) {
|
||||||
// Note that this can never happen in dryRun.
|
return DeletionResult.create(DeletionResult.Status.ALREADY_DELETED, 0);
|
||||||
if (manifest == null) {
|
|
||||||
return DeletionResult.create(DeletionResult.Status.ALREADY_DELETED, 0);
|
|
||||||
}
|
|
||||||
// Doing a sanity check on the date. This is the only place we use the CommitLogManifest,
|
|
||||||
// so maybe removing this test will improve performance. However, unless it's proven that
|
|
||||||
// the performance boost is significant (and we've tested this enough to be sure it never
|
|
||||||
// happens)- the safty of "let's not delete stuff we need from prod" is more important.
|
|
||||||
if (manifest.getCommitTime().isAfter(deletionThreshold)) {
|
|
||||||
return DeletionResult.create(DeletionResult.Status.AFTER_THRESHOLD, 0);
|
|
||||||
}
|
|
||||||
Iterable<Key<CommitLogMutation>> commitLogMutationKeys = ofy().load()
|
|
||||||
.type(CommitLogMutation.class)
|
|
||||||
.ancestor(manifestKey)
|
|
||||||
.keys()
|
|
||||||
.iterable();
|
|
||||||
ImmutableList<Key<?>> keysToDelete = ImmutableList.<Key<?>>builder()
|
|
||||||
.addAll(commitLogMutationKeys)
|
|
||||||
.add(manifestKey)
|
|
||||||
.build();
|
|
||||||
// Normally in a dry run we would log the entities that would be deleted, but those can
|
|
||||||
// number in the millions so we skip the logging.
|
|
||||||
if (!isDryRun) {
|
|
||||||
ofy().deleteWithoutBackup().keys(keysToDelete);
|
|
||||||
}
|
|
||||||
return DeletionResult.create(DeletionResult.Status.SUCCESS, keysToDelete.size());
|
|
||||||
}
|
}
|
||||||
|
// Doing a sanity check on the date. This is the only place we use the CommitLogManifest,
|
||||||
|
// so maybe removing this test will improve performance. However, unless it's proven that
|
||||||
|
// the performance boost is significant (and we've tested this enough to be sure it never
|
||||||
|
// happens)- the safty of "let's not delete stuff we need from prod" is more important.
|
||||||
|
if (manifest.getCommitTime().isAfter(deletionThreshold)) {
|
||||||
|
return DeletionResult.create(DeletionResult.Status.AFTER_THRESHOLD, 0);
|
||||||
|
}
|
||||||
|
Iterable<Key<CommitLogMutation>> commitLogMutationKeys = ofy().load()
|
||||||
|
.type(CommitLogMutation.class)
|
||||||
|
.ancestor(manifestKey)
|
||||||
|
.keys()
|
||||||
|
.iterable();
|
||||||
|
ImmutableList<Key<?>> keysToDelete = ImmutableList.<Key<?>>builder()
|
||||||
|
.addAll(commitLogMutationKeys)
|
||||||
|
.add(manifestKey)
|
||||||
|
.build();
|
||||||
|
// Normally in a dry run we would log the entities that would be deleted, but those can
|
||||||
|
// number in the millions so we skip the logging.
|
||||||
|
if (!isDryRun) {
|
||||||
|
ofy().deleteWithoutBackup().keys(keysToDelete);
|
||||||
|
}
|
||||||
|
return DeletionResult.create(DeletionResult.Status.SUCCESS, keysToDelete.size());
|
||||||
});
|
});
|
||||||
|
|
||||||
switch (deletionResult.status()) {
|
switch (deletionResult.status()) {
|
||||||
|
|
|
@ -38,7 +38,6 @@ import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Range;
|
import com.google.common.collect.Range;
|
||||||
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.Work;
|
|
||||||
import google.registry.mapreduce.MapreduceRunner;
|
import google.registry.mapreduce.MapreduceRunner;
|
||||||
import google.registry.mapreduce.inputs.NullInput;
|
import google.registry.mapreduce.inputs.NullInput;
|
||||||
import google.registry.model.EppResource;
|
import google.registry.model.EppResource;
|
||||||
|
@ -151,89 +150,86 @@ public class ExpandRecurringBillingEventsAction implements Runnable {
|
||||||
getContext().incrementCounter("Recurring billing events ignored");
|
getContext().incrementCounter("Recurring billing events ignored");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int billingEventsSaved = 0;
|
int numBillingEventsSaved = 0;
|
||||||
try {
|
try {
|
||||||
billingEventsSaved = ofy().transactNew(new Work<Integer>() {
|
numBillingEventsSaved = ofy().transactNew(() -> {
|
||||||
@Override
|
ImmutableSet.Builder<OneTime> syntheticOneTimesBuilder =
|
||||||
public Integer run() {
|
new ImmutableSet.Builder<>();
|
||||||
ImmutableSet.Builder<OneTime> syntheticOneTimesBuilder =
|
final Registry tld = Registry.get(getTldFromDomainName(recurring.getTargetId()));
|
||||||
new ImmutableSet.Builder<>();
|
|
||||||
final Registry tld = Registry.get(getTldFromDomainName(recurring.getTargetId()));
|
|
||||||
|
|
||||||
// Determine the complete set of times at which this recurring event should occur
|
// Determine the complete set of times at which this recurring event should occur
|
||||||
// (up to and including the runtime of the mapreduce).
|
// (up to and including the runtime of the mapreduce).
|
||||||
Iterable<DateTime> eventTimes =
|
Iterable<DateTime> eventTimes =
|
||||||
recurring.getRecurrenceTimeOfYear().getInstancesInRange(Range.closed(
|
recurring.getRecurrenceTimeOfYear().getInstancesInRange(Range.closed(
|
||||||
recurring.getEventTime(),
|
recurring.getEventTime(),
|
||||||
earliestOf(recurring.getRecurrenceEndTime(), executeTime)));
|
earliestOf(recurring.getRecurrenceEndTime(), executeTime)));
|
||||||
|
|
||||||
// Convert these event times to billing times
|
// Convert these event times to billing times
|
||||||
final ImmutableSet<DateTime> billingTimes =
|
final ImmutableSet<DateTime> billingTimes =
|
||||||
getBillingTimesInScope(eventTimes, cursorTime, executeTime, tld);
|
getBillingTimesInScope(eventTimes, cursorTime, executeTime, tld);
|
||||||
|
|
||||||
Key<? extends EppResource> domainKey = recurring.getParentKey().getParent();
|
Key<? extends EppResource> domainKey = recurring.getParentKey().getParent();
|
||||||
Iterable<OneTime> oneTimesForDomain =
|
Iterable<OneTime> oneTimesForDomain =
|
||||||
ofy().load().type(OneTime.class).ancestor(domainKey);
|
ofy().load().type(OneTime.class).ancestor(domainKey);
|
||||||
|
|
||||||
// Determine the billing times that already have OneTime events persisted.
|
// Determine the billing times that already have OneTime events persisted.
|
||||||
ImmutableSet<DateTime> existingBillingTimes =
|
ImmutableSet<DateTime> existingBillingTimes =
|
||||||
getExistingBillingTimes(oneTimesForDomain, recurring);
|
getExistingBillingTimes(oneTimesForDomain, recurring);
|
||||||
|
|
||||||
ImmutableSet.Builder<HistoryEntry> historyEntriesBuilder =
|
ImmutableSet.Builder<HistoryEntry> historyEntriesBuilder =
|
||||||
new ImmutableSet.Builder<>();
|
new ImmutableSet.Builder<>();
|
||||||
// Create synthetic OneTime events for all billing times that do not yet have an event
|
// Create synthetic OneTime events for all billing times that do not yet have an event
|
||||||
// persisted.
|
// persisted.
|
||||||
for (DateTime billingTime : difference(billingTimes, existingBillingTimes)) {
|
for (DateTime billingTime : difference(billingTimes, existingBillingTimes)) {
|
||||||
// Construct a new HistoryEntry that parents over the OneTime
|
// Construct a new HistoryEntry that parents over the OneTime
|
||||||
HistoryEntry historyEntry = new HistoryEntry.Builder()
|
HistoryEntry historyEntry = new HistoryEntry.Builder()
|
||||||
.setBySuperuser(false)
|
.setBySuperuser(false)
|
||||||
.setClientId(recurring.getClientId())
|
.setClientId(recurring.getClientId())
|
||||||
.setModificationTime(ofy().getTransactionTime())
|
.setModificationTime(ofy().getTransactionTime())
|
||||||
.setParent(domainKey)
|
.setParent(domainKey)
|
||||||
.setPeriod(Period.create(1, YEARS))
|
.setPeriod(Period.create(1, YEARS))
|
||||||
.setReason("Domain autorenewal by ExpandRecurringBillingEventsAction")
|
.setReason("Domain autorenewal by ExpandRecurringBillingEventsAction")
|
||||||
.setRequestedByRegistrar(false)
|
.setRequestedByRegistrar(false)
|
||||||
.setType(DOMAIN_AUTORENEW)
|
.setType(DOMAIN_AUTORENEW)
|
||||||
.setDomainTransactionRecords(
|
.setDomainTransactionRecords(
|
||||||
ImmutableSet.of(
|
ImmutableSet.of(
|
||||||
DomainTransactionRecord.create(
|
DomainTransactionRecord.create(
|
||||||
tld.getTldStr(),
|
tld.getTldStr(),
|
||||||
// We report this when the autorenew grace period ends
|
// We report this when the autorenew grace period ends
|
||||||
billingTime,
|
billingTime,
|
||||||
TransactionReportField.netRenewsFieldFromYears(1),
|
TransactionReportField.netRenewsFieldFromYears(1),
|
||||||
1)))
|
1)))
|
||||||
.build();
|
.build();
|
||||||
historyEntriesBuilder.add(historyEntry);
|
historyEntriesBuilder.add(historyEntry);
|
||||||
|
|
||||||
DateTime eventTime = billingTime.minus(tld.getAutoRenewGracePeriodLength());
|
DateTime eventTime = billingTime.minus(tld.getAutoRenewGracePeriodLength());
|
||||||
// Determine the cost for a one-year renewal.
|
// Determine the cost for a one-year renewal.
|
||||||
Money renewCost = getDomainRenewCost(recurring.getTargetId(), eventTime, 1);
|
Money renewCost = getDomainRenewCost(recurring.getTargetId(), eventTime, 1);
|
||||||
syntheticOneTimesBuilder.add(new BillingEvent.OneTime.Builder()
|
syntheticOneTimesBuilder.add(new OneTime.Builder()
|
||||||
.setBillingTime(billingTime)
|
.setBillingTime(billingTime)
|
||||||
.setClientId(recurring.getClientId())
|
.setClientId(recurring.getClientId())
|
||||||
.setCost(renewCost)
|
.setCost(renewCost)
|
||||||
.setEventTime(eventTime)
|
.setEventTime(eventTime)
|
||||||
.setFlags(union(recurring.getFlags(), Flag.SYNTHETIC))
|
.setFlags(union(recurring.getFlags(), Flag.SYNTHETIC))
|
||||||
.setParent(historyEntry)
|
.setParent(historyEntry)
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
.setReason(recurring.getReason())
|
.setReason(recurring.getReason())
|
||||||
.setSyntheticCreationTime(executeTime)
|
.setSyntheticCreationTime(executeTime)
|
||||||
.setCancellationMatchingBillingEvent(Key.create(recurring))
|
.setCancellationMatchingBillingEvent(Key.create(recurring))
|
||||||
.setTargetId(recurring.getTargetId())
|
.setTargetId(recurring.getTargetId())
|
||||||
.build());
|
.build());
|
||||||
}
|
|
||||||
Set<HistoryEntry> historyEntries = historyEntriesBuilder.build();
|
|
||||||
Set<OneTime> syntheticOneTimes = syntheticOneTimesBuilder.build();
|
|
||||||
if (!isDryRun) {
|
|
||||||
ImmutableSet<ImmutableObject> entitiesToSave =
|
|
||||||
new ImmutableSet.Builder<ImmutableObject>()
|
|
||||||
.addAll(historyEntries)
|
|
||||||
.addAll(syntheticOneTimes)
|
|
||||||
.build();
|
|
||||||
ofy().save().entities(entitiesToSave).now();
|
|
||||||
}
|
|
||||||
return syntheticOneTimes.size();
|
|
||||||
}
|
}
|
||||||
|
Set<HistoryEntry> historyEntries = historyEntriesBuilder.build();
|
||||||
|
Set<OneTime> syntheticOneTimes = syntheticOneTimesBuilder.build();
|
||||||
|
if (!isDryRun) {
|
||||||
|
ImmutableSet<ImmutableObject> entitiesToSave =
|
||||||
|
new ImmutableSet.Builder<ImmutableObject>()
|
||||||
|
.addAll(historyEntries)
|
||||||
|
.addAll(syntheticOneTimes)
|
||||||
|
.build();
|
||||||
|
ofy().save().entities(entitiesToSave).now();
|
||||||
|
}
|
||||||
|
return syntheticOneTimes.size();
|
||||||
});
|
});
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
logger.severefmt(
|
logger.severefmt(
|
||||||
|
@ -243,10 +239,10 @@ public class ExpandRecurringBillingEventsAction implements Runnable {
|
||||||
throw t;
|
throw t;
|
||||||
}
|
}
|
||||||
if (!isDryRun) {
|
if (!isDryRun) {
|
||||||
getContext().incrementCounter("Saved OneTime billing events", billingEventsSaved);
|
getContext().incrementCounter("Saved OneTime billing events", numBillingEventsSaved);
|
||||||
} else {
|
} else {
|
||||||
getContext().incrementCounter(
|
getContext().incrementCounter(
|
||||||
"Generated OneTime billing events (dry run)", billingEventsSaved);
|
"Generated OneTime billing events (dry run)", numBillingEventsSaved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ import com.google.appengine.tools.mapreduce.Reducer;
|
||||||
import com.google.appengine.tools.mapreduce.ReducerInput;
|
import com.google.appengine.tools.mapreduce.ReducerInput;
|
||||||
import com.google.appengine.tools.mapreduce.inputs.DatastoreKeyInput;
|
import com.google.appengine.tools.mapreduce.inputs.DatastoreKeyInput;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
|
@ -141,9 +140,10 @@ public class VerifyEntityIntegrityAction implements Runnable {
|
||||||
ImmutableSet.Builder<Input<? extends Object>> builder =
|
ImmutableSet.Builder<Input<? extends Object>> builder =
|
||||||
new ImmutableSet.Builder<Input<? extends Object>>()
|
new ImmutableSet.Builder<Input<? extends Object>>()
|
||||||
.add(EppResourceInputs.createIndexInput());
|
.add(EppResourceInputs.createIndexInput());
|
||||||
for (Class<?> clazz : RESOURCE_CLASSES) {
|
RESOURCE_CLASSES
|
||||||
builder.add(new DatastoreKeyInput(getKind(clazz), NUM_SHARDS));
|
.stream()
|
||||||
}
|
.map(clazz -> new DatastoreKeyInput(getKind(clazz), NUM_SHARDS))
|
||||||
|
.forEach(builder::add);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,17 +265,7 @@ public class VerifyEntityIntegrityAction implements Runnable {
|
||||||
.getTransferData()
|
.getTransferData()
|
||||||
.getServerApproveEntities()
|
.getServerApproveEntities()
|
||||||
.stream()
|
.stream()
|
||||||
.map(
|
.map(VerifyEntityIntegrityMapper::castTransferServerApproveEntityKey)
|
||||||
new Function<
|
|
||||||
Key<? extends TransferServerApproveEntity>,
|
|
||||||
Key<TransferServerApproveEntity>>() {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public Key<TransferServerApproveEntity> apply(
|
|
||||||
Key<? extends TransferServerApproveEntity> key) {
|
|
||||||
return (Key<TransferServerApproveEntity>) key;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(toImmutableSet()));
|
.collect(toImmutableSet()));
|
||||||
verifyExistence(key, domain.getApplication());
|
verifyExistence(key, domain.getApplication());
|
||||||
verifyExistence(key, domain.getAutorenewBillingEvent());
|
verifyExistence(key, domain.getAutorenewBillingEvent());
|
||||||
|
@ -306,6 +296,12 @@ public class VerifyEntityIntegrityAction implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static Key<TransferServerApproveEntity> castTransferServerApproveEntityKey(
|
||||||
|
Key<? extends TransferServerApproveEntity> key) {
|
||||||
|
return (Key<TransferServerApproveEntity>) key;
|
||||||
|
}
|
||||||
|
|
||||||
private void mapForeignKeyIndex(ForeignKeyIndex<?> fki) {
|
private void mapForeignKeyIndex(ForeignKeyIndex<?> fki) {
|
||||||
Key<ForeignKeyIndex<?>> fkiKey = Key.create(fki);
|
Key<ForeignKeyIndex<?>> fkiKey = Key.create(fki);
|
||||||
@SuppressWarnings("cast")
|
@SuppressWarnings("cast")
|
||||||
|
|
|
@ -55,7 +55,6 @@ import com.google.common.base.Function;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableTable;
|
import com.google.common.collect.ImmutableTable;
|
||||||
import com.google.common.io.BaseEncoding;
|
import com.google.common.io.BaseEncoding;
|
||||||
import com.google.common.util.concurrent.AsyncFunction;
|
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
|
@ -454,15 +453,7 @@ public class BigqueryConnection implements AutoCloseable {
|
||||||
.setQuery(new JobConfigurationQuery()
|
.setQuery(new JobConfigurationQuery()
|
||||||
.setQuery(querySql)
|
.setQuery(querySql)
|
||||||
.setDefaultDataset(getDataset())));
|
.setDefaultDataset(getDataset())));
|
||||||
return transform(
|
return transform(runJobToCompletion(job), this::getQueryResults, directExecutor());
|
||||||
runJobToCompletion(job),
|
|
||||||
new Function<Job, ImmutableTable<Integer, TableFieldSchema, Object>>() {
|
|
||||||
@Override
|
|
||||||
public ImmutableTable<Integer, TableFieldSchema, Object> apply(Job job) {
|
|
||||||
return getQueryResults(job);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
directExecutor());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -593,12 +584,7 @@ public class BigqueryConnection implements AutoCloseable {
|
||||||
DestinationTable tempTable = buildTemporaryTable().build();
|
DestinationTable tempTable = buildTemporaryTable().build();
|
||||||
return transformAsync(
|
return transformAsync(
|
||||||
query(querySql, tempTable),
|
query(querySql, tempTable),
|
||||||
new AsyncFunction<DestinationTable, String>() {
|
tempTable1 -> extractTable(tempTable1, destinationUri, destinationFormat, printHeader),
|
||||||
@Override
|
|
||||||
public ListenableFuture<String> apply(DestinationTable tempTable) {
|
|
||||||
return extractTable(tempTable, destinationUri, destinationFormat, printHeader);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
directExecutor());
|
directExecutor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
package google.registry.export;
|
package google.registry.export;
|
||||||
|
|
||||||
import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;
|
import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;
|
||||||
import static google.registry.model.EntityClasses.CLASS_TO_KIND_FUNCTION;
|
|
||||||
import static google.registry.util.TypeUtils.hasAnnotation;
|
import static google.registry.util.TypeUtils.hasAnnotation;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Ordering;
|
import com.google.common.collect.Ordering;
|
||||||
|
import com.googlecode.objectify.Key;
|
||||||
import google.registry.model.EntityClasses;
|
import google.registry.model.EntityClasses;
|
||||||
import google.registry.model.annotations.NotBackedUp;
|
import google.registry.model.annotations.NotBackedUp;
|
||||||
import google.registry.model.annotations.ReportedOn;
|
import google.registry.model.annotations.ReportedOn;
|
||||||
|
@ -36,7 +36,7 @@ public final class ExportConstants {
|
||||||
.stream()
|
.stream()
|
||||||
.filter(hasAnnotation(VirtualEntity.class).negate())
|
.filter(hasAnnotation(VirtualEntity.class).negate())
|
||||||
.filter(hasAnnotation(NotBackedUp.class).negate())
|
.filter(hasAnnotation(NotBackedUp.class).negate())
|
||||||
.map(CLASS_TO_KIND_FUNCTION)
|
.map(Key::getKind)
|
||||||
.collect(toImmutableSortedSet(Ordering.natural()));
|
.collect(toImmutableSortedSet(Ordering.natural()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ public final class ExportConstants {
|
||||||
.stream()
|
.stream()
|
||||||
.filter(hasAnnotation(ReportedOn.class))
|
.filter(hasAnnotation(ReportedOn.class))
|
||||||
.filter(hasAnnotation(VirtualEntity.class).negate())
|
.filter(hasAnnotation(VirtualEntity.class).negate())
|
||||||
.map(CLASS_TO_KIND_FUNCTION)
|
.map(Key::getKind)
|
||||||
.collect(toImmutableSortedSet(Ordering.natural()));
|
.collect(toImmutableSortedSet(Ordering.natural()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import google.registry.flows.EppException.AuthorizationErrorException;
|
import google.registry.flows.EppException.AuthorizationErrorException;
|
||||||
import google.registry.flows.EppException.InvalidAuthorizationInformationErrorException;
|
import google.registry.flows.EppException.InvalidAuthorizationInformationErrorException;
|
||||||
import google.registry.flows.EppException.ObjectDoesNotExistException;
|
import google.registry.flows.EppException.ObjectDoesNotExistException;
|
||||||
|
@ -179,31 +178,28 @@ public final class ResourceFlowUtils {
|
||||||
EppException failfastException =
|
EppException failfastException =
|
||||||
ofy()
|
ofy()
|
||||||
.doTransactionless(
|
.doTransactionless(
|
||||||
new Work<EppException>() {
|
() -> {
|
||||||
@Override
|
final ForeignKeyIndex<R> fki =
|
||||||
public EppException run() {
|
ForeignKeyIndex.load(resourceClass, targetId, now);
|
||||||
final ForeignKeyIndex<R> fki =
|
if (fki == null) {
|
||||||
ForeignKeyIndex.load(resourceClass, targetId, now);
|
return new ResourceDoesNotExistException(resourceClass, targetId);
|
||||||
if (fki == null) {
|
|
||||||
return new ResourceDoesNotExistException(resourceClass, targetId);
|
|
||||||
}
|
|
||||||
/* Query for the first few linked domains, and if found, actually load them. The
|
|
||||||
* query is eventually consistent and so might be very stale, but the direct
|
|
||||||
* load will not be stale, just non-transactional. If we find at least one
|
|
||||||
* actual reference then we can reliably fail. If we don't find any, we can't
|
|
||||||
* trust the query and need to do the full mapreduce.
|
|
||||||
*/
|
|
||||||
Iterable<Key<DomainBase>> keys =
|
|
||||||
queryForLinkedDomains(fki.getResourceKey(), now)
|
|
||||||
.limit(FAILFAST_CHECK_COUNT)
|
|
||||||
.keys();
|
|
||||||
Predicate<DomainBase> predicate =
|
|
||||||
domain ->
|
|
||||||
getPotentialReferences.apply(domain).contains(fki.getResourceKey());
|
|
||||||
return ofy().load().keys(keys).values().stream().anyMatch(predicate)
|
|
||||||
? new ResourceToDeleteIsReferencedException()
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
/* Query for the first few linked domains, and if found, actually load them. The
|
||||||
|
* query is eventually consistent and so might be very stale, but the direct
|
||||||
|
* load will not be stale, just non-transactional. If we find at least one
|
||||||
|
* actual reference then we can reliably fail. If we don't find any, we can't
|
||||||
|
* trust the query and need to do the full mapreduce.
|
||||||
|
*/
|
||||||
|
Iterable<Key<DomainBase>> keys =
|
||||||
|
queryForLinkedDomains(fki.getResourceKey(), now)
|
||||||
|
.limit(FAILFAST_CHECK_COUNT)
|
||||||
|
.keys();
|
||||||
|
Predicate<DomainBase> predicate =
|
||||||
|
domain ->
|
||||||
|
getPotentialReferences.apply(domain).contains(fki.getResourceKey());
|
||||||
|
return ofy().load().keys(keys).values().stream().anyMatch(predicate)
|
||||||
|
? new ResourceToDeleteIsReferencedException()
|
||||||
|
: null;
|
||||||
});
|
});
|
||||||
if (failfastException != null) {
|
if (failfastException != null) {
|
||||||
throw failfastException;
|
throw failfastException;
|
||||||
|
|
|
@ -23,7 +23,6 @@ import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||||
|
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import google.registry.flows.EppException;
|
import google.registry.flows.EppException;
|
||||||
import google.registry.flows.EppException.AuthorizationErrorException;
|
import google.registry.flows.EppException.AuthorizationErrorException;
|
||||||
import google.registry.flows.EppException.ObjectDoesNotExistException;
|
import google.registry.flows.EppException.ObjectDoesNotExistException;
|
||||||
|
@ -131,11 +130,7 @@ public class PollAckFlow implements TransactionalFlow {
|
||||||
// acked, then we return a special status code indicating that. Note that the query will
|
// acked, then we return a special status code indicating that. Note that the query will
|
||||||
// include the message being acked.
|
// include the message being acked.
|
||||||
|
|
||||||
int messageCount = ofy().doTransactionless(new Work<Integer>() {
|
int messageCount = ofy().doTransactionless(() -> getPollMessagesQuery(clientId, now).count());
|
||||||
@Override
|
|
||||||
public Integer run() {
|
|
||||||
return getPollMessagesQuery(clientId, now).count();
|
|
||||||
}});
|
|
||||||
if (!includeAckedMessageInCount) {
|
if (!includeAckedMessageInCount) {
|
||||||
messageCount--;
|
messageCount--;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
package google.registry.mapreduce.inputs;
|
package google.registry.mapreduce.inputs;
|
||||||
|
|
||||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||||
import static google.registry.model.EntityClasses.CLASS_TO_KIND_FUNCTION;
|
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
|
|
||||||
import com.google.appengine.api.datastore.Cursor;
|
import com.google.appengine.api.datastore.Cursor;
|
||||||
|
@ -138,6 +137,6 @@ abstract class EppResourceBaseReader<T> extends InputReader<T> {
|
||||||
// Ignore EppResource when finding kinds, since it doesn't have one and doesn't imply filtering.
|
// Ignore EppResource when finding kinds, since it doesn't have one and doesn't imply filtering.
|
||||||
return resourceClasses.contains(EppResource.class)
|
return resourceClasses.contains(EppResource.class)
|
||||||
? ImmutableSet.of()
|
? ImmutableSet.of()
|
||||||
: resourceClasses.stream().map(CLASS_TO_KIND_FUNCTION).collect(toImmutableSet());
|
: resourceClasses.stream().map(Key::getKind).collect(toImmutableSet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,7 @@
|
||||||
|
|
||||||
package google.registry.model;
|
package google.registry.model;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import google.registry.model.billing.BillingEvent;
|
import google.registry.model.billing.BillingEvent;
|
||||||
import google.registry.model.billing.RegistrarBillingEntry;
|
import google.registry.model.billing.RegistrarBillingEntry;
|
||||||
import google.registry.model.billing.RegistrarCredit;
|
import google.registry.model.billing.RegistrarCredit;
|
||||||
|
@ -113,15 +111,5 @@ public final class EntityClasses {
|
||||||
SignedMarkRevocationList.class,
|
SignedMarkRevocationList.class,
|
||||||
TmchCrl.class);
|
TmchCrl.class);
|
||||||
|
|
||||||
/**
|
|
||||||
* Function that converts an Objectify-registered class to its Datastore kind name.
|
|
||||||
*
|
|
||||||
* <p>Note that this mapping is not one-to-one, since polymorphic subclasses of an entity all have
|
|
||||||
* the same Datastore kind. (In theory, two distinct top-level entities could also map to the same
|
|
||||||
* kind since it's just {@code class.getSimpleName()}, but we test against that.)
|
|
||||||
*/
|
|
||||||
public static final Function<Class<? extends ImmutableObject>, String> CLASS_TO_KIND_FUNCTION =
|
|
||||||
(Class<? extends ImmutableObject> clazz) -> Key.getKind(clazz);
|
|
||||||
|
|
||||||
private EntityClasses() {}
|
private EntityClasses() {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
package google.registry.model;
|
package google.registry.model;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.collect.Iterables.transform;
|
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
import static google.registry.util.DateTimeUtils.isAtOrAfter;
|
import static google.registry.util.DateTimeUtils.isAtOrAfter;
|
||||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||||
|
@ -160,11 +160,15 @@ public final class EppResourceUtils {
|
||||||
*/
|
*/
|
||||||
public static <T extends EppResource> Iterable<T> queryNotDeleted(
|
public static <T extends EppResource> Iterable<T> queryNotDeleted(
|
||||||
Class<T> clazz, DateTime now, String filterDefinition, Object filterValue) {
|
Class<T> clazz, DateTime now, String filterDefinition, Object filterValue) {
|
||||||
return transform(
|
return ofy()
|
||||||
ofy().load().type(clazz)
|
.load()
|
||||||
.filter(filterDefinition, filterValue)
|
.type(clazz)
|
||||||
.filter("deletionTime >", now.toDate()),
|
.filter(filterDefinition, filterValue)
|
||||||
EppResourceUtils.transformAtTime(now));
|
.filter("deletionTime >", now.toDate())
|
||||||
|
.list()
|
||||||
|
.stream()
|
||||||
|
.map(EppResourceUtils.transformAtTime(now))
|
||||||
|
.collect(toImmutableSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -262,15 +266,13 @@ public final class EppResourceUtils {
|
||||||
(isAtOrAfter(timestamp, resource.getUpdateAutoTimestamp().getTimestamp()))
|
(isAtOrAfter(timestamp, resource.getUpdateAutoTimestamp().getTimestamp()))
|
||||||
? new ResultNow<>(resource)
|
? new ResultNow<>(resource)
|
||||||
: loadMostRecentRevisionAtTime(resource, timestamp);
|
: loadMostRecentRevisionAtTime(resource, timestamp);
|
||||||
return new Result<T>() {
|
return () -> {
|
||||||
@Override
|
T loadedResource = loadResult.now();
|
||||||
public T now() {
|
return (loadedResource == null) ? null
|
||||||
T loadedResource = loadResult.now();
|
: (isActive(loadedResource, timestamp)
|
||||||
return loadedResource == null ? null
|
? cloneProjectedAtTime(loadedResource, timestamp)
|
||||||
: (isActive(loadedResource, timestamp)
|
: null);
|
||||||
? cloneProjectedAtTime(loadedResource, timestamp)
|
};
|
||||||
: null);
|
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -290,19 +292,16 @@ public final class EppResourceUtils {
|
||||||
}
|
}
|
||||||
final Result<CommitLogMutation> mutationResult =
|
final Result<CommitLogMutation> mutationResult =
|
||||||
ofy().load().key(CommitLogMutation.createKey(revision, resourceKey));
|
ofy().load().key(CommitLogMutation.createKey(revision, resourceKey));
|
||||||
return new Result<T>() {
|
return () -> {
|
||||||
@Override
|
CommitLogMutation mutation = mutationResult.now();
|
||||||
public T now() {
|
if (mutation != null) {
|
||||||
CommitLogMutation mutation = mutationResult.now();
|
return ofy().load().fromEntity(mutation.getEntity());
|
||||||
if (mutation != null) {
|
|
||||||
return ofy().load().fromEntity(mutation.getEntity());
|
|
||||||
}
|
|
||||||
logger.severefmt(
|
|
||||||
"Couldn't load mutation for revision at %s for %s, falling back to resource."
|
|
||||||
+ " Revision: %s",
|
|
||||||
timestamp, resourceKey, revision);
|
|
||||||
return resource;
|
|
||||||
}
|
}
|
||||||
|
logger.severefmt(
|
||||||
|
"Couldn't load mutation for revision at %s for %s, falling back to resource."
|
||||||
|
+ " Revision: %s",
|
||||||
|
timestamp, resourceKey, revision);
|
||||||
|
return resource;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ import com.google.common.base.MoreObjects;
|
||||||
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.Work;
|
|
||||||
import google.registry.model.EppResource;
|
import google.registry.model.EppResource;
|
||||||
import google.registry.model.ImmutableObject;
|
import google.registry.model.ImmutableObject;
|
||||||
import google.registry.model.contact.ContactResource;
|
import google.registry.model.contact.ContactResource;
|
||||||
|
@ -447,12 +446,8 @@ public class DomainCommand {
|
||||||
private static <T extends EppResource> ImmutableMap<String, Key<T>> loadByForeignKey(
|
private static <T extends EppResource> ImmutableMap<String, Key<T>> loadByForeignKey(
|
||||||
final Set<String> foreignKeys, final Class<T> clazz, final DateTime now)
|
final Set<String> foreignKeys, final Class<T> clazz, final DateTime now)
|
||||||
throws InvalidReferencesException {
|
throws InvalidReferencesException {
|
||||||
Map<String, ForeignKeyIndex<T>> fkis = ofy().doTransactionless(
|
Map<String, ForeignKeyIndex<T>> fkis =
|
||||||
new Work<Map<String, ForeignKeyIndex<T>>>() {
|
ofy().doTransactionless(() -> ForeignKeyIndex.load(clazz, foreignKeys, now));
|
||||||
@Override
|
|
||||||
public Map<String, ForeignKeyIndex<T>> run() {
|
|
||||||
return ForeignKeyIndex.load(clazz, foreignKeys, now);
|
|
||||||
}});
|
|
||||||
if (!fkis.keySet().equals(foreignKeys)) {
|
if (!fkis.keySet().equals(foreignKeys)) {
|
||||||
throw new InvalidReferencesException(
|
throw new InvalidReferencesException(
|
||||||
clazz, ImmutableSet.copyOf(difference(foreignKeys, fkis.keySet())));
|
clazz, ImmutableSet.copyOf(difference(foreignKeys, fkis.keySet())));
|
||||||
|
|
|
@ -21,7 +21,6 @@ import static google.registry.util.CollectionUtils.isNullOrEmpty;
|
||||||
|
|
||||||
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.Work;
|
|
||||||
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.BackupGroupRoot;
|
import google.registry.model.BackupGroupRoot;
|
||||||
|
@ -100,17 +99,15 @@ public class DomainApplicationIndex extends BackupGroupRoot {
|
||||||
return ImmutableSet.of();
|
return ImmutableSet.of();
|
||||||
}
|
}
|
||||||
// Perform eventually consistent query, to avoid overenlisting cross entity groups
|
// Perform eventually consistent query, to avoid overenlisting cross entity groups
|
||||||
return ofy().doTransactionless(new Work<ImmutableSet<DomainApplication>>() {
|
return ofy().doTransactionless(() -> {
|
||||||
@Override
|
ImmutableSet.Builder<DomainApplication> apps = new ImmutableSet.Builder<>();
|
||||||
public ImmutableSet<DomainApplication> run() {
|
for (DomainApplication app : ofy().load().keys(index.getKeys()).values()) {
|
||||||
ImmutableSet.Builder<DomainApplication> apps = new ImmutableSet.Builder<>();
|
if (app.getDeletionTime().isAfter(now)) {
|
||||||
for (DomainApplication app : ofy().load().keys(index.getKeys()).values()) {
|
apps.add(app);
|
||||||
if (app.getDeletionTime().isAfter(now)) {
|
}
|
||||||
apps.add(app);
|
}
|
||||||
}
|
return apps.build();
|
||||||
}
|
});
|
||||||
return apps.build();
|
|
||||||
}});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -274,26 +274,24 @@ public class Ofy {
|
||||||
* its own retryable read-only transaction.
|
* its own retryable read-only transaction.
|
||||||
*/
|
*/
|
||||||
private <R> Boolean checkIfAlreadySucceeded(final CommitLoggedWork<R> work) {
|
private <R> Boolean checkIfAlreadySucceeded(final CommitLoggedWork<R> work) {
|
||||||
return work.hasRun() && transactNewReadOnly(new Work<Boolean>() {
|
return work.hasRun() && transactNewReadOnly(() -> {
|
||||||
@Override
|
CommitLogManifest manifest = work.getManifest();
|
||||||
public Boolean run() {
|
if (manifest == null) {
|
||||||
CommitLogManifest manifest = work.getManifest();
|
// Work ran but no commit log was created. This might mean that the transaction did not
|
||||||
if (manifest == null) {
|
// write anything to Datastore. We can safely retry because it only reads. (Although the
|
||||||
// Work ran but no commit log was created. This might mean that the transaction did not
|
// transaction might have written a task to a queue, we consider that safe to retry too
|
||||||
// write anything to Datastore. We can safely retry because it only reads. (Although the
|
// since we generally assume that tasks might be doubly executed.) Alternatively it
|
||||||
// transaction might have written a task to a queue, we consider that safe to retry too
|
// might mean that the transaction wrote to Datastore but turned off commit logs by
|
||||||
// since we generally assume that tasks might be doubly executed.) Alternatively it
|
// exclusively using save/deleteWithoutBackups() rather than save/delete(). Although we
|
||||||
// might mean that the transaction wrote to Datastore but turned off commit logs by
|
// have no hard proof that retrying is safe, we use these methods judiciously and it is
|
||||||
// exclusively using save/deleteWithoutBackups() rather than save/delete(). Although we
|
// reasonable to assume that if the transaction really did succeed that the retry will
|
||||||
// have no hard proof that retrying is safe, we use these methods judiciously and it is
|
// either be idempotent or will fail with a non-transient error.
|
||||||
// reasonable to assume that if the transaction really did succeed that the retry will
|
return false;
|
||||||
// either be idempotent or will fail with a non-transient error.
|
}
|
||||||
return false;
|
return Objects.equals(
|
||||||
}
|
union(work.getMutations(), manifest),
|
||||||
return Objects.equals(
|
ImmutableSet.copyOf(load().ancestor(manifest)));
|
||||||
union(work.getMutations(), manifest),
|
});
|
||||||
ImmutableSet.copyOf(load().ancestor(manifest)));
|
|
||||||
}});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A read-only transaction is useful to get strongly consistent reads at a shared timestamp. */
|
/** A read-only transaction is useful to get strongly consistent reads at a shared timestamp. */
|
||||||
|
|
|
@ -193,9 +193,7 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||||
* Compare two instances of {@link RegistrarContact} by their email addresses lexicographically.
|
* Compare two instances of {@link RegistrarContact} by their email addresses lexicographically.
|
||||||
*/
|
*/
|
||||||
private static final Comparator<RegistrarContact> CONTACT_EMAIL_COMPARATOR =
|
private static final Comparator<RegistrarContact> CONTACT_EMAIL_COMPARATOR =
|
||||||
comparing(
|
comparing(RegistrarContact::getEmailAddress, String::compareTo);
|
||||||
(RegistrarContact arg) -> arg.getEmailAddress(),
|
|
||||||
(String leftProperty, String rightProperty) -> leftProperty.compareTo(rightProperty));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A caching {@link Supplier} of a clientId to {@link Registrar} map.
|
* A caching {@link Supplier} of a clientId to {@link Registrar} map.
|
||||||
|
@ -208,9 +206,7 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||||
() ->
|
() ->
|
||||||
ofy()
|
ofy()
|
||||||
.doTransactionless(
|
.doTransactionless(
|
||||||
() -> {
|
() -> Maps.uniqueIndex(loadAll(), Registrar::getClientId)));
|
||||||
return Maps.uniqueIndex(loadAll(), Registrar::getClientId);
|
|
||||||
}));
|
|
||||||
|
|
||||||
@Parent
|
@Parent
|
||||||
Key<EntityGroupRoot> parent = getCrossTldKey();
|
Key<EntityGroupRoot> parent = getCrossTldKey();
|
||||||
|
|
|
@ -32,7 +32,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.google.common.net.InternetDomainName;
|
import com.google.common.net.InternetDomainName;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import google.registry.model.registry.Registry.TldType;
|
import google.registry.model.registry.Registry.TldType;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@ -55,17 +54,14 @@ public final class Registries {
|
||||||
() ->
|
() ->
|
||||||
ofy()
|
ofy()
|
||||||
.doTransactionless(
|
.doTransactionless(
|
||||||
new Work<ImmutableMap<String, TldType>>() {
|
() -> {
|
||||||
@Override
|
ImmutableMap.Builder<String, TldType> builder =
|
||||||
public ImmutableMap<String, TldType> run() {
|
new ImmutableMap.Builder<>();
|
||||||
ImmutableMap.Builder<String, TldType> builder =
|
for (Registry registry :
|
||||||
new ImmutableMap.Builder<>();
|
ofy().load().type(Registry.class).ancestor(getCrossTldKey())) {
|
||||||
for (Registry registry :
|
builder.put(registry.getTldStr(), registry.getTldType());
|
||||||
ofy().load().type(Registry.class).ancestor(getCrossTldKey())) {
|
|
||||||
builder.put(registry.getTldStr(), registry.getTldType());
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
}
|
||||||
|
return builder.build();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@ import com.google.common.collect.Ordering;
|
||||||
import com.google.common.collect.Range;
|
import com.google.common.collect.Range;
|
||||||
import com.google.common.net.InternetDomainName;
|
import com.google.common.net.InternetDomainName;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import com.googlecode.objectify.annotation.Embed;
|
import com.googlecode.objectify.annotation.Embed;
|
||||||
import com.googlecode.objectify.annotation.Entity;
|
import com.googlecode.objectify.annotation.Entity;
|
||||||
import com.googlecode.objectify.annotation.Id;
|
import com.googlecode.objectify.annotation.Id;
|
||||||
|
@ -245,15 +244,10 @@ public class Registry extends ImmutableObject implements Buildable {
|
||||||
return Optional.ofNullable(
|
return Optional.ofNullable(
|
||||||
ofy()
|
ofy()
|
||||||
.doTransactionless(
|
.doTransactionless(
|
||||||
new Work<Registry>() {
|
() -> ofy()
|
||||||
@Override
|
.load()
|
||||||
public Registry run() {
|
.key(Key.create(getCrossTldKey(), Registry.class, tld))
|
||||||
return ofy()
|
.now()));
|
||||||
.load()
|
|
||||||
.key(Key.create(getCrossTldKey(), Registry.class, tld))
|
|
||||||
.now();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ 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 com.googlecode.objectify.VoidWork;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
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;
|
||||||
|
@ -162,28 +161,26 @@ public final class PremiumListUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the new PremiumList and revision itself.
|
// Save the new PremiumList and revision itself.
|
||||||
PremiumList updated = ofy().transactNew(new Work<PremiumList>() {
|
PremiumList updated = ofy().transactNew(() -> {
|
||||||
@Override
|
DateTime now = ofy().getTransactionTime();
|
||||||
public PremiumList run() {
|
// Assert that the premium list hasn't been changed since we started this process.
|
||||||
DateTime now = ofy().getTransactionTime();
|
PremiumList existing = ofy().load()
|
||||||
// Assert that the premium list hasn't been changed since we started this process.
|
.type(PremiumList.class)
|
||||||
PremiumList existing = ofy().load()
|
.parent(getCrossTldKey())
|
||||||
.type(PremiumList.class)
|
.id(premiumList.getName())
|
||||||
.parent(getCrossTldKey())
|
.now();
|
||||||
.id(premiumList.getName())
|
checkState(
|
||||||
.now();
|
Objects.equals(existing, oldPremiumList.orElse(null)),
|
||||||
checkState(
|
"PremiumList was concurrently edited");
|
||||||
Objects.equals(existing, oldPremiumList.orElse(null)),
|
PremiumList newList = premiumList.asBuilder()
|
||||||
"PremiumList was concurrently edited");
|
.setLastUpdateTime(now)
|
||||||
PremiumList newList = premiumList.asBuilder()
|
.setCreationTime(
|
||||||
.setLastUpdateTime(now)
|
oldPremiumList.isPresent() ? oldPremiumList.get().creationTime : now)
|
||||||
.setCreationTime(
|
.setRevision(newRevisionKey)
|
||||||
oldPremiumList.isPresent() ? oldPremiumList.get().creationTime : now)
|
.build();
|
||||||
.setRevision(newRevisionKey)
|
ofy().save().entities(newList, newRevision);
|
||||||
.build();
|
return newList;
|
||||||
ofy().save().entities(newList, newRevision);
|
});
|
||||||
return newList;
|
|
||||||
}});
|
|
||||||
// Update the cache.
|
// Update the cache.
|
||||||
cachePremiumLists.put(premiumList.getName(), updated);
|
cachePremiumLists.put(premiumList.getName(), updated);
|
||||||
// Delete the entities under the old PremiumList.
|
// Delete the entities under the old PremiumList.
|
||||||
|
|
|
@ -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.googlecode.objectify.VoidWork;
|
import com.googlecode.objectify.VoidWork;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
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;
|
||||||
|
@ -171,39 +170,37 @@ public class Lock extends ImmutableObject {
|
||||||
// It's important to use transactNew rather than transact, because a Lock can be used to control
|
// It's important to use transactNew rather than transact, because a Lock can be used to control
|
||||||
// access to resources like GCS that can't be transactionally rolled back. Therefore, the lock
|
// access to resources like GCS that can't be transactionally rolled back. Therefore, the lock
|
||||||
// must be definitively acquired before it is used, even when called inside another transaction.
|
// must be definitively acquired before it is used, even when called inside another transaction.
|
||||||
AcquireResult acquireResult = ofy().transactNew(new Work<AcquireResult>() {
|
AcquireResult acquireResult = ofy().transactNew(() -> {
|
||||||
@Override
|
DateTime now = ofy().getTransactionTime();
|
||||||
public AcquireResult run() {
|
|
||||||
DateTime now = ofy().getTransactionTime();
|
|
||||||
|
|
||||||
// Checking if an unexpired lock still exists - if so, the lock can't be acquired.
|
// Checking if an unexpired lock still exists - if so, the lock can't be acquired.
|
||||||
Lock lock = ofy().load().type(Lock.class).id(lockId).now();
|
Lock lock = ofy().load().type(Lock.class).id(lockId).now();
|
||||||
if (lock != null) {
|
if (lock != null) {
|
||||||
logger.infofmt(
|
logger.infofmt(
|
||||||
"Loaded existing lock: %s for request: %s", lock.lockId, lock.requestLogId);
|
"Loaded existing lock: %s for request: %s", lock.lockId, lock.requestLogId);
|
||||||
}
|
}
|
||||||
LockState lockState;
|
LockState lockState;
|
||||||
if (lock == null) {
|
if (lock == null) {
|
||||||
lockState = LockState.FREE;
|
lockState = LockState.FREE;
|
||||||
} else if (isAtOrAfter(now, lock.expirationTime)) {
|
} else if (isAtOrAfter(now, lock.expirationTime)) {
|
||||||
lockState = LockState.TIMED_OUT;
|
lockState = LockState.TIMED_OUT;
|
||||||
} else if (!requestStatusChecker.isRunning(lock.requestLogId)) {
|
} else if (!requestStatusChecker.isRunning(lock.requestLogId)) {
|
||||||
lockState = LockState.OWNER_DIED;
|
lockState = LockState.OWNER_DIED;
|
||||||
} else {
|
} else {
|
||||||
lockState = LockState.IN_USE;
|
lockState = LockState.IN_USE;
|
||||||
return AcquireResult.create(now, lock, null, lockState);
|
return AcquireResult.create(now, lock, null, lockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lock newLock = create(
|
Lock newLock = create(
|
||||||
resourceName,
|
resourceName,
|
||||||
tld,
|
tld,
|
||||||
requestStatusChecker.getLogId(),
|
requestStatusChecker.getLogId(),
|
||||||
now.plus(leaseLength));
|
now.plus(leaseLength));
|
||||||
// Locks are not parented under an EntityGroupRoot (so as to avoid write contention) and
|
// Locks are not parented under an EntityGroupRoot (so as to avoid write contention) and
|
||||||
// don't need to be backed up.
|
// don't need to be backed up.
|
||||||
ofy().saveWithoutBackup().entity(newLock);
|
ofy().saveWithoutBackup().entity(newLock);
|
||||||
return AcquireResult.create(now, lock, newLock, lockState);
|
return AcquireResult.create(now, lock, newLock, lockState);
|
||||||
}});
|
});
|
||||||
|
|
||||||
logAcquireResult(acquireResult);
|
logAcquireResult(acquireResult);
|
||||||
lockMetrics.record(resourceName, tld, acquireResult.lockState());
|
lockMetrics.record(resourceName, tld, acquireResult.lockState());
|
||||||
|
|
|
@ -21,7 +21,6 @@ import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.google.common.primitives.Longs;
|
import com.google.common.primitives.Longs;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import com.googlecode.objectify.annotation.Entity;
|
import com.googlecode.objectify.annotation.Entity;
|
||||||
import com.googlecode.objectify.annotation.Unindex;
|
import com.googlecode.objectify.annotation.Unindex;
|
||||||
import google.registry.model.annotations.NotBackedUp;
|
import google.registry.model.annotations.NotBackedUp;
|
||||||
|
@ -55,18 +54,16 @@ public class ServerSecret extends CrossTldSingleton {
|
||||||
return secret;
|
return secret;
|
||||||
}
|
}
|
||||||
// Slow path - transactionally create a new ServerSecret (once per app setup).
|
// Slow path - transactionally create a new ServerSecret (once per app setup).
|
||||||
return ofy().transact(new Work<ServerSecret>() {
|
return ofy().transact(() -> {
|
||||||
@Override
|
// Check again for an existing secret within the transaction to avoid races.
|
||||||
public ServerSecret run() {
|
ServerSecret secret1 = ofy().load().entity(new ServerSecret()).now();
|
||||||
// Check again for an existing secret within the transaction to avoid races.
|
if (secret1 == null) {
|
||||||
ServerSecret secret = ofy().load().entity(new ServerSecret()).now();
|
UUID uuid = UUID.randomUUID();
|
||||||
if (secret == null) {
|
secret1 = create(uuid.getMostSignificantBits(), uuid.getLeastSignificantBits());
|
||||||
UUID uuid = UUID.randomUUID();
|
ofy().saveWithoutBackup().entity(secret1).now();
|
||||||
secret = create(uuid.getMostSignificantBits(), uuid.getLeastSignificantBits());
|
}
|
||||||
ofy().saveWithoutBackup().entity(secret).now();
|
return secret1;
|
||||||
}
|
});
|
||||||
return secret;
|
|
||||||
}});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@ import com.google.common.collect.FluentIterable;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import com.googlecode.objectify.annotation.EmbedMap;
|
import com.googlecode.objectify.annotation.EmbedMap;
|
||||||
import com.googlecode.objectify.annotation.Entity;
|
import com.googlecode.objectify.annotation.Entity;
|
||||||
import com.googlecode.objectify.annotation.Id;
|
import com.googlecode.objectify.annotation.Id;
|
||||||
|
@ -95,31 +94,28 @@ public class SignedMarkRevocationList extends ImmutableObject {
|
||||||
() ->
|
() ->
|
||||||
ofy()
|
ofy()
|
||||||
.transactNewReadOnly(
|
.transactNewReadOnly(
|
||||||
new Work<SignedMarkRevocationList>() {
|
() -> {
|
||||||
@Override
|
Iterable<SignedMarkRevocationList> shards =
|
||||||
public SignedMarkRevocationList run() {
|
ofy()
|
||||||
Iterable<SignedMarkRevocationList> shards =
|
.load()
|
||||||
ofy()
|
.type(SignedMarkRevocationList.class)
|
||||||
.load()
|
.ancestor(getCrossTldKey());
|
||||||
.type(SignedMarkRevocationList.class)
|
DateTime creationTime =
|
||||||
.ancestor(getCrossTldKey());
|
isEmpty(shards)
|
||||||
DateTime creationTime =
|
? START_OF_TIME
|
||||||
isEmpty(shards)
|
: checkNotNull(
|
||||||
? START_OF_TIME
|
Iterables.get(shards, 0).creationTime, "creationTime");
|
||||||
: checkNotNull(
|
ImmutableMap.Builder<String, DateTime> revokes =
|
||||||
Iterables.get(shards, 0).creationTime, "creationTime");
|
new ImmutableMap.Builder<>();
|
||||||
ImmutableMap.Builder<String, DateTime> revokes =
|
for (SignedMarkRevocationList shard : shards) {
|
||||||
new ImmutableMap.Builder<>();
|
revokes.putAll(shard.revokes);
|
||||||
for (SignedMarkRevocationList shard : shards) {
|
checkState(
|
||||||
revokes.putAll(shard.revokes);
|
creationTime.equals(shard.creationTime),
|
||||||
checkState(
|
"Inconsistent creation times: %s vs. %s",
|
||||||
creationTime.equals(shard.creationTime),
|
creationTime,
|
||||||
"Inconsistent creation times: %s vs. %s",
|
shard.creationTime);
|
||||||
creationTime,
|
|
||||||
shard.creationTime);
|
|
||||||
}
|
|
||||||
return create(creationTime, revokes.build());
|
|
||||||
}
|
}
|
||||||
|
return create(creationTime, revokes.build());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/** Return a single logical instance that combines all Datastore shards. */
|
/** Return a single logical instance that combines all Datastore shards. */
|
||||||
|
|
|
@ -26,7 +26,6 @@ import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import com.googlecode.objectify.annotation.EmbedMap;
|
import com.googlecode.objectify.annotation.EmbedMap;
|
||||||
import com.googlecode.objectify.annotation.Entity;
|
import com.googlecode.objectify.annotation.Entity;
|
||||||
import com.googlecode.objectify.annotation.Id;
|
import com.googlecode.objectify.annotation.Id;
|
||||||
|
@ -112,15 +111,12 @@ public class ClaimsListShard extends ImmutableObject {
|
||||||
(final Key<ClaimsListShard> key) ->
|
(final Key<ClaimsListShard> key) ->
|
||||||
ofy()
|
ofy()
|
||||||
.transactNewReadOnly(
|
.transactNewReadOnly(
|
||||||
new Work<ClaimsListShard>() {
|
() -> {
|
||||||
@Override
|
ClaimsListShard claimsListShard = ofy().load().key(key).now();
|
||||||
public ClaimsListShard run() {
|
checkState(
|
||||||
ClaimsListShard claimsListShard = ofy().load().key(key).now();
|
claimsListShard != null,
|
||||||
checkState(
|
"Key not found when loading claims list shards.");
|
||||||
claimsListShard != null,
|
return claimsListShard;
|
||||||
"Key not found when loading claims list shards.");
|
|
||||||
return claimsListShard;
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Combine the shards together and return the concatenated ClaimsList.
|
// Combine the shards together and return the concatenated ClaimsList.
|
||||||
|
|
|
@ -460,7 +460,7 @@ public class RdapDomainSearchAction extends RdapActionBase {
|
||||||
}
|
}
|
||||||
Streams.stream(query)
|
Streams.stream(query)
|
||||||
.filter(domain -> isAuthorized(domain, now))
|
.filter(domain -> isAuthorized(domain, now))
|
||||||
.forEach(domain -> domainSetBuilder.add(domain));
|
.forEach(domainSetBuilder::add);
|
||||||
}
|
}
|
||||||
List<DomainResource> domains = domainSetBuilder.build().asList();
|
List<DomainResource> domains = domainSetBuilder.build().asList();
|
||||||
metricInformationBuilder.setNumHostsRetrieved(numHostKeysSearched);
|
metricInformationBuilder.setNumHostsRetrieved(numHostKeysSearched);
|
||||||
|
|
|
@ -19,7 +19,6 @@ import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSetMultimap;
|
import com.google.common.collect.ImmutableSetMultimap;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import google.registry.config.RegistryConfig.Config;
|
import google.registry.config.RegistryConfig.Config;
|
||||||
import google.registry.model.common.Cursor;
|
import google.registry.model.common.Cursor;
|
||||||
import google.registry.model.common.Cursor.CursorType;
|
import google.registry.model.common.Cursor.CursorType;
|
||||||
|
@ -107,16 +106,16 @@ public final class PendingDepositChecker {
|
||||||
final Registry registry,
|
final Registry registry,
|
||||||
final CursorType cursorType,
|
final CursorType cursorType,
|
||||||
final DateTime initialValue) {
|
final DateTime initialValue) {
|
||||||
return ofy().transact(new Work<DateTime>() {
|
return ofy()
|
||||||
@Override
|
.transact(
|
||||||
public DateTime run() {
|
() -> {
|
||||||
Cursor cursor = ofy().load().key(Cursor.createKey(cursorType, registry)).now();
|
Cursor cursor = ofy().load().key(Cursor.createKey(cursorType, registry)).now();
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
return cursor.getCursorTime();
|
return cursor.getCursorTime();
|
||||||
}
|
}
|
||||||
ofy().save().entity(Cursor.create(cursorType, initialValue, registry));
|
ofy().save().entity(Cursor.create(cursorType, initialValue, registry));
|
||||||
return initialValue;
|
return initialValue;
|
||||||
}});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DateTime advanceToDayOfWeek(DateTime date, int dayOfWeek) {
|
private static DateTime advanceToDayOfWeek(DateTime date, int dayOfWeek) {
|
||||||
|
|
|
@ -26,7 +26,6 @@ import com.google.appengine.tools.mapreduce.Mapper;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.net.InternetDomainName;
|
import com.google.common.net.InternetDomainName;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import google.registry.config.RegistryConfig.Config;
|
import google.registry.config.RegistryConfig.Config;
|
||||||
import google.registry.flows.host.HostFlowUtils;
|
import google.registry.flows.host.HostFlowUtils;
|
||||||
import google.registry.mapreduce.MapreduceRunner;
|
import google.registry.mapreduce.MapreduceRunner;
|
||||||
|
@ -110,37 +109,34 @@ public class RdeHostLinkAction implements Runnable {
|
||||||
try {
|
try {
|
||||||
final InternetDomainName hostName = InternetDomainName.from(xjcHost.getName());
|
final InternetDomainName hostName = InternetDomainName.from(xjcHost.getName());
|
||||||
|
|
||||||
HostLinkResult hostLinkResult = ofy().transact(new Work<HostLinkResult>() {
|
HostLinkResult hostLinkResult = ofy().transact(() -> {
|
||||||
@Override
|
Optional<DomainResource> superordinateDomain =
|
||||||
public HostLinkResult run() {
|
lookupSuperordinateDomain(hostName, ofy().getTransactionTime());
|
||||||
Optional<DomainResource> superordinateDomain =
|
// if suporordinateDomain is absent, this is an out of zone host and can't be linked.
|
||||||
lookupSuperordinateDomain(hostName, ofy().getTransactionTime());
|
// absent is only returned for out of zone hosts, and an exception is thrown for in
|
||||||
// if suporordinateDomain is absent, this is an out of zone host and can't be linked.
|
// zone hosts with no superordinate domain.
|
||||||
// absent is only returned for out of zone hosts, and an exception is thrown for in
|
if (!superordinateDomain.isPresent()) {
|
||||||
// zone hosts with no superordinate domain.
|
return HostLinkResult.HOST_OUT_OF_ZONE;
|
||||||
if (!superordinateDomain.isPresent()) {
|
|
||||||
return HostLinkResult.HOST_OUT_OF_ZONE;
|
|
||||||
}
|
|
||||||
if (superordinateDomain.get().getStatusValues().contains(StatusValue.PENDING_DELETE)) {
|
|
||||||
return HostLinkResult.SUPERORDINATE_DOMAIN_IN_PENDING_DELETE;
|
|
||||||
}
|
|
||||||
Key<DomainResource> superordinateDomainKey = Key.create(superordinateDomain.get());
|
|
||||||
// link host to superordinate domain and set time of last superordinate change to
|
|
||||||
// the time of the import
|
|
||||||
HostResource host =
|
|
||||||
ofy().load().now(Key.create(HostResource.class, xjcHost.getRoid()));
|
|
||||||
if (host == null) {
|
|
||||||
return HostLinkResult.HOST_NOT_FOUND;
|
|
||||||
}
|
|
||||||
// link domain to subordinate host
|
|
||||||
ofy().save().<EppResource>entities(
|
|
||||||
host.asBuilder().setSuperordinateDomain(superordinateDomainKey)
|
|
||||||
.setLastSuperordinateChange(ofy().getTransactionTime())
|
|
||||||
.build(),
|
|
||||||
superordinateDomain.get().asBuilder()
|
|
||||||
.addSubordinateHost(host.getFullyQualifiedHostName()).build());
|
|
||||||
return HostLinkResult.HOST_LINKED;
|
|
||||||
}
|
}
|
||||||
|
if (superordinateDomain.get().getStatusValues().contains(StatusValue.PENDING_DELETE)) {
|
||||||
|
return HostLinkResult.SUPERORDINATE_DOMAIN_IN_PENDING_DELETE;
|
||||||
|
}
|
||||||
|
Key<DomainResource> superordinateDomainKey = Key.create(superordinateDomain.get());
|
||||||
|
// link host to superordinate domain and set time of last superordinate change to
|
||||||
|
// the time of the import
|
||||||
|
HostResource host =
|
||||||
|
ofy().load().now(Key.create(HostResource.class, xjcHost.getRoid()));
|
||||||
|
if (host == null) {
|
||||||
|
return HostLinkResult.HOST_NOT_FOUND;
|
||||||
|
}
|
||||||
|
// link domain to subordinate host
|
||||||
|
ofy().save().<EppResource>entities(
|
||||||
|
host.asBuilder().setSuperordinateDomain(superordinateDomainKey)
|
||||||
|
.setLastSuperordinateChange(ofy().getTransactionTime())
|
||||||
|
.build(),
|
||||||
|
superordinateDomain.get().asBuilder()
|
||||||
|
.addSubordinateHost(host.getFullyQualifiedHostName()).build());
|
||||||
|
return HostLinkResult.HOST_LINKED;
|
||||||
});
|
});
|
||||||
// increment counter and log appropriately based on result of transaction
|
// increment counter and log appropriately based on result of transaction
|
||||||
switch (hostLinkResult) {
|
switch (hostLinkResult) {
|
||||||
|
|
|
@ -196,7 +196,7 @@ public class IcannReportingStager {
|
||||||
private String constructTotalRow(List<Integer> totals) {
|
private String constructTotalRow(List<Integer> totals) {
|
||||||
StringBuilder rowString = new StringBuilder("Totals,,");
|
StringBuilder rowString = new StringBuilder("Totals,,");
|
||||||
rowString.append(
|
rowString.append(
|
||||||
totals.stream().map((Integer i) -> i.toString()).collect(Collectors.joining(",")));
|
totals.stream().map(Object::toString).collect(Collectors.joining(",")));
|
||||||
return rowString.toString();
|
return rowString.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ 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 com.googlecode.objectify.VoidWork;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
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;
|
||||||
|
@ -71,27 +70,24 @@ final class AllocateDomainCommand extends MutatingEppToolCommand {
|
||||||
.append(
|
.append(
|
||||||
ofy()
|
ofy()
|
||||||
.transactNewReadOnly(
|
.transactNewReadOnly(
|
||||||
new Work<String>() {
|
() -> {
|
||||||
@Override
|
String failureMessage =
|
||||||
public String run() {
|
ofy()
|
||||||
String failureMessage =
|
.load()
|
||||||
ofy()
|
.keys(applicationKeys)
|
||||||
.load()
|
.values()
|
||||||
.keys(applicationKeys)
|
.stream()
|
||||||
.values()
|
.map(
|
||||||
.stream()
|
application ->
|
||||||
.map(
|
application.getApplicationStatus()
|
||||||
application ->
|
== ApplicationStatus.ALLOCATED
|
||||||
application.getApplicationStatus()
|
? null
|
||||||
== ApplicationStatus.ALLOCATED
|
: application.getFullyQualifiedDomainName())
|
||||||
? null
|
.filter(Objects::nonNull)
|
||||||
: application.getFullyQualifiedDomainName())
|
.collect(joining("\n"));
|
||||||
.filter(Objects::nonNull)
|
return failureMessage.isEmpty()
|
||||||
.collect(joining("\n"));
|
? "ALL SUCCEEDED"
|
||||||
return failureMessage.isEmpty()
|
: addHeader("FAILURES", failureMessage);
|
||||||
? "ALL SUCCEEDED"
|
|
||||||
: addHeader("FAILURES", failureMessage);
|
|
||||||
}
|
|
||||||
}))
|
}))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import com.google.api.client.http.HttpHeaders;
|
||||||
import com.google.api.client.http.HttpRequest;
|
import com.google.api.client.http.HttpRequest;
|
||||||
import com.google.api.client.http.HttpRequestFactory;
|
import com.google.api.client.http.HttpRequestFactory;
|
||||||
import com.google.api.client.http.HttpResponse;
|
import com.google.api.client.http.HttpResponse;
|
||||||
import com.google.api.client.http.HttpUnsuccessfulResponseHandler;
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -98,20 +97,15 @@ class AppEngineConnection implements Connection {
|
||||||
request.setFollowRedirects(false);
|
request.setFollowRedirects(false);
|
||||||
request.setThrowExceptionOnExecuteError(false);
|
request.setThrowExceptionOnExecuteError(false);
|
||||||
request.setUnsuccessfulResponseHandler(
|
request.setUnsuccessfulResponseHandler(
|
||||||
new HttpUnsuccessfulResponseHandler() {
|
(request1, response, supportsRetry) -> {
|
||||||
@Override
|
String errorTitle = extractHtmlTitle(getErrorHtmlAsString(response));
|
||||||
public boolean handleResponse(
|
throw new IOException(
|
||||||
HttpRequest request, HttpResponse response, boolean supportsRetry)
|
String.format(
|
||||||
throws IOException {
|
"Error from %s: %d %s%s",
|
||||||
String errorTitle = extractHtmlTitle(getErrorHtmlAsString(response));
|
request1.getUrl().toString(),
|
||||||
throw new IOException(
|
response.getStatusCode(),
|
||||||
String.format(
|
response.getStatusMessage(),
|
||||||
"Error from %s: %d %s%s",
|
(errorTitle == null ? "" : ": " + errorTitle)));
|
||||||
request.getUrl().toString(),
|
|
||||||
response.getStatusCode(),
|
|
||||||
response.getStatusMessage(),
|
|
||||||
(errorTitle == null ? "" : ": " + errorTitle)));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
HttpResponse response = null;
|
HttpResponse response = null;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -28,11 +28,11 @@ import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ComparisonChain;
|
import com.google.common.collect.ComparisonChain;
|
||||||
import com.google.common.collect.FluentIterable;
|
import com.google.common.collect.FluentIterable;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableList.Builder;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Ordering;
|
import com.google.common.collect.Ordering;
|
||||||
import com.google.common.net.InternetDomainName;
|
import com.google.common.net.InternetDomainName;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import google.registry.model.contact.ContactResource;
|
import google.registry.model.contact.ContactResource;
|
||||||
import google.registry.model.domain.DomainApplication;
|
import google.registry.model.domain.DomainApplication;
|
||||||
import google.registry.tools.Command.RemoteApiCommand;
|
import google.registry.tools.Command.RemoteApiCommand;
|
||||||
|
@ -71,20 +71,17 @@ final class AuctionStatusCommand implements RemoteApiCommand {
|
||||||
fullyQualifiedDomainName);
|
fullyQualifiedDomainName);
|
||||||
return ofy()
|
return ofy()
|
||||||
.transactNewReadOnly(
|
.transactNewReadOnly(
|
||||||
new Work<Iterable<String>>() {
|
() -> {
|
||||||
@Override
|
Builder<DomainApplication> applications =
|
||||||
public Iterable<String> run() {
|
new Builder<>();
|
||||||
ImmutableList.Builder<DomainApplication> applications =
|
for (String domain : domains) {
|
||||||
new ImmutableList.Builder<>();
|
applications.addAll(
|
||||||
for (String domain : domains) {
|
loadActiveApplicationsByDomainName(
|
||||||
applications.addAll(
|
domain, ofy().getTransactionTime()));
|
||||||
loadActiveApplicationsByDomainName(
|
|
||||||
domain, ofy().getTransactionTime()));
|
|
||||||
}
|
|
||||||
return Lists.transform(
|
|
||||||
ImmutableList.sortedCopyOf(ORDERING, applications.build()),
|
|
||||||
APPLICATION_FORMATTER);
|
|
||||||
}
|
}
|
||||||
|
return Lists.transform(
|
||||||
|
ImmutableList.sortedCopyOf(ORDERING, applications.build()),
|
||||||
|
APPLICATION_FORMATTER);
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
UTF_8);
|
UTF_8);
|
||||||
|
|
|
@ -15,9 +15,7 @@
|
||||||
package google.registry.tools;
|
package google.registry.tools;
|
||||||
|
|
||||||
import com.google.api.client.auth.oauth2.Credential;
|
import com.google.api.client.auth.oauth2.Credential;
|
||||||
import com.google.api.client.http.HttpRequest;
|
|
||||||
import com.google.api.client.http.HttpRequestFactory;
|
import com.google.api.client.http.HttpRequestFactory;
|
||||||
import com.google.api.client.http.HttpRequestInitializer;
|
|
||||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||||
import dagger.Binds;
|
import dagger.Binds;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
|
@ -50,14 +48,9 @@ class DefaultRequestFactoryModule {
|
||||||
if (connectionFlags.getServer().getHost().equals("localhost")) {
|
if (connectionFlags.getServer().getHost().equals("localhost")) {
|
||||||
return new NetHttpTransport()
|
return new NetHttpTransport()
|
||||||
.createRequestFactory(
|
.createRequestFactory(
|
||||||
new HttpRequestInitializer() {
|
request -> request
|
||||||
@Override
|
.getHeaders()
|
||||||
public void initialize(HttpRequest request) {
|
.setCookie("dev_appserver_login=test@example.com:true:1858047912411"));
|
||||||
request
|
|
||||||
.getHeaders()
|
|
||||||
.setCookie("dev_appserver_login=test@example.com:true:1858047912411");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
return new NetHttpTransport().createRequestFactory(credentialProvider.get());
|
return new NetHttpTransport().createRequestFactory(credentialProvider.get());
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,9 @@ import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||||
|
|
||||||
import com.beust.jcommander.Parameter;
|
import com.beust.jcommander.Parameter;
|
||||||
import com.beust.jcommander.Parameters;
|
import com.beust.jcommander.Parameters;
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import google.registry.model.domain.DomainResource;
|
import google.registry.model.domain.DomainResource;
|
||||||
import google.registry.model.domain.secdns.DelegationSignerData;
|
|
||||||
import google.registry.model.host.HostResource;
|
import google.registry.model.host.HostResource;
|
||||||
import google.registry.tools.Command.RemoteApiCommand;
|
import google.registry.tools.Command.RemoteApiCommand;
|
||||||
import google.registry.tools.params.PathParameter;
|
import google.registry.tools.params.PathParameter;
|
||||||
|
@ -104,16 +102,12 @@ final class GenerateDnsReportCommand implements RemoteApiCommand {
|
||||||
.getDsData()
|
.getDsData()
|
||||||
.stream()
|
.stream()
|
||||||
.map(
|
.map(
|
||||||
new Function<DelegationSignerData, Map<String, ?>>() {
|
dsData1 ->
|
||||||
@Override
|
ImmutableMap.of(
|
||||||
public Map<String, ?> apply(DelegationSignerData dsData) {
|
"keyTag", dsData1.getKeyTag(),
|
||||||
return ImmutableMap.of(
|
"algorithm", dsData1.getAlgorithm(),
|
||||||
"keyTag", dsData.getKeyTag(),
|
"digestType", dsData1.getDigestType(),
|
||||||
"algorithm", dsData.getAlgorithm(),
|
"digest", base16().encode(dsData1.getDigest())))
|
||||||
"digestType", dsData.getDigestType(),
|
|
||||||
"digest", base16().encode(dsData.getDigest()));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(toImmutableList());
|
.collect(toImmutableList());
|
||||||
ImmutableMap.Builder<String, Object> mapBuilder = new ImmutableMap.Builder<>();
|
ImmutableMap.Builder<String, Object> mapBuilder = new ImmutableMap.Builder<>();
|
||||||
mapBuilder.put("domain", domain.getFullyQualifiedDomainName());
|
mapBuilder.put("domain", domain.getFullyQualifiedDomainName());
|
||||||
|
|
|
@ -20,7 +20,6 @@ import com.beust.jcommander.Parameter;
|
||||||
import com.beust.jcommander.Parameters;
|
import com.beust.jcommander.Parameters;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import google.registry.model.billing.RegistrarCredit;
|
import google.registry.model.billing.RegistrarCredit;
|
||||||
import google.registry.model.billing.RegistrarCreditBalance.BalanceMap;
|
import google.registry.model.billing.RegistrarCreditBalance.BalanceMap;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
|
@ -52,22 +51,19 @@ final class ListCreditsCommand implements RemoteApiCommand {
|
||||||
private ImmutableList<String> createCreditStrings(final Registrar registrar) {
|
private ImmutableList<String> createCreditStrings(final Registrar registrar) {
|
||||||
return ofy()
|
return ofy()
|
||||||
.transactNewReadOnly(
|
.transactNewReadOnly(
|
||||||
new Work<ImmutableList<String>>() {
|
() -> {
|
||||||
@Override
|
ImmutableList.Builder<String> builder = new ImmutableList.Builder<>();
|
||||||
public ImmutableList<String> run() {
|
for (RegistrarCredit credit : RegistrarCredit.loadAllForRegistrar(registrar)) {
|
||||||
ImmutableList.Builder<String> builder = new ImmutableList.Builder<>();
|
BalanceMap balanceMap = BalanceMap.createForCredit(credit);
|
||||||
for (RegistrarCredit credit : RegistrarCredit.loadAllForRegistrar(registrar)) {
|
Optional<Money> activeBalance =
|
||||||
BalanceMap balanceMap = BalanceMap.createForCredit(credit);
|
balanceMap.getActiveBalanceAtTime(ofy().getTransactionTime());
|
||||||
Optional<Money> activeBalance =
|
// Unless showAll is true, only show credits with a positive active balance (which
|
||||||
balanceMap.getActiveBalanceAtTime(ofy().getTransactionTime());
|
// excludes just zero-balance credits since credit balances cannot be negative).
|
||||||
// Unless showAll is true, only show credits with a positive active balance (which
|
if (showAll || (activeBalance.isPresent() && activeBalance.get().isPositive())) {
|
||||||
// excludes just zero-balance credits since credit balances cannot be negative).
|
builder.add(credit.getSummary() + "\n" + balanceMap);
|
||||||
if (showAll || (activeBalance.isPresent() && activeBalance.get().isPositive())) {
|
|
||||||
builder.add(credit.getSummary() + "\n" + balanceMap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return builder.build();
|
|
||||||
}
|
}
|
||||||
|
return builder.build();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,15 +71,12 @@ public final class SoyTemplateUtils {
|
||||||
return memoize(
|
return memoize(
|
||||||
() -> {
|
() -> {
|
||||||
final ImmutableMap<String, String> renames = getCssRenames(cssMap, cssMapDebug);
|
final ImmutableMap<String, String> renames = getCssRenames(cssMap, cssMapDebug);
|
||||||
return new SoyCssRenamingMap() {
|
return (cssClassName) -> {
|
||||||
@Override
|
List<String> result = new ArrayList<>();
|
||||||
public String get(String cssClassName) {
|
for (String part : CSS_CLASS_SPLITTER.split(cssClassName)) {
|
||||||
List<String> result = new ArrayList<>();
|
result.add(renames.getOrDefault(part, part));
|
||||||
for (String part : CSS_CLASS_SPLITTER.split(cssClassName)) {
|
|
||||||
result.add(renames.getOrDefault(part, part));
|
|
||||||
}
|
|
||||||
return CSS_CLASS_JOINER.join(result);
|
|
||||||
}
|
}
|
||||||
|
return CSS_CLASS_JOINER.join(result);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,13 @@ import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||||
import static com.google.common.collect.Iterables.toArray;
|
import static com.google.common.collect.Iterables.toArray;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import com.google.common.collect.Streams;
|
import com.google.common.collect.Streams;
|
||||||
import google.registry.config.RegistryConfig.Config;
|
import google.registry.config.RegistryConfig.Config;
|
||||||
import google.registry.util.FormattingLogger;
|
import google.registry.util.FormattingLogger;
|
||||||
import google.registry.util.NonFinalForTesting;
|
import google.registry.util.NonFinalForTesting;
|
||||||
import google.registry.util.SendEmailService;
|
import google.registry.util.SendEmailService;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.mail.Message;
|
import javax.mail.Message;
|
||||||
import javax.mail.internet.AddressException;
|
import javax.mail.internet.AddressException;
|
||||||
|
@ -77,7 +77,7 @@ public class SendEmailUtils {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(Predicates.notNull())
|
.filter(Objects::nonNull)
|
||||||
.collect(toImmutableList());
|
.collect(toImmutableList());
|
||||||
if (emails.isEmpty()) {
|
if (emails.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -15,15 +15,11 @@
|
||||||
package google.registry.util;
|
package google.registry.util;
|
||||||
|
|
||||||
import com.google.appengine.api.datastore.Key;
|
import com.google.appengine.api.datastore.Key;
|
||||||
import com.google.common.base.Function;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/** Utility methods for working with the App Engine Datastore service. */
|
/** Utility methods for working with the App Engine Datastore service. */
|
||||||
public class DatastoreServiceUtils {
|
public class DatastoreServiceUtils {
|
||||||
|
|
||||||
/** Helper function that extracts the kind from a regular Datastore entity key. */
|
|
||||||
public static final Function<Key, String> KEY_TO_KIND_FUNCTION = Key::getKind;
|
|
||||||
|
|
||||||
/** Returns the name or id of a key, which may be a string or a long. */
|
/** Returns the name or id of a key, which may be a string or a long. */
|
||||||
public static Object getNameOrId(Key key) {
|
public static Object getNameOrId(Key key) {
|
||||||
return Optional.<Object>ofNullable(key.getName()).orElse(key.getId());
|
return Optional.<Object>ofNullable(key.getName()).orElse(key.getId());
|
||||||
|
|
|
@ -32,7 +32,6 @@ import google.registry.whois.WhoisException.UncheckedWhoisException;
|
||||||
import google.registry.whois.WhoisMetrics.WhoisMetric;
|
import google.registry.whois.WhoisMetrics.WhoisMetric;
|
||||||
import google.registry.whois.WhoisResponse.WhoisResponseResults;
|
import google.registry.whois.WhoisResponse.WhoisResponseResults;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
@ -87,17 +86,14 @@ public class WhoisServer implements Runnable {
|
||||||
metricBuilder.setCommand(command);
|
metricBuilder.setCommand(command);
|
||||||
WhoisResponseResults results =
|
WhoisResponseResults results =
|
||||||
retrier.callWithRetry(
|
retrier.callWithRetry(
|
||||||
new Callable<WhoisResponseResults>() {
|
() -> {
|
||||||
@Override
|
WhoisResponseResults results1;
|
||||||
public WhoisResponseResults call() {
|
try {
|
||||||
WhoisResponseResults results;
|
results1 = command.executeQuery(now).getResponse(PREFER_UNICODE, disclaimer);
|
||||||
try {
|
} catch (WhoisException e) {
|
||||||
results = command.executeQuery(now).getResponse(PREFER_UNICODE, disclaimer);
|
throw new UncheckedWhoisException(e);
|
||||||
} catch (WhoisException e) {
|
|
||||||
throw new UncheckedWhoisException(e);
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
return results1;
|
||||||
},
|
},
|
||||||
DatastoreTimeoutException.class,
|
DatastoreTimeoutException.class,
|
||||||
DatastoreFailureException.class);
|
DatastoreFailureException.class);
|
||||||
|
|
|
@ -61,9 +61,7 @@ import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Captor;
|
import org.mockito.Captor;
|
||||||
import org.mockito.Matchers;
|
import org.mockito.Matchers;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
/** Test case for {@link CloudDnsWriter}. */
|
/** Test case for {@link CloudDnsWriter}. */
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
@ -119,44 +117,36 @@ public class CloudDnsWriterTest {
|
||||||
// Return records from our stub zone when a request to list the records is executed
|
// Return records from our stub zone when a request to list the records is executed
|
||||||
when(listResourceRecordSetsRequest.execute())
|
when(listResourceRecordSetsRequest.execute())
|
||||||
.thenAnswer(
|
.thenAnswer(
|
||||||
new Answer<ResourceRecordSetsListResponse>() {
|
invocationOnMock ->
|
||||||
@Override
|
new ResourceRecordSetsListResponse()
|
||||||
public ResourceRecordSetsListResponse answer(InvocationOnMock invocationOnMock)
|
|
||||||
throws Throwable {
|
|
||||||
return new ResourceRecordSetsListResponse()
|
|
||||||
.setRrsets(
|
.setRrsets(
|
||||||
stubZone
|
stubZone
|
||||||
.stream()
|
.stream()
|
||||||
.filter(
|
.filter(
|
||||||
rs ->
|
rs ->
|
||||||
rs != null && rs.getName().equals(recordNameCaptor.getValue()))
|
rs != null && rs.getName().equals(recordNameCaptor.getValue()))
|
||||||
.collect(toImmutableList()));
|
.collect(toImmutableList())));
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
when(changes.create(anyString(), zoneNameCaptor.capture(), changeCaptor.capture()))
|
when(changes.create(anyString(), zoneNameCaptor.capture(), changeCaptor.capture()))
|
||||||
.thenReturn(createChangeRequest);
|
.thenReturn(createChangeRequest);
|
||||||
// Change our stub zone when a request to change the records is executed
|
// Change our stub zone when a request to change the records is executed
|
||||||
when(createChangeRequest.execute())
|
when(createChangeRequest.execute())
|
||||||
.thenAnswer(
|
.thenAnswer(
|
||||||
new Answer<Change>() {
|
invocationOnMock -> {
|
||||||
@Override
|
Change requestedChange = changeCaptor.getValue();
|
||||||
public Change answer(InvocationOnMock invocationOnMock) throws IOException {
|
ImmutableSet<ResourceRecordSet> toDelete =
|
||||||
Change requestedChange = changeCaptor.getValue();
|
ImmutableSet.copyOf(requestedChange.getDeletions());
|
||||||
ImmutableSet<ResourceRecordSet> toDelete =
|
ImmutableSet<ResourceRecordSet> toAdd =
|
||||||
ImmutableSet.copyOf(requestedChange.getDeletions());
|
ImmutableSet.copyOf(requestedChange.getAdditions());
|
||||||
ImmutableSet<ResourceRecordSet> toAdd =
|
// Fail if the records to delete has records that aren't in the stub zone.
|
||||||
ImmutableSet.copyOf(requestedChange.getAdditions());
|
// This matches documented Google Cloud DNS behavior.
|
||||||
// Fail if the records to delete has records that aren't in the stub zone.
|
if (!Sets.difference(toDelete, stubZone).isEmpty()) {
|
||||||
// This matches documented Google Cloud DNS behavior.
|
throw new IOException();
|
||||||
if (!Sets.difference(toDelete, stubZone).isEmpty()) {
|
|
||||||
throw new IOException();
|
|
||||||
}
|
|
||||||
stubZone =
|
|
||||||
Sets.union(Sets.difference(stubZone, toDelete).immutableCopy(), toAdd)
|
|
||||||
.immutableCopy();
|
|
||||||
return requestedChange;
|
|
||||||
}
|
}
|
||||||
|
stubZone =
|
||||||
|
Sets.union(Sets.difference(stubZone, toDelete).immutableCopy(), toAdd)
|
||||||
|
.immutableCopy();
|
||||||
|
return requestedChange;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ import static google.registry.testing.DatastoreHelper.persistActiveContact;
|
||||||
import static google.registry.testing.DatastoreHelper.persistActiveHost;
|
import static google.registry.testing.DatastoreHelper.persistActiveHost;
|
||||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||||
import static google.registry.testing.TestDataHelper.loadFileWithSubstitutions;
|
import static google.registry.testing.TestDataHelper.loadFileWithSubstitutions;
|
||||||
import static google.registry.util.DatastoreServiceUtils.KEY_TO_KIND_FUNCTION;
|
|
||||||
|
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.ImmutableList;
|
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;
|
||||||
|
@ -331,22 +331,20 @@ public class DomainApplicationInfoFlowTest
|
||||||
int numPreviousReads = RequestCapturingAsyncDatastoreService.getReads().size();
|
int numPreviousReads = RequestCapturingAsyncDatastoreService.getReads().size();
|
||||||
doSuccessfulTest("domain_info_sunrise_response.xml", HostsState.HOSTS_EXIST);
|
doSuccessfulTest("domain_info_sunrise_response.xml", HostsState.HOSTS_EXIST);
|
||||||
// Get all of the keys loaded in the flow, with each distinct load() call as a list of keys.
|
// Get all of the keys loaded in the flow, with each distinct load() call as a list of keys.
|
||||||
int numReadsWithContactsOrHosts =
|
long numReadsWithContactsOrHosts =
|
||||||
(int)
|
RequestCapturingAsyncDatastoreService.getReads()
|
||||||
RequestCapturingAsyncDatastoreService.getReads()
|
.stream()
|
||||||
.stream()
|
.skip(numPreviousReads)
|
||||||
.skip(numPreviousReads)
|
.filter(
|
||||||
.filter(
|
keys ->
|
||||||
keys ->
|
keys.stream()
|
||||||
keys.stream()
|
.map(com.google.appengine.api.datastore.Key::getKind)
|
||||||
.map(KEY_TO_KIND_FUNCTION)
|
.anyMatch(
|
||||||
.anyMatch(
|
Predicates.in(
|
||||||
kind ->
|
ImmutableSet.of(
|
||||||
ImmutableSet.of(
|
Key.getKind(ContactResource.class),
|
||||||
Key.getKind(ContactResource.class),
|
Key.getKind(HostResource.class)))))
|
||||||
Key.getKind(HostResource.class))
|
.count();
|
||||||
.contains(kind)))
|
|
||||||
.count();
|
|
||||||
assertThat(numReadsWithContactsOrHosts).isEqualTo(1);
|
assertThat(numReadsWithContactsOrHosts).isEqualTo(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ import static google.registry.testing.DatastoreHelper.persistActiveContact;
|
||||||
import static google.registry.testing.DatastoreHelper.persistActiveHost;
|
import static google.registry.testing.DatastoreHelper.persistActiveHost;
|
||||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||||
import static google.registry.testing.TestDataHelper.loadFileWithSubstitutions;
|
import static google.registry.testing.TestDataHelper.loadFileWithSubstitutions;
|
||||||
import static google.registry.util.DatastoreServiceUtils.KEY_TO_KIND_FUNCTION;
|
|
||||||
|
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
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;
|
||||||
|
@ -644,13 +644,12 @@ public class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Dom
|
||||||
.filter(
|
.filter(
|
||||||
keys ->
|
keys ->
|
||||||
keys.stream()
|
keys.stream()
|
||||||
.map(KEY_TO_KIND_FUNCTION)
|
.map(com.google.appengine.api.datastore.Key::getKind)
|
||||||
.anyMatch(
|
.anyMatch(
|
||||||
kind ->
|
Predicates.in(
|
||||||
ImmutableSet.of(
|
ImmutableSet.of(
|
||||||
Key.getKind(ContactResource.class),
|
Key.getKind(ContactResource.class),
|
||||||
Key.getKind(HostResource.class))
|
Key.getKind(HostResource.class)))))
|
||||||
.contains(kind)))
|
|
||||||
.count();
|
.count();
|
||||||
assertThat(numReadsWithContactsOrHosts).isEqualTo(1);
|
assertThat(numReadsWithContactsOrHosts).isEqualTo(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,7 +242,7 @@ public class ComparatorKeyringTest {
|
||||||
when(secondKeyring.getRdeSigningKey()).thenReturn(keyPair);
|
when(secondKeyring.getRdeSigningKey()).thenReturn(keyPair);
|
||||||
Keyring comparatorKeyring = ComparatorKeyring.create(actualKeyring, secondKeyring);
|
Keyring comparatorKeyring = ComparatorKeyring.create(actualKeyring, secondKeyring);
|
||||||
|
|
||||||
assertThrows(KeyringException.class, () -> comparatorKeyring.getRdeSigningKey());
|
assertThrows(KeyringException.class, comparatorKeyring::getRdeSigningKey);
|
||||||
|
|
||||||
assertAboutLogs()
|
assertAboutLogs()
|
||||||
.that(testLogHandler)
|
.that(testLogHandler)
|
||||||
|
@ -278,7 +278,7 @@ public class ComparatorKeyringTest {
|
||||||
when(secondKeyring.getRdeSigningKey()).thenThrow(new KeyringException("message"));
|
when(secondKeyring.getRdeSigningKey()).thenThrow(new KeyringException("message"));
|
||||||
Keyring comparatorKeyring = ComparatorKeyring.create(actualKeyring, secondKeyring);
|
Keyring comparatorKeyring = ComparatorKeyring.create(actualKeyring, secondKeyring);
|
||||||
|
|
||||||
assertThrows(KeyringException.class, () -> comparatorKeyring.getRdeSigningKey());
|
assertThrows(KeyringException.class, comparatorKeyring::getRdeSigningKey);
|
||||||
|
|
||||||
assertAboutLogs().that(testLogHandler).hasNoLogsAtLevel(Level.SEVERE);
|
assertAboutLogs().that(testLogHandler).hasNoLogsAtLevel(Level.SEVERE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,11 @@ package google.registry.model;
|
||||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.model.EntityClasses.ALL_CLASSES;
|
import static google.registry.model.EntityClasses.ALL_CLASSES;
|
||||||
import static google.registry.model.EntityClasses.CLASS_TO_KIND_FUNCTION;
|
|
||||||
import static google.registry.util.TypeUtils.hasAnnotation;
|
import static google.registry.util.TypeUtils.hasAnnotation;
|
||||||
import static java.util.stream.Collectors.toSet;
|
import static java.util.stream.Collectors.toSet;
|
||||||
|
|
||||||
import com.google.common.collect.Ordering;
|
import com.google.common.collect.Ordering;
|
||||||
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.annotation.Entity;
|
import com.googlecode.objectify.annotation.Entity;
|
||||||
import com.googlecode.objectify.annotation.EntitySubclass;
|
import com.googlecode.objectify.annotation.EntitySubclass;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -50,7 +50,7 @@ public class EntityClassesTest {
|
||||||
ALL_CLASSES
|
ALL_CLASSES
|
||||||
.stream()
|
.stream()
|
||||||
.filter(hasAnnotation(Entity.class))
|
.filter(hasAnnotation(Entity.class))
|
||||||
.map(CLASS_TO_KIND_FUNCTION)
|
.map(Key::getKind)
|
||||||
.collect(toImmutableSet()))
|
.collect(toImmutableSet()))
|
||||||
.named("base entity kinds")
|
.named("base entity kinds")
|
||||||
.containsNoDuplicates();
|
.containsNoDuplicates();
|
||||||
|
@ -62,13 +62,13 @@ public class EntityClassesTest {
|
||||||
ALL_CLASSES
|
ALL_CLASSES
|
||||||
.stream()
|
.stream()
|
||||||
.filter(hasAnnotation(Entity.class))
|
.filter(hasAnnotation(Entity.class))
|
||||||
.map(CLASS_TO_KIND_FUNCTION)
|
.map(Key::getKind)
|
||||||
.collect(toSet());
|
.collect(toSet());
|
||||||
Set<String> entitySubclassKinds =
|
Set<String> entitySubclassKinds =
|
||||||
ALL_CLASSES
|
ALL_CLASSES
|
||||||
.stream()
|
.stream()
|
||||||
.filter(hasAnnotation(EntitySubclass.class))
|
.filter(hasAnnotation(EntitySubclass.class))
|
||||||
.map(CLASS_TO_KIND_FUNCTION)
|
.map(Key::getKind)
|
||||||
.collect(toSet());
|
.collect(toSet());
|
||||||
assertThat(baseEntityKinds).named("base entity kinds").containsAllIn(entitySubclassKinds);
|
assertThat(baseEntityKinds).named("base entity kinds").containsAllIn(entitySubclassKinds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import static java.util.Arrays.asList;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.io.ByteSource;
|
import com.google.common.io.ByteSource;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import google.registry.model.contact.ContactResource;
|
import google.registry.model.contact.ContactResource;
|
||||||
import google.registry.model.contact.PostalInfo;
|
import google.registry.model.contact.PostalInfo;
|
||||||
import google.registry.model.eppcommon.StatusValue;
|
import google.registry.model.eppcommon.StatusValue;
|
||||||
|
@ -191,12 +190,7 @@ public class XjcToContactResourceConverterTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ContactResource convertContactInTransaction(final XjcRdeContact xjcContact) {
|
private static ContactResource convertContactInTransaction(final XjcRdeContact xjcContact) {
|
||||||
return ofy().transact(new Work<ContactResource>() {
|
return ofy().transact(() -> XjcToContactResourceConverter.convertContact(xjcContact));
|
||||||
@Override
|
|
||||||
public ContactResource run() {
|
|
||||||
return XjcToContactResourceConverter.convertContact(xjcContact);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private XjcRdeContact loadContactFromRdeXml() throws Exception {
|
private XjcRdeContact loadContactFromRdeXml() throws Exception {
|
||||||
|
|
|
@ -33,7 +33,6 @@ import com.google.common.base.Joiner;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.io.ByteSource;
|
import com.google.common.io.ByteSource;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import google.registry.model.billing.BillingEvent;
|
import google.registry.model.billing.BillingEvent;
|
||||||
import google.registry.model.billing.BillingEvent.Flag;
|
import google.registry.model.billing.BillingEvent.Flag;
|
||||||
import google.registry.model.billing.BillingEvent.Reason;
|
import google.registry.model.billing.BillingEvent.Reason;
|
||||||
|
@ -413,18 +412,15 @@ public class XjcToDomainResourceConverterTest {
|
||||||
private static DomainResource convertDomainInTransaction(final XjcRdeDomain xjcDomain) {
|
private static DomainResource convertDomainInTransaction(final XjcRdeDomain xjcDomain) {
|
||||||
return ofy()
|
return ofy()
|
||||||
.transact(
|
.transact(
|
||||||
new Work<DomainResource>() {
|
() -> {
|
||||||
@Override
|
HistoryEntry historyEntry = createHistoryEntryForDomainImport(xjcDomain);
|
||||||
public DomainResource run() {
|
BillingEvent.Recurring autorenewBillingEvent =
|
||||||
HistoryEntry historyEntry = createHistoryEntryForDomainImport(xjcDomain);
|
createAutoRenewBillingEventForDomainImport(xjcDomain, historyEntry);
|
||||||
BillingEvent.Recurring autorenewBillingEvent =
|
PollMessage.Autorenew autorenewPollMessage =
|
||||||
createAutoRenewBillingEventForDomainImport(xjcDomain, historyEntry);
|
createAutoRenewPollMessageForDomainImport(xjcDomain, historyEntry);
|
||||||
PollMessage.Autorenew autorenewPollMessage =
|
ofy().save().entities(historyEntry, autorenewBillingEvent, autorenewPollMessage);
|
||||||
createAutoRenewPollMessageForDomainImport(xjcDomain, historyEntry);
|
return XjcToDomainResourceConverter.convertDomain(
|
||||||
ofy().save().entities(historyEntry, autorenewBillingEvent, autorenewPollMessage);
|
xjcDomain, autorenewBillingEvent, autorenewPollMessage);
|
||||||
return XjcToDomainResourceConverter.convertDomain(
|
|
||||||
xjcDomain, autorenewBillingEvent, autorenewPollMessage);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ import com.google.common.base.Joiner;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.io.ByteSource;
|
import com.google.common.io.ByteSource;
|
||||||
import com.google.common.net.InetAddresses;
|
import com.google.common.net.InetAddresses;
|
||||||
import com.googlecode.objectify.Work;
|
|
||||||
import google.registry.model.eppcommon.StatusValue;
|
import google.registry.model.eppcommon.StatusValue;
|
||||||
import google.registry.model.host.HostResource;
|
import google.registry.model.host.HostResource;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
@ -135,12 +134,7 @@ public class XjcToHostResourceConverterTest extends ShardableTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HostResource convertHostInTransaction(final XjcRdeHost xjcHost) {
|
private static HostResource convertHostInTransaction(final XjcRdeHost xjcHost) {
|
||||||
return ofy().transact(new Work<HostResource>() {
|
return ofy().transact(() -> XjcToHostResourceConverter.convert(xjcHost));
|
||||||
@Override
|
|
||||||
public HostResource run() {
|
|
||||||
return XjcToHostResourceConverter.convert(xjcHost);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private XjcRdeHost loadHostFromRdeXml() throws Exception {
|
private XjcRdeHost loadHostFromRdeXml() throws Exception {
|
||||||
|
|
|
@ -21,7 +21,6 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||||
import static com.google.common.collect.Multimaps.filterKeys;
|
import static com.google.common.collect.Multimaps.filterKeys;
|
||||||
import static com.google.common.collect.Sets.difference;
|
import static com.google.common.collect.Sets.difference;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.model.EntityClasses.CLASS_TO_KIND_FUNCTION;
|
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
import static google.registry.testing.DatastoreHelper.createTld;
|
import static google.registry.testing.DatastoreHelper.createTld;
|
||||||
import static google.registry.testing.DatastoreHelper.persistActiveContact;
|
import static google.registry.testing.DatastoreHelper.persistActiveContact;
|
||||||
|
@ -78,7 +77,7 @@ public class KillAllEppResourcesActionTest extends MapreduceTestCase<KillAllEppR
|
||||||
PollMessage.class,
|
PollMessage.class,
|
||||||
BillingEvent.OneTime.class,
|
BillingEvent.OneTime.class,
|
||||||
BillingEvent.Recurring.class)
|
BillingEvent.Recurring.class)
|
||||||
.map(CLASS_TO_KIND_FUNCTION)
|
.map(Key::getKind)
|
||||||
.collect(toImmutableSet());
|
.collect(toImmutableSet());
|
||||||
|
|
||||||
private void runMapreduce() throws Exception {
|
private void runMapreduce() throws Exception {
|
||||||
|
|
|
@ -291,7 +291,7 @@ public class CidrAddressBlockTest extends TestCase {
|
||||||
Iterator<InetAddress> i = b2.iterator();
|
Iterator<InetAddress> i = b2.iterator();
|
||||||
i.next();
|
i.next();
|
||||||
i.next();
|
i.next();
|
||||||
assertThrows(NoSuchElementException.class, () -> i.next());
|
assertThrows(NoSuchElementException.class, i::next);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSerializability() {
|
public void testSerializability() {
|
||||||
|
|
|
@ -41,8 +41,6 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
/** Unit tests for {@link UrlFetchUtils}. */
|
/** Unit tests for {@link UrlFetchUtils}. */
|
||||||
@RunWith(JUnit4.class)
|
@RunWith(JUnit4.class)
|
||||||
|
@ -62,12 +60,13 @@ public class UrlFetchUtilsTest {
|
||||||
public void setupRandomZeroes() throws Exception {
|
public void setupRandomZeroes() throws Exception {
|
||||||
Random random = mock(Random.class);
|
Random random = mock(Random.class);
|
||||||
inject.setStaticField(UrlFetchUtils.class, "random", random);
|
inject.setStaticField(UrlFetchUtils.class, "random", random);
|
||||||
doAnswer(new Answer<Void>() {
|
doAnswer(
|
||||||
@Override
|
info -> {
|
||||||
public Void answer(InvocationOnMock info) throws Throwable {
|
Arrays.fill((byte[]) info.getArguments()[0], (byte) 0);
|
||||||
Arrays.fill((byte[]) info.getArguments()[0], (byte) 0);
|
return null;
|
||||||
return null;
|
})
|
||||||
}}).when(random).nextBytes(any(byte[].class));
|
.when(random)
|
||||||
|
.nextBytes(any(byte[].class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue