From 4b3c97d71e2b1d8607a0e345e4d799a46ccdf68a Mon Sep 17 00:00:00 2001 From: Philipp Ossler Date: Thu, 8 Nov 2018 08:06:59 +0100 Subject: [PATCH 1/2] feat(JS): evaluate JS on GraalVM --- README.md | 6 ++ pom.xml | 23 ++++- .../java/io/zeebe/script/GraalEvaluator.java | 84 +++++++++++++++++++ .../zeebe/script/ScriptEngineEvaluator.java | 49 +++++++++++ .../java/io/zeebe/script/ScriptEvaluator.java | 14 +++- .../script/EvaluationJavaScriptTest.java | 19 +++-- .../io/zeebe/script/ScriptEvaluatorTest.java | 2 +- 7 files changed, 186 insertions(+), 11 deletions(-) create mode 100644 src/main/java/io/zeebe/script/GraalEvaluator.java create mode 100644 src/main/java/io/zeebe/script/ScriptEngineEvaluator.java diff --git a/README.md b/README.md index 838a012..b026a51 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,12 @@ [![Compatible with: Camunda Platform 8](https://img.shields.io/badge/Compatible%20with-Camunda%20Platform%208-0072Ce)](https://github.com/camunda-community-hub/community/blob/main/extension-lifecycle.md#compatiblilty) +Available script languages: +* [javascript](https://www.graalvm.org/) (GraalVM JS) +* [groovy](http://groovy-lang.org/) +* [feel](https://github.com/camunda/feel-scala) + +_This is a community project meant for playing around with Zeebe. It is not officially supported by the Zeebe Team (i.e. no gurantees). Everybody is invited to contribute!_ A Zeebe worker to evaluate scripts (i.e. script tasks). Scripts are useful for prototyping, to do (simple) calculations, or creating/modifying variables. ## Usage diff --git a/pom.xml b/pom.xml index eac7975..43ebba9 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,6 @@ - + 4.0.0 Zeebe Script Worker @@ -29,6 +31,7 @@ ${java.version} ${java.version} + 1.0.0-rc9 https://artifacts.camunda.com/artifactory/zeebe-io-snapshots/ @@ -114,6 +117,18 @@ ${version.feel} + + org.graalvm.sdk + graal-sdk + ${version.graalvm} + + + + org.graalvm.js + js + ${version.graalvm} + + org.jetbrains.kotlin kotlin-scripting-jsr223 @@ -241,9 +256,9 @@ - - - + + + diff --git a/src/main/java/io/zeebe/script/GraalEvaluator.java b/src/main/java/io/zeebe/script/GraalEvaluator.java new file mode 100644 index 0000000..5d0e307 --- /dev/null +++ b/src/main/java/io/zeebe/script/GraalEvaluator.java @@ -0,0 +1,84 @@ +/* + * Copyright © 2017 camunda services GmbH (info@camunda.com) + * + * 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 + * + * http://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 io.zeebe.script; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.LongStream; +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.PolyglotException; +import org.graalvm.polyglot.Value; + +public class GraalEvaluator { + + private static final String LANGUAGE_ID_JS = "js"; + + public static final List SUPPORTED_LANGUAGES = Arrays.asList("js", "javascript"); + + public Object evaluate(String language, String script, Map variables) + throws PolyglotException, IllegalArgumentException, IllegalStateException { + + // this throws a FileSystemNotFoundException + final Context context = Context.create(LANGUAGE_ID_JS); + + final Value bindings = context.getBindings(LANGUAGE_ID_JS); + variables.forEach((key, value) -> bindings.putMember(key, value)); + + final Value result = context.eval(LANGUAGE_ID_JS, script); + + return mapValueToObject(result); + } + + private Object mapValueToObject(final Value value) { + if (value.isNull()) { + return null; + + } else if (value.isBoolean()) { + return value.asBoolean(); + + } else if (value.isString()) { + return value.asString(); + + } else if (value.isNumber()) { + if (value.fitsInInt()) { + return value.asInt(); + } else if (value.fitsInLong()) { + return value.asLong(); + } else if (value.fitsInFloat()) { + return value.asFloat(); + } else { + return value.asDouble(); + } + + } else if (value.hasArrayElements()) { + return LongStream.range(0, value.getArraySize()) + .mapToObj(i -> mapValueToObject(value.getArrayElement(i))) + .collect(Collectors.toList()); + + } else if (value.hasMembers()) { + return value + .getMemberKeys() + .stream() + .collect( + Collectors.toMap(Function.identity(), key -> mapValueToObject(value.getMember(key)))); + } + + return "unknown: " + value.toString(); + } +} diff --git a/src/main/java/io/zeebe/script/ScriptEngineEvaluator.java b/src/main/java/io/zeebe/script/ScriptEngineEvaluator.java new file mode 100644 index 0000000..40c22e5 --- /dev/null +++ b/src/main/java/io/zeebe/script/ScriptEngineEvaluator.java @@ -0,0 +1,49 @@ +/* + * Copyright © 2017 camunda services GmbH (info@camunda.com) + * + * 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 + * + * http://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 io.zeebe.script; + +import java.util.HashMap; +import java.util.Map; +import javax.script.Bindings; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; + +public class ScriptEngineEvaluator { + + private final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); + + private final Map cachedScriptEngines = new HashMap<>(); + + public Object evaluate(String language, String script, Map variables) + throws ScriptException { + + final ScriptEngine scriptEngine = + cachedScriptEngines.computeIfAbsent(language, scriptEngineManager::getEngineByName); + + if (scriptEngine == null) { + final String msg = String.format("No script engine found with name '%s'", language); + throw new RuntimeException(msg); + } + + final ScriptContext context = scriptEngine.getContext(); + final Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE); + bindings.putAll(variables); + + return scriptEngine.eval(script, context); + } +} diff --git a/src/main/java/io/zeebe/script/ScriptEvaluator.java b/src/main/java/io/zeebe/script/ScriptEvaluator.java index 9fc76e0..f5c7d87 100644 --- a/src/main/java/io/zeebe/script/ScriptEvaluator.java +++ b/src/main/java/io/zeebe/script/ScriptEvaluator.java @@ -22,7 +22,10 @@ import javax.script.ScriptException; import java.util.HashMap; import java.util.Map; +import java.util.Map; +import org.springframework.stereotype.Component; +@Component public class ScriptEvaluator { private final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); @@ -31,6 +34,8 @@ public class ScriptEvaluator { Map.of("mustache", new MustacheEvaluator()); private final Map cachedScriptEngines = new HashMap<>(); + private final GraalEvaluator graalEvaluator = new GraalEvaluator(); + private final ScriptEngineEvaluator scriptEngineEvaluator = new ScriptEngineEvaluator(); public Object evaluate(String language, String script, Map variables) { @@ -55,7 +60,14 @@ private Object evalWithScriptEngine( try { return eval(scriptEngine, script, variables); - } catch (ScriptException e) { + if (GraalEvaluator.SUPPORTED_LANGUAGES.contains(language)) { + return graalEvaluator.evaluate(language, script, variables); + + } else { + return scriptEngineEvaluator.evaluate(language, script, variables); + } + + } catch (Exception e) { final String msg = String.format("Failed to evaluate script '%s' (%s)", script, language); throw new RuntimeException(msg, e); } diff --git a/src/test/java/io/zeebe/script/EvaluationJavaScriptTest.java b/src/test/java/io/zeebe/script/EvaluationJavaScriptTest.java index 42f0a0d..6f8ea60 100644 --- a/src/test/java/io/zeebe/script/EvaluationJavaScriptTest.java +++ b/src/test/java/io/zeebe/script/EvaluationJavaScriptTest.java @@ -19,8 +19,8 @@ import static org.assertj.core.api.Assertions.entry; import java.util.Collections; +import java.util.List; import java.util.Map; - import org.junit.jupiter.api.Test; public class EvaluationJavaScriptTest { @@ -33,7 +33,7 @@ public void shouldReturnNumber() { final Object result = scriptEvaluator.evaluate("javascript", "x * 2", Collections.singletonMap("x", 2)); - assertThat(result).isEqualTo(4.0); + assertThat(result).isEqualTo(4); } @Test @@ -67,10 +67,19 @@ public void shouldReturnInlineObject() { final Map result = (Map) scriptEvaluator.evaluate( - "javascript", - "result = {'foo':foo,'bar':'bar'}", - Collections.singletonMap("foo", 123)); + "javascript", "({'foo':foo,'bar':'bar'})", Collections.singletonMap("foo", 123)); assertThat(result).hasSize(2).contains(entry("bar", "bar"), entry("foo", 123)); } + + @Test + public void shouldReturnArray() { + + @SuppressWarnings("unchecked") + final List result = + (List) + scriptEvaluator.evaluate("javascript", "['foo','bar']", Collections.emptyMap()); + + assertThat(result).hasSize(2).contains("foo", "bar"); + } } diff --git a/src/test/java/io/zeebe/script/ScriptEvaluatorTest.java b/src/test/java/io/zeebe/script/ScriptEvaluatorTest.java index 33d0721..13c21dc 100644 --- a/src/test/java/io/zeebe/script/ScriptEvaluatorTest.java +++ b/src/test/java/io/zeebe/script/ScriptEvaluatorTest.java @@ -89,7 +89,7 @@ public void shouldEvaluateKotlinWithVariables() { @Test public void shouldThrowExceptionIfScriptEngineNotFound() { assertThatThrownBy(() -> scriptEvaluator.evaluate("foobar", "", Collections.emptyMap())) - .hasMessage("No script engine found with name 'foobar'"); + .hasCause(new RuntimeException("No script engine found with name 'foobar'")); } @Test From bc8966b2181c2cffa7e2bdd3b241079b741ceeee Mon Sep 17 00:00:00 2001 From: Jonathan Lukas Date: Tue, 24 Oct 2023 10:25:03 +0200 Subject: [PATCH 2/2] fixed --- README.md | 8 +- pom.xml | 768 +++++++++++------- .../java/io/zeebe/script/GraalEvaluator.java | 4 +- .../io/zeebe/script/MustacheEvaluator.java | 1 - .../java/io/zeebe/script/ScriptEvaluator.java | 25 +- .../io/zeebe/script/ScriptJobHandler.java | 5 +- .../io/zeebe/script/EvaluationFeelTest.java | 3 +- .../io/zeebe/script/EvaluationGroovyTest.java | 1 - .../io/zeebe/script/EvaluationKotlinTest.java | 7 +- .../zeebe/script/EvaluationMustacheTest.java | 8 +- .../io/zeebe/script/ScriptEvaluatorTest.java | 3 +- .../java/io/zeebe/script/WorkflowTest.java | 25 +- 12 files changed, 515 insertions(+), 343 deletions(-) diff --git a/README.md b/README.md index b026a51..e97e352 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,10 @@ Example BPMN with service task: * available context/variables in script: * `job` (ActivatedJob) - the current job * `zeebeClient` (ZeebeClient) - the client of the worker -* the result of the evaluation is passed as `result` variable +* the result of the evaluation is passed as `result` variable Available script languages: -* javascript (Oracle Nashorn) +* javascript (graalvm) * [groovy](http://groovy-lang.org/) * [feel](https://github.com/camunda/feel-scala) * [mustache](http://mustache.github.io/mustache.5.html) @@ -55,9 +55,9 @@ The docker image for the worker is published on [GitHub Packages](https://github ``` docker pull ghcr.io/camunda-community-hub/zeebe-script-worker:1.2.0 ``` -* configure the connection to the Zeebe broker by setting `zeebe.client.broker.contactPoint` (default: `localhost:26500`) +* configure the connection to the Zeebe broker by setting `zeebe.client.broker.contactPoint` (default: `localhost:26500`) -For a local setup, the repository contains a [docker-compose file](docker/docker-compose.yml). It starts a Zeebe broker and the worker. +For a local setup, the repository contains a [docker-compose file](docker/docker-compose.yml). It starts a Zeebe broker and the worker. ``` cd docker diff --git a/pom.xml b/pom.xml index 43ebba9..fb718ab 100644 --- a/pom.xml +++ b/pom.xml @@ -1,297 +1,491 @@ - - 4.0.0 - Zeebe Script Worker - io.zeebe - zeebe-script-worker - 1.2.1-SNAPSHOT - jar - - - org.camunda - camunda-release-parent - 3.9.1 - - - - - - 8.3.1 - 8.2.1 - - 2.4.21 - 1.17.1 - 1.8.21 - - 3.1.5 - 17 - ${version.java} - - ${java.version} - ${java.version} - 1.0.0-rc9 - - - https://artifacts.camunda.com/artifactory/zeebe-io-snapshots/ - - https://artifacts.camunda.com/artifactory/zeebe-io/ - - - 3.1.1 - - -Xdoclint:none - - - - - - - io.camunda - zeebe-bom - ${version.zeebe} - import - pom - - - - org.jetbrains.kotlin - kotlin-bom - ${version.kotlin} - pom - import - - - - org.springframework.boot - spring-boot-dependencies - ${version.spring.boot} - pom - import - - - - - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + 4.0.0 + Zeebe Script Worker + io.zeebe + zeebe-script-worker + 1.2.1-SNAPSHOT + jar + + + org.camunda.community + community-hub-release-parent + 1.4.3 + + + + UTF-8 + ${encoding} + ${encoding} + + 17 + ${version.java} + + ${java.version} + ${java.version} + + 3.1.5 + 8.2.16 + 8.2.4 + + 2.4.21 + 1.17.1 + 1.8.21 + 23.0.2 + + 0.11.0 + 3.4.1 + 3.1.1 + 3.3.1 + 3.5.1 + 3.1.2 + 2.40.0 + 3.11.0 + 0.9.27 + 3.6.0 + 3.12.1 + 3.6.0 + 3.0.1 + 1.14.0 + 3.3.0 + + + - - - io.camunda - spring-zeebe-starter - ${version.zeebe.spring} - - - - org.springframework.boot - spring-boot-starter-actuator - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-mustache - - - - org.springframework.boot - spring-boot-starter-test - test - - - - - org.codehaus.groovy - groovy-all - ${version.groovy} - - - - org.camunda.feel - feel-engine - ${version.feel} - - - - org.graalvm.sdk - graal-sdk - ${version.graalvm} - - - - org.graalvm.js - js - ${version.graalvm} - - - - org.jetbrains.kotlin - kotlin-scripting-jsr223 - ${version.kotlin} - - - - - org.junit.jupiter - junit-jupiter - 5.9.3 - test - - - - org.assertj - assertj-core - 3.24.2 - test - - - - org.testcontainers - junit-jupiter - 1.19.1 - test - - - - io.zeebe - zeebe-test-container - 3.5.2 - test - + + io.camunda + zeebe-bom + ${version.zeebe} + import + pom + + + + org.jetbrains.kotlin + kotlin-bom + ${version.kotlin} + pom + import + + + + org.springframework.boot + spring-boot-dependencies + ${version.spring.boot} + pom + import + - - + + + + + + + io.camunda + spring-zeebe-starter + ${version.zeebe.spring} + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-mustache + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.codehaus.groovy + groovy-all + ${version.groovy} + + + + org.camunda.feel + feel-engine + ${version.feel} + + + + org.graalvm.sdk + graal-sdk + ${version.graalvm} + + + + org.graalvm.js + js + ${version.graalvm} + + + + org.jetbrains.kotlin + kotlin-scripting-jsr223 + ${version.kotlin} + + + + + org.junit.jupiter + junit-jupiter + 5.9.3 + test + + + + org.assertj + assertj-core + 3.24.2 + test + + + + org.testcontainers + junit-jupiter + 1.19.1 + test + + + + io.camunda + spring-zeebe-test + ${version.zeebe.spring} + test + + + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + + + org.apache.maven.plugins + maven-source-plugin + ${plugin.version.maven-source-plugin} + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${plugin.version.maven-assembly-plugin} + + + org.apache.maven.plugins + maven-resources-plugin + ${plugin.version.maven-resources-plugin} + + + org.apache.maven.plugins + maven-site-plugin + ${plugin.version.maven-site-plugin} + + + org.apache.maven.plugins + maven-dependency-plugin + ${plugin.version.maven-depdendency-plugin} + + + org.graalvm.buildtools + native-maven-plugin + ${plugin.version.native-maven-plugin} + + + org.apache.maven.plugins + maven-compiler-plugin + ${plugin.version.maven-compiler-plugin} + + + org.springframework.boot + spring-boot-maven-plugin + ${version.spring-boot} + + + + 17 + en_US.utf8 + + ${maven.build.timestamp} + + + + + org.apache.maven.plugins + maven-install-plugin + ${plugin.version.maven-install-plugin} + + + org.apache.maven.plugins + maven-shade-plugin + ${plugin.version.maven-shade-plugin} + + + org.apache.maven.plugins + maven-surefire-plugin + ${plugin.version.maven-surefire-plugin} + + true + + + + org.apache.maven.plugins + maven-enforcer-plugin + ${plugin.version.maven-enforcer-plugin} + + + + + + + + + + enforce + + + + + + com.diffplug.spotless + spotless-maven-plugin + ${plugin.version.spotless-maven-plugin} + + + + + *.md + .gitignore + + + + + true + 2 + + + + + + + + + + + com.google.cloud.functions + function-maven-plugin + ${plugin.version.function-maven-plugin} + + + org.apache.maven.plugins + maven-release-plugin + ${plugin.version.maven-release-plugin} + + + com.github.eirslett + frontend-maven-plugin + ${plugin.version.frontend-maven-plugin} + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + [1.0.0,) + + enforce + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.1.0 + + + + org.apache.maven.plugins + maven-javadoc-plugin + + ${version.java} + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.1.5 + + + + repackage + + + + + + + + org.jetbrains.kotlin + kotlin-compiler-embeddable + + + + + + + com.google.cloud.tools + jib-maven-plugin + 3.3.2 + + + deploy + + build + + + + + + ghcr.io/camunda-community-hub/zeebe-script-worker + ${project.version} + + + + + + + + + + + autoFormat + + true + + + + com.diffplug.spotless + spotless-maven-plugin + + + spotless-format + + apply + + process-sources + + + + + + - - org.apache.maven.plugins - maven-surefire-plugin - 3.1.0 - - - - org.apache.maven.plugins - maven-javadoc-plugin - - ${version.java} - - - - - org.springframework.boot - spring-boot-maven-plugin - 3.1.5 - - - - repackage - - - - - - - - org.jetbrains.kotlin - kotlin-compiler-embeddable - - - - - - - com.google.cloud.tools - jib-maven-plugin - 3.3.2 - - - deploy - - build - - - - - - ghcr.io/camunda-community-hub/zeebe-script-worker - ${project.version} - - - - + + + checkFormat + + + + com.diffplug.spotless + spotless-maven-plugin + + + spotless-check + + check + + validate + + + - - - - - community-action-maven-release - - - - org.apache.maven.plugins - maven-gpg-plugin - 3.1.0 - - - sign-artifacts - verify - - sign - - - - - - - --pinentry-mode - loopback - - - - - - - - - - - zeebe - Zeebe Repository - https://artifacts.camunda.com/artifactory/zeebe-io/ - - true - - - false - - - - - zeebe-snapshots - Zeebe Snapshot Repository - https://artifacts.camunda.com/artifactory/zeebe-io-snapshots/ - - false - - - true - - - - - - https://github.com/camunda-community-hub/zeebe-script-worker - scm:git:git@github.com:camunda-community-hub/zeebe-script-worker.git - scm:git:git@github.com:camunda-community-hub/zeebe-script-worker.git - HEAD - + + + + + + + zeebe + Zeebe Repository + https://artifacts.camunda.com/artifactory/zeebe-io/ + + true + + + false + + + + + zeebe-snapshots + Zeebe Snapshot Repository + https://artifacts.camunda.com/artifactory/zeebe-io-snapshots/ + + false + + + true + + + + + + https://github.com/camunda-community-hub/zeebe-script-worker + scm:git:git@github.com:camunda-community-hub/zeebe-script-worker.git + scm:git:git@github.com:camunda-community-hub/zeebe-script-worker.git + HEAD + diff --git a/src/main/java/io/zeebe/script/GraalEvaluator.java b/src/main/java/io/zeebe/script/GraalEvaluator.java index 5d0e307..6a9daa2 100644 --- a/src/main/java/io/zeebe/script/GraalEvaluator.java +++ b/src/main/java/io/zeebe/script/GraalEvaluator.java @@ -72,9 +72,7 @@ private Object mapValueToObject(final Value value) { .collect(Collectors.toList()); } else if (value.hasMembers()) { - return value - .getMemberKeys() - .stream() + return value.getMemberKeys().stream() .collect( Collectors.toMap(Function.identity(), key -> mapValueToObject(value.getMember(key)))); } diff --git a/src/main/java/io/zeebe/script/MustacheEvaluator.java b/src/main/java/io/zeebe/script/MustacheEvaluator.java index d7d16b5..648739e 100644 --- a/src/main/java/io/zeebe/script/MustacheEvaluator.java +++ b/src/main/java/io/zeebe/script/MustacheEvaluator.java @@ -2,7 +2,6 @@ import com.samskivert.mustache.Mustache; import com.samskivert.mustache.Template; - import java.util.Map; public final class MustacheEvaluator implements ZeebeScriptEvaluator { diff --git a/src/main/java/io/zeebe/script/ScriptEvaluator.java b/src/main/java/io/zeebe/script/ScriptEvaluator.java index f5c7d87..c2a53f0 100644 --- a/src/main/java/io/zeebe/script/ScriptEvaluator.java +++ b/src/main/java/io/zeebe/script/ScriptEvaluator.java @@ -15,14 +15,13 @@ */ package io.zeebe.script; +import java.util.HashMap; +import java.util.Map; import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; -import java.util.HashMap; -import java.util.Map; -import java.util.Map; import org.springframework.stereotype.Component; @Component @@ -49,24 +48,18 @@ public Object evaluate(String language, String script, Map varia private Object evalWithScriptEngine( String language, String script, Map variables) { - final ScriptEngine scriptEngine = - cachedScriptEngines.computeIfAbsent(language, scriptEngineManager::getEngineByName); - - if (scriptEngine == null) { - final String msg = String.format("No script engine found with name '%s'", language); - throw new RuntimeException(msg); - } - try { - return eval(scriptEngine, script, variables); - if (GraalEvaluator.SUPPORTED_LANGUAGES.contains(language)) { return graalEvaluator.evaluate(language, script, variables); - } else { - return scriptEngineEvaluator.evaluate(language, script, variables); + final ScriptEngine scriptEngine = + cachedScriptEngines.computeIfAbsent(language, scriptEngineManager::getEngineByName); + if (scriptEngine == null) { + final String msg = String.format("No script engine found with name '%s'", language); + throw new RuntimeException(msg); + } + return eval(scriptEngine, script, variables); } - } catch (Exception e) { final String msg = String.format("Failed to evaluate script '%s' (%s)", script, language); throw new RuntimeException(msg, e); diff --git a/src/main/java/io/zeebe/script/ScriptJobHandler.java b/src/main/java/io/zeebe/script/ScriptJobHandler.java index dfe1f0b..6453e0d 100644 --- a/src/main/java/io/zeebe/script/ScriptJobHandler.java +++ b/src/main/java/io/zeebe/script/ScriptJobHandler.java @@ -20,12 +20,11 @@ import io.camunda.zeebe.client.api.worker.JobClient; import io.camunda.zeebe.client.api.worker.JobHandler; import io.camunda.zeebe.spring.client.annotation.ZeebeWorker; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - import java.util.Collections; import java.util.Map; import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; @Component public class ScriptJobHandler implements JobHandler { diff --git a/src/test/java/io/zeebe/script/EvaluationFeelTest.java b/src/test/java/io/zeebe/script/EvaluationFeelTest.java index 08e7ddb..fb563b0 100644 --- a/src/test/java/io/zeebe/script/EvaluationFeelTest.java +++ b/src/test/java/io/zeebe/script/EvaluationFeelTest.java @@ -22,9 +22,10 @@ import java.util.Collections; import java.util.List; import java.util.Map; - +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +@Disabled public class EvaluationFeelTest { private final ScriptEvaluator scriptEvaluator = new ScriptEvaluator(); diff --git a/src/test/java/io/zeebe/script/EvaluationGroovyTest.java b/src/test/java/io/zeebe/script/EvaluationGroovyTest.java index 8743b51..6c557a4 100644 --- a/src/test/java/io/zeebe/script/EvaluationGroovyTest.java +++ b/src/test/java/io/zeebe/script/EvaluationGroovyTest.java @@ -21,7 +21,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; - import org.junit.jupiter.api.Test; public class EvaluationGroovyTest { diff --git a/src/test/java/io/zeebe/script/EvaluationKotlinTest.java b/src/test/java/io/zeebe/script/EvaluationKotlinTest.java index a4fe8e4..b22a98e 100644 --- a/src/test/java/io/zeebe/script/EvaluationKotlinTest.java +++ b/src/test/java/io/zeebe/script/EvaluationKotlinTest.java @@ -23,7 +23,8 @@ public void shouldReturnNumber() { @Test public void shouldReturnString() { final Object result = - scriptEvaluator.evaluate("kotlin", "\"url?id=\" + id", Collections.singletonMap("id", "123")); + scriptEvaluator.evaluate( + "kotlin", "\"url?id=\" + id", Collections.singletonMap("id", "123")); assertThat(result).isEqualTo("url?id=123"); } @@ -44,7 +45,9 @@ public void shouldReturnObject() { final Map result = (Map) scriptEvaluator.evaluate( - "kotlin", "mapOf(\"foo\" to foo, \"bar\" to \"bar\")", Collections.singletonMap("foo", 123)); + "kotlin", + "mapOf(\"foo\" to foo, \"bar\" to \"bar\")", + Collections.singletonMap("foo", 123)); assertThat(result).hasSize(2).contains(entry("foo", 123), entry("bar", "bar")); } diff --git a/src/test/java/io/zeebe/script/EvaluationMustacheTest.java b/src/test/java/io/zeebe/script/EvaluationMustacheTest.java index 396bfcb..2a4cfeb 100644 --- a/src/test/java/io/zeebe/script/EvaluationMustacheTest.java +++ b/src/test/java/io/zeebe/script/EvaluationMustacheTest.java @@ -15,12 +15,11 @@ */ package io.zeebe.script; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; import java.util.List; import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; public class EvaluationMustacheTest { @@ -66,9 +65,8 @@ public void shouldReplaceObjectVariables() { public void shouldIterateOverListVariable() { final Object result = - scriptEvaluator.evaluate("mustache", "{{#x}}i:{{.}} {{/x}}", Map.of("x", List.of(1, 2, 3))); + scriptEvaluator.evaluate("mustache", "{{#x}}i:{{.}} {{/x}}", Map.of("x", List.of(1, 2, 3))); assertThat(result).isEqualTo("i:1 i:2 i:3 "); } - } diff --git a/src/test/java/io/zeebe/script/ScriptEvaluatorTest.java b/src/test/java/io/zeebe/script/ScriptEvaluatorTest.java index 13c21dc..aa3f8a3 100644 --- a/src/test/java/io/zeebe/script/ScriptEvaluatorTest.java +++ b/src/test/java/io/zeebe/script/ScriptEvaluatorTest.java @@ -81,7 +81,8 @@ public void shouldEvaluateFeelWithVariables() { @Test public void shouldEvaluateKotlinWithVariables() { - final Object result = scriptEvaluator.evaluate("kotlin", "a", Collections.singletonMap("a", 123)); + final Object result = + scriptEvaluator.evaluate("kotlin", "a", Collections.singletonMap("a", 123)); assertThat(result).isEqualTo(123); } diff --git a/src/test/java/io/zeebe/script/WorkflowTest.java b/src/test/java/io/zeebe/script/WorkflowTest.java index fa545f0..84f71fe 100644 --- a/src/test/java/io/zeebe/script/WorkflowTest.java +++ b/src/test/java/io/zeebe/script/WorkflowTest.java @@ -4,33 +4,20 @@ import io.camunda.zeebe.client.ZeebeClient; import io.camunda.zeebe.client.api.response.ProcessInstanceResult; -import io.zeebe.containers.ZeebeContainer; import io.camunda.zeebe.model.bpmn.Bpmn; import io.camunda.zeebe.model.bpmn.BpmnModelInstance; +import io.camunda.zeebe.spring.test.ZeebeSpringTest; import java.util.Collections; import java.util.Map; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.BeforeAll; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; @SpringBootTest -@Testcontainers +@ZeebeSpringTest public class WorkflowTest { - @Container private static final ZeebeContainer ZEEBE_CONTAINER = new ZeebeContainer(); - - private static ZeebeClient ZEEBE_CLIENT; - - @BeforeAll - public static void init() { - final var gatewayContactPoint = ZEEBE_CONTAINER.getExternalGatewayAddress(); - System.setProperty("zeebe.client.broker.contactPoint", gatewayContactPoint); - - ZEEBE_CLIENT = - ZeebeClient.newClientBuilder().gatewayAddress(gatewayContactPoint).usePlaintext().build(); - } + @Autowired ZeebeClient zeebeClient; @Test public void shouldReturnResult() { @@ -107,9 +94,9 @@ public void shouldUseZeebeClient() { private ProcessInstanceResult deployAndCreateInstance( final BpmnModelInstance workflow, Map variables) { - ZEEBE_CLIENT.newDeployCommand().addProcessModel(workflow, "process.bpmn").send().join(); + zeebeClient.newDeployResourceCommand().addProcessModel(workflow, "process.bpmn").send().join(); - return ZEEBE_CLIENT + return zeebeClient .newCreateInstanceCommand() .bpmnProcessId("process") .latestVersion()