mirror of
https://github.com/google/nomulus.git
synced 2025-05-17 09:57:17 +02:00
Convert domain label list code to use Java 8 streams features
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=172774927
This commit is contained in:
parent
f1c76d035f
commit
4828417c73
4 changed files with 69 additions and 95 deletions
|
@ -16,6 +16,7 @@ package google.registry.model.registry.label;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||||
|
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||||
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
|
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
|
||||||
import static google.registry.model.registry.Registries.getTlds;
|
import static google.registry.model.registry.Registries.getTlds;
|
||||||
|
|
||||||
|
@ -136,14 +137,11 @@ public abstract class BaseDomainLabelList<T extends Comparable<?>, R extends Dom
|
||||||
|
|
||||||
/** Gets the names of the tlds that reference this list. */
|
/** Gets the names of the tlds that reference this list. */
|
||||||
public final ImmutableSet<String> getReferencingTlds() {
|
public final ImmutableSet<String> getReferencingTlds() {
|
||||||
ImmutableSet.Builder<String> builder = new ImmutableSet.Builder<>();
|
|
||||||
Key<? extends BaseDomainLabelList<?, ?>> key = Key.create(this);
|
Key<? extends BaseDomainLabelList<?, ?>> key = Key.create(this);
|
||||||
for (String tld : getTlds()) {
|
return getTlds()
|
||||||
if (refersToKey(Registry.get(tld), key)) {
|
.stream()
|
||||||
builder.add(tld);
|
.filter((tld) -> refersToKey(Registry.get(tld), key))
|
||||||
}
|
.collect(toImmutableSet());
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract boolean refersToKey(
|
protected abstract boolean refersToKey(
|
||||||
|
|
|
@ -33,7 +33,6 @@ import com.google.common.cache.LoadingCache;
|
||||||
import com.google.common.hash.BloomFilter;
|
import com.google.common.hash.BloomFilter;
|
||||||
import com.google.common.util.concurrent.UncheckedExecutionException;
|
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||||
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 com.googlecode.objectify.annotation.Parent;
|
import com.googlecode.objectify.annotation.Parent;
|
||||||
|
@ -113,13 +112,12 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
|
||||||
// encoding on them.
|
// encoding on them.
|
||||||
revision.probablePremiumLabels =
|
revision.probablePremiumLabels =
|
||||||
BloomFilter.create(unencodedCharsFunnel(), premiumLabels.size());
|
BloomFilter.create(unencodedCharsFunnel(), premiumLabels.size());
|
||||||
for (String label : premiumLabels) {
|
premiumLabels.forEach(revision.probablePremiumLabels::put);
|
||||||
revision.probablePremiumLabels.put(label);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
revision.probablePremiumLabels.writeTo(bos);
|
revision.probablePremiumLabels.writeTo(bos);
|
||||||
checkArgument(bos.size() <= MAX_BLOOM_FILTER_BYTES,
|
checkArgument(
|
||||||
|
bos.size() <= MAX_BLOOM_FILTER_BYTES,
|
||||||
"Too many premium labels were specified; Bloom filter exceeds max entity size");
|
"Too many premium labels were specified; Bloom filter exceeds max entity size");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IllegalStateException("Could not serialize premium labels Bloom filter", e);
|
throw new IllegalStateException("Could not serialize premium labels Bloom filter", e);
|
||||||
|
@ -137,26 +135,28 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
|
||||||
static final LoadingCache<String, PremiumList> cachePremiumLists =
|
static final LoadingCache<String, PremiumList> cachePremiumLists =
|
||||||
CacheBuilder.newBuilder()
|
CacheBuilder.newBuilder()
|
||||||
.expireAfterWrite(getDomainLabelListCacheDuration().getMillis(), MILLISECONDS)
|
.expireAfterWrite(getDomainLabelListCacheDuration().getMillis(), MILLISECONDS)
|
||||||
.build(new CacheLoader<String, PremiumList>() {
|
.build(
|
||||||
|
new CacheLoader<String, PremiumList>() {
|
||||||
@Override
|
@Override
|
||||||
public PremiumList load(final String listName) {
|
public PremiumList load(final String listName) {
|
||||||
return ofy().doTransactionless(new Work<PremiumList>() {
|
return ofy()
|
||||||
@Override
|
.doTransactionless(
|
||||||
public PremiumList run() {
|
() ->
|
||||||
return ofy().load()
|
ofy()
|
||||||
|
.load()
|
||||||
.type(PremiumList.class)
|
.type(PremiumList.class)
|
||||||
.parent(getCrossTldKey())
|
.parent(getCrossTldKey())
|
||||||
.id(listName)
|
.id(listName)
|
||||||
.now();
|
.now());
|
||||||
}});
|
}
|
||||||
}});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In-memory cache for {@link PremiumListRevision}s, used for retrieving Bloom filters quickly.
|
* In-memory cache for {@link PremiumListRevision}s, used for retrieving Bloom filters quickly.
|
||||||
*
|
*
|
||||||
* <p>This is cached for a long duration (essentially indefinitely) because a given
|
* <p>This is cached for a long duration (essentially indefinitely) because a given {@link
|
||||||
* {@link PremiumListRevision} is immutable and cannot ever be changed once created, so its cache
|
* PremiumListRevision} is immutable and cannot ever be changed once created, so its cache need
|
||||||
* need not ever expire.
|
* not ever expire.
|
||||||
*/
|
*/
|
||||||
static final LoadingCache<Key<PremiumListRevision>, PremiumListRevision>
|
static final LoadingCache<Key<PremiumListRevision>, PremiumListRevision>
|
||||||
cachePremiumListRevisions =
|
cachePremiumListRevisions =
|
||||||
|
@ -166,14 +166,9 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
|
||||||
new CacheLoader<Key<PremiumListRevision>, PremiumListRevision>() {
|
new CacheLoader<Key<PremiumListRevision>, PremiumListRevision>() {
|
||||||
@Override
|
@Override
|
||||||
public PremiumListRevision load(final Key<PremiumListRevision> revisionKey) {
|
public PremiumListRevision load(final Key<PremiumListRevision> revisionKey) {
|
||||||
return ofy()
|
return ofy().doTransactionless(() -> ofy().load().key(revisionKey).now());
|
||||||
.doTransactionless(
|
}
|
||||||
new Work<PremiumListRevision>() {
|
});
|
||||||
@Override
|
|
||||||
public PremiumListRevision run() {
|
|
||||||
return ofy().load().key(revisionKey).now();
|
|
||||||
}});
|
|
||||||
}});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In-memory cache for {@link PremiumListEntry}s for a given label and {@link PremiumListRevision}
|
* In-memory cache for {@link PremiumListEntry}s for a given label and {@link PremiumListRevision}
|
||||||
|
@ -206,10 +201,7 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
|
||||||
@Override
|
@Override
|
||||||
public Optional<PremiumListEntry> load(final Key<PremiumListEntry> entryKey) {
|
public Optional<PremiumListEntry> load(final Key<PremiumListEntry> entryKey) {
|
||||||
return ofy()
|
return ofy()
|
||||||
.doTransactionless(
|
.doTransactionless(() -> Optional.ofNullable(ofy().load().key(entryKey).now()));
|
||||||
() -> {
|
|
||||||
return Optional.ofNullable(ofy().load().key(entryKey).now());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
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.google.common.collect.Sets;
|
||||||
import com.google.common.net.InternetDomainName;
|
import com.google.common.net.InternetDomainName;
|
||||||
import com.google.common.util.concurrent.UncheckedExecutionException;
|
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
|
@ -45,7 +46,6 @@ import com.googlecode.objectify.annotation.Mapify;
|
||||||
import com.googlecode.objectify.mapper.Mapper;
|
import com.googlecode.objectify.mapper.Mapper;
|
||||||
import google.registry.model.registry.Registry;
|
import google.registry.model.registry.Registry;
|
||||||
import google.registry.model.registry.label.DomainLabelMetrics.MetricsReservedListMatch;
|
import google.registry.model.registry.label.DomainLabelMetrics.MetricsReservedListMatch;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -96,6 +96,7 @@ public final class ReservedList
|
||||||
|
|
||||||
/** Mapper for use with @Mapify */
|
/** Mapper for use with @Mapify */
|
||||||
static class LabelMapper implements Mapper<String, ReservedListEntry> {
|
static class LabelMapper implements Mapper<String, ReservedListEntry> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getKey(ReservedListEntry entry) {
|
public String getKey(ReservedListEntry entry) {
|
||||||
return entry.getLabel();
|
return entry.getLabel();
|
||||||
|
@ -130,7 +131,8 @@ public final class ReservedList
|
||||||
entry.allowedNameservers = Joiner.on(',').join(allowedNameservers);
|
entry.allowedNameservers = Joiner.on(',').join(allowedNameservers);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
checkArgument(reservationType != RESERVED_FOR_ANCHOR_TENANT,
|
checkArgument(
|
||||||
|
reservationType != RESERVED_FOR_ANCHOR_TENANT,
|
||||||
"Anchor tenant reservations must have an auth code configured");
|
"Anchor tenant reservations must have an auth code configured");
|
||||||
checkArgument(
|
checkArgument(
|
||||||
reservationType != NAMESERVER_RESTRICTED,
|
reservationType != NAMESERVER_RESTRICTED,
|
||||||
|
@ -143,13 +145,13 @@ public final class ReservedList
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkNameserversAreValid(Set<String> nameservers) {
|
private static void checkNameserversAreValid(Set<String> nameservers) {
|
||||||
for (String nameserver : nameservers) {
|
|
||||||
// A domain name with fewer than two parts cannot be a hostname, as a nameserver should be.
|
// A domain name with fewer than two parts cannot be a hostname, as a nameserver should be.
|
||||||
|
nameservers.forEach(
|
||||||
|
(ns) ->
|
||||||
checkArgument(
|
checkArgument(
|
||||||
InternetDomainName.from(nameserver).parts().size() >= 3,
|
InternetDomainName.from(ns).parts().size() >= 3,
|
||||||
"%s is not a valid nameserver hostname",
|
"%s is not a valid nameserver hostname",
|
||||||
nameserver);
|
ns));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -218,7 +220,7 @@ public final class ReservedList
|
||||||
}
|
}
|
||||||
return getReservedListEntries(label, tld)
|
return getReservedListEntries(label, tld)
|
||||||
.stream()
|
.stream()
|
||||||
.map((ReservedListEntry reservedListEntry) -> reservedListEntry.reservationType)
|
.map(ReservedListEntry::getValue)
|
||||||
.collect(toImmutableSet());
|
.collect(toImmutableSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,15 +232,13 @@ public final class ReservedList
|
||||||
*/
|
*/
|
||||||
public static boolean matchesAnchorTenantReservation(
|
public static boolean matchesAnchorTenantReservation(
|
||||||
InternetDomainName domainName, String authCode) {
|
InternetDomainName domainName, String authCode) {
|
||||||
ImmutableSet<ReservedListEntry> entries =
|
|
||||||
getReservedListEntries(domainName.parts().get(0), domainName.parent().toString());
|
|
||||||
|
|
||||||
Set<String> domainAuthCodes = new HashSet<>();
|
ImmutableSet<String> domainAuthCodes =
|
||||||
for (ReservedListEntry entry : entries) {
|
getReservedListEntries(domainName.parts().get(0), domainName.parent().toString())
|
||||||
if (entry.reservationType == RESERVED_FOR_ANCHOR_TENANT) {
|
.stream()
|
||||||
domainAuthCodes.add(entry.getAuthCode());
|
.filter((entry) -> entry.reservationType == RESERVED_FOR_ANCHOR_TENANT)
|
||||||
}
|
.map(ReservedListEntry::getAuthCode)
|
||||||
}
|
.collect(toImmutableSet());
|
||||||
checkState(
|
checkState(
|
||||||
domainAuthCodes.size() <= 1, "There are conflicting auth codes for domain: %s", domainName);
|
domainAuthCodes.size() <= 1, "There are conflicting auth codes for domain: %s", domainName);
|
||||||
|
|
||||||
|
@ -253,22 +253,13 @@ public final class ReservedList
|
||||||
* domain is not set with {@code NAMESERVER_RESTRICTED} reservation type.
|
* domain is not set with {@code NAMESERVER_RESTRICTED} reservation type.
|
||||||
*/
|
*/
|
||||||
public static ImmutableSet<String> getAllowedNameservers(InternetDomainName domainName) {
|
public static ImmutableSet<String> getAllowedNameservers(InternetDomainName domainName) {
|
||||||
HashSet<String> allowedNameservers = new HashSet<>();
|
return getReservedListEntries(domainName.parts().get(0), domainName.parent().toString())
|
||||||
boolean foundFirstNameserverRestricted = false;
|
.stream()
|
||||||
for (ReservedListEntry entry :
|
.filter((entry) -> entry.reservationType == NAMESERVER_RESTRICTED)
|
||||||
getReservedListEntries(domainName.parts().get(0), domainName.parent().toString())) {
|
.map(ReservedListEntry::getAllowedNameservers)
|
||||||
if (entry.reservationType == NAMESERVER_RESTRICTED) {
|
.reduce((types1, types2) -> Sets.intersection(types1, types2).immutableCopy())
|
||||||
if (foundFirstNameserverRestricted) {
|
.orElse(ImmutableSet.of());
|
||||||
allowedNameservers.retainAll(entry.getAllowedNameservers());
|
|
||||||
} else {
|
|
||||||
allowedNameservers = new HashSet<String>(entry.getAllowedNameservers());
|
|
||||||
foundFirstNameserverRestricted = true;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return ImmutableSet.copyOf(allowedNameservers);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to retrieve the entries associated with this label and TLD, or an empty set if
|
* Helper function to retrieve the entries associated with this label and TLD, or an empty set if
|
||||||
|
@ -276,15 +267,13 @@ public final class ReservedList
|
||||||
*/
|
*/
|
||||||
private static ImmutableSet<ReservedListEntry> getReservedListEntries(String label, String tld) {
|
private static ImmutableSet<ReservedListEntry> getReservedListEntries(String label, String tld) {
|
||||||
DateTime startTime = DateTime.now(UTC);
|
DateTime startTime = DateTime.now(UTC);
|
||||||
Registry registry = Registry.get(checkNotNull(tld, "tld"));
|
Registry registry = Registry.get(checkNotNull(tld, "tld must not be null"));
|
||||||
ImmutableSet<Key<ReservedList>> reservedLists = registry.getReservedLists();
|
|
||||||
ImmutableSet<ReservedList> lists = loadReservedLists(reservedLists);
|
|
||||||
ImmutableSet.Builder<ReservedListEntry> entriesBuilder = new ImmutableSet.Builder<>();
|
ImmutableSet.Builder<ReservedListEntry> entriesBuilder = new ImmutableSet.Builder<>();
|
||||||
ImmutableSet.Builder<MetricsReservedListMatch> metricMatchesBuilder =
|
ImmutableSet.Builder<MetricsReservedListMatch> metricMatchesBuilder =
|
||||||
new ImmutableSet.Builder<>();
|
new ImmutableSet.Builder<>();
|
||||||
|
|
||||||
// Loop through all reservation lists and add each of them.
|
// Loop through all reservation lists and add each of them.
|
||||||
for (ReservedList rl : lists) {
|
for (ReservedList rl : loadReservedLists(registry.getReservedLists())) {
|
||||||
if (rl.getReservedListEntries().containsKey(label)) {
|
if (rl.getReservedListEntries().containsKey(label)) {
|
||||||
ReservedListEntry entry = rl.getReservedListEntries().get(label);
|
ReservedListEntry entry = rl.getReservedListEntries().get(label);
|
||||||
entriesBuilder.add(entry);
|
entriesBuilder.add(entry);
|
||||||
|
@ -300,17 +289,20 @@ public final class ReservedList
|
||||||
|
|
||||||
private static ImmutableSet<ReservedList> loadReservedLists(
|
private static ImmutableSet<ReservedList> loadReservedLists(
|
||||||
ImmutableSet<Key<ReservedList>> reservedListKeys) {
|
ImmutableSet<Key<ReservedList>> reservedListKeys) {
|
||||||
ImmutableSet.Builder<ReservedList> builder = new ImmutableSet.Builder<>();
|
return reservedListKeys
|
||||||
for (Key<ReservedList> listKey : reservedListKeys) {
|
.stream()
|
||||||
|
.map(
|
||||||
|
(listKey) -> {
|
||||||
try {
|
try {
|
||||||
builder.add(cache.get(listKey.getName()));
|
return cache.get(listKey.getName());
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
throw new UncheckedExecutionException(String.format(
|
throw new UncheckedExecutionException(
|
||||||
"Could not load the reserved list '%s' from the cache", listKey.getName()), e);
|
String.format(
|
||||||
|
"Could not load the reserved list '%s' from the cache", listKey.getName()),
|
||||||
|
e);
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
.collect(toImmutableSet());
|
||||||
return builder.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LoadingCache<String, ReservedList> cache =
|
private static LoadingCache<String, ReservedList> cache =
|
||||||
|
|
|
@ -16,18 +16,14 @@ package google.registry.model.registry.label;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static com.google.common.truth.Truth.assertWithMessage;
|
import static com.google.common.truth.Truth.assertWithMessage;
|
||||||
import static com.google.common.truth.Truth8.assertThat;
|
|
||||||
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.persistPremiumList;
|
import static google.registry.testing.DatastoreHelper.persistPremiumList;
|
||||||
import static google.registry.testing.DatastoreHelper.persistReservedList;
|
import static google.registry.testing.DatastoreHelper.persistReservedList;
|
||||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import google.registry.model.registry.Registry;
|
import google.registry.model.registry.Registry;
|
||||||
import google.registry.model.registry.label.PremiumList.PremiumListEntry;
|
|
||||||
import google.registry.model.registry.label.PremiumList.PremiumListRevision;
|
import google.registry.model.registry.label.PremiumList.PremiumListRevision;
|
||||||
import google.registry.testing.AppEngineRule;
|
import google.registry.testing.AppEngineRule;
|
||||||
import google.registry.testing.ExceptionRule;
|
import google.registry.testing.ExceptionRule;
|
||||||
|
@ -93,8 +89,4 @@ public class PremiumListTest {
|
||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
"lol,USD 100", "rofl,USD 90", "paper,USD 80", "wood,USD 70", "lol,USD 200"));
|
"lol,USD 100", "rofl,USD 90", "paper,USD 80", "wood,USD 70", "lol,USD 200"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the label of a premium list entry. */
|
|
||||||
public static final Function<Key<PremiumListEntry>, String> GET_ENTRY_NAME_FUNCTION =
|
|
||||||
Key::getName;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue