mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
Add NBAdvisor Framework (#2070)
* Add NBAdvisor Framework * Revert "Add NBAdvisor Framework" This reverts commitf2f448ffc3. * Reapply "Add NBAdvisor Framework" This reverts commit8048402b88. * Update pom.xml * Adjust * Fix tabs * Revert change including test * Simplify toString * Advisor is now a global option * Added error checking * NB Advisor runtime scaffold prototype * fix double dispatch error * Make NBAdvisorLevel sticky and evaluate error count * Working towards better encapsulation * advisor refinements * document alignment of log levels and advisor levels * doc updates * Evaluation refactor and fix integration tests * Cleanup tabs * Rename Exception * Use a logger for output * Small cleanup * Remove extraneous dependency * OF - bug fix * Add Advisor Exception Test --------- Co-authored-by: Jonathan Shook <jshook@gmail.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import com.amazonaws.util.StringInputStream;
|
|||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import io.nosqlbench.nb.api.nbio.Content;
|
import io.nosqlbench.nb.api.nbio.Content;
|
||||||
import io.nosqlbench.nb.api.nbio.NBIO;
|
import io.nosqlbench.nb.api.nbio.NBIO;
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorException;
|
||||||
import io.nosqlbench.nb.api.errors.BasicError;
|
import io.nosqlbench.nb.api.errors.BasicError;
|
||||||
import io.nosqlbench.adapters.api.activityconfig.rawyaml.RawOpsDocList;
|
import io.nosqlbench.adapters.api.activityconfig.rawyaml.RawOpsDocList;
|
||||||
import io.nosqlbench.adapters.api.activityconfig.rawyaml.RawOpsLoader;
|
import io.nosqlbench.adapters.api.activityconfig.rawyaml.RawOpsLoader;
|
||||||
@@ -129,10 +130,10 @@ public class OpsLoader {
|
|||||||
System.err.println(stderrOutput);
|
System.err.println(stderrOutput);
|
||||||
if (resultStatus==0 && stderrOutput.isEmpty()) {
|
if (resultStatus==0 && stderrOutput.isEmpty()) {
|
||||||
logger.info("no errors detected during jsonnet evaluation.");
|
logger.info("no errors detected during jsonnet evaluation.");
|
||||||
System.exit(0);
|
throw new NBAdvisorException("dryrun=jsonnet: No errors detected.", 0);
|
||||||
} else {
|
} else {
|
||||||
logger.error("ERRORS detected during jsonnet evaluation:\n" + stderrOutput);
|
logger.error("ERRORS detected during jsonnet evaluation:\n" + stderrOutput);
|
||||||
System.exit(2);
|
throw new NBAdvisorException("dryrun=jsonnet: Errors detected.", 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!stderrOutput.isEmpty()) {
|
if (!stderrOutput.isEmpty()) {
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ public abstract class BaseDriverAdapter<RESULT
|
|||||||
.add(Param.defaultTo("dryrun", "none").setRegex("(op|jsonnet|emit|none)"))
|
.add(Param.defaultTo("dryrun", "none").setRegex("(op|jsonnet|emit|none)"))
|
||||||
.add(Param.optional("maxtries", Integer.class))
|
.add(Param.optional("maxtries", Integer.class))
|
||||||
.asReadOnly();
|
.asReadOnly();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -162,7 +162,6 @@
|
|||||||
<version>3.46.0.0</version>
|
<version>3.46.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package io.nosqlbench.nb.api.advisor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import io.nosqlbench.nb.api.components.core.NBComponent;
|
||||||
|
|
||||||
|
public abstract class BaseAdvisorBuilder<ELEMENT, T, SelfT extends BaseAdvisorBuilder<ELEMENT, T, SelfT>>
|
||||||
|
extends NBAdvisorPointOrBuilder<ELEMENT> {
|
||||||
|
|
||||||
|
protected NBComponent component;
|
||||||
|
protected String name;
|
||||||
|
protected String description;
|
||||||
|
|
||||||
|
protected abstract SelfT self();
|
||||||
|
|
||||||
|
public SelfT component(NBComponent component) {
|
||||||
|
this.component = component;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SelfT name(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SelfT desc(String description) {
|
||||||
|
this.description = description;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract <PTYPE> NBAdvisorPoint<PTYPE> build();
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package io.nosqlbench.nb.api.advisor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class NBAdvisorBuilder<PTYPE>
|
||||||
|
extends BaseAdvisorBuilder<PTYPE, NBAdvisorPoint<PTYPE>, NBAdvisorBuilder<PTYPE>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NBAdvisorBuilder<PTYPE> self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBAdvisorPoint<PTYPE> build() {
|
||||||
|
return (NBAdvisorPoint<PTYPE>) new NBAdvisorPoint<PTYPE>(name, description == null ? name : description);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package io.nosqlbench.nb.api.advisor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import io.nosqlbench.nb.api.components.core.NBNamedElement;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
|
public interface NBAdvisorCondition<T> extends Function<T, NBAdvisorPoint.Result<T>>, Predicate<T> {
|
||||||
|
|
||||||
|
Function<T, String> okMsg();
|
||||||
|
|
||||||
|
Function<T, String> errMsg();
|
||||||
|
|
||||||
|
Level level();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default NBAdvisorPoint.Result<T> apply(T element) {
|
||||||
|
boolean hasError = test(element);
|
||||||
|
return new NBAdvisorPoint.Result<>(
|
||||||
|
this,
|
||||||
|
element,
|
||||||
|
hasError ? NBAdvisorPoint.Status.ERROR : NBAdvisorPoint.Status.OK
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String getName();
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.nb.api.advisor;
|
||||||
|
|
||||||
|
public class NBAdvisorException extends RuntimeException {
|
||||||
|
private final String message;
|
||||||
|
private final int exitCode;
|
||||||
|
|
||||||
|
public NBAdvisorException(String message, int exitCode) {
|
||||||
|
this.message = message;
|
||||||
|
this.exitCode = exitCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExitCode() {
|
||||||
|
return this.exitCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.nb.api.advisor;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is related to {@link io.nosqlbench.nb.api.advisor.conditions.Conditions}, and the terms
|
||||||
|
* should be aligned. When possible, the the Conditions class should be used to capture
|
||||||
|
* re-usable conditions, so that there is only one instance of each distinct type in the runtime,
|
||||||
|
* regardless of how many components use it in their advisor points.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum NBAdvisorLevel {
|
||||||
|
/**
|
||||||
|
* Do not analyze arguments, scenarios, activities, and workloads
|
||||||
|
*/
|
||||||
|
none,
|
||||||
|
/**
|
||||||
|
* Provide advice about invalid, incorrect, and unused ops
|
||||||
|
*/
|
||||||
|
validate,
|
||||||
|
/**
|
||||||
|
* Only allow correct operations
|
||||||
|
*/
|
||||||
|
enforce;
|
||||||
|
|
||||||
|
// Static field to store the last used setting
|
||||||
|
private static NBAdvisorLevel level = none;
|
||||||
|
|
||||||
|
public static NBAdvisorLevel fromString(String advisorStr) {
|
||||||
|
try {
|
||||||
|
level = NBAdvisorLevel.valueOf(advisorStr.toLowerCase(Locale.ROOT));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
System.out.println("--advisor=" + advisorStr + " is invalid. Using 'none'");
|
||||||
|
level = NBAdvisorLevel.none;
|
||||||
|
}
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NBAdvisorLevel get() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAdvisorActive() {
|
||||||
|
return level != NBAdvisorLevel.none;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isEnforcerActive() {
|
||||||
|
return level == NBAdvisorLevel.enforce;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
package io.nosqlbench.nb.api.advisor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class NBAdvisorPoint<T> extends NBAdvisorPointOrBuilder<T> {
|
||||||
|
|
||||||
|
private final static Logger logger = LogManager.getLogger("ADVISOR");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final String description;
|
||||||
|
private NBAdvisorLevel advisorLevel = NBAdvisorLevel.none;
|
||||||
|
private NBAdvisorCondition<T>[] conditions = new NBAdvisorCondition[0];
|
||||||
|
private List<Result<?>> resultLog = new ArrayList<Result<?>>();
|
||||||
|
|
||||||
|
public NBAdvisorPoint(String name) {
|
||||||
|
this(name, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NBAdvisorPoint(String name, String description) {
|
||||||
|
this.name = name;
|
||||||
|
this.description = description == null ? name : description;
|
||||||
|
this.advisorLevel = NBAdvisorLevel.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<T>[] validateAll(Collection<T> elements) {
|
||||||
|
List<Result<T>> buffer = new ArrayList<>();
|
||||||
|
for (T element : elements) {
|
||||||
|
Result<T>[] oneElementValidation = validate(element);
|
||||||
|
for (Result<T> r : oneElementValidation) {
|
||||||
|
buffer.add(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer.toArray(new Result[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized Result<T>[] validate(T element) {
|
||||||
|
Result<T>[] results = new Result[conditions.length];
|
||||||
|
for (int i = 0; i < conditions.length; i++) {
|
||||||
|
results[i] = conditions[i].apply(element);
|
||||||
|
resultLog.add(results[i]);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Result<?>> getResultLog() {
|
||||||
|
return this.resultLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NBAdvisorPoint<T> add(NBAdvisorCondition<T> condition) {
|
||||||
|
_addArrayCondition(condition);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] errorMessages(T element) {
|
||||||
|
Result<T>[] results = this.validate(element);
|
||||||
|
return Arrays.stream(results).filter(Result::isError).map(Result::rendered).toArray(String[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void _addArrayCondition(NBAdvisorCondition<T> condition) {
|
||||||
|
NBAdvisorCondition<T>[] newConditions = new NBAdvisorCondition[conditions.length + 1];
|
||||||
|
System.arraycopy(conditions, 0, newConditions, 0, conditions.length);
|
||||||
|
newConditions[newConditions.length - 1] = condition;
|
||||||
|
conditions = newConditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum Status {
|
||||||
|
OK,
|
||||||
|
ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
public static record Result<T>(
|
||||||
|
NBAdvisorCondition<T> condition,
|
||||||
|
T element,
|
||||||
|
Status status
|
||||||
|
) {
|
||||||
|
public boolean isError() {
|
||||||
|
return status == Status.ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Level conditionLevel() {
|
||||||
|
return condition.level();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String rendered() {
|
||||||
|
return switch (status) {
|
||||||
|
case OK -> "OK: " + condition.okMsg().apply(element);
|
||||||
|
case ERROR -> conditionLevel() + ": " + condition.errMsg().apply(element);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package io.nosqlbench.nb.api.advisor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class NBAdvisorPointOrBuilder<T> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package io.nosqlbench.nb.api.advisor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public class NBAdvisorResults {
|
||||||
|
private final static Logger logger = LogManager.getLogger("ADVISOR");
|
||||||
|
private final List<NBAdvisorPoint<?>> points = new ArrayList<>();
|
||||||
|
|
||||||
|
public NBAdvisorResults(List<NBAdvisorPoint<?>> points) {
|
||||||
|
this.points.addAll(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<NBAdvisorPoint.Result<?>> getAdvisorResults() {
|
||||||
|
return points.stream().flatMap(a -> a.getResultLog().stream()).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render(Level level,String message) {
|
||||||
|
if (level == Level.INFO) {
|
||||||
|
logger.info(message);
|
||||||
|
} else if (level == Level.WARN) {
|
||||||
|
logger.warn(message);
|
||||||
|
} else if (level == Level.ERROR) {
|
||||||
|
logger.error(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int evaluate() {
|
||||||
|
List<NBAdvisorPoint.Result<?>> results = getAdvisorResults();
|
||||||
|
Iterator<NBAdvisorPoint.Result<?>> iterator = results.iterator();
|
||||||
|
int count = 0;
|
||||||
|
boolean terminate = false;
|
||||||
|
Level level = Level.INFO;
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
NBAdvisorPoint.Result<?> result = iterator.next();
|
||||||
|
level = result.isError() ? result.conditionLevel() : level.INFO;
|
||||||
|
switch (NBAdvisorLevel.get()) {
|
||||||
|
case NBAdvisorLevel.none:
|
||||||
|
if ( level == Level.ERROR ) {
|
||||||
|
render(level, result.rendered());
|
||||||
|
count++;
|
||||||
|
terminate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NBAdvisorLevel.validate:
|
||||||
|
if ( level == Level.ERROR ) {
|
||||||
|
render(level, result.rendered());
|
||||||
|
count++;
|
||||||
|
terminate = true;
|
||||||
|
} else {
|
||||||
|
render(Level.INFO, result.rendered());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NBAdvisorLevel.enforce:
|
||||||
|
if ( level == Level.ERROR || level == Level.WARN ) {
|
||||||
|
render(level, result.rendered());
|
||||||
|
count++;
|
||||||
|
terminate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( terminate ) {
|
||||||
|
String message = String.format("Advisor found %d actionable %s.",
|
||||||
|
count,
|
||||||
|
(count < 2 ? "error" : "errors"));
|
||||||
|
render(Level.ERROR, message);
|
||||||
|
throw new NBAdvisorException(message, 2);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package io.nosqlbench.nb.api.advisor.conditions;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorCondition;
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <P>The mappings between logging levels for conditions and the advisory
|
||||||
|
* levels should be consistent, so they will be described here to start.</P>
|
||||||
|
*
|
||||||
|
* <P>These are the levels which conditions should use:</P>
|
||||||
|
* <OL>
|
||||||
|
* <LI>Level.ERROR (internal to conditions, cause immediate exceptions)</LI>
|
||||||
|
* <LI>Level.WARN (conditions which should inform the user about a likely issue)</LI>
|
||||||
|
* <LI>Level.INFO (conditions which may inform the user about a possible issue)</LI>
|
||||||
|
* </OL>
|
||||||
|
*
|
||||||
|
* <P>This means that the following three behaviors are possible:
|
||||||
|
* <OL>
|
||||||
|
* <LI>{@link io.nosqlbench.nb.api.advisor.NBAdvisorLevel#none} - Only ERROR level results throw exceptions, no
|
||||||
|
* results are presented.</LI>
|
||||||
|
* <LI>{@link io.nosqlbench.nb.api.advisor.NBAdvisorLevel#validate} - Only ERROR level results throw exceptions,
|
||||||
|
* all results are presented. </LI>
|
||||||
|
* <LI>{@link io.nosqlbench.nb.api.advisor.NBAdvisorLevel#enforce} - ERROR and WARN levels throw exceptions.</LI>
|
||||||
|
* </P>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Conditions {
|
||||||
|
|
||||||
|
public static NoHyphens NoHyphensError = new NoHyphens(Level.ERROR);
|
||||||
|
public static NoHyphens NoHyphensWarning = new NoHyphens(Level.WARN);
|
||||||
|
public static NoSpaces NoSpacesError = new NoSpaces(Level.ERROR);
|
||||||
|
public static NoSpaces NoSpacesWarning = new NoSpaces(Level.WARN);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package io.nosqlbench.nb.api.advisor.conditions;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorCondition;
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class NoHyphens implements NBAdvisorCondition<String> {
|
||||||
|
|
||||||
|
private final Level level;
|
||||||
|
|
||||||
|
public NoHyphens(Level level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(String string) {
|
||||||
|
return string.contains("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Function<String, String> okMsg() {
|
||||||
|
return s -> "String '" + s + "' does not contain hyphens";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Function<String, String> errMsg() {
|
||||||
|
return s -> "String '" + s + "' should not contain hyphens";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Level level() {
|
||||||
|
return this.level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "no-hyphens";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package io.nosqlbench.nb.api.advisor.conditions;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorCondition;
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class NoSpaces implements NBAdvisorCondition<String> {
|
||||||
|
|
||||||
|
private final Level level;
|
||||||
|
|
||||||
|
public NoSpaces(Level level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Function<String, String> okMsg() {
|
||||||
|
return string -> "String '" + string + "' does not contain spaces";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Function<String, String> errMsg() {
|
||||||
|
return string -> "String '" +string + "' should not contain spaces";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Level level() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "no spaces";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(String s) {
|
||||||
|
return s.contains(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package io.nosqlbench.nb.api.components.core;
|
package io.nosqlbench.nb.api.components.core;
|
||||||
|
|
||||||
|
import io.nosqlbench.nb.api.advisor.*;
|
||||||
|
import io.nosqlbench.nb.api.advisor.conditions.Conditions;
|
||||||
import io.nosqlbench.nb.api.components.decorators.NBTokenWords;
|
import io.nosqlbench.nb.api.components.decorators.NBTokenWords;
|
||||||
import io.nosqlbench.nb.api.components.events.ComponentOutOfScope;
|
import io.nosqlbench.nb.api.components.events.ComponentOutOfScope;
|
||||||
import io.nosqlbench.nb.api.components.events.DownEvent;
|
import io.nosqlbench.nb.api.components.events.DownEvent;
|
||||||
@@ -24,6 +26,7 @@ import io.nosqlbench.nb.api.components.events.UpEvent;
|
|||||||
import io.nosqlbench.nb.api.engine.metrics.MetricsCloseable;
|
import io.nosqlbench.nb.api.engine.metrics.MetricsCloseable;
|
||||||
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetric;
|
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetric;
|
||||||
import io.nosqlbench.nb.api.labels.NBLabels;
|
import io.nosqlbench.nb.api.labels.NBLabels;
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
@@ -32,15 +35,17 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class NBBaseComponent extends NBBaseComponentMetrics implements NBComponent, NBTokenWords, NBComponentTimeline {
|
public class NBBaseComponent extends NBBaseComponentMetrics implements NBComponent, NBTokenWords, NBComponentTimeline {
|
||||||
private final static Logger logger = LogManager.getLogger("RUNTIME");
|
private final static Logger logger = LogManager.getLogger("RUNTIME");
|
||||||
protected final NBComponent parent;
|
protected final NBComponent parent;
|
||||||
protected final NBLabels labels;
|
protected final NBLabels labels;
|
||||||
private final List<NBComponent> children = new ArrayList<>();
|
private final List<NBComponent> children = new ArrayList<>();
|
||||||
|
private final List<NBAdvisorPoint<?>> advisors = new ArrayList<>();
|
||||||
protected NBMetricsBuffer metricsBuffer = new NBMetricsBuffer();
|
protected NBMetricsBuffer metricsBuffer = new NBMetricsBuffer();
|
||||||
protected boolean bufferOrphanedMetrics = false;
|
protected boolean bufferOrphanedMetrics = false;
|
||||||
private ConcurrentHashMap<String,String> props = new ConcurrentHashMap<>();
|
private ConcurrentHashMap<String, String> props = new ConcurrentHashMap<>();
|
||||||
protected Exception error;
|
protected Exception error;
|
||||||
protected long started_ns, teardown_ns, closed_ns, errored_ns, started_epoch_ms;
|
protected long started_ns, teardown_ns, closed_ns, errored_ns, started_epoch_ms;
|
||||||
protected NBInvokableState state = NBInvokableState.STARTING;
|
protected NBInvokableState state = NBInvokableState.STARTING;
|
||||||
@@ -51,6 +56,19 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
|
|||||||
}
|
}
|
||||||
|
|
||||||
public NBBaseComponent(NBComponent parentComponent, NBLabels componentSpecificLabelsOnly) {
|
public NBBaseComponent(NBComponent parentComponent, NBLabels componentSpecificLabelsOnly) {
|
||||||
|
NBAdvisorPoint<String> labelsAdvisor = create().advisor(b -> b.name("Check labels"));
|
||||||
|
// ^ Explicitly name the generic type here
|
||||||
|
// ^ retain the advisor instance for customization, even though it is already attached to
|
||||||
|
// the current component
|
||||||
|
labelsAdvisor.add(Conditions.NoHyphensError);
|
||||||
|
labelsAdvisor.add(Conditions.NoSpacesWarning);
|
||||||
|
|
||||||
|
labelsAdvisor.validateAll(componentSpecificLabelsOnly.asMap().keySet());
|
||||||
|
labelsAdvisor.validateAll(componentSpecificLabelsOnly.asMap().values());
|
||||||
|
|
||||||
|
NBAdvisorResults advisorResults = getAdvisorResults();
|
||||||
|
advisorResults.evaluate();
|
||||||
|
|
||||||
this.started_ns = System.nanoTime();
|
this.started_ns = System.nanoTime();
|
||||||
this.started_epoch_ms = System.currentTimeMillis();
|
this.started_epoch_ms = System.currentTimeMillis();
|
||||||
this.labels = componentSpecificLabelsOnly;
|
this.labels = componentSpecificLabelsOnly;
|
||||||
@@ -60,11 +78,11 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
|
|||||||
} else {
|
} else {
|
||||||
parent = null;
|
parent = null;
|
||||||
}
|
}
|
||||||
state = (state==NBInvokableState.ERRORED) ? state : NBInvokableState.RUNNING;
|
state = (state == NBInvokableState.ERRORED) ? state : NBInvokableState.RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBBaseComponent(NBComponent parentComponent, NBLabels componentSpecificLabelsOnly, Map<String, String> props) {
|
public NBBaseComponent(NBComponent parentComponent, NBLabels componentSpecificLabelsOnly, Map<String, String> props) {
|
||||||
this(parentComponent,componentSpecificLabelsOnly);
|
this(parentComponent, componentSpecificLabelsOnly);
|
||||||
props.forEach(this::setComponentProp);
|
props.forEach(this::setComponentProp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,10 +100,8 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
|
|||||||
NBLabels eachLabels = extant.getComponentOnlyLabels();
|
NBLabels eachLabels = extant.getComponentOnlyLabels();
|
||||||
NBLabels newLabels = child.getComponentOnlyLabels();
|
NBLabels newLabels = child.getComponentOnlyLabels();
|
||||||
|
|
||||||
if (eachLabels!=null && newLabels!=null && !eachLabels.isEmpty() && !newLabels.isEmpty() && child.getComponentOnlyLabels().equals(extant.getComponentOnlyLabels())) {
|
if (eachLabels != null && newLabels != null && !eachLabels.isEmpty() && !newLabels.isEmpty() && child.getComponentOnlyLabels().equals(extant.getComponentOnlyLabels())) {
|
||||||
throw new RuntimeException("Adding second child under already-defined labels is not allowed:\n" +
|
throw new RuntimeException("Adding second child under already-defined labels is not allowed:\n" + " extant: (" + extant.getClass().getSimpleName() + ") " + extant.description() + "\n" + " adding: (" + child.getClass().getSimpleName() + ") " + child.description());
|
||||||
" extant: (" + extant.getClass().getSimpleName() + ") " + extant.description() + "\n" +
|
|
||||||
" adding: (" + child.getClass().getSimpleName() + ") " + child.description());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +145,7 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void close() throws RuntimeException {
|
public final void close() throws RuntimeException {
|
||||||
state = (state==NBInvokableState.ERRORED) ? state : NBInvokableState.CLOSING;
|
state = (state == NBInvokableState.ERRORED) ? state : NBInvokableState.CLOSING;
|
||||||
closed_ns = System.nanoTime();
|
closed_ns = System.nanoTime();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -156,8 +172,9 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
|
|||||||
RuntimeException wrapped = new RuntimeException("While in state " + this.state + ", an error occured: " + e, e);
|
RuntimeException wrapped = new RuntimeException("While in state " + this.state + ", an error occured: " + e, e);
|
||||||
logger.error(wrapped);
|
logger.error(wrapped);
|
||||||
this.error = wrapped;
|
this.error = wrapped;
|
||||||
state=NBInvokableState.ERRORED;
|
state = NBInvokableState.ERRORED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override this method in your component implementations when you need to do something
|
* Override this method in your component implementations when you need to do something
|
||||||
* to close out your component.
|
* to close out your component.
|
||||||
@@ -165,7 +182,7 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
|
|||||||
protected void teardown() {
|
protected void teardown() {
|
||||||
logger.debug("tearing down " + description());
|
logger.debug("tearing down " + description());
|
||||||
this.teardown_ns = System.nanoTime();
|
this.teardown_ns = System.nanoTime();
|
||||||
this.state=(state==NBInvokableState.ERRORED) ? state : NBInvokableState.STOPPED;
|
this.state = (state == NBInvokableState.ERRORED) ? state : NBInvokableState.STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -240,7 +257,8 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
|
|||||||
* This method is called by the engine to report a component going out of scope. The metrics for that component
|
* This method is called by the engine to report a component going out of scope. The metrics for that component
|
||||||
* will bubble up through the component layers and can be buffered for reporting at multiple levels.
|
* will bubble up through the component layers and can be buffered for reporting at multiple levels.
|
||||||
*
|
*
|
||||||
* @param m The metric to report
|
* @param m
|
||||||
|
* The metric to report
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void reportExecutionMetric(NBMetric m) {
|
public void reportExecutionMetric(NBMetric m) {
|
||||||
@@ -254,8 +272,8 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getNanosSinceStart() {
|
public long getNanosSinceStart() {
|
||||||
if (teardown_ns ==0) {
|
if (teardown_ns == 0) {
|
||||||
return System.nanoTime()- started_ns;
|
return System.nanoTime() - started_ns;
|
||||||
} else {
|
} else {
|
||||||
return teardown_ns - started_ns;
|
return teardown_ns - started_ns;
|
||||||
}
|
}
|
||||||
@@ -263,10 +281,10 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<String> getComponentProp(String name) {
|
public Optional<String> getComponentProp(String name) {
|
||||||
if (this.props!=null && this.props.containsKey(name)) {
|
if (this.props != null && this.props.containsKey(name)) {
|
||||||
return Optional.ofNullable(this.props.get(name));
|
return Optional.ofNullable(this.props.get(name));
|
||||||
} else if (this.getParent()!=null) {
|
} else if (this.getParent() != null) {
|
||||||
return this.getParent().getComponentProp(name);
|
return this.getParent().getComponentProp(name);
|
||||||
} else {
|
} else {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
@@ -274,7 +292,7 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBComponentProps setComponentProp(String name, String value) {
|
public NBComponentProps setComponentProp(String name, String value) {
|
||||||
if (this.props==null) {
|
if (this.props == null) {
|
||||||
this.props = new ConcurrentHashMap<>();
|
this.props = new ConcurrentHashMap<>();
|
||||||
}
|
}
|
||||||
props.put(name, value);
|
props.put(name, value);
|
||||||
@@ -315,4 +333,13 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
|
|||||||
metricsCloseables.add(metric);
|
metricsCloseables.add(metric);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAdvisor(NBAdvisorPoint advisor) {
|
||||||
|
this.advisors.add(advisor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NBAdvisorPoint<?>> getAdvisors() {
|
||||||
|
return advisors;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ public interface NBComponent extends
|
|||||||
NBComponentServices,
|
NBComponentServices,
|
||||||
NBComponentEvents,
|
NBComponentEvents,
|
||||||
NBProviderSearch,
|
NBProviderSearch,
|
||||||
NBComponentProps {
|
NBComponentProps,
|
||||||
|
NBComponentAdvisors {
|
||||||
|
|
||||||
NBComponent EMPTY_COMPONENT = new NBBaseComponent(null);
|
NBComponent EMPTY_COMPONENT = new NBBaseComponent(null);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package io.nosqlbench.nb.api.components.core;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorPoint;
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorResults;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public interface NBComponentAdvisors {
|
||||||
|
|
||||||
|
void addAdvisor(NBAdvisorPoint<?> advisor);
|
||||||
|
|
||||||
|
List<NBAdvisorPoint<?>> getAdvisors();
|
||||||
|
|
||||||
|
default NBAdvisorResults getAdvisorResults() {
|
||||||
|
return new NBAdvisorResults(getAdvisors());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
package io.nosqlbench.nb.api.components.core;
|
package io.nosqlbench.nb.api.components.core;
|
||||||
|
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorBuilder;
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorPoint;
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorPointOrBuilder;
|
||||||
import io.nosqlbench.nb.api.csvoutput.CsvOutputPluginWriter;
|
import io.nosqlbench.nb.api.csvoutput.CsvOutputPluginWriter;
|
||||||
import com.codahale.metrics.Meter;
|
import com.codahale.metrics.Meter;
|
||||||
import io.nosqlbench.nb.api.engine.metrics.*;
|
import io.nosqlbench.nb.api.engine.metrics.*;
|
||||||
@@ -42,6 +45,7 @@ import java.util.*;
|
|||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -56,7 +60,7 @@ public class NBCreators {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public NBMetricTimer timer(String metricFamilyName, MetricCategory category, String description) {
|
public NBMetricTimer timer(String metricFamilyName, MetricCategory category, String description) {
|
||||||
return timer(metricFamilyName,3, category,description);
|
return timer(metricFamilyName, 3, category, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBMetricTimer timer(String metricFamilyName, int hdrdigits, MetricCategory category, String description) {
|
public NBMetricTimer timer(String metricFamilyName, int hdrdigits, MetricCategory category, String description) {
|
||||||
@@ -72,7 +76,7 @@ public class NBCreators {
|
|||||||
|
|
||||||
public Meter meter(String metricFamilyName, MetricCategory category, String description) {
|
public Meter meter(String metricFamilyName, MetricCategory category, String description) {
|
||||||
NBLabels labels = base.getLabels().and("name", metricFamilyName);
|
NBLabels labels = base.getLabels().and("name", metricFamilyName);
|
||||||
NBMetricMeter meter = new NBMetricMeter(labels,description, category);
|
NBMetricMeter meter = new NBMetricMeter(labels, description, category);
|
||||||
base.addComponentMetric(meter, category, description);
|
base.addComponentMetric(meter, category, description);
|
||||||
return meter;
|
return meter;
|
||||||
}
|
}
|
||||||
@@ -113,7 +117,7 @@ public class NBCreators {
|
|||||||
for (WindowSummaryGauge.Stat stat : stats) {
|
for (WindowSummaryGauge.Stat stat : stats) {
|
||||||
anyGauge = new WindowSummaryGauge(
|
anyGauge = new WindowSummaryGauge(
|
||||||
window,
|
window,
|
||||||
base.getLabels().and(NBLabels.forKV("name", name+"_w"+window, "stat", stat)),
|
base.getLabels().and(NBLabels.forKV("name", name + "_w" + window, "stat", stat)),
|
||||||
stat,
|
stat,
|
||||||
description,
|
description,
|
||||||
category
|
category
|
||||||
@@ -136,7 +140,7 @@ public class NBCreators {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public NBMetricHistogram histogram(String metricFamilyName, MetricCategory category, String description) {
|
public NBMetricHistogram histogram(String metricFamilyName, MetricCategory category, String description) {
|
||||||
return histogram(metricFamilyName,4, category, description);
|
return histogram(metricFamilyName, 4, category, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBMetricHistogram histogram(String metricFamilyName, int hdrdigits, MetricCategory category, String description) {
|
public NBMetricHistogram histogram(String metricFamilyName, int hdrdigits, MetricCategory category, String description) {
|
||||||
@@ -486,4 +490,18 @@ public class NBCreators {
|
|||||||
() -> new RuntimeException("unable to load extension with name '" + name + "' and type '" + type.getSimpleName() + "'")
|
() -> new RuntimeException("unable to load extension with name '" + name + "' and type '" + type.getSimpleName() + "'")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <PTYPE> NBAdvisorPoint<PTYPE> advisor(Function<NBAdvisorBuilder<PTYPE>, NBAdvisorPointOrBuilder<PTYPE>> builderOrPointF) {
|
||||||
|
NBAdvisorBuilder<PTYPE> newBuilder = new NBAdvisorBuilder<PTYPE>();
|
||||||
|
NBAdvisorPointOrBuilder<PTYPE> builderOrPoint = builderOrPointF.apply(newBuilder);
|
||||||
|
NBAdvisorPoint<PTYPE> point = switch (builderOrPoint) {
|
||||||
|
case NBAdvisorPoint p -> p;
|
||||||
|
case NBAdvisorBuilder builder -> builder.build();
|
||||||
|
default -> throw new RuntimeException(
|
||||||
|
"unknown type for mapping builder: " + builderOrPoint.getClass().getCanonicalName()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
base.addAdvisor(point);
|
||||||
|
return point;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,13 @@ package io.nosqlbench.nb.api.components.decorators;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <P>This is a canonical way to get the words which are acceptable and valid
|
||||||
|
* for token transformations in strings, particularly in identifiers for
|
||||||
|
* external reporting or logging. No other methods should be used to determine
|
||||||
|
* which tokens are valid across NB components. All tokens which are deemed
|
||||||
|
* useful or necessary should be included here. (This derives from built-in labels)</P>
|
||||||
|
*/
|
||||||
public interface NBTokenWords {
|
public interface NBTokenWords {
|
||||||
Map<String,String> getTokens();
|
Map<String,String> getTokens();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class PromPushReporterComponent extends PeriodicTaskComponent {
|
|||||||
private String bearerToken;
|
private String bearerToken;
|
||||||
|
|
||||||
public PromPushReporterComponent(NBComponent parent, String endpoint,long intervalMs, NBLabels nbLabels, String prompushApikeyfile) {
|
public PromPushReporterComponent(NBComponent parent, String endpoint,long intervalMs, NBLabels nbLabels, String prompushApikeyfile) {
|
||||||
super(parent, nbLabels.and("_type", "prom-push"), intervalMs, "REPORT-PROMPUSH",FirstReport.OnInterval, LastReport.OnInterrupt);
|
super(parent, nbLabels.and("_type", "prom_push"), intervalMs, "REPORT-PROMPUSH",FirstReport.OnInterval, LastReport.OnInterrupt);
|
||||||
String jobname = getLabels().valueOfOptional("jobname").orElse("default");
|
String jobname = getLabels().valueOfOptional("jobname").orElse("default");
|
||||||
String instance = getLabels().valueOfOptional("instance").orElse("default");
|
String instance = getLabels().valueOfOptional("instance").orElse("default");
|
||||||
if (jobname.equals("default") || instance.equals("default")) {
|
if (jobname.equals("default") || instance.equals("default")) {
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package io.nosqlbench.nb.api.components.core;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) nosqlbench
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorPoint;
|
||||||
|
import io.nosqlbench.nb.api.advisor.conditions.Conditions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class NBAdvisorPointTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAdvisorPointBasics() {
|
||||||
|
NBAdvisorPoint<String> nap = new NBAdvisorPoint<>("labels should have no hyphens");
|
||||||
|
nap.add(Conditions.NoHyphensError);
|
||||||
|
nap.add(Conditions.NoSpacesWarning);
|
||||||
|
|
||||||
|
String[] spaceErrors = nap.errorMessages("one two three");
|
||||||
|
assertThat(spaceErrors)
|
||||||
|
.containsExactly(new String[]{"WARN: String 'one two three' should not contain spaces"});
|
||||||
|
|
||||||
|
String[] hyphenErrors = nap.errorMessages("one-two");
|
||||||
|
assertThat(hyphenErrors)
|
||||||
|
.containsExactly(new String[]{"ERROR: String 'one-two' should not contain hyphens"});
|
||||||
|
|
||||||
|
String[] bothErrors = nap.errorMessages("one-two three");
|
||||||
|
assertThat(bothErrors)
|
||||||
|
.containsExactly(new String[]{
|
||||||
|
"ERROR: String 'one-two three' should not contain hyphens",
|
||||||
|
"WARN: String 'one-two three' should not contain spaces"
|
||||||
|
});
|
||||||
|
|
||||||
|
//int count = nap.evaluate();
|
||||||
|
//assertThat(count).isEqualTo(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@@ -64,7 +65,6 @@ class NBComponentServicesTest {
|
|||||||
metricsInTree.forEach(m -> {
|
metricsInTree.forEach(m -> {
|
||||||
System.out.println("metric: " + m.toString());
|
System.out.println("metric: " + m.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import java.util.Iterator;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
class NBComponentTraversalTest {
|
public class NBComponentTraversalTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
|
|||||||
@@ -136,12 +136,12 @@ public class NBCLI implements Function<String[], Integer>, NBLabeledElement {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String error = NBCLIErrorHandler.handle(e, showStackTraces, NBCLI.version);
|
final int result = NBCLIErrorHandler.handle(e, showStackTraces, NBCLI.version);
|
||||||
// Commented for now, as the above handler should do everything needed.
|
// Commented for now, as the above handler should do everything needed.
|
||||||
if (null != error) System.err.println("Scenario stopped due to error. See logs for details.");
|
if (result != 0) System.err.println("Scenario stopped due to error. See logs for details.");
|
||||||
System.err.flush();
|
System.err.flush();
|
||||||
System.out.flush();
|
System.out.flush();
|
||||||
return NBCLI.EXIT_ERROR;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,7 +412,8 @@ public class NBCLI implements Function<String[], Integer>, NBLabeledElement {
|
|||||||
"logsdir", options.getLogsDirectory().toString(),
|
"logsdir", options.getLogsDirectory().toString(),
|
||||||
"progress", options.getProgressSpec(),
|
"progress", options.getProgressSpec(),
|
||||||
"prompush_cache", "prompush_cache.txt",
|
"prompush_cache", "prompush_cache.txt",
|
||||||
"heartbeat", String.valueOf(options.wantsHeartbeatIntervalMs())
|
"heartbeat", String.valueOf(options.wantsHeartbeatIntervalMs()),
|
||||||
|
"advisor", String.valueOf(options.getAdvisor())
|
||||||
);
|
);
|
||||||
|
|
||||||
try (
|
try (
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import io.nosqlbench.engine.cli.atfiles.NBAtFile;
|
|||||||
import io.nosqlbench.engine.cmdstream.Cmd;
|
import io.nosqlbench.engine.cmdstream.Cmd;
|
||||||
import io.nosqlbench.engine.cmdstream.PathCanonicalizer;
|
import io.nosqlbench.engine.cmdstream.PathCanonicalizer;
|
||||||
import io.nosqlbench.engine.core.lifecycle.session.CmdParser;
|
import io.nosqlbench.engine.core.lifecycle.session.CmdParser;
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorLevel;
|
||||||
import io.nosqlbench.nb.api.engine.util.Unit;
|
import io.nosqlbench.nb.api.engine.util.Unit;
|
||||||
import io.nosqlbench.nb.api.errors.BasicError;
|
import io.nosqlbench.nb.api.errors.BasicError;
|
||||||
import io.nosqlbench.nb.api.labels.NBLabelSpec;
|
import io.nosqlbench.nb.api.labels.NBLabelSpec;
|
||||||
@@ -96,6 +97,8 @@ public class NBCLIOptions {
|
|||||||
private static final String ADD_LABELS = "--add-labels";
|
private static final String ADD_LABELS = "--add-labels";
|
||||||
private static final String ADD_LABEL = "--add-label";
|
private static final String ADD_LABEL = "--add-label";
|
||||||
|
|
||||||
|
private static final String ADVISOR = "--advisor";
|
||||||
|
|
||||||
// Execution
|
// Execution
|
||||||
private static final String EXPORT_CYCLE_LOG = "--export-cycle-log";
|
private static final String EXPORT_CYCLE_LOG = "--export-cycle-log";
|
||||||
private static final String IMPORT_CYCLE_LOG = "--import-cycle-log";
|
private static final String IMPORT_CYCLE_LOG = "--import-cycle-log";
|
||||||
@@ -103,7 +106,6 @@ public class NBCLIOptions {
|
|||||||
|
|
||||||
// Execution Options
|
// Execution Options
|
||||||
|
|
||||||
|
|
||||||
private static final String SESSION_NAME = "--session-name";
|
private static final String SESSION_NAME = "--session-name";
|
||||||
private static final String LOGS_DIR = "--logs-dir";
|
private static final String LOGS_DIR = "--logs-dir";
|
||||||
private static final String WORKSPACES_DIR = "--workspaces-dir";
|
private static final String WORKSPACES_DIR = "--workspaces-dir";
|
||||||
@@ -207,6 +209,7 @@ public class NBCLIOptions {
|
|||||||
private String reportSummaryTo = NBCLIOptions.REPORT_SUMMARY_TO_DEFAULT;
|
private String reportSummaryTo = NBCLIOptions.REPORT_SUMMARY_TO_DEFAULT;
|
||||||
private boolean enableAnsi = (null != System.getenv("TERM")) && !System.getenv("TERM").isEmpty();
|
private boolean enableAnsi = (null != System.getenv("TERM")) && !System.getenv("TERM").isEmpty();
|
||||||
private Maturity minMaturity = Maturity.Unspecified;
|
private Maturity minMaturity = Maturity.Unspecified;
|
||||||
|
private NBAdvisorLevel advisor = NBAdvisorLevel.none;
|
||||||
private String graphitelogLevel = "info";
|
private String graphitelogLevel = "info";
|
||||||
private boolean wantsListCommands;
|
private boolean wantsListCommands;
|
||||||
private boolean wantsListApps;
|
private boolean wantsListApps;
|
||||||
@@ -504,6 +507,12 @@ public class NBCLIOptions {
|
|||||||
String addLabeldata = arglist.removeFirst();
|
String addLabeldata = arglist.removeFirst();
|
||||||
addLabels(addLabeldata);
|
addLabels(addLabeldata);
|
||||||
break;
|
break;
|
||||||
|
case ADVISOR:
|
||||||
|
arglist.removeFirst();
|
||||||
|
final String advisorStr = this.readWordOrThrow(arglist, "advisor level for checking");
|
||||||
|
advisor = NBAdvisorLevel.fromString(advisorStr); // includes error checking. invalid values
|
||||||
|
// provide a warning.
|
||||||
|
break;
|
||||||
case NBCLIOptions.ENABLE_LOGGED_METRICS:
|
case NBCLIOptions.ENABLE_LOGGED_METRICS:
|
||||||
arglist.removeFirst();
|
arglist.removeFirst();
|
||||||
this.wantsConsoleMetrics = true;
|
this.wantsConsoleMetrics = true;
|
||||||
@@ -733,7 +742,7 @@ public class NBCLIOptions {
|
|||||||
.replaceAll("ARG", cmdParam)
|
.replaceAll("ARG", cmdParam)
|
||||||
.replaceAll("PROG", "nb5")
|
.replaceAll("PROG", "nb5")
|
||||||
.replaceAll("INCLUDES", String.join(",", wantsIncludes()))
|
.replaceAll("INCLUDES", String.join(",", wantsIncludes()))
|
||||||
+ (arglist.size()>0 && arglist.peekFirst().startsWith("nb") ?
|
+ (arglist.size() > 0 && arglist.peekFirst().startsWith("nb") ?
|
||||||
"""
|
"""
|
||||||
(HINT:) It looks like you are starting your command with ARGV0
|
(HINT:) It looks like you are starting your command with ARGV0
|
||||||
" which looks like the nb5 command itself. Maybe remove this?
|
" which looks like the nb5 command itself. Maybe remove this?
|
||||||
@@ -800,6 +809,10 @@ public class NBCLIOptions {
|
|||||||
return this.minMaturity;
|
return this.minMaturity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NBAdvisorLevel getAdvisor() {
|
||||||
|
return this.advisor;
|
||||||
|
}
|
||||||
|
|
||||||
public List<Cmd> getCommands() {
|
public List<Cmd> getCommands() {
|
||||||
return this.cmdList;
|
return this.cmdList;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ package io.nosqlbench.engine.api.activityimpl;
|
|||||||
|
|
||||||
public enum Dryrun {
|
public enum Dryrun {
|
||||||
/**
|
/**
|
||||||
* Ops are executed normally, no change to the dispenser behavior
|
* Ops are executed normally, no change to the dispenser behavior.
|
||||||
*/
|
*/
|
||||||
none,
|
none,
|
||||||
/**
|
/**
|
||||||
@@ -32,5 +32,12 @@ public enum Dryrun {
|
|||||||
* Ops will print the toString version of their result to stdout.
|
* Ops will print the toString version of their result to stdout.
|
||||||
* This is done by wrapping the synthesized op in a post-emit facade.
|
* This is done by wrapping the synthesized op in a post-emit facade.
|
||||||
*/
|
*/
|
||||||
emit
|
emit,
|
||||||
|
/**
|
||||||
|
* Jsonnet evaluation is a one time dry-run and then exit.
|
||||||
|
* With this value the run should exit after the first evaluation of jsonnet
|
||||||
|
* and Ops are not executed, but should processing fall through then processing
|
||||||
|
* will proceed as for none.
|
||||||
|
*/
|
||||||
|
jsonnet
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ public class OpWrappers {
|
|||||||
case none -> dispenser;
|
case none -> dispenser;
|
||||||
case op -> new DryCycleOpDispenserWrapper(adapter, pop, dispenser);
|
case op -> new DryCycleOpDispenserWrapper(adapter, pop, dispenser);
|
||||||
case emit -> new EmitterCycleOpDispenserWrapper(adapter, pop, dispenser);
|
case emit -> new EmitterCycleOpDispenserWrapper(adapter, pop, dispenser);
|
||||||
|
case jsonnet -> dispenser;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class ClientSystemMetricChecker extends NBBaseComponent {
|
|||||||
private List<ClientMetric> clientMetrics;
|
private List<ClientMetric> clientMetrics;
|
||||||
|
|
||||||
public ClientSystemMetricChecker(NBComponent parent, NBLabels additionalLabels, int pollIntervalSeconds) {
|
public ClientSystemMetricChecker(NBComponent parent, NBLabels additionalLabels, int pollIntervalSeconds) {
|
||||||
super(parent,additionalLabels.and("_type","client-metrics"));
|
super(parent,additionalLabels.and("_type","client_metrics"));
|
||||||
this.pollIntervalSeconds = pollIntervalSeconds;
|
this.pollIntervalSeconds = pollIntervalSeconds;
|
||||||
this.scheduler = Executors.newScheduledThreadPool(1);
|
this.scheduler = Executors.newScheduledThreadPool(1);
|
||||||
this.clientMetrics = new ArrayList<>();
|
this.clientMetrics = new ArrayList<>();
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package io.nosqlbench.engine.core.lifecycle.process;
|
package io.nosqlbench.engine.core.lifecycle.process;
|
||||||
|
|
||||||
import io.nosqlbench.nb.api.errors.BasicError;
|
import io.nosqlbench.nb.api.errors.BasicError;
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorException;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.graalvm.polyglot.PolyglotException;
|
import org.graalvm.polyglot.PolyglotException;
|
||||||
@@ -43,7 +44,7 @@ public class NBCLIErrorHandler {
|
|||||||
|
|
||||||
private final static Logger logger = LogManager.getLogger("ERRORHANDLER");
|
private final static Logger logger = LogManager.getLogger("ERRORHANDLER");
|
||||||
|
|
||||||
public static String handle(Throwable t, boolean wantsStackTraces, String version) {
|
public static int handle(Throwable t, boolean wantsStackTraces, String version) {
|
||||||
|
|
||||||
if (wantsStackTraces) {
|
if (wantsStackTraces) {
|
||||||
StackTraceElement[] st = Thread.currentThread().getStackTrace();
|
StackTraceElement[] st = Thread.currentThread().getStackTrace();
|
||||||
@@ -63,6 +64,9 @@ public class NBCLIErrorHandler {
|
|||||||
} else if (t instanceof BasicError) {
|
} else if (t instanceof BasicError) {
|
||||||
logger.trace("Handling basic error: " + t);
|
logger.trace("Handling basic error: " + t);
|
||||||
return handleBasicError((BasicError) t, wantsStackTraces, version);
|
return handleBasicError((BasicError) t, wantsStackTraces, version);
|
||||||
|
} else if (t instanceof NBAdvisorException) {
|
||||||
|
logger.trace("Handle processing early exit: " + t);
|
||||||
|
return handleNBAdvisorException((NBAdvisorException) t, wantsStackTraces, version);
|
||||||
} else if (t instanceof Exception) {
|
} else if (t instanceof Exception) {
|
||||||
logger.trace("Handling general exception: " + t);
|
logger.trace("Handling general exception: " + t);
|
||||||
return handleInternalError((Exception) t, wantsStackTraces, version);
|
return handleInternalError((Exception) t, wantsStackTraces, version);
|
||||||
@@ -72,7 +76,7 @@ public class NBCLIErrorHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String handleInternalError(Exception e, boolean wantsStackTraces, String version) {
|
private static int handleInternalError(Exception e, boolean wantsStackTraces, String version) {
|
||||||
String prefix = "internal error(" + version + "):";
|
String prefix = "internal error(" + version + "):";
|
||||||
if (e.getCause() != null && !e.getCause().getClass().getCanonicalName().contains("io.nosqlbench")) {
|
if (e.getCause() != null && !e.getCause().getClass().getCanonicalName().contains("io.nosqlbench")) {
|
||||||
prefix = "Error from driver or included library(" + version + "):";
|
prefix = "Error from driver or included library(" + version + "):";
|
||||||
@@ -87,10 +91,10 @@ public class NBCLIErrorHandler {
|
|||||||
logger.error(e.getMessage());
|
logger.error(e.getMessage());
|
||||||
logger.error("for the full stack trace, run with --show-stacktraces");
|
logger.error("for the full stack trace, run with --show-stacktraces");
|
||||||
}
|
}
|
||||||
return e.getMessage();
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String handleScriptException(ScriptException e, boolean wantsStackTraces, String version) {
|
private static int handleScriptException(ScriptException e, boolean wantsStackTraces, String version) {
|
||||||
Throwable cause = e.getCause();
|
Throwable cause = e.getCause();
|
||||||
if (cause instanceof PolyglotException) {
|
if (cause instanceof PolyglotException) {
|
||||||
Throwable hostException = ((PolyglotException) cause).asHostException();
|
Throwable hostException = ((PolyglotException) cause).asHostException();
|
||||||
@@ -107,17 +111,22 @@ public class NBCLIErrorHandler {
|
|||||||
logger.error("for the full stack trace, run with --show-stacktraces");
|
logger.error("for the full stack trace, run with --show-stacktraces");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return e.getMessage();
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String handleBasicError(BasicError e, boolean wantsStackTraces, String version) {
|
private static int handleBasicError(BasicError e, boolean wantsStackTraces, String version) {
|
||||||
if (wantsStackTraces) {
|
if (wantsStackTraces) {
|
||||||
logger.error(e.getMessage(), e);
|
logger.error(e.getMessage(), e);
|
||||||
} else {
|
} else {
|
||||||
logger.error(e.getMessage());
|
logger.error(e.getMessage());
|
||||||
logger.error("for the full stack trace, run with --show-stacktraces");
|
logger.error("for the full stack trace, run with --show-stacktraces");
|
||||||
}
|
}
|
||||||
return e.getMessage();
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int handleNBAdvisorException(NBAdvisorException e, boolean wantsStackTraces, String version) {
|
||||||
|
logger.info(e.toString());
|
||||||
|
return e.getExitCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package io.nosqlbench.engine.core;
|
|||||||
|
|
||||||
import io.nosqlbench.nb.api.config.standard.TestComponent;
|
import io.nosqlbench.nb.api.config.standard.TestComponent;
|
||||||
import io.nosqlbench.nb.api.engine.activityimpl.ActivityDef;
|
import io.nosqlbench.nb.api.engine.activityimpl.ActivityDef;
|
||||||
|
import io.nosqlbench.nb.api.advisor.NBAdvisorException;
|
||||||
import io.nosqlbench.engine.api.activityapi.core.*;
|
import io.nosqlbench.engine.api.activityapi.core.*;
|
||||||
import io.nosqlbench.engine.api.activityapi.input.Input;
|
import io.nosqlbench.engine.api.activityapi.input.Input;
|
||||||
import io.nosqlbench.engine.api.activityapi.input.InputDispenser;
|
import io.nosqlbench.engine.api.activityapi.input.InputDispenser;
|
||||||
@@ -81,10 +82,24 @@ class ActivityExecutorTest {
|
|||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
synchronized void testAdvisorError() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
ActivityDef activityDef = ActivityDef.parseActivityDef("driver=diag;alias=test-delayed-start;cycles=1000;initdelay=2000;");
|
||||||
|
new ActivityTypeLoader().load(activityDef, TestComponent.INSTANCE);
|
||||||
|
Activity activity = new DelayedInitActivity(activityDef);
|
||||||
|
fail("Expected an Advisor exception");
|
||||||
|
} catch (NBAdvisorException e) {
|
||||||
|
assertThat(e.toString().contains("error"));
|
||||||
|
assertThat(e.getExitCode() == 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
synchronized void testDelayedStartSanity() {
|
synchronized void testDelayedStartSanity() {
|
||||||
|
|
||||||
ActivityDef activityDef = ActivityDef.parseActivityDef("driver=diag;alias=test-delayed-start;cycles=1000;initdelay=2000;");
|
ActivityDef activityDef = ActivityDef.parseActivityDef("driver=diag;alias=test_delayed_start;cycles=1000;initdelay=2000;");
|
||||||
new ActivityTypeLoader().load(activityDef, TestComponent.INSTANCE);
|
new ActivityTypeLoader().load(activityDef, TestComponent.INSTANCE);
|
||||||
|
|
||||||
Activity activity = new DelayedInitActivity(activityDef);
|
Activity activity = new DelayedInitActivity(activityDef);
|
||||||
@@ -118,7 +133,7 @@ class ActivityExecutorTest {
|
|||||||
@Test
|
@Test
|
||||||
synchronized void testNewActivityExecutor() {
|
synchronized void testNewActivityExecutor() {
|
||||||
|
|
||||||
final ActivityDef activityDef = ActivityDef.parseActivityDef("driver=diag;alias=test-dynamic-params;cycles=1000;initdelay=5000;");
|
final ActivityDef activityDef = ActivityDef.parseActivityDef("driver=diag;alias=test_dynamic_params;cycles=1000;initdelay=5000;");
|
||||||
new ActivityTypeLoader().load(activityDef,TestComponent.INSTANCE);
|
new ActivityTypeLoader().load(activityDef,TestComponent.INSTANCE);
|
||||||
|
|
||||||
Activity simpleActivity = new SimpleActivity(TestComponent.INSTANCE,activityDef);
|
Activity simpleActivity = new SimpleActivity(TestComponent.INSTANCE,activityDef);
|
||||||
|
|||||||
Reference in New Issue
Block a user