From 428ffe718f3236e118352c7f477f9a4a0ff2fc4b Mon Sep 17 00:00:00 2001 From: Jonathan Shook Date: Fri, 28 Aug 2020 12:36:20 -0500 Subject: [PATCH] make error propagation modal --- .../docsys/components/WorkspaceSelector.vue | 2 +- .../main/node/docsys/mixins/get_namespaces.js | 2 +- docsys/src/main/node/docsys/package.json | 2 +- .../pages/ui/{build/index.vue => build.vue} | 10 +- docsys/src/main/node/docsys/pages/ui/run.vue | 322 ++++++++++++++++++ .../main/node/docsys/pages/ui/run/index.vue | 274 --------------- .../src/main/node/docsys/pages/ui/watch.vue | 226 ++++++++++++ .../main/node/docsys/pages/ui/watch/index.vue | 146 -------- .../{workspaces/index.vue => workspaces.vue} | 2 +- .../docsys/pages/ui/workspaces/detail.vue | 86 +++++ docsys/src/main/node/docsys/store/docs.js | 9 +- .../src/main/node/docsys/store/invocations.js | 33 -- .../src/main/node/docsys/store/scenarios.js | 49 +++ .../src/main/node/docsys/store/workloads.js | 20 +- .../src/main/node/docsys/store/workspaces.js | 21 +- .../engine/api/activityapi/core/Activity.java | 9 +- .../api/activityapi/core/ProgressMeter.java | 45 ++- .../activityimpl/ProgressAndStateMeter.java | 55 +++ .../api/activityimpl/SimpleActivity.java | 28 +- .../api/activityimpl/input/AtomicInput.java | 102 ++++-- .../activityimpl/input/ProgressCapable.java | 6 +- .../api/activityimpl/input/StateCapable.java | 7 + .../api/scenarios/NBCLIScenarioParser.java | 8 +- .../engine/api/scenarios/WorkloadDesc.java | 12 +- .../engine/api/util/SSLKsFactory.java | 27 +- .../nosqlbench/engine/cli/NBCLIScenarios.java | 2 +- .../engine/core/ActivityExecutor.java | 90 ++--- ...or.java => ActivityProgressIndicator.java} | 29 +- .../engine/core/ScenarioController.java | 16 +- .../docs-for-nb/nosqlbench/getting_support.md | 10 +- .../rest/resources/ServiceStatusEndpoint.java | 5 + 31 files changed, 1020 insertions(+), 635 deletions(-) rename docsys/src/main/node/docsys/pages/ui/{build/index.vue => build.vue} (98%) create mode 100644 docsys/src/main/node/docsys/pages/ui/run.vue delete mode 100644 docsys/src/main/node/docsys/pages/ui/run/index.vue create mode 100644 docsys/src/main/node/docsys/pages/ui/watch.vue delete mode 100644 docsys/src/main/node/docsys/pages/ui/watch/index.vue rename docsys/src/main/node/docsys/pages/ui/{workspaces/index.vue => workspaces.vue} (98%) create mode 100644 docsys/src/main/node/docsys/pages/ui/workspaces/detail.vue delete mode 100644 docsys/src/main/node/docsys/store/invocations.js create mode 100644 docsys/src/main/node/docsys/store/scenarios.js create mode 100644 engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/ProgressAndStateMeter.java create mode 100644 engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/input/StateCapable.java rename engine-core/src/main/java/io/nosqlbench/engine/core/{ProgressIndicator.java => ActivityProgressIndicator.java} (76%) diff --git a/docsys/src/main/node/docsys/components/WorkspaceSelector.vue b/docsys/src/main/node/docsys/components/WorkspaceSelector.vue index 1f99538a5..c4ddb97df 100644 --- a/docsys/src/main/node/docsys/components/WorkspaceSelector.vue +++ b/docsys/src/main/node/docsys/components/WorkspaceSelector.vue @@ -78,7 +78,7 @@ export default { }); }, commitWorkspace: function ({$store}) { - console.log("commit:" + JSON.stringify(this.new_workspace)); + // console.log("commit:" + JSON.stringify(this.new_workspace)); this.$store.dispatch("workspaces/activateWorkspace", this.new_workspace); this.new_workspace = ""; this.mode = "showing"; diff --git a/docsys/src/main/node/docsys/mixins/get_namespaces.js b/docsys/src/main/node/docsys/mixins/get_namespaces.js index e2f321c8c..893911650 100644 --- a/docsys/src/main/node/docsys/mixins/get_namespaces.js +++ b/docsys/src/main/node/docsys/mixins/get_namespaces.js @@ -45,7 +45,7 @@ export default { } let result={namespaces: collated}; - console.log("namespaces result:"+JSON.stringify(result)); + // console.log("namespaces result:"+JSON.stringify(result)); return result; } diff --git a/docsys/src/main/node/docsys/package.json b/docsys/src/main/node/docsys/package.json index 1ae0dc9ed..3a97a0c2d 100644 --- a/docsys/src/main/node/docsys/package.json +++ b/docsys/src/main/node/docsys/package.json @@ -5,7 +5,7 @@ "author": "Sebastian Estevez & Jonathan Shook", "private": true, "scripts": { - "dev": "nuxt -c nuxt.config.dev.js", + "dev": "nuxt -c nuxt.config.dev.js --port 3003", "build": "nuxt build", "start": "nuxt start", "generate": "nuxt generate", diff --git a/docsys/src/main/node/docsys/pages/ui/build/index.vue b/docsys/src/main/node/docsys/pages/ui/build.vue similarity index 98% rename from docsys/src/main/node/docsys/pages/ui/build/index.vue rename to docsys/src/main/node/docsys/pages/ui/build.vue index 14744d345..4e90507f8 100644 --- a/docsys/src/main/node/docsys/pages/ui/build/index.vue +++ b/docsys/src/main/node/docsys/pages/ui/build.vue @@ -2,9 +2,7 @@ NoSQLBench - Workload Builder - + @@ -62,9 +60,9 @@ import {saveAs} from "file-saver"; import yamlDumper from "js-yaml"; import CQL3Parser from '@/antlr/CQL3Parser.js'; import CQL3Lexer from '@/antlr/CQL3Lexer.js'; -import defaultYaml from '~/assets/default.yaml'; -import basictypes from '@/assets/basictypes.yaml'; -import WorkspaceSelector from "~/components/WorkspaceSelector"; +import defaultYaml from 'assets/default.yaml'; +import basictypes from 'assets/basictypes.yaml'; +import WorkspaceSelector from "@/components/WorkspaceSelector"; import AppSelector from "@/components/AppSelector"; import MainAppBar from "@/components/MainAppBar"; diff --git a/docsys/src/main/node/docsys/pages/ui/run.vue b/docsys/src/main/node/docsys/pages/ui/run.vue new file mode 100644 index 000000000..eb59a9229 --- /dev/null +++ b/docsys/src/main/node/docsys/pages/ui/run.vue @@ -0,0 +1,322 @@ + + + diff --git a/docsys/src/main/node/docsys/pages/ui/run/index.vue b/docsys/src/main/node/docsys/pages/ui/run/index.vue deleted file mode 100644 index 8cdd36b95..000000000 --- a/docsys/src/main/node/docsys/pages/ui/run/index.vue +++ /dev/null @@ -1,274 +0,0 @@ - - - diff --git a/docsys/src/main/node/docsys/pages/ui/watch.vue b/docsys/src/main/node/docsys/pages/ui/watch.vue new file mode 100644 index 000000000..daeb4984a --- /dev/null +++ b/docsys/src/main/node/docsys/pages/ui/watch.vue @@ -0,0 +1,226 @@ + + + + + diff --git a/docsys/src/main/node/docsys/pages/ui/watch/index.vue b/docsys/src/main/node/docsys/pages/ui/watch/index.vue deleted file mode 100644 index d7037742e..000000000 --- a/docsys/src/main/node/docsys/pages/ui/watch/index.vue +++ /dev/null @@ -1,146 +0,0 @@ - - - - - diff --git a/docsys/src/main/node/docsys/pages/ui/workspaces/index.vue b/docsys/src/main/node/docsys/pages/ui/workspaces.vue similarity index 98% rename from docsys/src/main/node/docsys/pages/ui/workspaces/index.vue rename to docsys/src/main/node/docsys/pages/ui/workspaces.vue index 2343b8e6d..5ed01b1e6 100644 --- a/docsys/src/main/node/docsys/pages/ui/workspaces/index.vue +++ b/docsys/src/main/node/docsys/pages/ui/workspaces.vue @@ -72,7 +72,7 @@ + + diff --git a/docsys/src/main/node/docsys/store/docs.js b/docsys/src/main/node/docsys/store/docs.js index f0cf7c2e6..5d28985dc 100644 --- a/docsys/src/main/node/docsys/store/docs.js +++ b/docsys/src/main/node/docsys/store/docs.js @@ -62,7 +62,7 @@ export const getters = { throw "unable to load active markdown for undefined category"; } if (state.active_topic===null) { - throw "uanble to load active markdown for undefined topic"; + throw "unable to load active markdown for undefined topic"; } return state.active_topic.content; } @@ -78,13 +78,6 @@ export const mutations = { setCategories(state, categories) { state.categories = categories; }, - // initializeStore(state) { - // if(localStorage.getItem('store')) { - // this.replaceState( - // Object.assign(state,JSON.parse(localStorage.getItem('store'))) - // ); - // } - // }, toggleDrawerState(state, newDrawerState) { if (state.isMenuLocked) { return; diff --git a/docsys/src/main/node/docsys/store/invocations.js b/docsys/src/main/node/docsys/store/invocations.js deleted file mode 100644 index d9dd87795..000000000 --- a/docsys/src/main/node/docsys/store/invocations.js +++ /dev/null @@ -1,33 +0,0 @@ -// https://www.mikestreety.co.uk/blog/vue-js-using-localstorage-with-the-vuex-store -import {mapGetters} from "vuex"; - -export const state = () => ({ - invocations: [] -}); - -export const getters = { - getInvocations: (state, getters) => { - return state.invocations; - } -} - -export const mutations = { - setInvocations(state, invocations) { - state.invocations = invocations; - } -}; - -export const actions = { - async loadInvocations({commit, state, dispatch}, reason) { - console.log("initializing scenarios because '" + reason + "'") - this.$axios.$get("/executor/scenarios/") - .then(res => { - console.log("axios/vuex invocations async get:" + JSON.stringify(res)); - console.log("committing setInvocations:" + JSON.stringify(res)); - commit('setInvocations', res) - }) - .catch((e) => { - console.error("axios/nuxt invocations async error:", e); - }) - } -}; diff --git a/docsys/src/main/node/docsys/store/scenarios.js b/docsys/src/main/node/docsys/store/scenarios.js new file mode 100644 index 000000000..3c5640783 --- /dev/null +++ b/docsys/src/main/node/docsys/store/scenarios.js @@ -0,0 +1,49 @@ +// https://www.mikestreety.co.uk/blog/vue-js-using-localstorage-with-the-vuex-store +import {mapGetters} from "vuex"; + +export const state = () => ({ + scenarios: [] +}); + +export const getters = { + getScenarios: (state, getters) => { + return state.scenarios; + } +} + +export const mutations = { + setScenarios(state, scenarios) { + state.scenarios = scenarios; + } +} + +export const actions = { + async loadScenarios({commit, state, dispatch}, reason) { + console.log("loading scenarios because '" + reason + "'") + await this.$axios.$get("/executor/scenarios/") + .then(res => { + // console.log("axios/vuex scenarios async get:" + JSON.stringify(res)); + // console.log("committing setScenarios:" + JSON.stringify(res)); + commit('setScenarios', res) + }) + .catch((e) => { + console.error("axios/nuxt scenarios async error:", e); + }) + }, + async stopScenario({commit, state, dispatch}, scenario_name) { + await this.$axios.$post("/executor/stop/" + scenario_name) + .then() + .catch((e) => { + console.error("axios/nuxt scenario stop error:", e); + }) + await dispatch("loadScenarios") + }, + async deleteScenario({commit, state, dispatch}, scenario_name) { + await this.$axios.$delete("/executor/scenario/" + scenario_name) + .then() + .catch((e) => { + console.error("axios/nuxt scenario stop error:", e); + }) + await dispatch("loadScenarios") + } +}; diff --git a/docsys/src/main/node/docsys/store/workloads.js b/docsys/src/main/node/docsys/store/workloads.js index b188bf350..7a6f4490a 100644 --- a/docsys/src/main/node/docsys/store/workloads.js +++ b/docsys/src/main/node/docsys/store/workloads.js @@ -33,36 +33,36 @@ export const mutations = { export const actions = { async setWorkloads({commit, state, dispatch}, val) { - console.log("committing setWorkloads:" + JSON.stringify(val)); + // console.log("committing setWorkloads:" + JSON.stringify(val)); commit('setWorkloads', val); }, async setTemplates({commit, state, dispatch}, val) { - console.log("commiting setTemplates:" + JSON.stringify(val)); + // console.log("commiting setTemplates:" + JSON.stringify(val)); commit("setTemplates", val); }, async setSearchin({commit, state, dispatch}, val) { - console.log("committing setsearchin:" + JSON.stringify(val)); + // console.log("committing setsearchin:" + JSON.stringify(val)); commit('setSearchin', val); }, - fetchWorkloads({commit, state, dispatch}, params) { + async fetchWorkloads({commit, state, dispatch}, params) { let reason = params.reason; let searchin = params.searchin; if (reason === undefined || searchin === undefined) { throw "Unable to fetch workloads without a reason or searchin: " + JSON.stringify(params); } - console.log("fetching workloads because '" + reason + "'") + // console.log("fetching workloads because '" + reason + "'") commit("setTemplates", undefined); this.$axios.$get("/workloads/?searchin=" + searchin) .then(res => { - console.log("axios/vuex workloads async get:" + JSON.stringify(res)); + // console.log("axios/vuex workloads async get:" + JSON.stringify(res)); commit("setWorkloads", res); }) .catch((e) => { console.error("axios/nuxt workloads async error:", e); }) }, - async fetchTemplates({commit, state, dispatch}, params) { + fetchTemplates({commit, state, dispatch}, params) { let reason = params.reason; let workload = params.workload; let searchin = params.searchin; @@ -71,13 +71,15 @@ export const actions = { } console.log("fetching templates for '" + workload + "' because '" + reason + "'") - this.$axios.$get("/workloads/parameters?workloadName=" + workload + "&" + searchin) + this.$axios.$get("/workloads/parameters?workloadName=" + workload + "&" + "searchin=" + searchin) .then(res => { - console.log("axios/vuex templates async get:" + JSON.stringify(res)); + // console.log("axios/vuex templates async get:" + JSON.stringify(res)); dispatch("setTemplates", res); }) .catch((e) => { console.error("axios/nuxt templates async error:", e); }) + + } }; diff --git a/docsys/src/main/node/docsys/store/workspaces.js b/docsys/src/main/node/docsys/store/workspaces.js index a16d6531d..e4918b7aa 100644 --- a/docsys/src/main/node/docsys/store/workspaces.js +++ b/docsys/src/main/node/docsys/store/workspaces.js @@ -3,7 +3,8 @@ import {mapGetters} from "vuex"; export const state = () => ({ workspace: 'default', - workspaces: [] + workspaces: [], + fileview: [] }); export const getters = { @@ -12,6 +13,9 @@ export const getters = { }, getWorkspaces: (state, getters) => { return state.workspaces; + }, + getFileview: (state, getters) => { + return state.fileview; } // ...mapGetters(['workspace','workspaces']) @@ -23,24 +27,27 @@ export const mutations = { }, setWorkspaces(state, workspaces) { state.workspaces = workspaces; + }, + setFileview(state, fileview) { + state.fileview = fileview; } }; export const actions = { async setWorkspace({commit, state, dispatch}, val) { - console.log("committing setWorkspace:" + JSON.stringify(val)); + // console.log("committing setWorkspace:" + JSON.stringify(val)); commit('setWorkspace', val); }, async setWorkspaces({commit, state, dispatch}, val) { - console.log("committing setWorkspaces:" + JSON.stringify(val)); + // console.log("committing setWorkspaces:" + JSON.stringify(val)); commit('setWorkspaces', val); }, async initWorkspaces({commit, state, dispatch}, reason) { - console.log("initializing workspaces because '" + reason + "'") + // console.log("initializing workspaces because '" + reason + "'") this.$axios.$get("/workspaces/") .then(res => { - console.log("axios/vuex workspaces async get:" + JSON.stringify(res)); - console.log("committing setWorkspaces:" + JSON.stringify(res)); + // console.log("axios/vuex workspaces async get:" + JSON.stringify(res)); + // console.log("committing setWorkspaces:" + JSON.stringify(res)); commit('setWorkspaces', res) }) .catch((e) => { @@ -66,7 +73,7 @@ export const actions = { async activateWorkspace({commit, state, dispatch}, workspace) { const fresh_workspace = await this.$axios.$get("/workspaces/" + workspace) .then(res => { - console.log("axios/vuex workspace async get:" + JSON.stringify(res)) + // console.log("axios/vuex workspace async get:" + JSON.stringify(res)) return res; }) .catch((e) => { diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/core/Activity.java b/engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/core/Activity.java index 1f0143c9b..d9f20b99e 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/core/Activity.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/core/Activity.java @@ -25,6 +25,8 @@ import io.nosqlbench.engine.api.activityapi.ratelimits.RateLimiter; import io.nosqlbench.engine.api.activityimpl.ActivityDef; import io.nosqlbench.engine.api.activityimpl.ParameterMap; import io.nosqlbench.engine.api.activityimpl.SimpleActivity; +import io.nosqlbench.engine.api.activityimpl.input.ProgressCapable; +import io.nosqlbench.engine.api.activityimpl.input.StateCapable; import java.io.InputStream; import java.io.PrintWriter; @@ -34,15 +36,17 @@ import java.util.function.Supplier; * Provides the components needed to build and run an activity a runtime. * The easiest way to build a useful Activity is to extend {@link SimpleActivity}. */ -public interface Activity extends Comparable, ActivityDefObserver { +public interface Activity extends Comparable, ActivityDefObserver, ProgressCapable, StateCapable { /** * Provide the activity with the controls needed to stop itself. + * * @param activityController The dedicated control interface for this activity */ void setActivityController(ActivityController activityController); ActivityController getActivityController(); + /** * Register an object which should be closed after this activity is shutdown. * @@ -89,8 +93,11 @@ public interface Activity extends Comparable, ActivityDefObserver { void setOutputDispenserDelegate(OutputDispenser outputDispenser); RunState getRunState(); + void setRunState(RunState runState); + long getStartedAtMillis(); + default void shutdownActivity() { } diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/core/ProgressMeter.java b/engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/core/ProgressMeter.java index 2a517314e..4ee921b10 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/core/ProgressMeter.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/core/ProgressMeter.java @@ -18,8 +18,47 @@ package io.nosqlbench.engine.api.activityapi.core; public interface ProgressMeter { - double getProgress(); String getProgressName(); - RunState getProgressState(); - String getProgressDetails(); + + // RunState getProgressState(); + long getStartedAtMillis(); + + long getProgressMin(); + + long getProgressCurrent(); + + long getProgressMax(); + + long getRecyclesCurrent(); + + long getRecyclesMax(); + + default String getProgressSummary() { + return "min=" + getProgressMin() + " cycle=" + getProgressCurrent() + " max=" + getProgressMax() + + (getRecyclesMax() > 0L ? " recycles=" + getRecyclesCurrent() + "/" + getRecyclesMax() : ""); + } + + default double getProgressRatio() { + return + ((double) (getProgressCurrent() - getProgressMin())) + / + ((double) (getProgressMax() - getProgressMin())); + } + + default double getProgressTotal() { + return (getProgressMax() - getProgressMin()); + } + + default double getProgressETAMillis() { + long then = getStartedAtMillis(); + long now = System.currentTimeMillis(); + double elapsed = now - then; + + double completed = getProgressCurrent() - getProgressMin(); + double rate = completed / elapsed; + + double remaining = getProgressMax() - getProgressCurrent(); + return remaining / rate; + } } + diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/ProgressAndStateMeter.java b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/ProgressAndStateMeter.java new file mode 100644 index 000000000..5ee6e3ffd --- /dev/null +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/ProgressAndStateMeter.java @@ -0,0 +1,55 @@ +package io.nosqlbench.engine.api.activityimpl; + +import io.nosqlbench.engine.api.activityapi.core.ProgressMeter; +import io.nosqlbench.engine.api.activityapi.core.RunState; +import io.nosqlbench.engine.api.activityimpl.input.StateCapable; + +public class ProgressAndStateMeter implements ProgressMeter, StateCapable { + private final ProgressMeter meter; + private final StateCapable statesrc; + + public ProgressAndStateMeter(ProgressMeter meter, StateCapable statesrc) { + this.meter = meter; + this.statesrc = statesrc; + } + + @Override + public String getProgressName() { + return meter.getProgressName(); + } + + @Override + public long getStartedAtMillis() { + return meter.getStartedAtMillis(); + } + + @Override + public long getProgressMin() { + return meter.getProgressMin(); + } + + @Override + public long getProgressCurrent() { + return meter.getProgressCurrent(); + } + + @Override + public long getProgressMax() { + return meter.getProgressMax(); + } + + @Override + public long getRecyclesCurrent() { + return meter.getRecyclesCurrent(); + } + + @Override + public long getRecyclesMax() { + return meter.getRecyclesMax(); + } + + @Override + public RunState getRunState() { + return statesrc.getRunState(); + } +} diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/SimpleActivity.java b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/SimpleActivity.java index 108c1c71f..5378d4280 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/SimpleActivity.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/SimpleActivity.java @@ -3,6 +3,7 @@ package io.nosqlbench.engine.api.activityimpl; import com.codahale.metrics.Timer; import io.nosqlbench.engine.api.activityapi.core.*; import io.nosqlbench.engine.api.activityapi.cyclelog.filters.IntPredicateDispenser; +import io.nosqlbench.engine.api.activityapi.input.Input; import io.nosqlbench.engine.api.activityapi.input.InputDispenser; import io.nosqlbench.engine.api.activityapi.output.OutputDispenser; import io.nosqlbench.engine.api.activityapi.planning.OpSequence; @@ -14,6 +15,7 @@ import io.nosqlbench.engine.api.activityapi.ratelimits.RateSpec; import io.nosqlbench.engine.api.activityconfig.StatementsLoader; import io.nosqlbench.engine.api.activityconfig.yaml.OpTemplate; import io.nosqlbench.engine.api.activityconfig.yaml.StmtsDocList; +import io.nosqlbench.engine.api.activityimpl.input.ProgressCapable; import io.nosqlbench.engine.api.metrics.ActivityMetrics; import io.nosqlbench.engine.api.templating.CommandTemplate; import io.nosqlbench.engine.api.templating.StrInterpolator; @@ -32,11 +34,11 @@ import java.util.function.Supplier; /** * A default implementation of an Activity, suitable for building upon. */ -public class SimpleActivity implements Activity { +public class SimpleActivity implements Activity, ProgressCapable { private final static Logger logger = LoggerFactory.getLogger(SimpleActivity.class); protected ActivityDef activityDef; - private List closeables = new ArrayList<>(); + private final List closeables = new ArrayList<>(); private MotorDispenser motorDispenser; private InputDispenser inputDispenser; private ActionDispenser actionDispenser; @@ -49,6 +51,7 @@ public class SimpleActivity implements Activity { private ActivityController activityController; private ActivityInstrumentation activityInstrumentation; private PrintWriter console; + private long startedAtMillis; public SimpleActivity(ActivityDef activityDef) { this.activityDef = activityDef; @@ -70,6 +73,14 @@ public class SimpleActivity implements Activity { public synchronized void setRunState(RunState runState) { this.runState = runState; + if (runState == RunState.Running) { + this.startedAtMillis = System.currentTimeMillis(); + } + } + + @Override + public long getStartedAtMillis() { + return startedAtMillis; } @Override @@ -207,6 +218,7 @@ public class SimpleActivity implements Activity { } + @Override public Timer getResultTimer() { return ActivityMetrics.timer(getActivityDef(), "result"); @@ -399,4 +411,16 @@ public class SimpleActivity implements Activity { return planner.resolve(); } + @Override + public ProgressMeter getProgressMeter() { + Input input = getInputDispenserDelegate().getInput(0); + if (input instanceof ProgressCapable) { + ProgressMeter meter = ((ProgressCapable) input).getProgressMeter(); + return new ProgressAndStateMeter(meter, this); + } else { + throw new RuntimeException("Progress meter must be implemented here."); + } + } + + } diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/input/AtomicInput.java b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/input/AtomicInput.java index 6e7aea58a..5385d72c9 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/input/AtomicInput.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/input/AtomicInput.java @@ -17,6 +17,7 @@ package io.nosqlbench.engine.api.activityimpl.input; import io.nosqlbench.engine.api.activityapi.core.ActivityDefObserver; +import io.nosqlbench.engine.api.activityapi.core.ProgressMeter; import io.nosqlbench.engine.api.activityapi.cyclelog.buffers.results.CycleSegment; import io.nosqlbench.engine.api.activityapi.input.Input; import io.nosqlbench.engine.api.activityimpl.ActivityDef; @@ -50,8 +51,9 @@ public class AtomicInput implements Input, ActivityDefObserver, ProgressCapable private final AtomicLong recycleValue = new AtomicLong(0L); private final AtomicLong recycleMax = new AtomicLong(0L); + private final long startedAt = System.currentTimeMillis(); - private ActivityDef activityDef; + private final ActivityDef activityDef; public AtomicInput(ActivityDef activityDef) { this.activityDef = activityDef; @@ -64,15 +66,15 @@ public class AtomicInput implements Input, ActivityDefObserver, ProgressCapable long current = this.cycleValue.get(); long next = current + stride; if (next > max.get()) { - if (recycleValue.get()>=recycleMax.get()) { + if (recycleValue.get() >= recycleMax.get()) { logger.trace("Exhausted input for " + activityDef.getAlias() + " at " + current + ", recycle " + "count " + recycleValue.get()); return null; } else { - if (cycleValue.compareAndSet(current,min.get()+stride)) { + if (cycleValue.compareAndSet(current, min.get() + stride)) { recycleValue.getAndIncrement(); logger.trace("recycling input for " + activityDef.getAlias() + " recycle:" + recycleValue.get()); - return new InputInterval.Segment(min.get(), min.get()+stride); + return new InputInterval.Segment(min.get(), min.get() + stride); } } } @@ -82,30 +84,30 @@ public class AtomicInput implements Input, ActivityDefObserver, ProgressCapable } } - @Override - public double getProgress() { - return (double) (cycleValue.get() - min.get()); - } - - @Override - public double getTotal() { - return (double) (max.get() - min.get()); - } - - @Override - public String getProgressDetails() { - return "min=" +min.get() + " cycle=" + cycleValue.get() + " max=" + max.get() + - (recycleMax.get()>0L ? " recycles=" + recycleValue.get() +"/" + recycleMax.get() : ""); - } +// @Override +// public double getProgress() { +// return (double) (cycleValue.get() - min.get()); +// } +// +// @Override +// public double getTotal() { +// return (double) (max.get() - min.get()); +// } +// +// @Override +// public AtomicInputProgress.Range getRange() { +// return new Range(this); +// } +// @Override public String toString() { return "AtomicInput{" + - "cycleValue=" + cycleValue + - ", min=" + min + - ", max=" + max + - ", activity=" + activityDef.getAlias() + - '}'; + "cycleValue=" + cycleValue + + ", min=" + min + + ", max=" + max + + ", activity=" + activityDef.getAlias() + + '}'; } @Override @@ -134,7 +136,10 @@ public class AtomicInput implements Input, ActivityDefObserver, ProgressCapable long recycles = activityDef.getParams().getOptionalString("recycles").flatMap(Unit::longCountFor).orElse(0L); this.recycleMax.set(recycles); + } + public long getStarteAtMillis() { + return this.startedAt; } @Override @@ -142,4 +147,53 @@ public class AtomicInput implements Input, ActivityDefObserver, ProgressCapable return true; } + @Override + public AtomicInputProgress getProgressMeter() { + return new AtomicInputProgress(activityDef.getAlias(), this); + } + + private static class AtomicInputProgress implements ProgressMeter { + private final AtomicInput input; + private final String name; + + public AtomicInputProgress(String name, AtomicInput input) { + this.name = name; + this.input = input; + } + + @Override + public String getProgressName() { + return name; + } + + @Override + public long getStartedAtMillis() { + return input.getStarteAtMillis(); + } + + @Override + public long getProgressMin() { + return input.min.get(); + } + + @Override + public long getProgressCurrent() { + return input.cycleValue.get(); + } + + @Override + public long getProgressMax() { + return input.max.get(); + } + + @Override + public long getRecyclesCurrent() { + return input.recycleValue.get(); + } + + @Override + public long getRecyclesMax() { + return input.recycleMax.get(); + } + } } diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/input/ProgressCapable.java b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/input/ProgressCapable.java index 1562fb2ff..5026fb4b9 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/input/ProgressCapable.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/input/ProgressCapable.java @@ -17,11 +17,11 @@ package io.nosqlbench.engine.api.activityimpl.input; +import io.nosqlbench.engine.api.activityapi.core.ProgressMeter; + /** * Any type that implements this interface can provide a double indicating relative progress. */ public interface ProgressCapable { - double getProgress(); - double getTotal(); - String getProgressDetails(); + ProgressMeter getProgressMeter(); } diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/input/StateCapable.java b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/input/StateCapable.java new file mode 100644 index 000000000..8f4701539 --- /dev/null +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/input/StateCapable.java @@ -0,0 +1,7 @@ +package io.nosqlbench.engine.api.activityimpl.input; + +import io.nosqlbench.engine.api.activityapi.core.RunState; + +public interface StateCapable { + RunState getRunState(); +} diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/scenarios/NBCLIScenarioParser.java b/engine-api/src/main/java/io/nosqlbench/engine/api/scenarios/NBCLIScenarioParser.java index 54cc091af..c3d9bad6b 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/scenarios/NBCLIScenarioParser.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/scenarios/NBCLIScenarioParser.java @@ -315,7 +315,7 @@ public class NBCLIScenarioParser { } String description = stmts.getDescription(); - workloadDescriptions.add(new WorkloadDesc(referenced, scenarioNames, sortedTemplates, description,"")); + workloadDescriptions.add(new WorkloadDesc(referenced, scenarioNames, sortedTemplates, description, "")); } } Collections.sort(workloadDescriptions); @@ -324,11 +324,15 @@ public class NBCLIScenarioParser { } + public static List getWorkloadsWithScenarioScripts(boolean defaultIncludes, Set includes) { + return getWorkloadsWithScenarioScripts(defaultIncludes, includes.toArray(new String[0])); + } + public static List getWorkloadsWithScenarioScripts(boolean defaultIncludes, String... includes) { NBPathsAPI.GetPrefix searchin = NBIO.all(); if (defaultIncludes) { - searchin= searchin.prefix(SEARCH_IN); + searchin = searchin.prefix(SEARCH_IN); } List> activities = searchin diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/scenarios/WorkloadDesc.java b/engine-api/src/main/java/io/nosqlbench/engine/api/scenarios/WorkloadDesc.java index f094bf79f..e42b73805 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/scenarios/WorkloadDesc.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/scenarios/WorkloadDesc.java @@ -48,10 +48,13 @@ public class WorkloadDesc implements Comparable { public String toString() { - return toString(true); + return + ((workspace != null && !workspace.isEmpty()) ? workspace + ":" : "") + + this.yamlPath; +// + (this.description != null ? "\ndesc: " + this.description : ""); } - public String toString(boolean includeScenarios) { + public String toMarkdown(boolean includeScenarios) { StringBuilder sb = new StringBuilder(); @@ -61,10 +64,10 @@ public class WorkloadDesc implements Comparable { if (!description.isEmpty()) { // sb.append("# description:\n"); - String formttedDesc = "# " + String.join("\n# ",description.split("\n")); + String formttedDesc = "# " + String.join("\n# ", description.split("\n")); sb.append(formttedDesc).append("\n"); while (sb.toString().endsWith("\n\n")) { - sb.setLength(sb.length()-1); + sb.setLength(sb.length() - 1); } // if (!description.endsWith("\n")) { // sb.append("\n"); @@ -124,4 +127,5 @@ public class WorkloadDesc implements Comparable { public String getWorkspace() { return workspace; } + } diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/util/SSLKsFactory.java b/engine-api/src/main/java/io/nosqlbench/engine/api/util/SSLKsFactory.java index 25d240dc4..3954c74d9 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/util/SSLKsFactory.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/util/SSLKsFactory.java @@ -17,11 +17,16 @@ package io.nosqlbench.engine.api.util; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; +import io.nosqlbench.engine.api.activityimpl.ActivityDef; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ServerSocketFactory; +import javax.net.SocketFactory; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import java.io.*; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.KeyStore; @@ -33,16 +38,6 @@ import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.Optional; import java.util.regex.Pattern; -import javax.net.ServerSocketFactory; -import javax.net.SocketFactory; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.nosqlbench.engine.api.activityimpl.ActivityDef; public class SSLKsFactory { private final static Logger logger = LoggerFactory.getLogger(SSLKsFactory.class); @@ -186,7 +181,7 @@ public class SSLKsFactory { kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(keyStore, keyPassword); } catch (Exception e) { - throw new RuntimeException("Unable to init KeyManagerFactory. Please check.", e); + throw new RuntimeException("Unable to init KeyManagerFactory. Please check password and location.", e); } TrustManagerFactory tmf; diff --git a/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIScenarios.java b/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIScenarios.java index 8aac7338c..5275ec82e 100644 --- a/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIScenarios.java +++ b/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIScenarios.java @@ -12,7 +12,7 @@ public class NBCLIScenarios { NBCLIScenarioParser.getWorkloadsWithScenarioScripts(true, includes); for (WorkloadDesc workload : workloads) { - System.out.println(workload.toString(includeScenarios)); + System.out.println(workload.toMarkdown(includeScenarios)); } if (!includeScenarios) { diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/ActivityExecutor.java b/engine-core/src/main/java/io/nosqlbench/engine/core/ActivityExecutor.java index de788d1bb..9c96337e3 100644 --- a/engine-core/src/main/java/io/nosqlbench/engine/core/ActivityExecutor.java +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/ActivityExecutor.java @@ -15,10 +15,8 @@ package io.nosqlbench.engine.core; import io.nosqlbench.engine.api.activityapi.core.*; -import io.nosqlbench.engine.api.activityapi.input.Input; import io.nosqlbench.engine.api.activityimpl.ActivityDef; import io.nosqlbench.engine.api.activityimpl.ParameterMap; -import io.nosqlbench.engine.api.activityimpl.SlotStateTracker; import io.nosqlbench.engine.api.activityimpl.input.ProgressCapable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,7 +44,7 @@ import java.util.stream.Collectors; * */ -public class ActivityExecutor implements ActivityController, ParameterMap.Listener, ProgressMeter { +public class ActivityExecutor implements ActivityController, ParameterMap.Listener, ProgressCapable { private static final Logger logger = LoggerFactory.getLogger(ActivityExecutor.class); private static final Logger activitylogger = LoggerFactory.getLogger("ACTIVITY"); @@ -121,14 +119,7 @@ public class ActivityExecutor implements ActivityController, ParameterMap.Listen } - /** - * Shutdown the activity executor, with a grace period for the motor threads. - * - * @param initialMillisToWait milliseconds to wait after graceful shutdownActivity request, before forcing - * everything to stop - */ - public synchronized void forceStopExecutor(int initialMillisToWait) { - + public synchronized RuntimeException forceStopScenario(int initialMillisToWait) { activitylogger.debug("FORCE STOP/before alias=(" + activity.getAlias() + ")"); activity.setRunState(RunState.Stopped); @@ -164,15 +155,28 @@ public class ActivityExecutor implements ActivityController, ParameterMap.Listen activity.closeAutoCloseables(); long activityShutdownEndedAt = System.currentTimeMillis(); logger.debug("took " + (activityShutdownEndedAt - activityShutdownStartedAt) + " ms to shutdown activity threads"); + activitylogger.debug("FORCE STOP/after alias=(" + activity.getAlias() + ")"); if (stoppingException != null) { activitylogger.debug("FORCE STOP/exception alias=(" + activity.getAlias() + ")"); - throw stoppingException; } - activitylogger.debug("FORCE STOP/after alias=(" + activity.getAlias() + ")"); + return stoppingException; } + /** + * Shutdown the activity executor, with a grace period for the motor threads. + * + * @param initialMillisToWait milliseconds to wait after graceful shutdownActivity request, before forcing + * everything to stop + */ + public synchronized void forceStopScenarioAndThrow(int initialMillisToWait, boolean rethrow) { + RuntimeException exception = forceStopScenario(initialMillisToWait); + if (exception != null && rethrow) { + throw exception; + } + } + public boolean requestStopExecutor(int secondsToWait) { activitylogger.debug("REQUEST STOP/before alias=(" + activity.getAlias() + ")"); @@ -465,61 +469,10 @@ public class ActivityExecutor implements ActivityController, ParameterMap.Listen return activity; } - @Override - public synchronized double getProgress() { - ArrayList inputs = motors.stream() - .map(Motor::getInput) - .distinct() - .collect(Collectors.toCollection(ArrayList::new)); - - double startCycle = getActivityDef().getStartCycle(); - double endCycle = getActivityDef().getEndCycle(); - double totalCycles = endCycle - startCycle; - - double total = 0.0D; - double progress = 0.0D; - - for (Input input : inputs) { - if (input instanceof ProgressCapable) { - ProgressCapable progressInput = (ProgressCapable) input; - total += progressInput.getTotal(); - progress += progressInput.getProgress(); - - } else { - logger.warn("input does not support activity progress: " + input); - return Double.NaN; - } - } - - return progress / total; - } - - @Override - public String getProgressDetails() { - return motors.stream().map(Motor::getInput).distinct().findFirst() - .filter(i -> i instanceof ProgressCapable) - .map(i -> ((ProgressCapable) i).getProgressDetails()).orElse(""); - } - - - @Override - public String getProgressName() { - return activityDef.getAlias(); - } - - @Override - public RunState getProgressState() { - Optional first = motors.stream() - .map(Motor::getSlotStateTracker).map(SlotStateTracker::getSlotState) - .distinct().sorted().findFirst(); - return first.orElse(RunState.Uninitialized); - } - - public synchronized void notifyException(Thread t, Throwable e) { //logger.error("Uncaught exception in activity thread forwarded to activity executor:", e); this.stoppingException = new RuntimeException("Error in activity thread " + t.getName(), e); - forceStopExecutor(10000); + forceStopScenario(10000); } @Override @@ -544,4 +497,11 @@ public class ActivityExecutor implements ActivityController, ParameterMap.Listen } requestStopMotors(); } + + @Override + public ProgressMeter getProgressMeter() { + return this.activity.getProgressMeter(); + } + + } diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/ProgressIndicator.java b/engine-core/src/main/java/io/nosqlbench/engine/core/ActivityProgressIndicator.java similarity index 76% rename from engine-core/src/main/java/io/nosqlbench/engine/core/ProgressIndicator.java rename to engine-core/src/main/java/io/nosqlbench/engine/core/ActivityProgressIndicator.java index 827eedf8d..b4d325767 100644 --- a/engine-core/src/main/java/io/nosqlbench/engine/core/ProgressIndicator.java +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/ActivityProgressIndicator.java @@ -17,8 +17,8 @@ package io.nosqlbench.engine.core; -import io.nosqlbench.engine.api.activityapi.core.ProgressMeter; import io.nosqlbench.engine.api.activityapi.core.RunState; +import io.nosqlbench.engine.api.activityimpl.ProgressAndStateMeter; import io.nosqlbench.engine.api.metrics.IndicatorMode; import io.nosqlbench.engine.api.metrics.PeriodicRunnable; import io.nosqlbench.engine.api.util.Unit; @@ -30,18 +30,18 @@ import java.util.HashSet; import java.util.Locale; import java.util.Set; -public class ProgressIndicator implements Runnable { +public class ActivityProgressIndicator implements Runnable { - private final static Logger logger = LoggerFactory.getLogger(ProgressIndicator.class); + private final static Logger logger = LoggerFactory.getLogger(ActivityProgressIndicator.class); private final String indicatorSpec; private final ScenarioController sc; - private PeriodicRunnable runnable; + private PeriodicRunnable runnable; private IndicatorMode indicatorMode = IndicatorMode.console; - private Set seen = new HashSet<>(); + private final Set seen = new HashSet<>(); - private long intervalMillis=1L; + private long intervalMillis = 1L; - public ProgressIndicator(ScenarioController sc, String indicatorSpec) { + public ActivityProgressIndicator(ScenarioController sc, String indicatorSpec) { this.sc = sc; this.indicatorSpec = indicatorSpec; start(); @@ -76,21 +76,22 @@ public class ProgressIndicator implements Runnable { @Override public void run() { - Collection progressMeters = sc.getProgressMeters(); - for (ProgressMeter meter : progressMeters) { + Collection progressMeters = sc.getProgressMeters(); + for (ProgressAndStateMeter meter : progressMeters) { - boolean lastReport=false; - if (meter.getProgress()>=1.0d || meter.getProgressState()== RunState.Finished) { + boolean lastReport = false; + if (meter.getProgressRatio() >= 1.0d || meter.getRunState() == RunState.Finished) { if (seen.contains(meter.getProgressName())) { continue; } else { seen.add(meter.getProgressName()); - lastReport=true; + lastReport = true; } } - String progress = meter.getProgressName() + ": " + formatProgress(meter.getProgress()) + "/" + meter.getProgressState() + - " (details: " + meter.getProgressDetails()+")" + (lastReport ? " (last report)" : ""); + String progress = + meter.getProgressName() + ": " + formatProgress(meter.getProgressRatio()) + "/" + meter.getRunState() + + " (details: " + meter.getProgressSummary() + ")" + (lastReport ? " (last report)" : ""); switch (indicatorMode) { case console: 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 38691ddcb..859648c86 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 @@ -16,11 +16,11 @@ package io.nosqlbench.engine.core; import io.nosqlbench.engine.api.activityapi.core.Activity; import io.nosqlbench.engine.api.activityapi.core.ActivityType; -import io.nosqlbench.engine.api.activityapi.core.ProgressMeter; import io.nosqlbench.engine.api.activityimpl.ActivityDef; import io.nosqlbench.engine.api.activityimpl.ParameterMap; -import io.nosqlbench.nb.api.errors.BasicError; +import io.nosqlbench.engine.api.activityimpl.ProgressAndStateMeter; import io.nosqlbench.engine.api.metrics.ActivityMetrics; +import io.nosqlbench.nb.api.errors.BasicError; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -332,9 +332,9 @@ public class ScenarioController { * * @param waitTimeMillis grace period during which an activity may cooperatively shut down */ - public void forceStopScenario(int waitTimeMillis) { + public void forceStopScenario(int waitTimeMillis, boolean rethrow) { logger.debug("Scenario force stopped."); - activityExecutors.values().forEach(a -> a.forceStopExecutor(waitTimeMillis)); + activityExecutors.values().forEach(a -> a.forceStopScenarioAndThrow(waitTimeMillis, rethrow)); } /** @@ -414,7 +414,11 @@ public class ScenarioController { return activityMap; } - public Collection getProgressMeters() { - return this.activityExecutors.values().stream().map(e -> (ProgressMeter) e).collect(Collectors.toList()); + public Collection getProgressMeters() { + List indicators = new ArrayList<>(); + for (ActivityExecutor ae : activityExecutors.values()) { + indicators.add(new ProgressAndStateMeter(ae.getProgressMeter(), ae.getActivity())); + } + return indicators; } } diff --git a/engine-docs/src/main/resources/docs-for-nb/nosqlbench/getting_support.md b/engine-docs/src/main/resources/docs-for-nb/nosqlbench/getting_support.md index 1445f35db..a154f8f0d 100644 --- a/engine-docs/src/main/resources/docs-for-nb/nosqlbench/getting_support.md +++ b/engine-docs/src/main/resources/docs-for-nb/nosqlbench/getting_support.md @@ -26,16 +26,12 @@ are automatically included when NoSQLBench is built. ## NoSQLBench Slack -There is a new slack channel at nosqlbench.slack.com. In order to access the slack channel, you'll need an invite. You -can get that through this simple form, which will send you an invite in email: -[Slack Invite](https://docs.google.com/forms/d/e/1FAIpQLSdUOJ8iAPqyxsLfh1nBBsKShI53RAeuzYW4bKExmRMWjj4ufQ/viewform). -This is just a simple google form that automates the invite process. +Please click the +[Invite Link for nosqlbench.slack.com](https://join.slack.com/t/nosqlbench/shared_invite/zt-grrg64g3-6SeVi2jaum0cxp51WnvOVA) +to join us. Please join it if you are a new or existing NoSQLBench user and help us get it going! - - - ## General Feedback These guidelines are mirrored at the diff --git a/engine-rest/src/main/java/io/nosqlbench/engine/rest/resources/ServiceStatusEndpoint.java b/engine-rest/src/main/java/io/nosqlbench/engine/rest/resources/ServiceStatusEndpoint.java index fc0c6da87..42066cce7 100644 --- a/engine-rest/src/main/java/io/nosqlbench/engine/rest/resources/ServiceStatusEndpoint.java +++ b/engine-rest/src/main/java/io/nosqlbench/engine/rest/resources/ServiceStatusEndpoint.java @@ -10,6 +10,8 @@ import javax.inject.Singleton; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import javax.ws.rs.core.Configuration; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; @Service(WebServiceObject.class) @@ -18,6 +20,9 @@ import javax.ws.rs.core.MediaType; public class ServiceStatusEndpoint implements WebServiceObject { private final static Logger logger = LogManager.getLogger(AutoDocsWebService.class); + @Context + private Configuration config; + @GET @Produces(MediaType.APPLICATION_JSON) public boolean isEnabled() {