diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1adf10d25..f5a268014 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/setup-java@v1 name: setup java with: - java-version: '14' + java-version: '15' java-package: jdk architecture: x64 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2228b2171..8757d8361 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: - name: setup java uses: actions/setup-java@v1 with: - java-version: '14' + java-version: '15' java-package: jdk architecture: x64 diff --git a/DOWNLOADS.md b/DOWNLOADS.md index d3d12e8ae..b20cb9575 100644 --- a/DOWNLOADS.md +++ b/DOWNLOADS.md @@ -9,7 +9,8 @@ The latest release of NoSQLBench is always available from github releases. - (be sure to `chmod +x nb` once you download it) - download [the latest release of nb.jar](https://github.com/nosqlbench/nosqlbench/releases/latest/download/nb.jar), a single-jar application. - - This requires java 14 or later, make sure your `java -version` command says that you are on Java 14 or later. + - This requires java 15 or later, make sure your `java -version + ` command says that you are on Java 15 or later. ## Docker diff --git a/driver-cql-shaded/src/main/java/io/nosqlbench/activitytype/cql/statements/core/CQLSessionCache.java b/driver-cql-shaded/src/main/java/io/nosqlbench/activitytype/cql/statements/core/CQLSessionCache.java index db84e375e..82787d3bb 100644 --- a/driver-cql-shaded/src/main/java/io/nosqlbench/activitytype/cql/statements/core/CQLSessionCache.java +++ b/driver-cql-shaded/src/main/java/io/nosqlbench/activitytype/cql/statements/core/CQLSessionCache.java @@ -11,11 +11,12 @@ import io.nosqlbench.activitytype.cql.core.ProxyTranslator; import io.nosqlbench.engine.api.activityapi.core.Shutdownable; import io.nosqlbench.engine.api.activityimpl.ActivityDef; import io.nosqlbench.engine.api.metrics.ActivityMetrics; -import io.nosqlbench.engine.api.scripting.NashornEvaluator; +import io.nosqlbench.engine.api.scripting.ExprEvaluator; +import io.nosqlbench.engine.api.scripting.GraalJsEvaluator; import io.nosqlbench.engine.api.util.SSLKsFactory; import io.nosqlbench.nb.api.errors.BasicError; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import javax.net.ssl.SSLContext; import java.io.File; @@ -129,7 +130,7 @@ public class CQLSessionCache implements Shutdownable { if (clusteropts.isPresent()) { try { logger.info("applying cbopts:" + clusteropts.get()); - NashornEvaluator clusterEval = new NashornEvaluator<>(DseCluster.Builder.class); + ExprEvaluator clusterEval = new GraalJsEvaluator<>(DseCluster.Builder.class); clusterEval.put("builder", builder); String importEnv = "load(\"nashorn:mozilla_compat.js\");\n" + diff --git a/driver-cqld4/src/main/java/io/nosqlbench/activitytype/cqld4/statements/core/CQLSessionCache.java b/driver-cqld4/src/main/java/io/nosqlbench/activitytype/cqld4/statements/core/CQLSessionCache.java index 7026e7fa7..f3075c5d5 100644 --- a/driver-cqld4/src/main/java/io/nosqlbench/activitytype/cqld4/statements/core/CQLSessionCache.java +++ b/driver-cqld4/src/main/java/io/nosqlbench/activitytype/cqld4/statements/core/CQLSessionCache.java @@ -19,7 +19,7 @@ import io.nosqlbench.activitytype.cqld4.core.ProxyTranslator; import io.nosqlbench.engine.api.activityapi.core.Shutdownable; import io.nosqlbench.engine.api.activityimpl.ActivityDef; import io.nosqlbench.engine.api.metrics.ActivityMetrics; -import io.nosqlbench.engine.api.scripting.NashornEvaluator; +import io.nosqlbench.engine.api.scripting.GraalJsEvaluator; import io.nosqlbench.engine.api.util.SSLKsFactory; import org.apache.tinkerpop.gremlin.driver.Cluster; import org.graalvm.options.OptionMap; @@ -170,7 +170,7 @@ public class CQLSessionCache implements Shutdownable { if (clusteropts.isPresent()) { try { logger.info("applying cbopts:" + clusteropts.get()); - NashornEvaluator clusterEval = new NashornEvaluator<>(CqlSessionBuilder.class); + GraalJsEvaluator clusterEval = new GraalJsEvaluator<>(CqlSessionBuilder.class); clusterEval.put("builder", builder); String importEnv = "load(\"nashorn:mozilla_compat.js\");\n" + diff --git a/driver-dsegraph-shaded/src/main/java/com/datastax/ebdrivers/dsegraph/GraphActivity.java b/driver-dsegraph-shaded/src/main/java/com/datastax/ebdrivers/dsegraph/GraphActivity.java index 51150cd6f..cd30f281d 100644 --- a/driver-dsegraph-shaded/src/main/java/com/datastax/ebdrivers/dsegraph/GraphActivity.java +++ b/driver-dsegraph-shaded/src/main/java/com/datastax/ebdrivers/dsegraph/GraphActivity.java @@ -23,7 +23,7 @@ import io.nosqlbench.engine.api.activityimpl.ParameterMap; import io.nosqlbench.engine.api.activityimpl.SimpleActivity; import io.nosqlbench.engine.api.metrics.ActivityMetrics; import io.nosqlbench.engine.api.metrics.ExceptionMeterMetrics; -import io.nosqlbench.engine.api.scripting.NashornEvaluator; +import io.nosqlbench.engine.api.scripting.GraalJsEvaluator; import io.nosqlbench.engine.api.templating.StrInterpolator; import io.nosqlbench.engine.api.util.TagFilter; import org.apache.logging.log4j.LogManager; @@ -188,7 +188,7 @@ public class GraphActivity extends SimpleActivity implements ActivityDefObserver if (clusteropts.isPresent()) { try { logger.info("applying cbopts:" + clusteropts.get()); - NashornEvaluator clusterEval = new NashornEvaluator<>(DseCluster.Builder.class); + GraalJsEvaluator clusterEval = new GraalJsEvaluator<>(DseCluster.Builder.class); clusterEval.put("builder", builder); String importEnv = "load(\"nashorn:mozilla_compat.js\");\n" + diff --git a/engine-api/pom.xml b/engine-api/pom.xml index c1423d140..4b9e0d05d 100644 --- a/engine-api/pom.xml +++ b/engine-api/pom.xml @@ -49,6 +49,13 @@ graal-sdk + + org.graalvm.js + js + runtime + + + io.dropwizard.metrics metrics-core diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/scripting/Evaluator.java b/engine-api/src/main/java/io/nosqlbench/engine/api/scripting/ExprEvaluator.java similarity index 77% rename from engine-api/src/main/java/io/nosqlbench/engine/api/scripting/Evaluator.java rename to engine-api/src/main/java/io/nosqlbench/engine/api/scripting/ExprEvaluator.java index 90e831af6..b6330187f 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/scripting/Evaluator.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/scripting/ExprEvaluator.java @@ -35,7 +35,7 @@ package io.nosqlbench.engine.api.scripting; * * @param The return type that is needed by the caller */ -public interface Evaluator { +public interface ExprEvaluator { /** * Evaluate the provided script, returning the value that it yields @@ -45,17 +45,24 @@ public interface Evaluator { T eval(); /** - * @param scriptText Nashorn compatible script text - * @return this NahornEvaluator, for method chaining + * @param scriptText script text + * @return this ExprEvaluator, for method chaining */ - NashornEvaluator script(String scriptText); + ExprEvaluator script(String scriptText); /** * Set the variable environment of the evaluator * * @param varName the variable name to add to the environment * @param var the object to bind to the varname - * @return this NashornEvaluator, for method chaining + * @return this ExprEvaluator, for method chaining */ - NashornEvaluator put(String varName, Object var); + ExprEvaluator put(String varName, Object var); + + default ExprEvaluator put(Object... vars) { + for (int i = 0; i < vars.length; i += 2) { + this.put(vars[i].toString(), vars[i + 1]); + } + return this; + } } diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/scripting/GraalJsEvaluator.java b/engine-api/src/main/java/io/nosqlbench/engine/api/scripting/GraalJsEvaluator.java new file mode 100644 index 000000000..94f3e5e07 --- /dev/null +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/scripting/GraalJsEvaluator.java @@ -0,0 +1,53 @@ +package io.nosqlbench.engine.api.scripting; + +import org.graalvm.polyglot.*; + +public class GraalJsEvaluator implements ExprEvaluator { + + private final Class resultType; + private Context context; + private Source script; + + public GraalJsEvaluator(Class resultType) { + this.resultType = resultType; + } + + private Context getContext() { + if (context == null) { + Context.Builder contextSettings = Context.newBuilder("js") + .allowHostAccess(HostAccess.ALL) + .allowNativeAccess(true) + .allowCreateThread(true) + .allowIO(true) + .allowHostClassLookup(s -> true) + .allowHostClassLoading(true) + .allowCreateProcess(true) + .allowAllAccess(true) + .allowEnvironmentAccess(EnvironmentAccess.INHERIT) + .allowPolyglotAccess(PolyglotAccess.ALL) + .option("js.ecmascript-version", "2020") + .option("js.nashorn-compat", "true"); + context = contextSettings.build(); + } + return context; + } + + @Override + public T eval() { + Value result = getContext().eval(this.script); + T asType = result.as(resultType); + return asType; + } + + @Override + public ExprEvaluator script(String scriptText) { + this.script = Source.create("js", scriptText); + return this; + } + + @Override + public ExprEvaluator put(String varName, Object var) { + getContext().getBindings("js").putMember(varName, var); + return this; + } +} diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/scripting/NashornEvaluator.java b/engine-api/src/main/java/io/nosqlbench/engine/api/scripting/NashornEvaluator.java deleted file mode 100644 index 4a9572728..000000000 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/scripting/NashornEvaluator.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * - * Copyright 2016 jshook - * 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.nosqlbench.engine.api.scripting; - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import javax.script.*; - -/** - * public void setBindings(Bindings bindings, int scope); - * - * @param generic parameter for return types from this evaluator - */ -public class NashornEvaluator implements Evaluator { - private final static Logger logger = LogManager.getLogger(NashornEvaluator.class); - - private static final ScriptEngineManager engineManager = new ScriptEngineManager(); - private final ScriptEngine scriptEngine; - private final SimpleBindings bindings = new SimpleBindings(); - private String script = ""; - private final Class resultType; - private CompiledScript compiled; - - /** - * Create a new NashornEvaluator. - * - * @param resultType The required class of the result type, which must extend generic parameter type t. - * @param vars Optional pairs of names and values. vars[0] is a name, vars[1] is a value, ... - */ - public NashornEvaluator(Class resultType, Object... vars) { - this.scriptEngine = engineManager.getEngineByName("nashorn"); - this.scriptEngine.setBindings(bindings, ScriptContext.ENGINE_SCOPE); - this.resultType = resultType; - for (int i = 0; i < vars.length; i += 2) { - this.put(vars[i].toString(), vars[i + 1]); - } - } - - /** - * Set the script that will be evaluated. - * @param scriptText Nashorn compatible script text - * @return this NashornEvaluator, for method chaining - */ - @Override - public NashornEvaluator script(String scriptText) { - this.script = scriptText; - try { - Object result = null; - if (scriptEngine instanceof Compilable) { - logger.info("Using direct script compilation"); - Compilable compilableEngine = (Compilable) scriptEngine; - compiled = compilableEngine.compile(script); - logger.trace("Compiled script:" + script); - } else { - logger.trace("Did not compile script: " + script); - } - } catch (ScriptException e) { - throw new RuntimeException("Script compilation error for " + scriptText + ": ", e); - } - return this; - } - - - /** - * Evaluate the compiled script if it is compiled, or the raw script text otherwise. - * It is not an error to call this without setting the script to something other than the default of "", - * but it not very useful in most cases. - * @return The value produced by the script, compiled or not - */ - @Override - public T eval() { - T result = null; - try { - Object evaled = null; - if (compiled != null) { - evaled = compiled.eval(); - } else { - evaled = scriptEngine.eval(script); - } - result = convert(resultType, evaled); - } catch (ScriptException e) { - throw new RuntimeException("Script error while evaluating result for '" + script + "':", e); - } catch (Exception o) { - throw new RuntimeException("Non-Script error while evaluating result for '" + script + "':", o); - } - return result; - } - - /** - * Put a varianble into the script environment - * @param varName the variable name to add to the environment - * @param var the object to bind to the varname - * @return this NashornEvaluator, for method chaining - */ - @Override - public NashornEvaluator put(String varName, Object var) { - bindings.put(varName, var); - return this; - } - - /** - * Convert some basic types from the script to the requested type. This makes it easier - * to deal with issues across the type systems, with the risk of unintended conversions. - * Be choosy about what you support here. Less is more. - * @param expectedType the wanted type to return - * @param result the result produced by the script - * @return the converted value - */ - private T convert(Class expectedType, Object result) { - if (expectedType.isAssignableFrom(result.getClass())) { - return expectedType.cast(result); - } - String desiredClass = expectedType.getSimpleName(); - Class resultClass = result.getClass(); - - if (resultClass == Double.class) { - switch (desiredClass) { - case "Long": - return expectedType.cast(((Double) result).longValue()); - case "Integer": - return expectedType.cast(((Double) result).intValue()); - case "Float": - return expectedType.cast(((Double) result).floatValue()); - default: - throw new RuntimeException("Incompatible result type requested for conversion from " + resultClass + " to " + desiredClass); - } - } - - if (resultClass == Long.class) { - switch (desiredClass) { - case "Integer": - return expectedType.cast(((Long) result).intValue()); - default: - throw new RuntimeException("Incompatible result type requested for conversion from " + resultClass + " to " + desiredClass); - } - } - throw new RuntimeException( - "Incompatible input type for conversion from evaluator:" + result.getClass() + ", " + - "when type " + expectedType.getSimpleName() + " was needed."); - - } - -} diff --git a/engine-api/src/test/java/io/nosqlbench/engine/api/scripting/NashornEvaluatorTest.java b/engine-api/src/test/java/io/nosqlbench/engine/api/scripting/GraalJsEvaluatorTest.java similarity index 79% rename from engine-api/src/test/java/io/nosqlbench/engine/api/scripting/NashornEvaluatorTest.java rename to engine-api/src/test/java/io/nosqlbench/engine/api/scripting/GraalJsEvaluatorTest.java index f191b4f61..d8b5de7c6 100644 --- a/engine-api/src/test/java/io/nosqlbench/engine/api/scripting/NashornEvaluatorTest.java +++ b/engine-api/src/test/java/io/nosqlbench/engine/api/scripting/GraalJsEvaluatorTest.java @@ -23,19 +23,19 @@ import java.util.Date; import static org.assertj.core.api.Assertions.assertThat; -public class NashornEvaluatorTest { +public class GraalJsEvaluatorTest { @Test public void testBasicOperations() { - NashornEvaluator ne = new NashornEvaluator<>(Long.class); - ne.put("one",1L).put("two",2L); + GraalJsEvaluator ne = new GraalJsEvaluator<>(Long.class); + ne.put("one", 1L).put("two", 2L); Long sum = ne.script("one + two;").eval(); assertThat(sum).isEqualTo(3L); } @Test public void testJavaReturnType() { - NashornEvaluator dateEval = new NashornEvaluator<>(Date.class); + GraalJsEvaluator dateEval = new GraalJsEvaluator<>(Date.class); dateEval.script("var d = new java.util.Date(234); d;"); Date aDate = dateEval.eval(); assertThat(aDate).isEqualTo(new Date(234)); @@ -43,7 +43,8 @@ public class NashornEvaluatorTest { @Test public void testOneLiner() { - String result = new NashornEvaluator(String.class, "fname", "afirstname", "lname", "alastname") + String result = new GraalJsEvaluator(String.class) + .put("fname", "afirstname", "lname", "alastname") .script("fname + lname").eval(); assertThat(result).isEqualTo("afirstnamealastname"); } diff --git a/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIOptions.java b/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIOptions.java index 75e8c59fc..c642f4cd2 100644 --- a/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIOptions.java +++ b/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIOptions.java @@ -403,9 +403,8 @@ public class NBCLIOptions { arglist.removeFirst(); break; case NASHORN_ENGINE: - engine = Scenario.Engine.Nashorn; - arglist.removeFirst(); - break; + throw new RuntimeException("The nashorn engine has been deprecated in this major version of " + + "NoSQLBench"); case COMPILE_SCRIPT: arglist.removeFirst(); compileScript = true; diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/NashornMetricRegistryBindings.java b/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/NashornMetricRegistryBindings.java deleted file mode 100644 index eb361ab8e..000000000 --- a/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/NashornMetricRegistryBindings.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * - * Copyright 2016 jshook - * 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.nosqlbench.engine.core.metrics; - -import com.codahale.metrics.*; -import com.codahale.metrics.Timer; -import io.nosqlbench.engine.core.script.ReadOnlyBindings; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.util.*; -import java.util.stream.Collectors; - -public class NashornMetricRegistryBindings extends ReadOnlyBindings implements MetricRegistryListener { - - private final static Logger logger = LogManager.getLogger(NashornMetricRegistryBindings.class); - - private final MetricRegistry registry; - private final MetricMap metricMap = new MetricMap("ROOT"); - private final boolean failfast = true; - - public NashornMetricRegistryBindings(MetricRegistry registry) { - this.registry = registry; - registry.addListener(this); - } - - @Override - public int size() { - return metricMap.map.size(); - } - - @Override - public boolean isEmpty() { - return metricMap.map.isEmpty(); - } - - @Override - public boolean containsKey(Object key) { - return metricMap.map.containsKey(key); - } - - @Override - public boolean containsValue(Object value) { - return metricMap.map.containsValue(value); - } - - @Override - public Object get(Object key) { - Object got = metricMap.map.get(key); - if (got==null) { - throw new RuntimeException("Attempted to get metrics node with name '" + key + "', but it was not found. Perhaps you were looking for one of its children: " - + this.keySet().stream().collect(Collectors.joining(",","[","]"))); - } - return got; - } - - @Override - public Set keySet() { - return metricMap.map.keySet(); - } - - @Override - public Collection values() { - return metricMap.map.values(); - } - - @Override - public Set> entrySet() { - return metricMap.map.entrySet(); - } - - @Override - public void onGaugeAdded(String name, Gauge metric) { - MetricMap parent = findParentNodeOf(name); - parent.map.put(nodeNameOf(name), metric); - } - - private String nodeNameOf(String name) { - String[] split = name.split("\\."); - return split[split.length - 1]; - } - - private synchronized void cleanEmptyMaps(MetricMap m) { - while (m.isEmpty() && m.parent != null) { - logger.debug("removing empty map:" + m.name); - MetricMap parent = m.parent; - m.parent = null; - parent.map.remove(m.name); - m = parent; - } - } - - private synchronized MetricMap findParentNodeOf(String fullName) { - String[] names = fullName.split("\\."); - MetricMap m = metricMap; - for (int i = 0; i < names.length - 1; i++) { - String edge = names[i]; - if (m.map.containsKey(edge)) { - Object o = m.map.get(edge); - if (o instanceof MetricMap) { - m = (MetricMap) m.map.get(edge); - logger.trace("traversing edge:" + edge + " while pathing to " + fullName); - - } else { - String error = "edge exists at level:" + i + ", while pathing to " + fullName; - logger.error(error); - if (failfast) { - throw new RuntimeException(error); - } - } - } else { - MetricMap newMap = new MetricMap(edge, m); - m.map.put(edge, newMap); - m = newMap; - logger.debug("adding edge:" + edge + " while pathing to " + fullName); - } - } - return m; - } - - @Override - public void onGaugeRemoved(String name) { - MetricMap parent = findParentNodeOf(name); - parent.map.remove(nodeNameOf(name)); - cleanEmptyMaps(parent); - } - - @Override - public void onCounterAdded(String name, Counter metric) { - MetricMap parent = findParentNodeOf(name); - parent.map.put(nodeNameOf(name), metric); - - } - - @Override - public void onCounterRemoved(String name) { - MetricMap parent = findParentNodeOf(name); - parent.map.remove(nodeNameOf(name)); - cleanEmptyMaps(parent); - } - - @Override - public void onHistogramAdded(String name, Histogram metric) { - MetricMap parent = findParentNodeOf(name); - parent.map.put(nodeNameOf(name), metric); - - } - - @Override - public void onHistogramRemoved(String name) { - MetricMap parent = findParentNodeOf(name); - parent.map.remove(nodeNameOf(name)); - cleanEmptyMaps(parent); - - } - - @Override - public void onMeterAdded(String name, Meter metric) { - MetricMap parent = findParentNodeOf(name); - parent.map.put(nodeNameOf(name), metric); - - } - - @Override - public void onMeterRemoved(String name) { - MetricMap parent = findParentNodeOf(name); - parent.map.remove(nodeNameOf(name)); - cleanEmptyMaps(parent); - - } - - @Override - public void onTimerAdded(String name, Timer metric) { - MetricMap parent = findParentNodeOf(name); - parent.map.put(nodeNameOf(name), metric); - - } - - @Override - public void onTimerRemoved(String name) { - MetricMap parent = findParentNodeOf(name); - parent.map.remove(nodeNameOf(name)); - cleanEmptyMaps(parent); - - } - - public Map getMetrics() { - return getMetrics(new LinkedHashMap(), "metrics", metricMap); - } - - private Map getMetrics(Map totalMap, String prefix, MetricMap map) { - for (Entry mEntry : map.entrySet()) { - Object o = mEntry.getValue(); - String name = prefix + "." + mEntry.getKey(); - if (o instanceof Metric) { - totalMap.put(name, (Metric) o); - } else if (o instanceof MetricMap) { - getMetrics(totalMap, name, (MetricMap) o); - } else { - throw new RuntimeException("entry value must be either a Metric or a MetricMap"); - } - } - return totalMap; - } - - private class MetricMap extends ReadOnlyBindings { - Map map = new HashMap(); - MetricMap parent = null; - public String name; - - MetricMap(String name) { - this.name = name; - } - - public MetricMap(String name, MetricMap parent) { - this.parent = parent; - this.name = name; - } - - public int size() { - return map.size(); - } - - @Override - public boolean isEmpty() { - return map.isEmpty(); - } - - @Override - public boolean containsKey(Object key) { - boolean containsKey=map.containsKey(key); - if (containsKey==false) { - throw new RuntimeException("Attempted to get metrics node with name '" + key + "', but it was not found. Perhaps you " + - "were looking for one of " + this.map.keySet().stream().collect(Collectors.joining(",","[","]"))); - } - return true; - } - - @Override - public boolean containsValue(Object value) { - return map.containsValue(value); - } - - @Override - public Object get(Object key) { - Object got=map.get(key); - if (got==null) { - throw new RuntimeException("Attempted to get metrics node with name '" + key + "', but it was not found. Perhaps you " + - "were looking for one of " + this.map.keySet().stream().collect(Collectors.joining(",","[","]"))); - } - return got; - } - - @Override - public Set keySet() { - return map.keySet(); - } - - @Override - public Collection values() { - return map.values(); - } - - @Override - public Set> entrySet() { - return map.entrySet(); - } - - } -} diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/PolyglotMetricRegistryBindings.java b/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/PolyglotMetricRegistryBindings.java index 33a9bdfc7..d4f78b648 100644 --- a/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/PolyglotMetricRegistryBindings.java +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/PolyglotMetricRegistryBindings.java @@ -24,6 +24,7 @@ import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyObject; import java.util.ArrayList; +import java.util.Map; /** * A view of metrics objects as an object tree. @@ -124,7 +125,7 @@ public class PolyglotMetricRegistryBindings implements ProxyObject, MetricRegist @Override public void onTimerAdded(String name, Timer timer) { - metrics.add(name,timer); + metrics.add(name, timer); logger.info("timer added: " + name); } @@ -134,6 +135,10 @@ public class PolyglotMetricRegistryBindings implements ProxyObject, MetricRegist logger.info("timer removed: " + name); } + public Map getMetrics() { + throw new RuntimeException("implement me"); + } + // @Override // public int size() { // return metricMap.map.size(); diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/script/MetricsMapper.java b/engine-core/src/main/java/io/nosqlbench/engine/core/script/MetricsMapper.java index 361e67411..b70f7f390 100644 --- a/engine-core/src/main/java/io/nosqlbench/engine/core/script/MetricsMapper.java +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/script/MetricsMapper.java @@ -19,13 +19,13 @@ import io.nosqlbench.engine.api.activityapi.core.Activity; import io.nosqlbench.engine.api.activityapi.core.ActivityType; import io.nosqlbench.engine.api.activityimpl.ActivityDef; import io.nosqlbench.engine.api.metrics.ActivityMetrics; -import io.nosqlbench.engine.core.metrics.NashornMetricRegistryBindings; -import org.apache.logging.log4j.Logger; +import io.nosqlbench.engine.core.metrics.PolyglotMetricRegistryBindings; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.lang.reflect.Method; -import java.util.*; import java.util.Timer; +import java.util.*; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -68,7 +68,7 @@ public class MetricsMapper { throw new RuntimeException("Activity type '" + activityDef.getActivityType() + "' does not exist in this runtime."); } Activity activity = activityType.get().getAssembledActivity(activityDef, new HashMap<>()); - NashornMetricRegistryBindings nashornMetricRegistryBindings = new NashornMetricRegistryBindings(ActivityMetrics.getMetricRegistry()); + PolyglotMetricRegistryBindings nashornMetricRegistryBindings = new PolyglotMetricRegistryBindings(ActivityMetrics.getMetricRegistry()); activity.initActivity(); activity.getInputDispenserDelegate().getInput(0); activity.getActionDispenserDelegate().getAction(0); diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/script/Scenario.java b/engine-core/src/main/java/io/nosqlbench/engine/core/script/Scenario.java index 9c2efee60..53763f855 100644 --- a/engine-core/src/main/java/io/nosqlbench/engine/core/script/Scenario.java +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/script/Scenario.java @@ -24,11 +24,9 @@ import io.nosqlbench.engine.core.PolyglotScenarioController; import io.nosqlbench.engine.core.ScenarioController; import io.nosqlbench.engine.core.ScenarioResult; import io.nosqlbench.engine.core.annotation.Annotators; -import io.nosqlbench.engine.core.metrics.NashornMetricRegistryBindings; import io.nosqlbench.engine.core.metrics.PolyglotMetricRegistryBindings; import io.nosqlbench.nb.api.Layer; import io.nosqlbench.nb.api.annotations.Annotation; -import jdk.nashorn.api.scripting.NashornScriptEngineFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.graalvm.polyglot.Context; @@ -87,8 +85,8 @@ public class Scenario implements Callable { private long endedAtMillis = -1L; public enum Engine { - Nashorn, - Graalvm + Graalvm, + Nashorn } public Scenario( @@ -153,12 +151,7 @@ public class Scenario implements Callable { switch (engine) { case Nashorn: - NashornScriptEngineFactory f = new NashornScriptEngineFactory(); - this.scriptEngine = f.getScriptEngine("--language=es6"); - - // engineManager.getEngineByName("nashorn"); - // TODO: Figure out how to do this in engine bindings: --language=es-6 - break; + throw new RuntimeException("The nashorn engine has been deprecated in this version of NoSQLBench."); case Graalvm: Context.Builder contextSettings = Context.newBuilder("js") .allowHostAccess(HostAccess.ALL) @@ -201,7 +194,7 @@ public class Scenario implements Callable { // https://github.com/graalvm/graaljs/blob/master/docs/user/JavaInterop.md if (wantsGraaljsCompatMode) { scriptEngine.put("scenario", scenarioController); - scriptEngine.put("metrics", new NashornMetricRegistryBindings(metricRegistry)); + scriptEngine.put("metrics", new PolyglotMetricRegistryBindings(metricRegistry)); scriptEngine.put("activities", new NashornActivityBindings(scenarioController)); } else { scriptEngine.put("scenario", new PolyglotScenarioController(scenarioController)); @@ -209,9 +202,7 @@ public class Scenario implements Callable { scriptEngine.put("activities", new NashornActivityBindings(scenarioController)); } } else if (engine == Engine.Nashorn) { - scriptEngine.put("scenario", scenarioController); - scriptEngine.put("metrics", new NashornMetricRegistryBindings(metricRegistry)); - scriptEngine.put("activities", new NashornActivityBindings(scenarioController)); + throw new RuntimeException("The Nashorn engine has been deprecated in this version of NoSQLBench."); } else { throw new RuntimeException("Unsupported engine: " + engine); } diff --git a/engine-core/src/test/resources/scripts/testlib.js b/engine-core/src/test/resources/scripts/testlib.js deleted file mode 100644 index 7d18cefbe..000000000 --- a/engine-core/src/test/resources/scripts/testlib.js +++ /dev/null @@ -1,62 +0,0 @@ -// This will be the basis for nashorn and timer-based events. - -var Platform = Java.type("javafx.application.Platform"); -var Timer = Java.type("java.util.Timer"); - -function setTimerRequest(handler, delay, interval, args) { - handler = handler || function() {}; - delay = delay || 0; - interval = interval || 0; - - var applyHandler = function() handler.apply(this, args); - var runLater = function() Platform.runLater(applyHandler); - - var timer = new Timer("setTimerRequest", true); - - if (interval > 0) { - timer.schedule(runLater, delay, interval); - } else { - timer.schedule(runLater, delay); - } - - return timer; -} - -function clearTimerRequest(timer) { - timer.cancel(); -} - -function setInterval() { - var args = Array.prototype.slice.call(arguments); - var handler = args.shift(); - var ms = args.shift(); - - return setTimerRequest(handler, ms, ms, args); -} - -function clearInterval(timer) { - clearTimerRequest(timer); -} - -function setTimeout() { - var args = Array.prototype.slice.call(arguments); - var handler = args.shift(); - var ms = args.shift(); - - return setTimerRequest(handler, ms, 0, args); -} - -function clearTimeout(timer) { - clearTimerRequest(timer); -} - -function setImmediate() { - var args = Array.prototype.slice.call(arguments); - var handler = args.shift(); - - return setTimerRequest(handler, 0, 0, args); -} - -function clearImmediate(timer) { - clearTimerRequest(timer); -} \ No newline at end of file diff --git a/engine-docs/src/main/resources/docs-for-nb/getting_started/index.md b/engine-docs/src/main/resources/docs-for-nb/getting_started/index.md index 08060ce21..38b1b8bef 100644 --- a/engine-docs/src/main/resources/docs-for-nb/getting_started/index.md +++ b/engine-docs/src/main/resources/docs-for-nb/getting_started/index.md @@ -26,7 +26,8 @@ downloading and executing nb, you get an error, please consult the ::: This documentation assumes you are using the Linux binary initiating NoSqlBench commands with `./nb`. If you are using -the jar, just replace `./nb` with `java -jar nb.jar` when running commands. If you are using the jar version, Java 14 is +the jar, just replace `./nb` with `java -jar nb.jar` when running + commands. If you are using the jar version, Java 15 is recommended, and will be required soon. ## Run a cluster diff --git a/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/BobyqaOptimizerInstance.java b/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/BobyqaOptimizerInstance.java index 58366bdfc..138f2acc8 100644 --- a/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/BobyqaOptimizerInstance.java +++ b/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/BobyqaOptimizerInstance.java @@ -18,7 +18,6 @@ package io.nosqlbench.engine.extensions.optimizers; import com.codahale.metrics.MetricRegistry; -import jdk.nashorn.api.scripting.ScriptObjectMirror; import org.apache.commons.math3.analysis.MultivariateFunction; import org.apache.commons.math3.optim.*; import org.apache.commons.math3.optim.nonlinear.scalar.GoalType; @@ -96,19 +95,12 @@ public class BobyqaOptimizerInstance { } public BobyqaOptimizerInstance setObjectiveFunction(Object f) { - if (f instanceof ScriptObjectMirror) { - ScriptObjectMirror scriptObject = (ScriptObjectMirror) f; - if (!scriptObject.isFunction()) { - throw new RuntimeException("Unable to setFunction with a non-function object"); - } - this.objectiveFunctionFromScript = - new NashornMultivariateObjectScript(logger, params, scriptObject); - } - if (f instanceof Function) { // Function function = (Function)f; this.objectiveFunctionFromScript = - new PolyglotMultivariateObjectScript(logger, params, f); + new PolyglotMultivariateObjectScript(logger, params, f); + } else { + throw new RuntimeException("The objective function must be recognizable as a polyglot Function"); } return this; diff --git a/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/MultivariateArrayScript.java b/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/MultivariateArrayScript.java deleted file mode 100644 index b8a1231a7..000000000 --- a/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/MultivariateArrayScript.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.nosqlbench.engine.extensions.optimizers; - -import jdk.nashorn.api.scripting.ScriptObjectMirror; -import org.apache.commons.math3.analysis.MultivariateFunction; -import org.apache.logging.log4j.Logger; - -import java.security.InvalidParameterException; -import java.util.HashMap; -import java.util.Map; - -public class MultivariateArrayScript implements MultivariateFunction { - private final ScriptObjectMirror script; - private final MVParams params; - private final Logger logger; - - public MultivariateArrayScript(Logger logger, MVParams params, ScriptObjectMirror script) { - this.logger = logger; - this.script = script; - this.params = params; - } - - @Override - public double value(double[] doubles) { - if (doubles.length != params.size()) { - throw new InvalidParameterException("Expected " + params.size() + " doubles, not " + doubles.length); - } - - Map map = new HashMap<>(); - - for (int i = 0; i < doubles.length; i++) { - map.put(i,doubles[i]); - } - - Object result = null; - result = this.script.call(script,doubles); - return Double.valueOf(result.toString()); - } -} diff --git a/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/MultivariateDynamicScript.java b/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/MultivariateDynamicScript.java deleted file mode 100644 index 59bc90855..000000000 --- a/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/MultivariateDynamicScript.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.nosqlbench.engine.extensions.optimizers; - -import jdk.nashorn.api.scripting.ScriptObjectMirror; -import org.apache.commons.math3.analysis.MultivariateFunction; -import org.apache.logging.log4j.Logger; - -import java.security.InvalidParameterException; -import java.util.Arrays; - -public class MultivariateDynamicScript implements MultivariateFunction { - private final ScriptObjectMirror script; - private final int varcount; - private final Logger logger; - - public MultivariateDynamicScript(Logger logger, int varcount, ScriptObjectMirror script) { - this.logger = logger; - this.script = script; - this.varcount = varcount; - } - - @Override - public double value(double[] doubles) { - logger.info("invoking function with " + Arrays.toString(doubles)); - if (doubles.length != varcount) { - throw new InvalidParameterException("Expected " + varcount + " doubles, not " + doubles.length); - } - Object result = null; - if (doubles.length == 1) { - result = this.script.call(script, - doubles[0] - ); - } else if (doubles.length == 2) { - result = this.script.call(script, - doubles[0], doubles[1] - ); - } else if (doubles.length == 3) { - result = this.script.call(script, - doubles[0], doubles[1], doubles[2] - ); - } else if (doubles.length == 4) { - result = this.script.call(script, - doubles[0], doubles[1], doubles[2], doubles[3] - ); - } else if (doubles.length == 5) { - result = this.script.call(script, - doubles[0], doubles[1], doubles[2], doubles[3], doubles[4]); - } - return Double.valueOf(result.toString()); - } -} diff --git a/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/NashornMultivariateObjectScript.java b/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/NashornMultivariateObjectScript.java deleted file mode 100644 index a4d2940c5..000000000 --- a/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/NashornMultivariateObjectScript.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.nosqlbench.engine.extensions.optimizers; - -import jdk.nashorn.api.scripting.ScriptObjectMirror; -import org.apache.commons.math3.analysis.MultivariateFunction; -import org.apache.logging.log4j.Logger; - -import java.security.InvalidParameterException; -import java.util.HashMap; -import java.util.Map; - -public class NashornMultivariateObjectScript implements MultivariateFunction { - private final ScriptObjectMirror script; - private final MVParams params; - private final Logger logger; - - public NashornMultivariateObjectScript(Logger logger, MVParams params, ScriptObjectMirror script) { - this.logger = logger; - this.script = script; - this.params = params; - } - - @Override - public double value(double[] doubles) { - if (doubles.length != params.size()) { - throw new InvalidParameterException("Expected " + params.size() + " doubles, not " + doubles.length); - } - - Map map = new HashMap<>(); - - for (int i = 0; i < doubles.length; i++) { - map.put(params.get(i).name, doubles[i]); - } - - Object object = ScriptObjectMirror.wrap(map, null); - Object result = null; - result = this.script.call(script,object); - return Double.valueOf(result.toString()); - } -} diff --git a/mvn-defaults/pom.xml b/mvn-defaults/pom.xml index 01b800135..42b5c62aa 100644 --- a/mvn-defaults/pom.xml +++ b/mvn-defaults/pom.xml @@ -71,7 +71,6 @@ 3.1.0 3.0.1 3.0.0-M4 - 20.1.0 ${project.artifactId} @@ -417,29 +416,29 @@ org.graalvm.sdk graal-sdk - ${graalvm.version} + 20.3.0 org.graalvm.js js - ${graalvm.version} + 20.3.0 runtime org.graalvm.js js-scriptengine - ${graalvm.version} + 20.3.0 org.graalvm.tools profiler - ${graalvm.version} + 20.3.0 runtime org.graalvm.tools chromeinspector - ${graalvm.version} + 20.3.0 runtime @@ -507,8 +506,8 @@ true - 11 - 11 + 15 + 15 diff --git a/nb/build-bin.sh b/nb/build-bin.sh index 7c254333a..cd8235572 100755 --- a/nb/build-bin.sh +++ b/nb/build-bin.sh @@ -37,19 +37,15 @@ then (cd cache && ( if [ "$BUILD_OPENJ9" = "true" ] then - wget -c https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk14u-2020-04-27-07-27/OpenJDK14U-jre_x64_linux_openj9_linuxXL_2020-04-27-07-27.tar.gz - tar xf OpenJDK14U-jre_x64_linux_openj9_linuxXL_2020-04-27-07-27.tar.gz - mv jdk-14.0.1+7-jre jre - rm OpenJDK14U-jre_x64_linux_openj9_linuxXL_2020-04-27-07-27.tar.gz + wget -c wget -c https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk15u-2020-11-19-07-04/OpenJDK15U-jre_x64_linux_openj9_linuxXL_2020-11-19-07-04.tar.gz + tar -xf OpenJDK15U-jre_x64_linux_openj9_linuxXL_2020-11-19-07-04.tar.gz + mv jdk-15.0.1+9-jre jre + rm OpenJDK15U-jre_x64_linux_openj9_linuxXL_2020-11-19-07-04.tar.gz else - wget -c https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk14u-2020-04-27-07-27/OpenJDK14U-jre_x64_linux_hotspot_2020-04-27-07-27.tar.gz - tar xf OpenJDK14U-jre_x64_linux_hotspot_2020-04-27-07-27.tar.gz - mv jdk-14.0.1+7-jre jre + wget -c https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk15u-2020-11-19-07-04/OpenJDK15U-jre_x64_linux_hotspot_2020-11-19-07-04.tar.gz + tar xf OpenJDK15U-jre_x64_linux_hotspot_2020-11-19-07-04.tar.gz + mv jdk-15.0.1+9-jre jre fi - # wget -c https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10/OpenJDK12U-jre_x64_linux_hotspot_12.0.2_10.tar.gz - # tar xf OpenJDK12U-jre_x64_linux_hotspot_12.0.2_10.tar.gz - # mv jdk-12.0.2+10-jre jre - # rm OpenJDK12U-jre_x64_linux_hotspot_12.0.2_10.tar.gz )) fi diff --git a/virtdata-userlibs/src/main/resources/docs-for-virtdata/bindings/funcref_conversion.md b/virtdata-userlibs/src/main/resources/docs-for-virtdata/bindings/funcref_conversion.md index d2341aaca..687db1d7f 100644 --- a/virtdata-userlibs/src/main/resources/docs-for-virtdata/bindings/funcref_conversion.md +++ b/virtdata-userlibs/src/main/resources/docs-for-virtdata/bindings/funcref_conversion.md @@ -32,7 +32,8 @@ appropriate, to ensure that VirtData selects the right functions within the flow ## Format Apply the Java String.format method to an incoming object. @see -[Java 14 String.format(...) javadoc](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/Formatter.html#syntax) Note: +[Java 15 String.format(...) javadoc](https://docs.oracle.com/en/java +/javase/14/docs/api/java.base/java/util/Formatter.html#syntax) Note: This function can often be quite slow, so more direct methods are generally preferrable. - java.lang.Object -> Format(java.lang.String: format) -> java.lang.String