mirror of
https://github.com/apple/pkl.git
synced 2026-07-09 22:52:44 +02:00
Clean up http-client changes (#295)
* pkl-excutor tests: symlink 0.25.0 distribution into pkl-executable/build * Use `IoUtils.getPklHomeDir` in HttpClientBuilder * Simplify Exceptions.java * Enable testing for older pkl-executor distribution
This commit is contained in:
@@ -26,24 +26,26 @@ import java.util.List;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import org.pkl.core.Release;
|
import org.pkl.core.Release;
|
||||||
import org.pkl.core.util.ErrorMessages;
|
import org.pkl.core.util.ErrorMessages;
|
||||||
|
import org.pkl.core.util.IoUtils;
|
||||||
|
|
||||||
final class HttpClientBuilder implements HttpClient.Builder {
|
final class HttpClientBuilder implements HttpClient.Builder {
|
||||||
private final Path userHome;
|
|
||||||
private String userAgent;
|
private String userAgent;
|
||||||
private Duration connectTimeout = Duration.ofSeconds(60);
|
private Duration connectTimeout = Duration.ofSeconds(60);
|
||||||
private Duration requestTimeout = Duration.ofSeconds(60);
|
private Duration requestTimeout = Duration.ofSeconds(60);
|
||||||
|
private final Path caCertsDir;
|
||||||
private final List<Path> certificateFiles = new ArrayList<>();
|
private final List<Path> certificateFiles = new ArrayList<>();
|
||||||
private final List<URI> certificateUris = new ArrayList<>();
|
private final List<URI> certificateUris = new ArrayList<>();
|
||||||
|
|
||||||
HttpClientBuilder() {
|
HttpClientBuilder() {
|
||||||
this(Path.of(System.getProperty("user.home")));
|
this(IoUtils.getPklHomeDir().resolve("cacerts"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// only exists for testing
|
// only exists for testing
|
||||||
HttpClientBuilder(Path userHome) {
|
HttpClientBuilder(Path caCertsDir) {
|
||||||
this.userHome = userHome;
|
|
||||||
var release = Release.current();
|
var release = Release.current();
|
||||||
userAgent = "Pkl/" + release.version() + " (" + release.os() + "; " + release.flavor() + ")";
|
this.caCertsDir = caCertsDir;
|
||||||
|
this.userAgent =
|
||||||
|
"Pkl/" + release.version() + " (" + release.os() + "; " + release.flavor() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpClient.Builder setUserAgent(String userAgent) {
|
public HttpClient.Builder setUserAgent(String userAgent) {
|
||||||
@@ -80,10 +82,9 @@ final class HttpClientBuilder implements HttpClient.Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public HttpClient.Builder addDefaultCliCertificates() {
|
public HttpClient.Builder addDefaultCliCertificates() {
|
||||||
var directory = userHome.resolve(".pkl").resolve("cacerts");
|
|
||||||
var fileCount = certificateFiles.size();
|
var fileCount = certificateFiles.size();
|
||||||
if (Files.isDirectory(directory)) {
|
if (Files.isDirectory(caCertsDir)) {
|
||||||
try (var files = Files.list(directory)) {
|
try (var files = Files.list(caCertsDir)) {
|
||||||
files.filter(Files::isRegularFile).forEach(certificateFiles::add);
|
files.filter(Files::isRegularFile).forEach(certificateFiles::add);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new HttpClientInitException(e);
|
throw new HttpClientInitException(e);
|
||||||
|
|||||||
@@ -132,11 +132,18 @@ public class ExecutorSpiImpl implements ExecutorSpi {
|
|||||||
private HttpClient getOrCreateHttpClient(ExecutorSpiOptions options) {
|
private HttpClient getOrCreateHttpClient(ExecutorSpiOptions options) {
|
||||||
List<Path> certificateFiles;
|
List<Path> certificateFiles;
|
||||||
List<URI> certificateUris;
|
List<URI> certificateUris;
|
||||||
if (options instanceof ExecutorSpiOptions2) {
|
try {
|
||||||
var options2 = (ExecutorSpiOptions2) options;
|
if (options instanceof ExecutorSpiOptions2) {
|
||||||
certificateFiles = options2.getCertificateFiles();
|
var options2 = (ExecutorSpiOptions2) options;
|
||||||
certificateUris = options2.getCertificateUris();
|
certificateFiles = options2.getCertificateFiles();
|
||||||
} else {
|
certificateUris = options2.getCertificateUris();
|
||||||
|
} else {
|
||||||
|
certificateFiles = List.of();
|
||||||
|
certificateUris = List.of();
|
||||||
|
}
|
||||||
|
// host pkl-executor does not have class ExecutorOptions2 defined.
|
||||||
|
// this will happen if the pkl-executor distribution is too old.
|
||||||
|
} catch (NoClassDefFoundError e) {
|
||||||
certificateFiles = List.of();
|
certificateFiles = List.of();
|
||||||
certificateUris = List.of();
|
certificateUris = List.of();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,8 @@ public final class Exceptions {
|
|||||||
|
|
||||||
public static Throwable getRootCause(Throwable t) {
|
public static Throwable getRootCause(Throwable t) {
|
||||||
var result = t;
|
var result = t;
|
||||||
var cause = result.getCause();
|
while (result.getCause() != null) {
|
||||||
while (cause != null) {
|
result = result.getCause();
|
||||||
result = cause;
|
|
||||||
cause = cause.getCause();
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,21 +103,22 @@ class HttpClientTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `can load certificates from Pkl user home cacerts directory`(@TempDir tempDir: Path) {
|
fun `can load certificates from Pkl user home cacerts directory`(@TempDir tempDir: Path) {
|
||||||
val certFile = tempDir.resolve(".pkl")
|
val certsDir = tempDir.resolve(".pkl")
|
||||||
.resolve("cacerts")
|
.resolve("cacerts")
|
||||||
.createDirectories()
|
.createDirectories()
|
||||||
.resolve("certs.pem")
|
.also { dir ->
|
||||||
FileTestUtils.selfSignedCertificate.copyTo(certFile)
|
FileTestUtils.selfSignedCertificate.copyTo(dir.resolve("certs.pem"))
|
||||||
|
}
|
||||||
|
|
||||||
assertDoesNotThrow {
|
assertDoesNotThrow {
|
||||||
HttpClientBuilder(tempDir).addDefaultCliCertificates().build()
|
HttpClientBuilder(certsDir).addDefaultCliCertificates().build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `loading certificates from cacerts directory falls back to built-in certificates`(@TempDir userHome: Path) {
|
fun `loading certificates from cacerts directory falls back to built-in certificates`(@TempDir certsDir: Path) {
|
||||||
assertDoesNotThrow {
|
assertDoesNotThrow {
|
||||||
HttpClientBuilder(userHome).addDefaultCliCertificates().build()
|
HttpClientBuilder(certsDir).addDefaultCliCertificates().build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import java.nio.file.Files
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
pklAllProjects
|
pklAllProjects
|
||||||
pklJavaLibrary
|
pklJavaLibrary
|
||||||
@@ -6,7 +8,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val pklDistributionCurrent: Configuration by configurations.creating
|
val pklDistributionCurrent: Configuration by configurations.creating
|
||||||
val pklDistribution025: Configuration by configurations.creating
|
val pklHistoricalDistributions: Configuration by configurations.creating
|
||||||
|
|
||||||
// Because pkl-executor doesn't depend on other Pkl modules
|
// Because pkl-executor doesn't depend on other Pkl modules
|
||||||
// (nor has overlapping dependencies that could cause a version conflict),
|
// (nor has overlapping dependencies that could cause a version conflict),
|
||||||
@@ -15,7 +17,7 @@ val pklDistribution025: Configuration by configurations.creating
|
|||||||
dependencies {
|
dependencies {
|
||||||
pklDistributionCurrent(project(":pkl-config-java", "fatJar"))
|
pklDistributionCurrent(project(":pkl-config-java", "fatJar"))
|
||||||
@Suppress("UnstableApiUsage")
|
@Suppress("UnstableApiUsage")
|
||||||
pklDistribution025(libs.pklConfigJavaAll025)
|
pklHistoricalDistributions(libs.pklConfigJavaAll025)
|
||||||
|
|
||||||
implementation(libs.slf4jApi)
|
implementation(libs.slf4jApi)
|
||||||
|
|
||||||
@@ -52,14 +54,29 @@ sourceSets {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this task could be folded into tasks.test by switching to IntelliJ's Gradle test runner
|
val prepareHistoricalDistributions by tasks.registering {
|
||||||
|
val outputDir = layout.buildDirectory.dir("pklHistoricalDistributions")
|
||||||
|
inputs.files(pklHistoricalDistributions.files())
|
||||||
|
outputs.dir(outputDir)
|
||||||
|
doLast {
|
||||||
|
val distributionDir = outputDir.get().asFile.toPath()
|
||||||
|
.also(Files::createDirectories)
|
||||||
|
for (file in pklHistoricalDistributions.files) {
|
||||||
|
val link = distributionDir.resolve(file.name)
|
||||||
|
if (!Files.isSymbolicLink(link)) {
|
||||||
|
if (Files.exists(link)) {
|
||||||
|
Files.delete(link)
|
||||||
|
}
|
||||||
|
Files.createSymbolicLink(link, file.toPath())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val prepareTest by tasks.registering {
|
val prepareTest by tasks.registering {
|
||||||
// used by EmbeddedExecutorTest
|
dependsOn(pklDistributionCurrent, prepareHistoricalDistributions)
|
||||||
dependsOn(pklDistributionCurrent, pklDistribution025)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.test {
|
tasks.test {
|
||||||
dependsOn(prepareTest)
|
dependsOn(prepareTest)
|
||||||
systemProperty("pklDistributionCurrent", pklDistributionCurrent.singleFile)
|
|
||||||
systemProperty("pklDistribution025", pklDistribution025.singleFile)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class EmbeddedExecutorTest {
|
|||||||
|
|
||||||
// This context has a pkl-executor version that is lower than the distribution version.
|
// This context has a pkl-executor version that is lower than the distribution version.
|
||||||
// It can be enabled once there is a distribution that includes pkl-executor.
|
// It can be enabled once there is a distribution that includes pkl-executor.
|
||||||
//ExecutionContext(executor1_2.value, ::convertToOptions1, "Options1, Executor1, Distribution2"),
|
ExecutionContext(executor1_2.value, ::convertToOptions1, "Options1, Executor1, Distribution2"),
|
||||||
|
|
||||||
ExecutionContext(executor2_1.value, ::convertToOptions1, "Options1, Executor2, Distribution1"),
|
ExecutionContext(executor2_1.value, ::convertToOptions1, "Options1, Executor2, Distribution1"),
|
||||||
ExecutionContext(executor2_1.value, ::convertToOptions2, "Options2, Executor2, Distribution1"),
|
ExecutionContext(executor2_1.value, ::convertToOptions2, "Options2, Executor2, Distribution1"),
|
||||||
@@ -70,7 +70,7 @@ class EmbeddedExecutorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A pkl-executor library that supports ExecutorSpiOptions up to v2
|
// A pkl-executor library that supports ExecutorSpiOptions up to v2
|
||||||
// and a Pkl distribution that supports ExecutorSpiOptions up to v.
|
// and a Pkl distribution that supports ExecutorSpiOptions up to v2.
|
||||||
private val executor2_2: Lazy<Executor> = lazy {
|
private val executor2_2: Lazy<Executor> = lazy {
|
||||||
EmbeddedExecutor(listOf(pklDistribution2), pklExecutorClassLoader2)
|
EmbeddedExecutor(listOf(pklDistribution2), pklExecutorClassLoader2)
|
||||||
}
|
}
|
||||||
@@ -101,25 +101,19 @@ class EmbeddedExecutorTest {
|
|||||||
|
|
||||||
// a Pkl distribution that supports ExecutorSpiOptions up to v1
|
// a Pkl distribution that supports ExecutorSpiOptions up to v1
|
||||||
private val pklDistribution1: Path by lazy {
|
private val pklDistribution1: Path by lazy {
|
||||||
val path = System.getProperty("pklDistribution025")?.toPath() ?:
|
FileTestUtils.rootProjectDir.resolve("pkl-executor/build/pklHistoricalDistributions/pkl-config-java-all-0.25.0.jar").apply {
|
||||||
// can get rid of this path by switching to IntelliJ's Gradle test runner
|
if (!exists()) {
|
||||||
System.getProperty("user.home").toPath()
|
throw AssertionError("Missing test fixture. " +
|
||||||
.resolve(".gradle/caches/modules-2/files-2.1/org.pkl-lang/pkl-config-java-all/" +
|
|
||||||
"0.25.0/e9451dda554f1659e49ff5bdd30accd26be7bf0f/pkl-config-java-all-0.25.0.jar")
|
|
||||||
path.apply {
|
|
||||||
if (!exists()) throw AssertionError("Missing test fixture. " +
|
|
||||||
"To fix this problem, run `./gradlew :pkl-executor:prepareTest`.")
|
"To fix this problem, run `./gradlew :pkl-executor:prepareTest`.")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// a Pkl distribution that supports ExecutorSpiOptions up to v2
|
// a Pkl distribution that supports ExecutorSpiOptions up to v2
|
||||||
private val pklDistribution2: Path by lazy {
|
private val pklDistribution2: Path by lazy {
|
||||||
val path = System.getProperty("pklDistributionCurrent")?.toPath() ?:
|
FileTestUtils.rootProjectDir
|
||||||
// can get rid of this path by switching to IntelliJ's Gradle test runner
|
.resolve("pkl-config-java/build/libs/pkl-config-java-all-" +
|
||||||
FileTestUtils.rootProjectDir
|
"${Release.current().version().withBuild(null).toString().replaceFirst("dev", "SNAPSHOT")}.jar").apply {
|
||||||
.resolve("pkl-config-java/build/libs/pkl-config-java-all-" +
|
|
||||||
"${Release.current().version().withBuild(null).toString().replaceFirst("dev", "SNAPSHOT")}.jar")
|
|
||||||
path.apply {
|
|
||||||
if (!exists()) throw AssertionError("Missing test fixture. " +
|
if (!exists()) throw AssertionError("Missing test fixture. " +
|
||||||
"To fix this problem, run `./gradlew :pkl-executor:prepareTest`.")
|
"To fix this problem, run `./gradlew :pkl-executor:prepareTest`.")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user