denominator.dynect.DynECTGeoResourceRecordSetApi Maven / Gradle / Ivy
package denominator.dynect;
import com.google.gson.JsonElement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.inject.Inject;
import javax.inject.Named;
import dagger.Lazy;
import denominator.common.Filter;
import denominator.dynect.DynECT.GeoService;
import denominator.dynect.DynECT.GeoService.GeoRegionGroup;
import denominator.dynect.DynECT.GeoService.Node;
import denominator.model.ResourceRecordSet;
import denominator.model.ResourceRecordSet.Builder;
import denominator.model.profile.Geo;
import denominator.model.profile.Weighted;
import denominator.profile.GeoResourceRecordSetApi;
import static denominator.common.Preconditions.checkNotNull;
import static denominator.common.Util.and;
import static denominator.common.Util.filter;
import static denominator.common.Util.nextOrNull;
import static denominator.model.ResourceRecordSets.nameAndTypeEqualTo;
import static denominator.model.ResourceRecordSets.nameEqualTo;
import static denominator.model.ResourceRecordSets.nameTypeAndQualifierEqualTo;
public final class DynECTGeoResourceRecordSetApi implements GeoResourceRecordSetApi {
private static final Filter> IS_GEO = new Filter>() {
@Override
public boolean apply(ResourceRecordSet> in) {
return in != null && in.geo() != null;
}
};
private final Map> regions;
private final ToBuilders toBuilders;
private final DynECT api;
private final String zoneFQDN;
DynECTGeoResourceRecordSetApi(Map> regions, DynECT api,
String zoneFQDN) {
this.regions = regions;
this.toBuilders = new ToBuilders(regions);
this.api = api;
this.zoneFQDN = zoneFQDN;
}
@Override
public Map> supportedRegions() {
return regions;
}
@Override
public Iterator> iterator() {
Map>>
rrsets =
new LinkedHashMap>>();
for (GeoService geo : api.geoServices().data) {
for (GeoRegionGroup geoGroup : geo.groups) {
for (Builder> rrset : toBuilders.apply(geoGroup)) {
for (Node node : geo.nodes) {
if (!rrsets.containsKey(node.zone)) {
rrsets.put(node.zone, new ArrayList>());
}
rrsets.get(node.zone).add(rrset.name(node.fqdn).build());
}
}
}
}
Collection> val = rrsets.get(zoneFQDN);
return val != null ? val.iterator() : Collections.>emptyList().iterator();
}
@Override
public Iterator> iterateByName(String name) {
return filter(iterator(), and(nameEqualTo(name), IS_GEO));
}
@Override
public Iterator> iterateByNameAndType(String name, String type) {
return filter(iterator(), and(nameAndTypeEqualTo(name, type), IS_GEO));
}
@Override
public ResourceRecordSet> getByNameTypeAndQualifier(String name, String type,
String qualifier) {
return nextOrNull(
filter(iterator(), and(nameTypeAndQualifierEqualTo(name, type, qualifier), IS_GEO)));
}
@Override
public void put(ResourceRecordSet> rrset) {
throw new UnsupportedOperationException();
}
@Override
public void deleteByNameTypeAndQualifier(String name, String type, String qualifier) {
throw new UnsupportedOperationException();
}
static final class Factory implements GeoResourceRecordSetApi.Factory {
private final Map> regions;
private final Lazy hasAllGeoPermissions;
private final DynECT api;
@Inject
Factory(@Named("geo") Map> regions,
@Named("hasAllGeoPermissions") Lazy hasAllGeoPermissions, DynECT api) {
this.regions = regions;
this.hasAllGeoPermissions = hasAllGeoPermissions;
this.api = api;
}
@Override
public GeoResourceRecordSetApi create(String idOrName) {
checkNotNull(idOrName, "idOrName was null");
if (!hasAllGeoPermissions.get()) {
return null;
}
return new DynECTGeoResourceRecordSetApi(regions, api, idOrName);
}
}
private static class ToBuilders {
private final Map> regions;
private final Map countryToRegions;
private ToBuilders(Map> regions) {
this.regions = regions;
Map countryToRegions = new HashMap(regions.values().size());
for (Entry> entry : regions.entrySet()) {
for (String country : entry.getValue()) {
countryToRegions.put(country, entry.getKey());
}
}
this.countryToRegions = countryToRegions;
}
public List> apply(GeoRegionGroup creepyGeoRegionGroup) {
List> rrsets = new ArrayList>();
Geo geo = Geo.create(indexCountries(creepyGeoRegionGroup.countries));
for (Entry> entry : creepyGeoRegionGroup.rdata.entrySet()) {
if (entry.getValue().isEmpty()) {
continue;
}
// ex. spf_rdata -> SPF
String type = entry.getKey().substring(0, entry.getKey().indexOf('_')).toUpperCase();
// ex. dhcid_ttl
int ttl = creepyGeoRegionGroup.ttl.get(type.toLowerCase() + "_ttl");
ResourceRecordSet.Builder