From 6f77a9c173ec8593595c86a1d79ad98b742c7f5b Mon Sep 17 00:00:00 2001 From: Jonathan Shook Date: Thu, 23 Apr 2020 12:42:03 -0500 Subject: [PATCH] support proxies for some polyglot types --- .../engine/api/activityimpl/ParameterMap.java | 33 +- .../core/PolyglotScenarioController.java | 114 ++++++ .../engine/core/ScenarioController.java | 6 +- .../engine/core/metrics/MetricMap.java | 107 +++++ ...ava => NashornMetricRegistryBindings.java} | 7 +- .../PolyglotMetricRegistryBindings.java | 384 ++++++++++++++++++ .../engine/core/script/MetricsMapper.java | 6 +- ...ings.java => NashornActivityBindings.java} | 33 +- ...a => NashornMultivariateObjectScript.java} | 4 +- 9 files changed, 677 insertions(+), 17 deletions(-) create mode 100644 engine-core/src/main/java/io/nosqlbench/engine/core/PolyglotScenarioController.java create mode 100644 engine-core/src/main/java/io/nosqlbench/engine/core/metrics/MetricMap.java rename engine-core/src/main/java/io/nosqlbench/engine/core/metrics/{MetricRegistryBindings.java => NashornMetricRegistryBindings.java} (97%) create mode 100644 engine-core/src/main/java/io/nosqlbench/engine/core/metrics/PolyglotMetricRegistryBindings.java rename engine-core/src/main/java/io/nosqlbench/engine/core/script/{ActivityBindings.java => NashornActivityBindings.java} (77%) rename engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/{MultivariateObjectScript.java => NashornMultivariateObjectScript.java} (85%) diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/ParameterMap.java b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/ParameterMap.java index 1d3401de0..a0ce7161b 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/ParameterMap.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/ParameterMap.java @@ -17,6 +17,9 @@ package io.nosqlbench.engine.api.activityimpl; import io.nosqlbench.engine.api.activityimpl.motor.ParamsParser; import io.nosqlbench.engine.api.util.Unit; + +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +41,7 @@ import java.util.stream.Collectors; *

No non-String types are used internally. Everything is encoded as a String, even though the * generic type is parameterized for Bindings support.

*/ -public class ParameterMap extends ConcurrentHashMap implements Bindings { +public class ParameterMap extends ConcurrentHashMap implements Bindings, ProxyObject { private final static Logger logger = LoggerFactory.getLogger(ParameterMap.class); @@ -276,7 +279,33 @@ public class ParameterMap extends ConcurrentHashMap implements Bi return getOptionalString(paramName).map(Integer::valueOf); } -// /** + @Override + public Object getMember(String key) { + return this.get(key); + } + + @Override + public Object getMemberKeys() { + return new ArrayList<>(this.keySet()); + } + + @Override + public boolean hasMember(String key) { + return this.containsKey(key); + } + + @Override + public void putMember(String key, Value value) { + this.put(key,value); + } + + @Override + public boolean removeMember(String key) { + Object removed = this.remove(key); + return removed!=null; + } + + // /** // * Parse positional parameters, each suffixed with the ';' terminator. // * This form simply allows for the initial parameter names to be elided, so long as they // * are sure to match up with a well-known order. This method cleans up the input, injecting diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/PolyglotScenarioController.java b/engine-core/src/main/java/io/nosqlbench/engine/core/PolyglotScenarioController.java new file mode 100644 index 000000000..9632e33b5 --- /dev/null +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/PolyglotScenarioController.java @@ -0,0 +1,114 @@ +package io.nosqlbench.engine.core; + +import io.nosqlbench.engine.api.activityimpl.ActivityDef; +import org.graalvm.polyglot.Value; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.security.InvalidParameterException; +import java.util.Map; + +public class PolyglotScenarioController { + + private static final Logger logger = LoggerFactory.getLogger("SCENARIO/POLYGLOT"); + + private final ScenarioController controller; + + public PolyglotScenarioController(ScenarioController inner) { + this.controller = inner; + } + + // for graal polyglot interop +// public synchronized void run(Value vtimeout, Value vspec) { +// int timeout = vtimeout.asInt(); +// run(timeout, vspec); +// } + public synchronized void run(Value v) { + run(Integer.MAX_VALUE, v); + } + + public synchronized void run(int timeout, Value spec) { + logger.debug("run(Value) called with:" + spec); + if (spec.isHostObject()) { + controller.run(timeout, (ActivityDef) spec.asHostObject()); + } else if (spec.isString()) { + controller.run(timeout, spec.asString()); + } else if (spec.hasMembers()) { + controller.run(timeout, spec.as(Map.class)); + } else if (spec.isHostObject()) { + Object o = spec.asHostObject(); + if (o instanceof ActivityDef) { + controller.run(timeout, (ActivityDef) o); + } else { + throw new RuntimeException("unrecognized polyglot host object type for run: " + spec.toString()); + } + } else { + throw new RuntimeException("unrecognized polyglot base type for run: " + spec.toString()); + } + } + + public synchronized void start(Value spec) { + if (spec.isHostObject()) { + controller.start((ActivityDef) spec.asHostObject()); + } else if (spec.isString()) { + controller.start(spec.asString()); + } else if (spec.hasMembers()) { + controller.start(spec.as(Map.class)); + } else { + throw new RuntimeException("unknown base type for graal polyglot: " + spec.toString()); + } + } + + public synchronized void stop(Value spec) { + if (spec.isHostObject()) { + controller.stop((ActivityDef) spec.asHostObject()); + } else if (spec.isString()) { + controller.stop(spec.asString()); + } else if (spec.hasMembers()) { + controller.stop(spec.as(Map.class)); + } else { + throw new RuntimeException("unknown base type for graal polyglot: " + spec.toString()); + } + } + + public synchronized void apply(Value spec) { + Map map = spec.as(Map.class); + controller.apply(map); + } + + public synchronized void await(Value spec) { + awaitActivity(spec); + } + public synchronized void awaitActivity(Value spec) { + if (spec.isHostObject()) { + controller.await((ActivityDef) spec.asHostObject()); + } else if (spec.hasMembers()) { + controller.await(spec.as(Map.class)); + } else if (spec.isString()) { + controller.await(spec.asString()); + } else { + throw new RuntimeException("unable to map type for await from polyglot value: " + spec); + } + } + + public synchronized void waitMillis(Value spec) { + if (spec.fitsInLong()) { + controller.waitMillis(spec.asLong()); + } else { + throw new InvalidParameterException("long type can't contain " + spec.toString()); + } + } + + public synchronized boolean isRunningActivity(Value spec) { + if (spec.isHostObject()) { + return controller.isRunningActivity((ActivityDef) spec.asHostObject()); + } else if (spec.isString()) { + return controller.isRunningActivity(spec.asString()); + } else if (spec.hasMembers()) { + return controller.isRunningActivity(spec.as(Map.class)); + } else { + throw new InvalidParameterException("unable to map type for isRunningActivity from polyglot value: " + spec); + } + } + +} diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/ScenarioController.java b/engine-core/src/main/java/io/nosqlbench/engine/core/ScenarioController.java index ad808211a..213e14a23 100644 --- a/engine-core/src/main/java/io/nosqlbench/engine/core/ScenarioController.java +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/ScenarioController.java @@ -105,11 +105,7 @@ public class ScenarioController { public synchronized void run(String activityDefString) { run(Integer.MAX_VALUE, activityDefString); } -// -// public synchronized void run(Value v) { -// logger.debug("run(Value) called with:" + v); -// throw new RuntimeException("fix it"); -// } + public synchronized void run(ActivityDef activityDef) { run(Integer.MAX_VALUE, activityDef); diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/MetricMap.java b/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/MetricMap.java new file mode 100644 index 000000000..e5b444c64 --- /dev/null +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/MetricMap.java @@ -0,0 +1,107 @@ +package io.nosqlbench.engine.core.metrics; + +import com.codahale.metrics.Metric; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.*; + +public class MetricMap implements ProxyObject { + + private final static Logger logger = LoggerFactory.getLogger(MetricMap.class); + private final String name; + private final String parent_name; + private final HashMap map = new HashMap<>(); + + public MetricMap(String name, String parent) { + this.name = name; + this.parent_name = parent; + } + + public MetricMap findOwner(String metricName) { + String[] names = metricName.split("\\."); + String[] pathTraversal = Arrays.copyOfRange(names, 0, names.length - 1); + MetricMap owner = findPath(pathTraversal); + return owner; + } + + @Override + public String toString() { + return "MetricMap{" + + "name='" + name + '\'' + + ", map=" + map + + (parent_name!=null ? ", parent=" + parent_name : "") + + '}'; + } + + public MetricMap findPath(String... names) { + MetricMap current = this; + for (int i = 0; i < names.length; i++) { + String edgeName = names[i]; + + if (current.map.containsKey(edgeName)) { + Object element = current.map.get(edgeName); + if (element instanceof MetricMap) { + current = (MetricMap) element; + logger.trace("traversing edge:" + edgeName); + } else { + String error = "edge exists at level:" + i; + logger.error(error); + throw new RuntimeException(error); + } + } else { + MetricMap newMap = new MetricMap(edgeName,this.name); + current.map.put(edgeName, newMap); + current = newMap; + logger.debug("adding edge:" + edgeName); + } + } + return current; + } + + public void add(String name, Metric metric) { + MetricMap owner = findOwner(name); + String leafName = name.substring(name.lastIndexOf(".")+1); + owner.map.put(leafName,metric); + } + + public void remove(String name) { + map.remove(name); + } + + public Object get(String key) { + return map.get(key); + } + + public Set getKeys() { + return map.keySet(); + } + + public boolean containsKey(String key) { + return map.containsKey(key); + } + + @Override + public Object getMember(String key) { + Object got = get(key); + return got; + } + + @Override + public Object getMemberKeys() { + ArrayList keys = new ArrayList<>(getKeys()); + return keys; + } + + @Override + public boolean hasMember(String key) { + boolean got = getKeys().contains(key); + return got; + } + + @Override + public void putMember(String key, Value value) { + throw new RuntimeException("Not allowed here"); + } +} diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/MetricRegistryBindings.java b/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/NashornMetricRegistryBindings.java similarity index 97% rename from engine-core/src/main/java/io/nosqlbench/engine/core/metrics/MetricRegistryBindings.java rename to engine-core/src/main/java/io/nosqlbench/engine/core/metrics/NashornMetricRegistryBindings.java index a0dd0c5d9..9b8d2879e 100644 --- a/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/MetricRegistryBindings.java +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/NashornMetricRegistryBindings.java @@ -26,14 +26,15 @@ import org.slf4j.LoggerFactory; import java.util.*; import java.util.stream.Collectors; -public class MetricRegistryBindings extends ReadOnlyBindings implements MetricRegistryListener { +public class NashornMetricRegistryBindings extends ReadOnlyBindings implements MetricRegistryListener { + + private final static Logger logger = LoggerFactory.getLogger(NashornMetricRegistryBindings.class); - private final static Logger logger = LoggerFactory.getLogger(MetricRegistryBindings.class); private final MetricRegistry registry; private MetricMap metricMap = new MetricMap("ROOT"); private boolean failfast = true; - public MetricRegistryBindings(MetricRegistry registry) { + public NashornMetricRegistryBindings(MetricRegistry registry) { this.registry = registry; registry.addListener(this); } 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 new file mode 100644 index 000000000..beb4e327f --- /dev/null +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/metrics/PolyglotMetricRegistryBindings.java @@ -0,0 +1,384 @@ +/* + * + * 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.Timer; +import com.codahale.metrics.*; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Set; + +/** + * A view of metrics objects as an object tree. + */ +public class PolyglotMetricRegistryBindings implements ProxyObject, MetricRegistryListener { + + private final static Logger logger = LoggerFactory.getLogger(PolyglotMetricRegistryBindings.class); + + private final MetricRegistry registry; + MetricMap metrics = new MetricMap("ROOT",null); + + public PolyglotMetricRegistryBindings(MetricRegistry registry) { + this.registry = registry; + registry.addListener(this); + } + + @Override + public Object getMember(String key) { + logger.info("get member: " + key); + Object o = metrics.get(key); + return o; + } + + @Override + public Object getMemberKeys() { + logger.info("get member keys"); + ArrayList keys = new ArrayList<>(metrics.getKeys()); + return keys; + } + + @Override + public boolean hasMember(String key) { + logger.info("has member? " + key); + boolean b = metrics.containsKey(key); + return b; + } + + @Override + public void putMember(String key, Value value) { + throw new UnsupportedOperationException("This view is not meant to be modified by users. It is modified " + + "automatically by metrics registry updates."); + } + + @Override + public boolean removeMember(String key) { + throw new UnsupportedOperationException("This view is not meant to be modified by users. It is modified " + + "automatically by metrics registry updates."); + } + + @Override + public void onGaugeAdded(String name, Gauge gauge) { + metrics.add(name,gauge); + logger.info("gauge added: " + name +", " + gauge); + } + + @Override + public void onGaugeRemoved(String name) { + metrics.findOwner(name).remove(name); + logger.info("gauge removed: " + name); + } + + @Override + public void onCounterAdded(String name, Counter counter) { + metrics.add(name,counter); + logger.info("counter added: " + name + ", " + counter); + } + + @Override + public void onCounterRemoved(String name) { + metrics.findOwner(name).remove(name); + logger.info("counter removed: " + name); + } + + @Override + public void onHistogramAdded(String name, Histogram histogram) { + metrics.add(name, histogram); + logger.info("histogram added: " + name + ", " + histogram); + } + + @Override + public void onHistogramRemoved(String name) { + metrics.findOwner(name).remove(name); + logger.info("histogram removed: " + name); + } + + @Override + public void onMeterAdded(String name, Meter meter) { + metrics.add(name,meter); + logger.info("meter added: " + name + ", " + meter); + } + + @Override + public void onMeterRemoved(String name) { + metrics.findOwner(name).remove(name); + logger.info("meter removed: " + name); + + } + + @Override + public void onTimerAdded(String name, Timer timer) { + metrics.add(name,timer); + logger.info("timer added: " + name); + } + + @Override + public void onTimerRemoved(String name) { + metrics.findOwner(name).remove(name); + logger.info("timer removed: " + name); + } + +// @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/script/MetricsMapper.java b/engine-core/src/main/java/io/nosqlbench/engine/core/script/MetricsMapper.java index c3a38c271..30822b3b9 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,7 +19,7 @@ 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.MetricRegistryBindings; +import io.nosqlbench.engine.core.metrics.NashornMetricRegistryBindings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -68,13 +68,13 @@ public class MetricsMapper { throw new RuntimeException("Activity type '" + activityDef.getActivityType() + "' does not exist in this runtime."); } Activity activity = activityType.get().getAssembledActivity(activityDef, new HashMap<>()); - MetricRegistryBindings metricRegistryBindings = new MetricRegistryBindings(ActivityMetrics.getMetricRegistry()); + NashornMetricRegistryBindings nashornMetricRegistryBindings = new NashornMetricRegistryBindings(ActivityMetrics.getMetricRegistry()); activity.initActivity(); activity.getInputDispenserDelegate().getInput(0); activity.getActionDispenserDelegate().getAction(0); activity.getMotorDispenserDelegate().getMotor(activityDef, 0); - Map metricMap = metricRegistryBindings.getMetrics(); + Map metricMap = nashornMetricRegistryBindings.getMetrics(); // Map> details = new LinkedHashMap<>(); diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/script/ActivityBindings.java b/engine-core/src/main/java/io/nosqlbench/engine/core/script/NashornActivityBindings.java similarity index 77% rename from engine-core/src/main/java/io/nosqlbench/engine/core/script/ActivityBindings.java rename to engine-core/src/main/java/io/nosqlbench/engine/core/script/NashornActivityBindings.java index e8aa118cc..c38200f35 100644 --- a/engine-core/src/main/java/io/nosqlbench/engine/core/script/ActivityBindings.java +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/script/NashornActivityBindings.java @@ -16,6 +16,8 @@ package io.nosqlbench.engine.core.script; import io.nosqlbench.engine.api.activityimpl.ActivityDef; import io.nosqlbench.engine.core.ScenarioController; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyObject; import javax.script.Bindings; import java.util.*; @@ -24,12 +26,12 @@ import java.util.stream.Collectors; /** * Provide a bindings wrapper around a ScenarioController, */ -public class ActivityBindings implements Bindings { +public class NashornActivityBindings implements Bindings, ProxyObject { private final ScenarioController scenario; private Map elementMap = new HashMap(); - public ActivityBindings(ScenarioController scenarioController) { + public NashornActivityBindings(ScenarioController scenarioController) { this.scenario = scenarioController; } @@ -105,4 +107,31 @@ public class ActivityBindings implements Bindings { throw new RuntimeException("this is not the advised way to forceStopMotors an activity"); // scenario.forceStopMotors(String.valueOf(key)); } + + @Override + public Object getMember(String key) { + Bindings bindings = get(key); + return bindings; + } + + @Override + public Object getMemberKeys() { + ArrayList keys = new ArrayList<>(keySet()); + return keys; + } + + @Override + public boolean hasMember(String key) { + boolean b = containsKey(key); + return b; + } + + @Override + public void putMember(String key, Value value) { + if (value.isHostObject()) { + put(key,value.asHostObject()); + } else { + throw new RuntimeException("Unable to put a non-host object into the activities bindings layer:" + value); + } + } } diff --git a/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/MultivariateObjectScript.java b/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/NashornMultivariateObjectScript.java similarity index 85% rename from engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/MultivariateObjectScript.java rename to engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/NashornMultivariateObjectScript.java index b88b11ba7..2a0cd70a0 100644 --- a/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/MultivariateObjectScript.java +++ b/engine-extensions/src/main/java/io/nosqlbench/engine/extensions/optimizers/NashornMultivariateObjectScript.java @@ -8,12 +8,12 @@ import java.security.InvalidParameterException; import java.util.HashMap; import java.util.Map; -public class MultivariateObjectScript implements MultivariateFunction { +public class NashornMultivariateObjectScript implements MultivariateFunction { private final ScriptObjectMirror script; private final MVParams params; private Logger logger; - public MultivariateObjectScript(Logger logger, MVParams params, ScriptObjectMirror script) { + public NashornMultivariateObjectScript(Logger logger, MVParams params, ScriptObjectMirror script) { this.logger = logger; this.script = script; this.params = params;