Skip to content

refactored interfaces #527

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package io.camunda.community.connector.script;

import io.camunda.community.connector.script.ScriptConnectorInput.Type;
import io.camunda.community.connector.script.ScriptConnectorInput.Type.Embedded;
import io.camunda.community.connector.script.ScriptConnectorInput.Type.Resource;
import io.camunda.connector.api.annotation.OutboundConnector;
import io.camunda.connector.api.outbound.OutboundConnectorContext;
import io.camunda.connector.api.outbound.OutboundConnectorFunction;
Expand All @@ -22,52 +19,19 @@ public class ScriptConnector implements OutboundConnectorFunction {
public static final String SCRIPT_CONNECTOR_TYPE = "io.camunda.community:script-connector";

private final ScriptEvaluator scriptEvaluator;
private final ScriptResourceProvider scriptResourceProvider;
private final LanguageProvider languageProvider;

public ScriptConnector() {
scriptEvaluator = new ScriptEvaluator();
scriptResourceProvider = new ScriptResourceProvider();
languageProvider = new LanguageProvider();
this(new ScriptEvaluator());
}

public ScriptConnector(
ScriptEvaluator scriptEvaluator,
ScriptResourceProvider scriptResourceProvider,
LanguageProvider languageProvider) {
public ScriptConnector(ScriptEvaluator scriptEvaluator) {
this.scriptEvaluator = scriptEvaluator;
this.scriptResourceProvider = scriptResourceProvider;
this.languageProvider = languageProvider;
}

@Override
public Object execute(OutboundConnectorContext outboundConnectorContext) {
ScriptConnectorInput scriptConnectorInput =
outboundConnectorContext.bindVariables(ScriptConnectorInput.class);
String script = extractScript(scriptConnectorInput);
String language = extractLanguage(scriptConnectorInput);
return scriptEvaluator.evaluate(language, script, scriptConnectorInput.context());
}

private String extractLanguage(ScriptConnectorInput scriptConnectorInput) {
Type script = scriptConnectorInput.script();
if (script instanceof Embedded e) {
return e.language();
} else if (script instanceof Resource r) {
return languageProvider.getLanguageForScriptResource(r.resource());
} else {
throw new IllegalStateException("No script or resource has been provided");
}
}

private String extractScript(ScriptConnectorInput scriptConnectorInput) {
Type script = scriptConnectorInput.script();
if (script instanceof Embedded e) {
return e.embedded();
} else if (script instanceof Resource r) {
return scriptResourceProvider.provideScript(r.resource());
} else {
throw new IllegalStateException("No script or resource has been provided");
}
return scriptEvaluator.evaluate(scriptConnectorInput.script(), scriptConnectorInput.context());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import io.camunda.community.connector.script.ScriptConnectorInput.Type.Embedded;
import io.camunda.community.connector.script.ScriptConnectorInput.Type.Resource;
import io.camunda.community.connector.script.ScriptConnectorInput.ScriptType.Embedded;
import io.camunda.community.connector.script.ScriptConnectorInput.ScriptType.Resource;
import io.camunda.connector.generator.dsl.Property.FeelMode;
import io.camunda.connector.generator.java.annotation.TemplateProperty;
import jakarta.validation.Valid;
Expand All @@ -17,7 +17,7 @@ public record ScriptConnectorInput(
@TemplateProperty(label = "Script description", description = "How the script is implemented")
@NotNull
@Valid
Type script,
ScriptType script,
@TemplateProperty(
label = "Script context",
feel = FeelMode.required,
Expand All @@ -29,7 +29,7 @@ public record ScriptConnectorInput(
@JsonSubTypes.Type(value = Embedded.class, name = "embedded"),
@JsonSubTypes.Type(value = Resource.class, name = "resource")
})
sealed interface Type {
public sealed interface ScriptType {
record Embedded(
@TemplateProperty(label = "Script", description = "The script to be executed") @NotNull
String embedded,
Expand All @@ -39,7 +39,7 @@ record Embedded(
"The language the script uses. By default, the ones available are: javascript, groovy, kotlin, mustache")
@NotNull
String language)
implements Type {}
implements ScriptType {}

record Resource(
@TemplateProperty(
Expand All @@ -48,6 +48,6 @@ record Resource(
"The resource that should be executed. Should be prefixed with 'classpath:' for a classpath resource, 'file:' for a file system resource. If none of these prefixes matches, it will attempt to load the provided resource as URL.")
@NotNull
String resource)
implements Type {}
implements ScriptType {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static java.util.Optional.*;

import io.camunda.community.connector.script.ScriptConnectorInput.ScriptType.Embedded;
import io.camunda.connector.api.annotation.OutboundConnector;
import io.camunda.connector.api.outbound.OutboundConnectorContext;
import io.camunda.connector.api.outbound.OutboundConnectorFunction;
Expand All @@ -28,7 +29,7 @@ public Object execute(OutboundConnectorContext outboundConnectorContext) throws

final Map<String, Object> variables = getVariablesAsMap(outboundConnectorContext);

return scriptEvaluator.evaluate(language, script, variables);
return scriptEvaluator.evaluate(new Embedded(script, language), variables);
}

private String getLanguage(Map<String, String> customHeaders) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.camunda.community.connector.script;

import io.camunda.community.connector.script.ScriptConnectorInput.ScriptType;
import io.camunda.community.connector.script.spi.ScriptEvaluatorExtension;
import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -49,14 +50,14 @@ public ScriptEvaluator(Set<ScriptEvaluatorExtension> extensions) {
.forEach(language -> scriptEvaluatorExtensions.put(language, e)));
}

public Object evaluate(String language, String script, Map<String, Object> variables) {

public Object evaluate(ScriptType script, Map<String, Object> variables) {
String language = ScriptTypeUtil.extractLanguage(script);
if (scriptEvaluatorExtensions.containsKey(language)) {
final var scriptEvaluator = scriptEvaluatorExtensions.get(language);
return scriptEvaluator.evaluateScript(script, variables);
}

return evalWithScriptEngine(language, script, variables);
return evalWithScriptEngine(language, ScriptTypeUtil.extractScript(script), variables);
}

private Object evalWithScriptEngine(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.camunda.community.connector.script;

import io.camunda.community.connector.script.ScriptConnectorInput.ScriptType;
import io.camunda.community.connector.script.ScriptConnectorInput.ScriptType.Embedded;
import io.camunda.community.connector.script.ScriptConnectorInput.ScriptType.Resource;

public class ScriptTypeUtil {

public static String extractScript(ScriptType script) {
return extractScript(script, new ScriptResourceProvider());
}

public static String extractScript(
ScriptType script, ScriptResourceProvider scriptResourceProvider) {
if (script instanceof Embedded e) {
return e.embedded();
} else if (script instanceof Resource(String resource)) {
return scriptResourceProvider.provideScript(resource);
} else {
throw new IllegalStateException("No script or resource has been provided");
}
}

public static String extractLanguage(ScriptType script) {
return extractLanguage(script, new LanguageProvider());
}

public static String extractLanguage(ScriptType script, LanguageProvider languageProvider) {
if (script instanceof Embedded e) {
return e.language();
} else if (script instanceof Resource(String resource)) {
return languageProvider.getLanguageForScriptResource(resource);
} else {
throw new IllegalStateException("No script or resource has been provided");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.camunda.community.connector.script.spi;

import io.camunda.community.connector.script.ScriptConnectorInput.ScriptType;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
Expand All @@ -13,5 +14,5 @@ static List<ScriptEvaluatorExtension> load() {

Set<String> getEvaluatedLanguage();

Object evaluateScript(String script, Map<String, Object> context);
Object evaluateScript(ScriptType script, Map<String, Object> context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import io.camunda.community.connector.script.ScriptConnectorInput.ScriptType;
import io.camunda.community.connector.script.ScriptTypeUtil;
import io.camunda.community.connector.script.spi.ScriptEvaluatorExtension;
import java.util.Map;
import java.util.Set;
Expand All @@ -13,8 +15,9 @@ public Set<String> getEvaluatedLanguage() {
}

@Override
public Object evaluateScript(String script, Map<String, Object> context) {
final Template template = Mustache.compiler().compile(script);
public Object evaluateScript(ScriptType script, Map<String, Object> context) {
String loadedScript = ScriptTypeUtil.extractScript(script);
final Template template = Mustache.compiler().compile(loadedScript);
return template.execute(context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;

import io.camunda.community.connector.script.ScriptConnectorInput.ScriptType.Embedded;
import java.util.Collections;
import java.util.List;
import java.util.Map;
Expand All @@ -31,7 +32,7 @@ public class EvaluationGroovyTest {
public void shouldReturnNumber() {

final Object result =
scriptEvaluator.evaluate("groovy", "x * 2", Collections.singletonMap("x", 2));
scriptEvaluator.evaluate(new Embedded("x * 2", "groovy"), Collections.singletonMap("x", 2));

assertThat(result).isEqualTo(4);
}
Expand All @@ -40,7 +41,8 @@ public void shouldReturnNumber() {
public void shouldReturnString() {

final Object result =
scriptEvaluator.evaluate("groovy", "'url?id=' + id", Collections.singletonMap("id", "123"));
scriptEvaluator.evaluate(
new Embedded("'url?id=' + id", "groovy"), Collections.singletonMap("id", "123"));

assertThat(result).isEqualTo("url?id=123");
}
Expand All @@ -50,7 +52,8 @@ public void shouldReturnList() {
@SuppressWarnings("unchecked")
final List<Object> result =
(List<Object>)
scriptEvaluator.evaluate("groovy", "[1,2,3]", Collections.singletonMap("x", 3));
scriptEvaluator.evaluate(
new Embedded("[1,2,3]", "groovy"), Collections.singletonMap("x", 3));

assertThat(result).hasSize(3).contains(1, 2, 3);
}
Expand All @@ -61,7 +64,8 @@ public void shouldReturnObject() {
final Map<String, Object> result =
(Map<String, Object>)
scriptEvaluator.evaluate(
"groovy", "[foo:foo,bar:'bar']", Collections.singletonMap("foo", 123));
new Embedded("[foo:foo,bar:'bar']", "groovy"),
Collections.singletonMap("foo", 123));

assertThat(result).hasSize(2).contains(entry("foo", 123), entry("bar", "bar"));
}
Expand All @@ -71,7 +75,8 @@ public void shouldReturnResultOfStringInterpolation() {

final Object result =
scriptEvaluator.evaluate(
"groovy", "\"url?id=${id}\".toString()", Collections.singletonMap("id", 123));
new Embedded("\"url?id=${id}\".toString()", "groovy"),
Collections.singletonMap("id", 123));

assertThat(result).isEqualTo("url?id=123");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
*/
package io.camunda.community.connector.script;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.assertj.core.api.Assertions.*;

import io.camunda.community.connector.script.ScriptConnectorInput.ScriptType.Embedded;
import java.util.Collections;
import java.util.List;
import java.util.Map;
Expand All @@ -31,7 +31,8 @@ public class EvaluationJavaScriptTest {
public void shouldReturnNumber() {

final Object result =
scriptEvaluator.evaluate("javascript", "x * 2", Collections.singletonMap("x", 2));
scriptEvaluator.evaluate(
new Embedded("x * 2", "javascript"), Collections.singletonMap("x", 2));

assertThat(result).isEqualTo(4);
}
Expand All @@ -41,7 +42,7 @@ public void shouldReturnString() {

final Object result =
scriptEvaluator.evaluate(
"javascript", "'url?id=' + id", Collections.singletonMap("id", 123));
new Embedded("'url?id=' + id", "javascript"), Collections.singletonMap("id", 123));

assertThat(result).isEqualTo("url?id=123");
}
Expand All @@ -53,8 +54,7 @@ public void shouldReturnObject() {
final Map<String, Object> result =
(Map<String, Object>)
scriptEvaluator.evaluate(
"javascript",
"x = {}; " + "x.bar = 'bar'; " + "x.foo = foo; " + "x",
new Embedded("x = {}; " + "x.bar = 'bar'; " + "x.foo = foo; " + "x", "javascript"),
Collections.singletonMap("foo", 123));

assertThat(result).hasSize(2).contains(entry("bar", "bar"), entry("foo", 123));
Expand All @@ -67,7 +67,8 @@ public void shouldReturnInlineObject() {
final Map<String, Object> result =
(Map<String, Object>)
scriptEvaluator.evaluate(
"javascript", "({'foo':foo,'bar':'bar'})", Collections.singletonMap("foo", 123));
new Embedded("({'foo':foo,'bar':'bar'})", "javascript"),
Collections.singletonMap("foo", 123));

assertThat(result).hasSize(2).contains(entry("bar", "bar"), entry("foo", 123));
}
Expand All @@ -78,7 +79,8 @@ public void shouldReturnArray() {
@SuppressWarnings("unchecked")
final List<String> result =
(List<String>)
scriptEvaluator.evaluate("javascript", "['foo','bar']", Collections.emptyMap());
scriptEvaluator.evaluate(
new Embedded("['foo','bar']", "javascript"), Collections.emptyMap());

assertThat(result).hasSize(2).contains("foo", "bar");
}
Expand Down
Loading