diff --git a/pom.xml b/pom.xml
index 12cf56a..ec2f060 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,6 +24,7 @@
6.6.8
3.27.1
2.43.0
+ 1.0.0
@@ -42,6 +43,13 @@
pom
import
+
+ com.dylibso.chicory
+ bom
+ ${chicory.version}
+ pom
+ import
+
@@ -73,6 +81,14 @@
generator-annotations
${fabric8-client.version}
+
+ com.dylibso.chicory
+ runtime
+
+
+ com.dylibso.chicory
+ wasi
+
org.awaitility
awaitility
@@ -88,23 +104,6 @@
io.quarkus
quarkus-container-image-jib
-
- org.graalvm.polyglot
- polyglot
- ${graalvm.version}
-
-
- org.graalvm.js
- js-scriptengine
- ${graalvm.version}
-
-
- org.graalvm.polyglot
- js-community
- ${graalvm.version}
- pom
- runtime
-
org.bouncycastle
bcpkix-jdk18on
@@ -207,6 +206,23 @@
+
+ com.dylibso.chicory
+ aot-maven-plugin-experimental
+ ${chicory.version}
+
+
+ quickJs
+
+ wasm-aot-gen
+
+
+ io.javaoperatorsdk.operator.glue.wasm.QuickJs
+ src/main/resources/wasm/quickjs-provider.wasm
+
+
+
+
diff --git a/src/main/java/io/javaoperatorsdk/operator/glue/conditions/JavaScripCondition.java b/src/main/java/io/javaoperatorsdk/operator/glue/conditions/JavaScripCondition.java
index 60c8ce4..a5bc608 100644
--- a/src/main/java/io/javaoperatorsdk/operator/glue/conditions/JavaScripCondition.java
+++ b/src/main/java/io/javaoperatorsdk/operator/glue/conditions/JavaScripCondition.java
@@ -1,12 +1,12 @@
package io.javaoperatorsdk.operator.glue.conditions;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Map;
import java.util.stream.Collectors;
-import javax.script.*;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -17,14 +17,20 @@
import io.javaoperatorsdk.operator.glue.GlueException;
import io.javaoperatorsdk.operator.glue.Utils;
import io.javaoperatorsdk.operator.glue.customresource.glue.Glue;
+import io.javaoperatorsdk.operator.glue.wasm.QuickJsModule;
import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition;
+import com.dylibso.chicory.runtime.ImportValues;
+import com.dylibso.chicory.runtime.Instance;
+import com.dylibso.chicory.wasi.WasiOptions;
+import com.dylibso.chicory.wasi.WasiPreview1;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
public class JavaScripCondition implements Condition {
private static final Logger LOG = LoggerFactory.getLogger(JavaScripCondition.class);
- private static final String RESOURCE_AS_STRING_NAME_SUFFIX = "Str";
-
private final String inputScript;
public JavaScripCondition(String inputScript) {
@@ -35,50 +41,71 @@ public JavaScripCondition(String inputScript) {
public boolean isMet(DependentResource dependentResource,
Glue glue,
Context context) {
- try {
+ try (var jsStderr = new ByteArrayOutputStream();
+ var wasi = WasiPreview1.builder()
+ .withOptions(WasiOptions.builder().withStderr(jsStderr).build()).build()) {
var start = LocalDateTime.now();
- ScriptEngineManager manager = new ScriptEngineManager();
- ScriptEngine engine = manager.getEngineByName("js");
+
+ var quickjs = Instance.builder(QuickJsModule.load())
+ .withImportValues(ImportValues.builder().addFunction(wasi.toHostFunctions()).build())
+ .withMachineFactory(QuickJsModule::create)
+ .build();
StringBuilder finalScript = new StringBuilder();
- addTargetResourceToScript(dependentResource, glue, context, engine, finalScript);
- addSecondaryResourceToScript(glue, context, engine, finalScript);
+ addTargetResourceToScript(dependentResource, glue, context, finalScript);
+ addSecondaryResourceToScript(glue, context, finalScript);
finalScript.append("\n").append(inputScript);
- LOG.debug("Final Condition JS:\n{}", finalScript);
+ // Using stderr to return the result
+ String finalJsCode = "console.error(eval(`" + finalScript + "`));";
+ LOG.debug("Final Condition JS:\n{}", finalJsCode);
+ byte[] jsCode = finalJsCode.getBytes(UTF_8);
+
+ var ptr =
+ quickjs.export("canonical_abi_realloc")
+ .apply(
+ 0, // original_ptr
+ 0, // original_size
+ 1, // alignment
+ jsCode.length // new size
+ )[0];
+
+ quickjs.memory().write((int) ptr, jsCode);
+ var aggregatedCodePtr = quickjs.export("compile_src").apply(ptr, jsCode.length)[0];
+
+ var codePtr = quickjs.memory().readI32((int) aggregatedCodePtr); // 32 bit
+ var codeLength = quickjs.memory().readU32((int) aggregatedCodePtr + 4);
+
+ quickjs.export("eval_bytecode").apply(codePtr, codeLength);
- CompiledScript script = ((Compilable) engine).compile(finalScript.toString());
- var res = (boolean) script.eval();
+ var res = Boolean.valueOf(jsStderr.toString().trim());
LOG.debug("JS Condition evaluated as: {} within {}ms", res,
ChronoUnit.MILLIS.between(start, LocalDateTime.now()));
return res;
- } catch (ScriptException e) {
+ } catch (IOException e) {
throw new GlueException(e);
}
}
private static void addSecondaryResourceToScript(Glue glue,
Context context,
- ScriptEngine engine, StringBuilder finalScript) {
+ StringBuilder finalScript) {
Map namedSecondaryResources =
nameAndSerializeSecondaryResources(context, glue);
namedSecondaryResources.forEach((k, v) -> {
- var stringKey = k + RESOURCE_AS_STRING_NAME_SUFFIX;
- engine.put(stringKey, v);
- finalScript.append("const ").append(k).append(" = JSON.parse(").append(stringKey)
- .append(");\n");
+ finalScript.append("const ").append(k).append(" = JSON.parse('").append(v)
+ .append("');\n");
});
}
private static void addTargetResourceToScript(
DependentResource dependentResource,
Glue glue,
- Context context, ScriptEngine engine, StringBuilder finalScript) {
+ Context context, StringBuilder finalScript) {
var target = dependentResource.getSecondaryResource(glue, context);
target.ifPresent(t -> {
- engine.put("targetStr", Serialization.asJson(t));
- finalScript.append("const target = JSON.parse(targetStr);\n");
+ finalScript.append("const target = JSON.parse('" + Serialization.asJson(t) + "');\n");
});
}
diff --git a/src/main/resources/wasm/quickjs-provider.wasm b/src/main/resources/wasm/quickjs-provider.wasm
new file mode 100644
index 0000000..abcdf4e
Binary files /dev/null and b/src/main/resources/wasm/quickjs-provider.wasm differ
diff --git a/src/test/java/io/javaoperatorsdk/operator/glue/JavaScripConditionTest.java b/src/test/java/io/javaoperatorsdk/operator/glue/JavaScripConditionTest.java
index dcd1e15..37b4028 100644
--- a/src/test/java/io/javaoperatorsdk/operator/glue/JavaScripConditionTest.java
+++ b/src/test/java/io/javaoperatorsdk/operator/glue/JavaScripConditionTest.java
@@ -40,7 +40,7 @@ void setup() {
void javaScriptSimpleConditionTest() {
var condition = new JavaScripCondition("""
- x = 1;
+ const x = 1;
x<2;
""");