diff --git a/pkl-core/src/main/java/org/pkl/core/evaluatorSettings/PklEvaluatorSettings.java b/pkl-core/src/main/java/org/pkl/core/evaluatorSettings/PklEvaluatorSettings.java index cb470566..30cb3c2e 100644 --- a/pkl-core/src/main/java/org/pkl/core/evaluatorSettings/PklEvaluatorSettings.java +++ b/pkl-core/src/main/java/org/pkl/core/evaluatorSettings/PklEvaluatorSettings.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -137,6 +137,7 @@ public record PklEvaluatorSettings( } public record Proxy(@Nullable URI address, @Nullable List noProxy) { + @Deprecated(forRemoval = true) public static Proxy create(@Nullable String address, @Nullable List noProxy) { URI addressUri; try { @@ -147,14 +148,19 @@ public record PklEvaluatorSettings( return new Proxy(addressUri, noProxy); } - @SuppressWarnings("unchecked") public static @Nullable Proxy parse(Value input) { if (input instanceof PNull) { return null; } else if (input instanceof PObject proxy) { var address = (String) proxy.get("address"); + @SuppressWarnings("unchecked") var noProxy = (List) proxy.get("noProxy"); - return create(address, noProxy); + try { + var addressUri = address == null ? null : new URI(address); + return new Proxy(addressUri, noProxy); + } catch (URISyntaxException e) { + throw new PklException(ErrorMessages.create("invalidUri", address)); + } } else { throw PklBugException.unreachableCode(); } diff --git a/pkl-core/src/main/java/org/pkl/core/module/ExternalModuleResolver.java b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalModuleResolver.java similarity index 75% rename from pkl-core/src/main/java/org/pkl/core/module/ExternalModuleResolver.java rename to pkl-core/src/main/java/org/pkl/core/externalreader/ExternalModuleResolver.java index a9e46c0b..c5a8d256 100644 --- a/pkl-core/src/main/java/org/pkl/core/module/ExternalModuleResolver.java +++ b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalModuleResolver.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,24 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.pkl.core.module; +package org.pkl.core.externalreader; import java.io.IOException; import java.net.URI; import java.util.List; import org.pkl.core.SecurityManager; import org.pkl.core.SecurityManagerException; +import org.pkl.core.messaging.MessageTransport; +import org.pkl.core.module.PathElement; public interface ExternalModuleResolver { - - interface Spec { - boolean hasHierarchicalUris(); - - boolean isGlobbable(); - - boolean isLocal(); - - String scheme(); + static ExternalModuleResolver of(MessageTransport transport, long evaluatorId) { + return new ExternalModuleResolverImpl(transport, evaluatorId); } String resolveModule(SecurityManager securityManager, URI uri) diff --git a/pkl-core/src/main/java/org/pkl/core/messaging/MessageTransportModuleResolver.java b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalModuleResolverImpl.java similarity index 91% rename from pkl-core/src/main/java/org/pkl/core/messaging/MessageTransportModuleResolver.java rename to pkl-core/src/main/java/org/pkl/core/externalreader/ExternalModuleResolverImpl.java index a799e94e..f876a4d4 100644 --- a/pkl-core/src/main/java/org/pkl/core/messaging/MessageTransportModuleResolver.java +++ b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalModuleResolverImpl.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.pkl.core.messaging; +package org.pkl.core.externalreader; import java.io.IOException; import java.net.URI; @@ -26,21 +26,23 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; import org.pkl.core.SecurityManager; import org.pkl.core.SecurityManagerException; +import org.pkl.core.messaging.MessageTransport; +import org.pkl.core.messaging.MessageTransports; import org.pkl.core.messaging.Messages.ListModulesRequest; import org.pkl.core.messaging.Messages.ListModulesResponse; import org.pkl.core.messaging.Messages.ReadModuleRequest; import org.pkl.core.messaging.Messages.ReadModuleResponse; -import org.pkl.core.module.ExternalModuleResolver; +import org.pkl.core.messaging.ProtocolException; import org.pkl.core.module.PathElement; -public class MessageTransportModuleResolver implements ExternalModuleResolver { +final class ExternalModuleResolverImpl implements ExternalModuleResolver { private final MessageTransport transport; private final long evaluatorId; private final Map> readResponses = new ConcurrentHashMap<>(); private final Map>> listResponses = new ConcurrentHashMap<>(); private final Random requestIdGenerator = new Random(); - public MessageTransportModuleResolver(MessageTransport transport, long evaluatorId) { + ExternalModuleResolverImpl(MessageTransport transport, long evaluatorId) { this.transport = transport; this.evaluatorId = evaluatorId; } diff --git a/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderMessagePackDecoder.java b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderMessagePackDecoder.java index 51bf6a12..9578b6a3 100644 --- a/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderMessagePackDecoder.java +++ b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderMessagePackDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderMessages.java b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderMessages.java index 09cf69b2..6714ec79 100644 --- a/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderMessages.java +++ b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderMessages.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,35 +23,33 @@ import org.pkl.core.util.Nullable; final class ExternalReaderMessages { private ExternalReaderMessages() {} - public record InitializeModuleReaderRequest(long requestId, String scheme) - implements Server.Request { + record InitializeModuleReaderRequest(long requestId, String scheme) implements Server.Request { public Type type() { return Type.INITIALIZE_MODULE_READER_REQUEST; } } - public record InitializeResourceReaderRequest(long requestId, String scheme) - implements Server.Request { + record InitializeResourceReaderRequest(long requestId, String scheme) implements Server.Request { public Type type() { return Type.INITIALIZE_RESOURCE_READER_REQUEST; } } - public record InitializeModuleReaderResponse(long requestId, @Nullable ModuleReaderSpec spec) + record InitializeModuleReaderResponse(long requestId, @Nullable ModuleReaderSpec spec) implements Client.Response { public Type type() { return Type.INITIALIZE_MODULE_READER_RESPONSE; } } - public record InitializeResourceReaderResponse(long requestId, @Nullable ResourceReaderSpec spec) + record InitializeResourceReaderResponse(long requestId, @Nullable ResourceReaderSpec spec) implements Client.Response { public Type type() { return Type.INITIALIZE_RESOURCE_READER_RESPONSE; } } - public record CloseExternalProcess() implements Server.OneWay { + record CloseExternalProcess() implements Server.OneWay { public Type type() { return Type.CLOSE_EXTERNAL_PROCESS; } diff --git a/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderProcess.java b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderProcess.java index b43b30c2..b03950b9 100644 --- a/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderProcess.java +++ b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderProcess.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,6 @@ package org.pkl.core.externalreader; import java.io.IOException; import org.pkl.core.evaluatorSettings.PklEvaluatorSettings.ExternalReader; -import org.pkl.core.module.ExternalModuleResolver; -import org.pkl.core.resource.ExternalResourceResolver; import org.pkl.core.util.Nullable; /** An external process that reads Pkl modules and resources. */ @@ -56,7 +54,8 @@ public interface ExternalReaderProcess extends AutoCloseable { * @throws IllegalStateException if this process has already been {@linkplain #close closed} * @throws IOException if an I/O error occurs */ - ExternalModuleResolver.@Nullable Spec getModuleReaderSpec(String scheme) throws IOException; + @Nullable + ModuleReaderSpec getModuleReaderSpec(String scheme) throws IOException; /** * Returns the spec, if available, of this process's resource reader with the given scheme. @@ -64,7 +63,8 @@ public interface ExternalReaderProcess extends AutoCloseable { * @throws IllegalStateException if this process has already been {@linkplain #close closed} * @throws IOException if an I/O error occurs */ - ExternalResourceResolver.@Nullable Spec getResourceReaderSpec(String scheme) throws IOException; + @Nullable + ResourceReaderSpec getResourceReaderSpec(String scheme) throws IOException; /** * Closes this process, releasing any associated resources. diff --git a/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderProcessImpl.java b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderProcessImpl.java index 95b705c2..de35f6b0 100644 --- a/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderProcessImpl.java +++ b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalReaderProcessImpl.java @@ -30,12 +30,8 @@ import javax.annotation.concurrent.GuardedBy; import org.pkl.core.evaluatorSettings.PklEvaluatorSettings.ExternalReader; import org.pkl.core.externalreader.ExternalReaderMessages.*; import org.pkl.core.messaging.MessageTransport; -import org.pkl.core.messaging.MessageTransportModuleResolver; -import org.pkl.core.messaging.MessageTransportResourceResolver; import org.pkl.core.messaging.MessageTransports; import org.pkl.core.messaging.ProtocolException; -import org.pkl.core.module.ExternalModuleResolver; -import org.pkl.core.resource.ExternalResourceResolver; import org.pkl.core.util.ErrorMessages; import org.pkl.core.util.LateInit; import org.pkl.core.util.Nullable; @@ -46,9 +42,9 @@ final class ExternalReaderProcessImpl implements ExternalReaderProcess { private final ExternalReader spec; private final @Nullable String logPrefix; - private final Map> - initializeModuleReaderResponses = new ConcurrentHashMap<>(); - private final Map> + private final Map> initializeModuleReaderResponses = + new ConcurrentHashMap<>(); + private final Map> initializeResourceReaderResponses = new ConcurrentHashMap<>(); private final Random requestIdGenerator = new Random(); @@ -80,13 +76,13 @@ final class ExternalReaderProcessImpl implements ExternalReaderProcess { @Override public ExternalModuleResolver getModuleResolver(long evaluatorId) throws ExternalReaderProcessException { - return new MessageTransportModuleResolver(getTransport(), evaluatorId); + return ExternalModuleResolver.of(getTransport(), evaluatorId); } @Override public ExternalResourceResolver getResourceResolver(long evaluatorId) throws ExternalReaderProcessException { - return new MessageTransportResourceResolver(getTransport(), evaluatorId); + return ExternalResourceResolver.of(getTransport(), evaluatorId); } private MessageTransport getTransport() throws ExternalReaderProcessException { @@ -175,13 +171,12 @@ final class ExternalReaderProcessImpl implements ExternalReaderProcess { } @Override - public ExternalModuleResolver.@Nullable Spec getModuleReaderSpec(String uriScheme) - throws IOException { + public ModuleReaderSpec getModuleReaderSpec(String uriScheme) throws IOException { return MessageTransports.resolveFuture( initializeModuleReaderResponses.computeIfAbsent( uriScheme, (scheme) -> { - var future = new CompletableFuture(); + var future = new CompletableFuture<@Nullable ModuleReaderSpec>(); var request = new InitializeModuleReaderRequest(requestIdGenerator.nextLong(), scheme); try { @@ -190,7 +185,15 @@ final class ExternalReaderProcessImpl implements ExternalReaderProcess { request, (response) -> { if (response instanceof InitializeModuleReaderResponse resp) { - future.complete(resp.spec()); + var spec = + resp.spec() == null + ? null + : new ModuleReaderSpec( + resp.spec().scheme(), + resp.spec().hasHierarchicalUris(), + resp.spec().isLocal(), + resp.spec().isGlobbable()); + future.complete(spec); } else { future.completeExceptionally( new ProtocolException("unexpected response")); @@ -204,13 +207,12 @@ final class ExternalReaderProcessImpl implements ExternalReaderProcess { } @Override - public ExternalResourceResolver.@Nullable Spec getResourceReaderSpec(String uriScheme) - throws IOException { + public ResourceReaderSpec getResourceReaderSpec(String uriScheme) throws IOException { return MessageTransports.resolveFuture( initializeResourceReaderResponses.computeIfAbsent( uriScheme, (scheme) -> { - var future = new CompletableFuture(); + var future = new CompletableFuture<@Nullable ResourceReaderSpec>(); var request = new InitializeResourceReaderRequest(requestIdGenerator.nextLong(), scheme); try { @@ -220,7 +222,14 @@ final class ExternalReaderProcessImpl implements ExternalReaderProcess { (response) -> { log(response.toString()); if (response instanceof InitializeResourceReaderResponse resp) { - future.complete(resp.spec()); + var spec = + resp.spec() == null + ? null + : new ResourceReaderSpec( + resp.spec().scheme(), + resp.spec().hasHierarchicalUris(), + resp.spec().isGlobbable()); + future.complete(spec); } else { future.completeExceptionally( new ProtocolException("unexpected response")); diff --git a/pkl-core/src/main/java/org/pkl/core/resource/ExternalResourceResolver.java b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalResourceResolver.java similarity index 77% rename from pkl-core/src/main/java/org/pkl/core/resource/ExternalResourceResolver.java rename to pkl-core/src/main/java/org/pkl/core/externalreader/ExternalResourceResolver.java index 188ba9cb..59621935 100644 --- a/pkl-core/src/main/java/org/pkl/core/resource/ExternalResourceResolver.java +++ b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalResourceResolver.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.pkl.core.resource; +package org.pkl.core.externalreader; import java.io.IOException; import java.net.URI; @@ -21,16 +21,12 @@ import java.util.List; import java.util.Optional; import org.pkl.core.SecurityManager; import org.pkl.core.SecurityManagerException; +import org.pkl.core.messaging.MessageTransport; import org.pkl.core.module.PathElement; public interface ExternalResourceResolver { - - interface Spec { - boolean hasHierarchicalUris(); - - boolean isGlobbable(); - - String scheme(); + static ExternalResourceResolver of(MessageTransport transport, long evaluatorId) { + return new ExternalResourceResolverImpl(transport, evaluatorId); } Optional read(URI uri) throws IOException; diff --git a/pkl-core/src/main/java/org/pkl/core/messaging/MessageTransportResourceResolver.java b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalResourceResolverImpl.java similarity index 91% rename from pkl-core/src/main/java/org/pkl/core/messaging/MessageTransportResourceResolver.java rename to pkl-core/src/main/java/org/pkl/core/externalreader/ExternalResourceResolverImpl.java index d09ed225..03b892d1 100644 --- a/pkl-core/src/main/java/org/pkl/core/messaging/MessageTransportResourceResolver.java +++ b/pkl-core/src/main/java/org/pkl/core/externalreader/ExternalResourceResolverImpl.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.pkl.core.messaging; +package org.pkl.core.externalreader; import java.io.IOException; import java.net.URI; @@ -27,19 +27,21 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; import org.pkl.core.SecurityManager; import org.pkl.core.SecurityManagerException; +import org.pkl.core.messaging.MessageTransport; +import org.pkl.core.messaging.MessageTransports; import org.pkl.core.messaging.Messages.*; +import org.pkl.core.messaging.ProtocolException; import org.pkl.core.module.PathElement; -import org.pkl.core.resource.ExternalResourceResolver; import org.pkl.core.resource.Resource; -public class MessageTransportResourceResolver implements ExternalResourceResolver { +final class ExternalResourceResolverImpl implements ExternalResourceResolver { private final MessageTransport transport; private final long evaluatorId; private final Map> readResponses = new ConcurrentHashMap<>(); private final Map>> listResponses = new ConcurrentHashMap<>(); private final Random requestIdGenerator = new Random(); - public MessageTransportResourceResolver(MessageTransport transport, long evaluatorId) { + ExternalResourceResolverImpl(MessageTransport transport, long evaluatorId) { this.transport = transport; this.evaluatorId = evaluatorId; } diff --git a/pkl-core/src/main/java/org/pkl/core/externalreader/ModuleReaderSpec.java b/pkl-core/src/main/java/org/pkl/core/externalreader/ModuleReaderSpec.java new file mode 100644 index 00000000..9a46ca29 --- /dev/null +++ b/pkl-core/src/main/java/org/pkl/core/externalreader/ModuleReaderSpec.java @@ -0,0 +1,19 @@ +/* + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.pkl.core.externalreader; + +public record ModuleReaderSpec( + String scheme, boolean hasHierarchicalUris, boolean isLocal, boolean isGlobbable) {} diff --git a/pkl-core/src/main/java/org/pkl/core/externalreader/ResourceReaderSpec.java b/pkl-core/src/main/java/org/pkl/core/externalreader/ResourceReaderSpec.java new file mode 100644 index 00000000..8f282f94 --- /dev/null +++ b/pkl-core/src/main/java/org/pkl/core/externalreader/ResourceReaderSpec.java @@ -0,0 +1,18 @@ +/* + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.pkl.core.externalreader; + +public record ResourceReaderSpec(String scheme, boolean hasHierarchicalUris, boolean isGlobbable) {} diff --git a/pkl-core/src/main/java/org/pkl/core/messaging/Messages.java b/pkl-core/src/main/java/org/pkl/core/messaging/Messages.java index 4433a463..74197085 100644 --- a/pkl-core/src/main/java/org/pkl/core/messaging/Messages.java +++ b/pkl-core/src/main/java/org/pkl/core/messaging/Messages.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,20 +20,17 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; import org.pkl.core.messaging.Message.*; -import org.pkl.core.module.ExternalModuleResolver; import org.pkl.core.module.PathElement; -import org.pkl.core.resource.ExternalResourceResolver; import org.pkl.core.util.Nullable; public final class Messages { private Messages() {} public record ModuleReaderSpec( - String scheme, boolean hasHierarchicalUris, boolean isLocal, boolean isGlobbable) - implements ExternalModuleResolver.Spec {} + String scheme, boolean hasHierarchicalUris, boolean isLocal, boolean isGlobbable) {} - public record ResourceReaderSpec(String scheme, boolean hasHierarchicalUris, boolean isGlobbable) - implements ExternalResourceResolver.Spec {} + public record ResourceReaderSpec( + String scheme, boolean hasHierarchicalUris, boolean isGlobbable) {} public record ListResourcesRequest(long requestId, long evaluatorId, URI uri) implements Server.Request { diff --git a/pkl-core/src/main/java/org/pkl/core/module/ModuleKeyFactories.java b/pkl-core/src/main/java/org/pkl/core/module/ModuleKeyFactories.java index 5cbbb707..f0ca0896 100644 --- a/pkl-core/src/main/java/org/pkl/core/module/ModuleKeyFactories.java +++ b/pkl-core/src/main/java/org/pkl/core/module/ModuleKeyFactories.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import java.util.Optional; import java.util.ServiceLoader; import javax.annotation.concurrent.GuardedBy; import org.pkl.core.Closeables; +import org.pkl.core.externalreader.ExternalModuleResolver; import org.pkl.core.externalreader.ExternalReaderProcess; import org.pkl.core.externalreader.ExternalReaderProcessException; import org.pkl.core.util.ErrorMessages; diff --git a/pkl-core/src/main/java/org/pkl/core/module/ModuleKeys.java b/pkl-core/src/main/java/org/pkl/core/module/ModuleKeys.java index a6274ea3..f5127e1f 100644 --- a/pkl-core/src/main/java/org/pkl/core/module/ModuleKeys.java +++ b/pkl-core/src/main/java/org/pkl/core/module/ModuleKeys.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,9 @@ import java.util.List; import java.util.Map; import org.pkl.core.SecurityManager; import org.pkl.core.SecurityManagerException; +import org.pkl.core.externalreader.ExternalModuleResolver; import org.pkl.core.externalreader.ExternalReaderProcessException; +import org.pkl.core.externalreader.ModuleReaderSpec; import org.pkl.core.packages.Dependency; import org.pkl.core.packages.Dependency.LocalDependency; import org.pkl.core.packages.PackageAssetUri; @@ -130,7 +132,7 @@ public final class ModuleKeys { /** Creates a module key for an externally read module. */ public static ModuleKey externalResolver( - URI uri, ExternalModuleResolver.Spec spec, ExternalModuleResolver resolver) { + URI uri, ModuleReaderSpec spec, ExternalModuleResolver resolver) { return new ExternalResolver(uri, spec, resolver); } @@ -778,10 +780,10 @@ public final class ModuleKeys { public static class ExternalResolver implements ModuleKey { private final URI uri; - private final ExternalModuleResolver.Spec spec; + private final ModuleReaderSpec spec; private final ExternalModuleResolver resolver; - ExternalResolver(URI uri, ExternalModuleResolver.Spec spec, ExternalModuleResolver resolver) { + ExternalResolver(URI uri, ModuleReaderSpec spec, ExternalModuleResolver resolver) { this.uri = uri; this.spec = spec; this.resolver = resolver; diff --git a/pkl-core/src/main/java/org/pkl/core/resource/ResourceReaders.java b/pkl-core/src/main/java/org/pkl/core/resource/ResourceReaders.java index 567566a7..20c1c741 100644 --- a/pkl-core/src/main/java/org/pkl/core/resource/ResourceReaders.java +++ b/pkl-core/src/main/java/org/pkl/core/resource/ResourceReaders.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,8 @@ import org.pkl.core.SecurityManager; import org.pkl.core.SecurityManagerException; import org.pkl.core.externalreader.ExternalReaderProcess; import org.pkl.core.externalreader.ExternalReaderProcessException; +import org.pkl.core.externalreader.ExternalResourceResolver; +import org.pkl.core.externalreader.ResourceReaderSpec; import org.pkl.core.module.FileResolver; import org.pkl.core.module.ModulePathResolver; import org.pkl.core.module.PathElement; @@ -162,7 +164,7 @@ public final class ResourceReaders { /** Returns a reader for external and client reader resources. */ public static ResourceReader externalResolver( - ExternalResourceResolver.Spec spec, ExternalResourceResolver resolver) { + ResourceReaderSpec spec, ExternalResourceResolver resolver) { return new ExternalResolver(spec, resolver); } @@ -691,11 +693,10 @@ public final class ResourceReaders { } private static final class ExternalResolver implements ResourceReader { - private final ExternalResourceResolver.Spec readerSpec; + private final ResourceReaderSpec readerSpec; private final ExternalResourceResolver resolver; - public ExternalResolver( - ExternalResourceResolver.Spec readerSpec, ExternalResourceResolver resolver) { + public ExternalResolver(ResourceReaderSpec readerSpec, ExternalResourceResolver resolver) { this.readerSpec = readerSpec; this.resolver = resolver; } diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmImportAnalyzer.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmImportAnalyzer.java index dfbcbc98..4a36c56e 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmImportAnalyzer.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmImportAnalyzer.java @@ -43,7 +43,7 @@ import org.pkl.core.util.IoUtils; public class VmImportAnalyzer { @TruffleBoundary public static ImportGraph analyze(URI[] moduleUris, VmContext context) - throws IOException, SecurityManagerException { + throws IOException, SecurityManagerException, ExternalReaderProcessException { var imports = new TreeMap>(); var resolvedImports = new TreeMap(); for (var moduleUri : moduleUris) { diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/analyze/AnalyzeNodes.java b/pkl-core/src/main/java/org/pkl/core/stdlib/analyze/AnalyzeNodes.java index ed9ecbf6..7b10a474 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/analyze/AnalyzeNodes.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/analyze/AnalyzeNodes.java @@ -23,6 +23,7 @@ import java.net.URISyntaxException; import org.pkl.core.ImportGraph; import org.pkl.core.ImportGraph.Import; import org.pkl.core.SecurityManagerException; +import org.pkl.core.externalreader.ExternalReaderProcessException; import org.pkl.core.packages.PackageLoadError; import org.pkl.core.runtime.AnalyzeModule; import org.pkl.core.runtime.VmContext; @@ -91,7 +92,10 @@ public final class AnalyzeNodes { try { var results = VmImportAnalyzer.analyze(uris, context); return importGraphFactory.create(results); - } catch (IOException | SecurityManagerException | PackageLoadError e) { + } catch (IOException + | SecurityManagerException + | PackageLoadError + | ExternalReaderProcessException e) { throw exceptionBuilder().withCause(e).build(); } } diff --git a/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalModuleReader.kt b/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalModuleReader.kt index e9be21d6..e862b1e7 100644 --- a/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalModuleReader.kt +++ b/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalModuleReader.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ package org.pkl.core.externalreader import java.net.URI import org.pkl.core.messaging.Messages.ModuleReaderSpec -/** An external module reader, to be used with [ExternalReaderRuntime]. */ +/** An external module reader, to be used with [ExternalReaderClient]. */ interface ExternalModuleReader : ExternalReaderBase { val isLocal: Boolean diff --git a/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalReaderRuntime.kt b/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalReaderClient.kt similarity index 94% rename from pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalReaderRuntime.kt rename to pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalReaderClient.kt index d1c6e6e3..da61420f 100644 --- a/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalReaderRuntime.kt +++ b/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalReaderClient.kt @@ -19,14 +19,15 @@ import java.io.IOException import org.pkl.core.externalreader.ExternalReaderMessages.* import org.pkl.core.messaging.Message import org.pkl.core.messaging.MessageTransport +import org.pkl.core.messaging.Messages import org.pkl.core.messaging.Messages.* import org.pkl.core.messaging.ProtocolException import org.pkl.core.util.Nullable /** An implementation of the client side of the external reader flow */ -class ExternalReaderRuntime( - private val moduleReaders: List, - private val resourceReaders: List, +class ExternalReaderClient( + private val externalModuleReaders: List, + private val externalResourceReaders: List, private val transport: MessageTransport, ) { /** Close the runtime and its transport. */ @@ -35,7 +36,7 @@ class ExternalReaderRuntime( } private fun findModuleReader(scheme: String): @Nullable ExternalModuleReader? { - for (moduleReader in moduleReaders) { + for (moduleReader in externalModuleReaders) { if (moduleReader.scheme.equals(scheme, ignoreCase = true)) { return moduleReader } @@ -44,7 +45,7 @@ class ExternalReaderRuntime( } private fun findResourceReader(scheme: String): @Nullable ExternalResourceReader? { - for (resourceReader in resourceReaders) { + for (resourceReader in externalResourceReaders) { if (resourceReader.scheme.equals(scheme, ignoreCase = true)) { return resourceReader } @@ -72,7 +73,7 @@ class ExternalReaderRuntime( Message.Type.INITIALIZE_MODULE_READER_REQUEST -> { val req = msg as InitializeModuleReaderRequest val reader = findModuleReader(req.scheme) - var spec: @Nullable ModuleReaderSpec? = null + var spec: Messages.ModuleReaderSpec? = null if (reader != null) { spec = reader.spec } @@ -81,7 +82,7 @@ class ExternalReaderRuntime( Message.Type.INITIALIZE_RESOURCE_READER_REQUEST -> { val req = msg as InitializeResourceReaderRequest val reader = findResourceReader(req.scheme) - var spec: @Nullable ResourceReaderSpec? = null + var spec: Messages.ResourceReaderSpec? = null if (reader != null) { spec = reader.spec } diff --git a/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalResourceReader.kt b/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalResourceReader.kt index bf5ab46f..68eef504 100644 --- a/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalResourceReader.kt +++ b/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalResourceReader.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ package org.pkl.core.externalreader import java.net.URI import org.pkl.core.messaging.Messages.ResourceReaderSpec -/** An external resource reader, to be used with [ExternalReaderRuntime]. */ +/** An external resource reader, to be used with [ExternalReaderClient]. */ interface ExternalResourceReader : ExternalReaderBase { fun read(uri: URI): ByteArray diff --git a/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalProcessProcessReaderMessagePackCodecTest.kt b/pkl-core/src/test/kotlin/org/pkl/core/externalreader/MessagePackCodecTest.kt similarity index 94% rename from pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalProcessProcessReaderMessagePackCodecTest.kt rename to pkl-core/src/test/kotlin/org/pkl/core/externalreader/MessagePackCodecTest.kt index 235524fd..faa85dfc 100644 --- a/pkl-core/src/test/kotlin/org/pkl/core/externalreader/ExternalProcessProcessReaderMessagePackCodecTest.kt +++ b/pkl-core/src/test/kotlin/org/pkl/core/externalreader/MessagePackCodecTest.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ import org.msgpack.core.MessagePack import org.pkl.core.externalreader.ExternalReaderMessages.* import org.pkl.core.messaging.* -class ExternalProcessProcessReaderMessagePackCodecTest { +class MessagePackCodecTest { private val encoder: MessageEncoder private val decoder: MessageDecoder diff --git a/pkl-core/src/test/kotlin/org/pkl/core/externalreader/TestExternalModuleReader.kt b/pkl-core/src/test/kotlin/org/pkl/core/externalreader/TestExternalModuleReader.kt index 12b543ce..36263ed9 100644 --- a/pkl-core/src/test/kotlin/org/pkl/core/externalreader/TestExternalModuleReader.kt +++ b/pkl-core/src/test/kotlin/org/pkl/core/externalreader/TestExternalModuleReader.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/pkl-core/src/test/kotlin/org/pkl/core/externalreader/TestExternalReaderProcess.kt b/pkl-core/src/test/kotlin/org/pkl/core/externalreader/TestExternalReaderProcess.kt index 3c09be23..dd7fec31 100644 --- a/pkl-core/src/test/kotlin/org/pkl/core/externalreader/TestExternalReaderProcess.kt +++ b/pkl-core/src/test/kotlin/org/pkl/core/externalreader/TestExternalReaderProcess.kt @@ -25,10 +25,7 @@ import java.util.concurrent.Future import kotlin.random.Random import org.pkl.core.externalreader.ExternalReaderMessages.* import org.pkl.core.messaging.MessageTransport -import org.pkl.core.messaging.MessageTransportModuleResolver -import org.pkl.core.messaging.MessageTransportResourceResolver import org.pkl.core.messaging.MessageTransports -import org.pkl.core.messaging.Messages.* import org.pkl.core.messaging.ProtocolException class TestExternalReaderProcess(private val transport: MessageTransport) : ExternalReaderProcess { @@ -42,11 +39,11 @@ class TestExternalReaderProcess(private val transport: MessageTransport) : Exter transport.close() } - override fun getModuleResolver(evaluatorId: Long): MessageTransportModuleResolver = - MessageTransportModuleResolver(transport, evaluatorId) + override fun getModuleResolver(evaluatorId: Long): ExternalModuleResolver = + ExternalModuleResolver.of(transport, evaluatorId) - override fun getResourceResolver(evaluatorId: Long): MessageTransportResourceResolver = - MessageTransportResourceResolver(transport, evaluatorId) + override fun getResourceResolver(evaluatorId: Long): ExternalResourceResolver = + ExternalResourceResolver.of(transport, evaluatorId) fun run() { try { @@ -69,7 +66,11 @@ class TestExternalReaderProcess(private val transport: MessageTransport) : Exter transport.send(request) { response -> when (response) { is InitializeModuleReaderResponse -> { - complete(response.spec) + val spec = + response.spec?.let { + ModuleReaderSpec(it.scheme, it.hasHierarchicalUris, it.isLocal, it.isGlobbable) + } + complete(spec) } else -> completeExceptionally(ProtocolException("unexpected response")) } @@ -86,7 +87,11 @@ class TestExternalReaderProcess(private val transport: MessageTransport) : Exter transport.send(request) { response -> when (response) { is InitializeResourceReaderResponse -> { - complete(response.spec) + val spec = + response.spec?.let { + ResourceReaderSpec(it.scheme, it.hasHierarchicalUris, it.isGlobbable) + } + complete(spec) } else -> completeExceptionally(ProtocolException("unexpected response")) } @@ -97,9 +102,9 @@ class TestExternalReaderProcess(private val transport: MessageTransport) : Exter companion object { fun initializeTestHarness( - moduleReaders: List, - resourceReaders: List, - ): Pair { + externalModuleReaders: List, + externalResourceReaders: List, + ): Pair { val rxIn = PipedInputStream(10240) val rxOut = PipedOutputStream(rxIn) val txIn = PipedInputStream(10240) @@ -115,13 +120,14 @@ class TestExternalReaderProcess(private val transport: MessageTransport) : Exter ExternalReaderMessagePackEncoder(rxOut), ) {} - val runtime = ExternalReaderRuntime(moduleReaders, resourceReaders, clientTransport) + val client = + ExternalReaderClient(externalModuleReaders, externalResourceReaders, clientTransport) val proc = TestExternalReaderProcess(serverTransport) - Thread(runtime::run).start() + Thread(client::run).start() Thread(proc::run).start() - return proc to runtime + return proc to client } } } diff --git a/pkl-core/src/test/kotlin/org/pkl/core/resource/ResourceReadersTest.kt b/pkl-core/src/test/kotlin/org/pkl/core/resource/ResourceReadersTest.kt index 58c34b46..8fb09f6d 100644 --- a/pkl-core/src/test/kotlin/org/pkl/core/resource/ResourceReadersTest.kt +++ b/pkl-core/src/test/kotlin/org/pkl/core/resource/ResourceReadersTest.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/pkl-server/src/main/kotlin/org/pkl/server/ClientModuleKeyFactory.kt b/pkl-server/src/main/kotlin/org/pkl/server/ClientModuleKeyFactory.kt index 77aa8585..288a6a8a 100644 --- a/pkl-server/src/main/kotlin/org/pkl/server/ClientModuleKeyFactory.kt +++ b/pkl-server/src/main/kotlin/org/pkl/server/ClientModuleKeyFactory.kt @@ -17,9 +17,9 @@ package org.pkl.server import java.net.URI import java.util.Optional +import org.pkl.core.externalreader.ExternalModuleResolver +import org.pkl.core.externalreader.ModuleReaderSpec import org.pkl.core.messaging.* -import org.pkl.core.messaging.MessageTransportModuleResolver -import org.pkl.core.messaging.Messages.* import org.pkl.core.module.* internal class ClientModuleKeyFactory( @@ -29,8 +29,7 @@ internal class ClientModuleKeyFactory( ) : ModuleKeyFactory { private val schemes = readerSpecs.map { it.scheme } - private val resolver: MessageTransportModuleResolver = - MessageTransportModuleResolver(transport, evaluatorId) + private val resolver: ExternalModuleResolver = ExternalModuleResolver.of(transport, evaluatorId) override fun create(uri: URI): Optional = when (uri.scheme) { diff --git a/pkl-server/src/main/kotlin/org/pkl/server/Server.kt b/pkl-server/src/main/kotlin/org/pkl/server/Server.kt index b721a120..7bc12f47 100644 --- a/pkl-server/src/main/kotlin/org/pkl/server/Server.kt +++ b/pkl-server/src/main/kotlin/org/pkl/server/Server.kt @@ -21,13 +21,16 @@ import java.net.URI import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ExecutorService import java.util.concurrent.Executors +import java.util.regex.Pattern import kotlin.random.Random import org.pkl.core.* -import org.pkl.core.evaluatorSettings.PklEvaluatorSettings.ExternalReader +import org.pkl.core.evaluatorSettings.PklEvaluatorSettings import org.pkl.core.externalreader.ExternalReaderProcess +import org.pkl.core.externalreader.ExternalResourceResolver +import org.pkl.core.externalreader.ModuleReaderSpec +import org.pkl.core.externalreader.ResourceReaderSpec import org.pkl.core.http.HttpClient import org.pkl.core.messaging.MessageTransport -import org.pkl.core.messaging.MessageTransportResourceResolver import org.pkl.core.messaging.MessageTransports import org.pkl.core.messaging.ProtocolException import org.pkl.core.module.ModuleKeyFactories @@ -182,8 +185,8 @@ class Server(private val transport: MessageTransport) : AutoCloseable { private fun createEvaluator(message: CreateEvaluatorRequest, evaluatorId: Long): BinaryEvaluator { val modulePaths = message.modulePaths ?: emptyList() val resolver = ModulePathResolver(modulePaths) - val allowedModules = message.allowedModules ?: emptyList() - val allowedResources = message.allowedResources ?: emptyList() + val allowedModules = message.allowedModules?.map { Pattern.compile(it) } ?: emptyList() + val allowedResources = message.allowedResources?.map { Pattern.compile(it) } ?: emptyList() val rootDir = message.rootDir val env = message.env ?: emptyMap() val properties = message.properties ?: emptyMap() @@ -247,8 +250,12 @@ class Server(private val transport: MessageTransport) : AutoCloseable { for (readerSpec in message.clientResourceReaders ?: emptyList()) { add( ResourceReaders.externalResolver( - readerSpec, - MessageTransportResourceResolver(transport, evaluatorId), + ResourceReaderSpec( + readerSpec.scheme, + readerSpec.hasHierarchicalUris, + readerSpec.isGlobbable, + ), + ExternalResourceResolver.of(transport, evaluatorId), ) ) } @@ -261,7 +268,11 @@ class Server(private val transport: MessageTransport) : AutoCloseable { ): List = buildList { // add client-side module key factory first to ensure it wins over builtin ones if (message.clientModuleReaders?.isNotEmpty() == true) { - add(ClientModuleKeyFactory(message.clientModuleReaders, transport, evaluatorId)) + val readerSpecs = + message.clientModuleReaders.map { + ModuleReaderSpec(it.scheme, it.hasHierarchicalUris, it.isLocal, it.isGlobbable) + } + add(ClientModuleKeyFactory(readerSpecs, transport, evaluatorId)) } for ((scheme, spec) in message.externalModuleReaders ?: emptyMap()) { add( @@ -285,5 +296,7 @@ class Server(private val transport: MessageTransport) : AutoCloseable { private fun getExternalProcess(evaluatorId: Long, spec: ExternalReader): ExternalReaderProcess = externalReaderProcesses .computeIfAbsent(evaluatorId) { ConcurrentHashMap() } - .computeIfAbsent(spec) { ExternalReaderProcess.of(it) } + .computeIfAbsent(spec) { + ExternalReaderProcess.of(PklEvaluatorSettings.ExternalReader(it.executable, it.arguments)) + } } diff --git a/pkl-server/src/main/kotlin/org/pkl/server/ServerMessagePackDecoder.kt b/pkl-server/src/main/kotlin/org/pkl/server/ServerMessagePackDecoder.kt index 57aa3b78..62926a72 100644 --- a/pkl-server/src/main/kotlin/org/pkl/server/ServerMessagePackDecoder.kt +++ b/pkl-server/src/main/kotlin/org/pkl/server/ServerMessagePackDecoder.kt @@ -19,12 +19,9 @@ import java.io.InputStream import java.net.URI import java.nio.file.Path import java.time.Duration -import java.util.regex.Pattern import org.msgpack.core.MessagePack import org.msgpack.core.MessageUnpacker import org.msgpack.value.Value -import org.pkl.core.evaluatorSettings.PklEvaluatorSettings -import org.pkl.core.evaluatorSettings.PklEvaluatorSettings.ExternalReader import org.pkl.core.messaging.BaseMessagePackDecoder import org.pkl.core.messaging.Message import org.pkl.core.packages.Checksums @@ -38,8 +35,8 @@ class ServerMessagePackDecoder(unpacker: MessageUnpacker) : BaseMessagePackDecod Message.Type.CREATE_EVALUATOR_REQUEST -> CreateEvaluatorRequest( get(map, "requestId").asIntegerValue().asLong(), - unpackStringListOrNull(map, "allowedModules", Pattern::compile), - unpackStringListOrNull(map, "allowedResources", Pattern::compile), + unpackStringListOrNull(map, "allowedModules"), + unpackStringListOrNull(map, "allowedResources"), unpackListOrNull(map, "clientModuleReaders") { unpackModuleReaderSpec(it)!! }, unpackListOrNull(map, "clientResourceReaders") { unpackResourceReaderSpec(it)!! }, unpackStringListOrNull(map, "modulePaths", Path::of), @@ -101,11 +98,11 @@ class ServerMessagePackDecoder(unpacker: MessageUnpacker) : BaseMessagePackDecod return Http(caCertificates, proxy) } - private fun Map.unpackProxy(): PklEvaluatorSettings.Proxy? { + private fun Map.unpackProxy(): Proxy? { val proxyMap = getNullable(this, "proxy")?.asMapValue()?.map() ?: return null val address = unpackString(proxyMap, "address") val noProxy = unpackStringListOrNull(proxyMap, "noProxy") - return PklEvaluatorSettings.Proxy.create(address, noProxy) + return Proxy(URI(address), noProxy) } private fun Map.unpackDependencies(name: String): Map { diff --git a/pkl-server/src/main/kotlin/org/pkl/server/ServerMessagePackEncoder.kt b/pkl-server/src/main/kotlin/org/pkl/server/ServerMessagePackEncoder.kt index 111bc259..b613cd3f 100644 --- a/pkl-server/src/main/kotlin/org/pkl/server/ServerMessagePackEncoder.kt +++ b/pkl-server/src/main/kotlin/org/pkl/server/ServerMessagePackEncoder.kt @@ -20,7 +20,6 @@ import java.nio.file.Path import kotlin.io.path.pathString import org.msgpack.core.MessagePack import org.msgpack.core.MessagePacker -import org.pkl.core.evaluatorSettings.PklEvaluatorSettings.ExternalReader import org.pkl.core.messaging.BaseMessagePackEncoder import org.pkl.core.messaging.Message import org.pkl.core.packages.Checksums @@ -105,8 +104,8 @@ class ServerMessagePackEncoder(packer: MessagePacker) : BaseMessagePackEncoder(p msg.externalResourceReaders, ) packKeyValue("requestId", msg.requestId()) - packKeyValue("allowedModules", msg.allowedModules?.map { it.toString() }) - packKeyValue("allowedResources", msg.allowedResources?.map { it.toString() }) + packKeyValue("allowedModules", msg.allowedModules) + packKeyValue("allowedResources", msg.allowedResources) if (msg.clientModuleReaders != null) { packer.packString("clientModuleReaders") packer.packArrayHeader(msg.clientModuleReaders.size) diff --git a/pkl-server/src/main/kotlin/org/pkl/server/ServerMessages.kt b/pkl-server/src/main/kotlin/org/pkl/server/ServerMessages.kt index cbb7ad89..5eb3fe64 100644 --- a/pkl-server/src/main/kotlin/org/pkl/server/ServerMessages.kt +++ b/pkl-server/src/main/kotlin/org/pkl/server/ServerMessages.kt @@ -19,23 +19,16 @@ import java.net.URI import java.nio.file.Path import java.time.Duration import java.util.* -import java.util.regex.Pattern -import org.pkl.core.evaluatorSettings.PklEvaluatorSettings.ExternalReader -import org.pkl.core.evaluatorSettings.PklEvaluatorSettings.Proxy import org.pkl.core.messaging.Message -import org.pkl.core.messaging.Messages.* +import org.pkl.core.messaging.Messages import org.pkl.core.packages.Checksums -private fun T?.equalsNullable(other: Any?): Boolean { - return Objects.equals(this, other) -} - data class CreateEvaluatorRequest( private val requestId: Long, - val allowedModules: List?, - val allowedResources: List?, - val clientModuleReaders: List?, - val clientResourceReaders: List?, + val allowedModules: List?, + val allowedResources: List?, + val clientModuleReaders: List?, + val clientResourceReaders: List?, val modulePaths: List?, val env: Map?, val properties: Map?, @@ -52,58 +45,12 @@ data class CreateEvaluatorRequest( override fun type(): Message.Type = Message.Type.CREATE_EVALUATOR_REQUEST override fun requestId(): Long = requestId - - // need to implement this manually because [Pattern.equals] returns false for two patterns - // that have the same underlying pattern string. - override fun equals(other: Any?): Boolean { - if (other == null) return false - if (other !is CreateEvaluatorRequest) return false - return requestId == other.requestId && - Objects.equals( - allowedModules?.map { it.pattern() }, - other.allowedModules?.map { it.pattern() }, - ) && - Objects.equals( - allowedResources?.map { it.pattern() }, - other.allowedResources?.map { it.pattern() }, - ) && - clientModuleReaders.equalsNullable(other.clientModuleReaders) && - clientResourceReaders.equalsNullable(other.clientResourceReaders) && - modulePaths.equalsNullable(other.modulePaths) && - env.equalsNullable(other.env) && - properties.equalsNullable(other.properties) && - timeout.equalsNullable(other.timeout) && - rootDir.equalsNullable(other.rootDir) && - cacheDir.equalsNullable(other.cacheDir) && - outputFormat.equalsNullable(other.outputFormat) && - project.equalsNullable(other.project) && - http.equalsNullable(other.http) && - externalModuleReaders.equalsNullable(other.externalModuleReaders) && - externalResourceReaders.equalsNullable(other.externalResourceReaders) - } - - @Suppress("DuplicatedCode") // false duplicate within method - override fun hashCode(): Int { - var result = requestId.hashCode() - result = 31 * result + allowedModules?.map { it.pattern() }.hashCode() - result = 31 * result + allowedResources?.map { it.pattern() }.hashCode() - result = 31 * result + clientModuleReaders.hashCode() - result = 31 * result + clientResourceReaders.hashCode() - result = 31 * result + modulePaths.hashCode() - result = 31 * result + env.hashCode() - result = 31 * result + properties.hashCode() - result = 31 * result + timeout.hashCode() - result = 31 * result + rootDir.hashCode() - result = 31 * result + cacheDir.hashCode() - result = 31 * result + outputFormat.hashCode() - result = 31 * result + project.hashCode() - result = 31 * result + http.hashCode() - result = 31 * result + externalModuleReaders.hashCode() - result = 31 * result + externalResourceReaders.hashCode() - return result - } } +data class ExternalReader(val executable: String, val arguments: List?) + +data class Proxy(val address: URI?, val noProxy: List?) + data class Http( /** PEM-format CA certificates as raw bytes. */ val caCertificates: ByteArray?, diff --git a/pkl-server/src/test/kotlin/org/pkl/server/AbstractServerTest.kt b/pkl-server/src/test/kotlin/org/pkl/server/AbstractServerTest.kt index 05eb94fb..21a5c320 100644 --- a/pkl-server/src/test/kotlin/org/pkl/server/AbstractServerTest.kt +++ b/pkl-server/src/test/kotlin/org/pkl/server/AbstractServerTest.kt @@ -19,7 +19,6 @@ import java.net.URI import java.nio.file.Path import java.util.concurrent.ExecutorService import java.util.concurrent.Executors -import java.util.regex.Pattern import kotlin.io.path.createDirectories import kotlin.io.path.outputStream import kotlin.io.path.writeText @@ -947,8 +946,8 @@ abstract class AbstractServerTest { val message = CreateEvaluatorRequest( 123, - listOf(Pattern.compile(".*")), - listOf(Pattern.compile(".*")), + listOf(".*"), + listOf(".*"), moduleReaders, resourceReaders, modulePaths, diff --git a/pkl-server/src/test/kotlin/org/pkl/server/ServerMessagePackCodecTest.kt b/pkl-server/src/test/kotlin/org/pkl/server/ServerMessagePackCodecTest.kt index d0dff6e0..8ecfd0cf 100644 --- a/pkl-server/src/test/kotlin/org/pkl/server/ServerMessagePackCodecTest.kt +++ b/pkl-server/src/test/kotlin/org/pkl/server/ServerMessagePackCodecTest.kt @@ -20,16 +20,13 @@ import java.io.PipedOutputStream import java.net.URI import java.nio.file.Path import java.time.Duration -import java.util.regex.Pattern import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.msgpack.core.MessagePack -import org.pkl.core.evaluatorSettings.PklEvaluatorSettings -import org.pkl.core.evaluatorSettings.PklEvaluatorSettings.ExternalReader import org.pkl.core.messaging.Message import org.pkl.core.messaging.MessageDecoder import org.pkl.core.messaging.MessageEncoder -import org.pkl.core.messaging.Messages.* +import org.pkl.core.messaging.Messages import org.pkl.core.packages.Checksums class ServerMessagePackCodecTest { @@ -52,18 +49,16 @@ class ServerMessagePackCodecTest { @Test fun `round-trip CreateEvaluatorRequest`() { - val resourceReader1 = ResourceReaderSpec("resourceReader1", true, true) - val resourceReader2 = ResourceReaderSpec("resourceReader2", true, false) - val moduleReader1 = ModuleReaderSpec("moduleReader1", true, true, true) - val moduleReader2 = ModuleReaderSpec("moduleReader2", true, false, false) + val resourceReader1 = Messages.ResourceReaderSpec("resourceReader1", true, true) + val resourceReader2 = Messages.ResourceReaderSpec("resourceReader2", true, false) + val moduleReader1 = Messages.ModuleReaderSpec("moduleReader1", true, true, true) + val moduleReader2 = Messages.ModuleReaderSpec("moduleReader2", true, false, false) val externalReader = ExternalReader("external-cmd", listOf("arg1", "arg2")) roundtrip( CreateEvaluatorRequest( requestId = 123, - allowedModules = listOf("pkl", "file", "https").map(Pattern::compile), - allowedResources = - listOf("pkl", "file", "https", "resourceReader1", "resourceReader2") - .map(Pattern::compile), + allowedModules = listOf("pkl", "file", "https"), + allowedResources = listOf("pkl", "file", "https", "resourceReader1", "resourceReader2"), clientResourceReaders = listOf(resourceReader1, resourceReader2), clientModuleReaders = listOf(moduleReader1, moduleReader2), modulePaths = listOf(Path.of("some/path.zip"), Path.of("other/path.zip")), @@ -99,7 +94,7 @@ class ServerMessagePackCodecTest { ), http = Http( - proxy = PklEvaluatorSettings.Proxy(URI("http://foo.com:1234"), listOf("bar", "baz")), + proxy = Proxy(URI("http://foo.com:1234"), listOf("bar", "baz")), caCertificates = byteArrayOf(1, 2, 3, 4), ), externalModuleReaders = mapOf("external" to externalReader, "external2" to externalReader),