Convert StaticIpResolver to kotlin.
This commit is contained in:
parent
21deb6803c
commit
ce4b7c2d7f
3 changed files with 97 additions and 78 deletions
|
@ -1,5 +1,7 @@
|
|||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm" version "1.8.0"
|
||||
id "java-library"
|
||||
id "org.jlleitschuh.gradle.ktlint" version "11.1.0"
|
||||
}
|
||||
|
||||
java {
|
||||
|
@ -7,6 +9,13 @@ java {
|
|||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
// NOTE: For now, in order to run ktlint on this project, you have to manually run ./gradlew :build-logic:tools:ktlintFormat
|
||||
// Gotta figure out how to get it auto-included in the normal ./gradlew ktlintFormat
|
||||
ktlint {
|
||||
// Use a newer version to resolve https://github.com/JLLeitschuh/ktlint-gradle/issues/507
|
||||
version = "0.47.1"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation libs.dnsjava
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
package org.signal.buildtools;
|
||||
|
||||
import org.xbill.DNS.ARecord;
|
||||
import org.xbill.DNS.Lookup;
|
||||
import org.xbill.DNS.Record;
|
||||
import org.xbill.DNS.Resolver;
|
||||
import org.xbill.DNS.SimpleResolver;
|
||||
import org.xbill.DNS.Type;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class StaticIpResolver {
|
||||
|
||||
private StaticIpResolver() {}
|
||||
|
||||
public static String resolveToBuildConfig(String hostName) {
|
||||
String[] ips = resolve(hostName);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("new String[]{");
|
||||
for (int i = 0; i < ips.length; i++) {
|
||||
builder.append("\"").append(ips[i]).append("\"");
|
||||
if (i < ips.length - 1) {
|
||||
builder.append(",");
|
||||
}
|
||||
}
|
||||
return builder.append("}").toString();
|
||||
}
|
||||
|
||||
private static String[] resolve(String hostname) {
|
||||
Set<String> ips = new HashSet<>();
|
||||
|
||||
// Run several resolves to mitigate DNS round robin
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ips.addAll(resolveOnce(hostname));
|
||||
}
|
||||
|
||||
return ips.stream().sorted().toArray(String[]::new);
|
||||
}
|
||||
|
||||
private static List<String> resolveOnce(String hostName) {
|
||||
try {
|
||||
Resolver resolver = new SimpleResolver("1.1.1.1");
|
||||
Lookup lookup = doLookup(hostName);
|
||||
|
||||
lookup.setResolver(resolver);
|
||||
|
||||
Record[] records = lookup.run();
|
||||
|
||||
if (records != null) {
|
||||
return Arrays.stream(records)
|
||||
.filter(r -> r.getType() == Type.A)
|
||||
.map(r -> (ARecord) r)
|
||||
.map(ARecord::getAddress)
|
||||
.map(InetAddress::getHostAddress)
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
throw new IllegalStateException("Failed to resolve host! " + hostName);
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
throw new IllegalStateException("Failed to resolve host! " + hostName);
|
||||
}
|
||||
}
|
||||
|
||||
private static Lookup doLookup(String hostname) throws UnknownHostException {
|
||||
try {
|
||||
return new Lookup(hostname);
|
||||
} catch (Throwable e) {
|
||||
throw new UnknownHostException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package org.signal.buildtools
|
||||
|
||||
import org.xbill.DNS.ARecord
|
||||
import org.xbill.DNS.Lookup
|
||||
import org.xbill.DNS.Record
|
||||
import org.xbill.DNS.SimpleResolver
|
||||
import org.xbill.DNS.Type
|
||||
import java.net.UnknownHostException
|
||||
import kotlin.streams.toList
|
||||
|
||||
/**
|
||||
* A tool to resolve hostname to static IPs.
|
||||
* Feeds into our custom DNS resolver to provide a static IP fallback for our services.
|
||||
*/
|
||||
object StaticIpResolver {
|
||||
|
||||
/**
|
||||
* Resolves a hostname to a list of IPs, represented as a Java array declaration. e.g.
|
||||
*
|
||||
* ```java
|
||||
* new String[]{"192.168.1.1", "192.168.1.2"}
|
||||
* ```
|
||||
*
|
||||
* This is intended to be injected as a BuildConfig.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun resolveToBuildConfig(hostName: String): String {
|
||||
val ips: List<String> = resolve(hostName)
|
||||
val builder = StringBuilder()
|
||||
|
||||
builder.append("new String[]{")
|
||||
|
||||
ips.forEachIndexed { i, ip ->
|
||||
builder.append("\"").append(ip).append("\"")
|
||||
|
||||
if (i < ips.size - 1) {
|
||||
builder.append(",")
|
||||
}
|
||||
}
|
||||
|
||||
return builder.append("}").toString()
|
||||
}
|
||||
|
||||
private fun resolve(hostname: String): List<String> {
|
||||
val ips: MutableSet<String> = mutableSetOf()
|
||||
|
||||
// Run several resolves to mitigate DNS round robin
|
||||
for (i in 1..10) {
|
||||
ips.addAll(resolveOnce(hostname))
|
||||
}
|
||||
|
||||
return ips.stream().sorted().toList()
|
||||
}
|
||||
|
||||
private fun resolveOnce(hostName: String): List<String> {
|
||||
try {
|
||||
val resolver = SimpleResolver("1.1.1.1")
|
||||
val lookup: Lookup = doLookup(hostName)
|
||||
|
||||
lookup.setResolver(resolver)
|
||||
|
||||
val records: Array<Record>? = lookup.run()
|
||||
|
||||
if (records != null) {
|
||||
return records
|
||||
.filter { it.type == Type.A }
|
||||
.map { it as ARecord }
|
||||
.map { it.address }
|
||||
.map { it.hostAddress }
|
||||
.filterNotNull()
|
||||
} else {
|
||||
throw IllegalStateException("Failed to resolve host! $hostName")
|
||||
}
|
||||
} catch (e: UnknownHostException) {
|
||||
throw IllegalStateException("Failed to resolve host! $hostName")
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(UnknownHostException::class)
|
||||
private fun doLookup(hostname: String): Lookup {
|
||||
try {
|
||||
return Lookup(hostname)
|
||||
} catch (e: Throwable) {
|
||||
throw UnknownHostException()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue