mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
merge http_finish fixes into main
This commit is contained in:
commit
dc3002a809
@ -2,6 +2,7 @@
|
||||
|
||||
This is a work in progress...
|
||||
|
||||
|
||||
This is the document to read if you want to know if your NoSQLBench driver is complete.
|
||||
Within this document, the phrase `conformant` will be taken to mean that a driver or feature
|
||||
is implemented according to the design intent and standards of the NoSQLBench driver API.
|
||||
@ -13,6 +14,22 @@ reliable way for users from one driver to another.
|
||||
Over time, the standards in this guide will be programmatically enforced by the NoSQLBench
|
||||
driver API.
|
||||
|
||||
## Op Templates
|
||||
|
||||
The core building block of a NoSQLBench driver is the op template. This is the form of a
|
||||
statement or operation that users add to a yaml or workload editor to represent a single operation.
|
||||
|
||||
For example, in the CQL driver, this is called a "statement template", but going forward, they will
|
||||
all be called Op Templates and internal API names will reflect that.
|
||||
|
||||
It is the driver's responsibility to create a quick-draw version of an operation.
|
||||
|
||||
## Op Sequencing
|
||||
|
||||
A conformant driver should use the standard method of creating an operational sequence. This means
|
||||
that a driver simply has to provide a function to map an OpTemplate to a more ready to use form that
|
||||
is specific to the low level driver in question.
|
||||
|
||||
## Terms
|
||||
|
||||
- NB Driver - The NoSQLBench level driver, the code that this document
|
||||
@ -120,8 +137,17 @@ The next exception handler `ignore` should also be called, but this is
|
||||
simply a named 'no-op' which is generally the last fall-through case in a
|
||||
switch statement.
|
||||
|
||||
TBD
|
||||
|
||||
## Result Validation
|
||||
|
||||
## Diagnostic Mode
|
||||
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
TBD
|
||||
|
||||
### Parameter naming
|
||||
|
||||
Parameters should be formatted as snake_case by default. Hyphens or camel
|
||||
@ -147,8 +173,13 @@ with the help command `nb help <name>`. For example, if a driver module
|
||||
contains `../src/main/resources/mydriver-specials.md`, then a user would
|
||||
be able to find this help by running `nb help mydriver-specials`.
|
||||
|
||||
These sources of documentation can be wired into the main NoSQLBench documentation system with a set
|
||||
of content descriptors.
|
||||
|
||||
## Named Scenarios
|
||||
|
||||
Conformant driver implementations should come with one or more examples of a workload under the
|
||||
activities directory path.
|
||||
Useful driver implementations should come with one or more examples of a
|
||||
workloads under the activities directory path. These examples should
|
||||
employ the "named scenarios" format as described in the main docs. By
|
||||
@ -177,6 +208,9 @@ option in addition to the `--list-scenarios` command.
|
||||
|
||||
## Testing and Docs
|
||||
|
||||
Complete driver implementations should also come with a set of examples under the examples
|
||||
directory path.
|
||||
|
||||
Unit testing within the NB code base is necessary in many places, but not
|
||||
in others. Use your judgement about when to *not* add unit testing, but
|
||||
default to adding it when it seems subjective. A treatise on when and how
|
||||
|
8
devdocs/sketches/opdata.puml
Normal file
8
devdocs/sketches/opdata.puml
Normal file
@ -0,0 +1,8 @@
|
||||
@startuml
|
||||
actor a as activity
|
||||
actor nd as "NB Driver"
|
||||
actor pd as "Native Driver"
|
||||
actor r as "ReadyOp"
|
||||
actor op as "op"
|
||||
|
||||
@enduml
|
44
devdocs/sketches/transforms.dot
Normal file
44
devdocs/sketches/transforms.dot
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
digraph {
|
||||
// rankdir=LR;
|
||||
node [shape = none]
|
||||
|
||||
|
||||
cycles[label="read input"]
|
||||
c_err[shape="none",label="[ERR,null]"]
|
||||
c_ok[shape="none",label="[OK,cycle] (OpCycle)"]
|
||||
|
||||
cycles -> c_err
|
||||
cycles -> c_ok
|
||||
|
||||
|
||||
bind_template[label="bind template"]
|
||||
template_ok[label="[OK,template] (OpTemplate)"]
|
||||
template_err[label="[ERR,template]"]
|
||||
c_ok -> bind_template
|
||||
bind_template -> template_err
|
||||
bind_template -> template_ok
|
||||
|
||||
exec_cmd[label="execute command"]
|
||||
command_err[label="[ERR,template]"]
|
||||
command_ok[label="[OK,result] (OpResult)"]
|
||||
template_ok -> exec_cmd
|
||||
exec_cmd -> command_err
|
||||
exec_cmd -> command_ok
|
||||
|
||||
verify_result[label="verify result"]
|
||||
command_ok -> verify_result
|
||||
result_invalid[label="[ERR,result]"]
|
||||
result_ok[label="[OK,result]"]
|
||||
verify_result -> result_invalid
|
||||
verify_result -> result_ok
|
||||
|
||||
|
||||
|
||||
|
||||
// <tr><td>Error<sub>none</sub></td></tr>
|
||||
// ⁅⁆⟦⟧ ⟬⟭ ⟮⟯ ⟨⟩ ⁅⁆
|
||||
// <td rowspan="*"><FONT POINT-SIZE="32">{</FONT></td>
|
||||
// <td rowspan="*"><FONT POINT-SIZE="32">}</FONT></td>
|
||||
|
||||
}
|
@ -55,7 +55,7 @@ public class NBWebServer implements Runnable {
|
||||
private String bindHost = "localhost";
|
||||
private int bindPort = 12345;
|
||||
|
||||
private Map<String,Object> contextParams = new LinkedHashMap<>();
|
||||
private final Map<String,Object> contextParams = new LinkedHashMap<>();
|
||||
|
||||
public NBWebServer withContextParams(Map<String,Object> cp) {
|
||||
this.contextParams.putAll(cp);
|
||||
|
@ -79,7 +79,7 @@ public class CqlAsyncAction extends BaseAsyncAction<CqlOpData, CqlActivity> {
|
||||
|
||||
@Override
|
||||
public void startOpCycle(TrackedOp<CqlOpData> opc) {
|
||||
CqlOpData cqlop = opc.getData();
|
||||
CqlOpData cqlop = opc.getOpData();
|
||||
long cycle = opc.getCycle();
|
||||
|
||||
// bind timer covers all statement selection and binding, skipping, transforming logic
|
||||
@ -123,7 +123,7 @@ public class CqlAsyncAction extends BaseAsyncAction<CqlOpData, CqlActivity> {
|
||||
|
||||
|
||||
public void onSuccess(StartedOp<CqlOpData> sop) {
|
||||
CqlOpData cqlop = sop.getData();
|
||||
CqlOpData cqlop = sop.getOpData();
|
||||
|
||||
HashedCQLErrorHandler.resetThreadStatusCode();
|
||||
if (cqlop.skipped) {
|
||||
@ -217,7 +217,7 @@ public class CqlAsyncAction extends BaseAsyncAction<CqlOpData, CqlActivity> {
|
||||
|
||||
public void onFailure(StartedOp<CqlOpData> startedOp) {
|
||||
|
||||
CqlOpData cqlop = startedOp.getData();
|
||||
CqlOpData cqlop = startedOp.getOpData();
|
||||
long serviceTime = startedOp.getCurrentServiceTimeNanos();
|
||||
|
||||
// Even if this is retryable, we expose error events
|
||||
|
@ -20,7 +20,7 @@ public class Save implements RowCycleOperator {
|
||||
|
||||
ThreadLocal<HashMap<String, Object>> tl_objectMap = SharedState.tl_ObjectMap;
|
||||
|
||||
private String[] varnames;
|
||||
private final String[] varnames;
|
||||
|
||||
public Save(String... varnames) {
|
||||
this.varnames = varnames;
|
||||
|
@ -43,8 +43,8 @@ public class NBCycleErrorHandler implements CycleErrorHandler<Throwable, ErrorSt
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(NBCycleErrorHandler.class);
|
||||
|
||||
private ErrorResponse errorResponse;
|
||||
private ExceptionCountMetrics exceptionCountMetrics;
|
||||
private final ErrorResponse errorResponse;
|
||||
private final ExceptionCountMetrics exceptionCountMetrics;
|
||||
private final ExceptionHistoMetrics exceptionHistoMetrics;
|
||||
private boolean throwExceptionOnStop=false;
|
||||
|
||||
|
@ -151,8 +151,8 @@ public class AsyncDiagAction extends BaseAsyncAction<DiagOpData, DiagActivity> i
|
||||
|
||||
@Override
|
||||
public void startOpCycle(TrackedOp<DiagOpData> opc) {
|
||||
opc.getData().log("starting at " + System.nanoTime());
|
||||
opc.getData().setSimulatedDelayNanos(delayFunc.applyAsLong(opc.getCycle()));
|
||||
opc.getOpData().log("starting at " + System.nanoTime());
|
||||
opc.getOpData().setSimulatedDelayNanos(delayFunc.applyAsLong(opc.getCycle()));
|
||||
StartedOp<DiagOpData> started = opc.start();
|
||||
opQueue.add(started);
|
||||
}
|
||||
@ -239,7 +239,7 @@ public class AsyncDiagAction extends BaseAsyncAction<DiagOpData, DiagActivity> i
|
||||
try {
|
||||
opc=queue.take();
|
||||
|
||||
DiagOpData op = opc.getData();
|
||||
DiagOpData op = opc.getOpData();
|
||||
long now = System.nanoTime();
|
||||
long simulatedCompletionTime = opc.getStartedAtNanos() + op.getSimulatedDelayNanos();
|
||||
|
||||
@ -269,7 +269,7 @@ public class AsyncDiagAction extends BaseAsyncAction<DiagOpData, DiagActivity> i
|
||||
logger.info("processing stride output for " + completedOps.get(0).getCycle());
|
||||
long start = completedOps.get(0).getCycle();
|
||||
long endPlus = completedOps.get(completedOps.size()-1).getCycle()+1;
|
||||
String diagLog = completedOps.get(0).getData().getDiagLog().stream().collect(Collectors.joining("\n"));
|
||||
String diagLog = completedOps.get(0).getOpData().getDiagLog().stream().collect(Collectors.joining("\n"));
|
||||
activity.getSequenceBlocker().awaitAndRun(start, endPlus, () -> logger.info(" => " + start + " -> " + endPlus + ": " + diagLog));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
package io.nosqlbench.activitytype.cmds;
|
||||
|
||||
import io.nosqlbench.activitytype.http.async.HttpAsyncAction;
|
||||
|
||||
import java.net.http.HttpClient;
|
||||
|
||||
public class HttpAsyncOp {
|
||||
public final HttpAsyncAction action;
|
||||
public final ReadyHttpOp op;
|
||||
public final long cycle;
|
||||
|
||||
private final HttpOp httpOp;
|
||||
private final HttpClient client;
|
||||
|
||||
public HttpAsyncOp(HttpAsyncAction action, ReadyHttpOp op, long cycle, HttpClient client) {
|
||||
this.action = action;
|
||||
this.op = op;
|
||||
this.cycle = cycle;
|
||||
this.client = client;
|
||||
this.httpOp = op.apply(cycle);
|
||||
|
||||
}
|
||||
|
||||
public HttpOp getOp() {
|
||||
return httpOp;
|
||||
}
|
||||
|
||||
public HttpClient getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public HttpAsyncAction getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package io.nosqlbench.activitytype.cmds;
|
||||
|
||||
import java.net.http.HttpRequest;
|
||||
|
||||
public class HttpOp {
|
||||
public final String ok_status;
|
||||
public final String ok_body;
|
||||
public final HttpRequest request;
|
||||
|
||||
public HttpOp(HttpRequest request, String ok_status, String ok_body) {
|
||||
this.request = request;
|
||||
this.ok_status = ok_status;
|
||||
this.ok_body = ok_body;
|
||||
}
|
||||
}
|
@ -7,19 +7,21 @@ import io.nosqlbench.nb.api.errors.BasicError;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class ReadyHttpRequest implements LongFunction<HttpRequest> {
|
||||
public class ReadyHttpOp implements LongFunction<HttpOp> {
|
||||
|
||||
private final CommandTemplate propertyTemplate;
|
||||
|
||||
// only populated if there is no value which is an actual bindings template
|
||||
private final HttpRequest cachedRequest;
|
||||
private final HttpOp cachedOp;
|
||||
|
||||
public ReadyHttpRequest(OpTemplate stmtDef) {
|
||||
public ReadyHttpOp(OpTemplate stmtDef) {
|
||||
propertyTemplate = new CommandTemplate(stmtDef,
|
||||
List.of(
|
||||
HttpFormatParser::parseUrl,
|
||||
@ -28,18 +30,18 @@ public class ReadyHttpRequest implements LongFunction<HttpRequest> {
|
||||
);
|
||||
|
||||
if (propertyTemplate.isStatic()) {
|
||||
cachedRequest = apply(0);
|
||||
cachedOp = apply(0);
|
||||
} else {
|
||||
cachedRequest = null;
|
||||
cachedOp = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest apply(long value) {
|
||||
public HttpOp apply(long value) {
|
||||
|
||||
// If the request is invariant, simply return it, since it is thread-safe
|
||||
if (this.cachedRequest != null) {
|
||||
return this.cachedRequest;
|
||||
if (this.cachedOp != null) {
|
||||
return this.cachedOp;
|
||||
}
|
||||
|
||||
Map<String, String> cmd = propertyTemplate.getCommand(value);
|
||||
@ -76,12 +78,20 @@ public class ReadyHttpRequest implements LongFunction<HttpRequest> {
|
||||
}
|
||||
}
|
||||
|
||||
String ok_status = cmd.remove("ok-status");
|
||||
String ok_body = cmd.remove("ok-body");
|
||||
|
||||
String timeoutStr = cmd.remove("timeout");
|
||||
if (timeoutStr!=null) {
|
||||
builder.timeout(Duration.of(Long.parseLong(timeoutStr), ChronoUnit.MILLIS));
|
||||
}
|
||||
|
||||
if (cmd.size()>0) {
|
||||
throw new BasicError("Some provided request fields were not used: " + cmd.toString());
|
||||
}
|
||||
|
||||
HttpRequest request = builder.build();
|
||||
return request;
|
||||
return new HttpOp(request, ok_status, ok_body);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package io.nosqlbench.activitytype.http;
|
||||
|
||||
public enum ClientScope {
|
||||
thread,
|
||||
activity
|
||||
}
|
@ -1,18 +1,17 @@
|
||||
package io.nosqlbench.activitytype.http;
|
||||
|
||||
import com.codahale.metrics.Timer;
|
||||
import io.nosqlbench.activitytype.cmds.ReadyHttpRequest;
|
||||
import io.nosqlbench.activitytype.cmds.HttpOp;
|
||||
import io.nosqlbench.activitytype.cmds.ReadyHttpOp;
|
||||
import io.nosqlbench.engine.api.activityapi.core.SyncAction;
|
||||
import io.nosqlbench.engine.api.activityapi.planning.OpSequence;
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
import io.nosqlbench.engine.api.templating.CommandTemplate;
|
||||
import io.nosqlbench.nb.api.errors.BasicError;
|
||||
import io.nosqlbench.virtdata.core.templates.StringBindings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
@ -20,8 +19,6 @@ import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class HttpAction implements SyncAction {
|
||||
@ -30,13 +27,14 @@ public class HttpAction implements SyncAction {
|
||||
|
||||
private final HttpActivity httpActivity;
|
||||
private final int slot;
|
||||
private int maxTries = 1;
|
||||
private final int maxTries = 1;
|
||||
private boolean showstmts;
|
||||
|
||||
private OpSequence<ReadyHttpRequest> sequencer;
|
||||
private OpSequence<ReadyHttpOp> sequencer;
|
||||
private HttpClient client;
|
||||
private HttpResponse.BodyHandler<String> bodyreader = HttpResponse.BodyHandlers.ofString();
|
||||
private long timeoutMillis=30000L;
|
||||
|
||||
private final HttpResponse.BodyHandler<String> bodyreader = HttpResponse.BodyHandlers.ofString();
|
||||
private final long timeoutMillis=30000L;
|
||||
|
||||
|
||||
public HttpAction(ActivityDef activityDef, int slot, HttpActivity httpActivity) {
|
||||
@ -46,9 +44,12 @@ public class HttpAction implements SyncAction {
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
this.sequencer = httpActivity.getOpSequence();
|
||||
this.client = HttpClient.newHttpClient();
|
||||
this.sequencer = httpActivity.getSequencer();
|
||||
this.client = initClient(httpActivity.getClientScope());
|
||||
}
|
||||
|
||||
private HttpClient initClient(ClientScope clientScope) {
|
||||
return httpActivity.getClient().apply(Thread.currentThread());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -62,7 +63,7 @@ public class HttpAction implements SyncAction {
|
||||
// op construction
|
||||
|
||||
// The request to be used must be constructed from the template each time.
|
||||
HttpRequest request=null;
|
||||
HttpOp httpOp=null;
|
||||
|
||||
// A specifier for what makes a response ok. If this is provided, then it is
|
||||
// either a list of valid http status codes, or if non-numeric, a regex for the body
|
||||
@ -71,10 +72,19 @@ public class HttpAction implements SyncAction {
|
||||
String ok;
|
||||
|
||||
try (Timer.Context bindTime = httpActivity.bindTimer.time()) {
|
||||
ReadyHttpRequest readyHttpRequest = httpActivity.getOpSequence().get(cycleValue);
|
||||
request =readyHttpRequest.apply(cycleValue);
|
||||
ReadyHttpOp readHTTPOperation = httpActivity.getSequencer().get(cycleValue);
|
||||
httpOp =readHTTPOperation.apply(cycleValue);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("while binding request in cycle " + cycleValue + ": ",e);
|
||||
throw new RuntimeException("while binding request in cycle " + cycleValue + ": " + e.getMessage(),e);
|
||||
} finally {
|
||||
if (httpActivity.isDiagnosticMode()) {
|
||||
System.out.println("==== cycle " + cycleValue + " DIAGNOSTICS ====");
|
||||
if (httpOp!=null) {
|
||||
httpActivity.console.summarizeRequest(httpOp.request,System.out,cycleValue);
|
||||
} else {
|
||||
System.out.println("---- REQUEST was null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int tries = 0;
|
||||
@ -83,18 +93,49 @@ public class HttpAction implements SyncAction {
|
||||
|
||||
CompletableFuture<HttpResponse<String>> responseFuture;
|
||||
try (Timer.Context executeTime = httpActivity.executeTimer.time()) {
|
||||
responseFuture = client.sendAsync(request, this.bodyreader);
|
||||
responseFuture = client.sendAsync(httpOp.request, this.bodyreader);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("while waiting for response in cycle " + cycleValue + ":" + e.getMessage(), e);
|
||||
}
|
||||
|
||||
HttpResponse<String> response;
|
||||
try (Timer.Context resultTime = httpActivity.resultTimer.time()) {
|
||||
response = responseFuture.get(httpActivity.getTimeoutMs(), TimeUnit.MILLISECONDS);
|
||||
HttpResponse<String> response=null;
|
||||
long startat = System.nanoTime();
|
||||
Exception error = null;
|
||||
try {
|
||||
response = responseFuture.get(httpActivity.getTimeoutMillis(), TimeUnit.MILLISECONDS);
|
||||
if (httpOp.ok_status!=null) {
|
||||
if (!String.valueOf(response.statusCode()).matches(httpOp.ok_status)) {
|
||||
throw new InvalidStatusCodeException(cycleValue,httpOp.ok_status,response.statusCode());
|
||||
}
|
||||
}
|
||||
if (httpOp.ok_body!=null) {
|
||||
if (!response.body().matches(httpOp.ok_body)) {
|
||||
throw new InvalidResponseBodyException(cycleValue, httpOp.ok_body, response.body());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("while waiting for response in cycle " + cycleValue + ":", e);
|
||||
error = new RuntimeException("while waiting for response in cycle " + cycleValue + ":" + e.getMessage(), e);
|
||||
} finally {
|
||||
long nanos = System.nanoTime() - startat;
|
||||
httpActivity.resultTimer.update(nanos, TimeUnit.NANOSECONDS);
|
||||
if (error==null) {
|
||||
httpActivity.resultSuccessTimer.update(nanos, TimeUnit.NANOSECONDS);
|
||||
}
|
||||
if (httpActivity.isDiagnosticMode()) {
|
||||
if (response!=null) {
|
||||
httpActivity.console.summarizeResponse(response,System.out,cycleValue,nanos);
|
||||
} else {
|
||||
System.out.println("---- RESPONSE was null");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
if (error!=null) {
|
||||
// count and log exception types
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if (ok == null) {
|
||||
// if (response.statusCode() != 200) {
|
||||
// throw new ResponseError("Result had status code " +
|
||||
@ -205,4 +246,4 @@ public class HttpAction implements SyncAction {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -3,32 +3,31 @@ package io.nosqlbench.activitytype.http;
|
||||
import com.codahale.metrics.Histogram;
|
||||
import com.codahale.metrics.Meter;
|
||||
import com.codahale.metrics.Timer;
|
||||
import io.nosqlbench.activitytype.cmds.ReadyHttpRequest;
|
||||
import io.nosqlbench.activitytype.cmds.ReadyHttpOp;
|
||||
import io.nosqlbench.engine.api.activityapi.core.Activity;
|
||||
import io.nosqlbench.engine.api.activityapi.core.ActivityDefObserver;
|
||||
import io.nosqlbench.engine.api.activityapi.planning.OpSequence;
|
||||
import io.nosqlbench.engine.api.activityconfig.yaml.StmtsDocList;
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
import io.nosqlbench.engine.api.activityimpl.SimpleActivity;
|
||||
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.http.HttpClient;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class HttpActivity extends SimpleActivity implements Activity, ActivityDefObserver {
|
||||
private final static Logger logger = LoggerFactory.getLogger(HttpActivity.class);
|
||||
private final ActivityDef activityDef;
|
||||
public HttpConsoleFormats console;
|
||||
|
||||
public StmtsDocList getStmtsDocList() {
|
||||
return stmtsDocList;
|
||||
}
|
||||
// Used when sclientScope == ClientScope.activity
|
||||
private HttpClient activityClient;
|
||||
private ClientScope clientScope = ClientScope.activity;
|
||||
|
||||
private StmtsDocList stmtsDocList;
|
||||
|
||||
|
||||
private int stride;
|
||||
private Integer maxTries;
|
||||
private long timeout_ms = 30_000L;
|
||||
private Boolean showstmnts;
|
||||
public Timer bindTimer;
|
||||
public Timer executeTimer;
|
||||
public Histogram triesHisto;
|
||||
@ -37,10 +36,9 @@ public class HttpActivity extends SimpleActivity implements Activity, ActivityDe
|
||||
public Histogram skippedTokens;
|
||||
public Timer resultSuccessTimer;
|
||||
|
||||
private String[] hosts;
|
||||
private int port;
|
||||
|
||||
private OpSequence<ReadyHttpRequest> opSequence;
|
||||
private OpSequence<ReadyHttpOp> sequencer;
|
||||
private boolean diagnosticsEnabled;
|
||||
private long timeout = Long.MAX_VALUE;
|
||||
|
||||
public HttpActivity(ActivityDef activityDef) {
|
||||
super(activityDef);
|
||||
@ -48,59 +46,80 @@ public class HttpActivity extends SimpleActivity implements Activity, ActivityDe
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void initActivity() {
|
||||
super.initActivity();
|
||||
|
||||
// stride = activityDef.getParams().getOptionalInteger("stride").orElse(1);
|
||||
maxTries = activityDef.getParams().getOptionalInteger("maxTries").orElse(1);
|
||||
timeout_ms = activityDef.getParams().getOptionalLong("timeout_ms").orElse(30_000L);
|
||||
// showstmnts = activityDef.getParams().getOptionalBoolean("showstmnts").orElse(false);
|
||||
|
||||
// hosts = activityDef.getParams().getOptionalString("host").orElse("localhost").split(",");
|
||||
// port = activityDef.getParams().getOptionalInteger("port").orElse(80);
|
||||
|
||||
this.opSequence = createOpSequence(ReadyHttpRequest::new);
|
||||
this.setDefaultsFromOpSequence(opSequence);
|
||||
|
||||
bindTimer = ActivityMetrics.timer(activityDef, "bind");
|
||||
executeTimer = ActivityMetrics.timer(activityDef, "execute");
|
||||
resultTimer = ActivityMetrics.timer(activityDef, "result");
|
||||
triesHisto = ActivityMetrics.histogram(activityDef, "tries");
|
||||
rowCounter = ActivityMetrics.meter(activityDef, "rows");
|
||||
skippedTokens = ActivityMetrics.histogram(activityDef, "skipped-tokens");
|
||||
resultSuccessTimer = ActivityMetrics.timer(activityDef,"result-success");
|
||||
|
||||
resultSuccessTimer = ActivityMetrics.timer(activityDef, "result-success");
|
||||
this.sequencer = createOpSequence(ReadyHttpOp::new);
|
||||
setDefaultsFromOpSequence(sequencer);
|
||||
onActivityDefUpdate(activityDef);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onActivityDefUpdate(ActivityDef activityDef) {
|
||||
super.onActivityDefUpdate(activityDef);
|
||||
String[] diag = getParams().getOptionalString("diag").orElse("").split(",");
|
||||
Set<String> diags = new HashSet<String>(Arrays.asList(diag));
|
||||
this.console = new HttpConsoleFormats(diags);
|
||||
this.diagnosticsEnabled = console.isDiagnosticMode();
|
||||
this.timeout = getParams().getOptionalLong("timeout").orElse(Long.MAX_VALUE);
|
||||
|
||||
getParams().getOptionalString("client_scope")
|
||||
.map(ClientScope::valueOf)
|
||||
.ifPresent(this::setClientScope);
|
||||
|
||||
}
|
||||
|
||||
public Integer getMaxTries() {
|
||||
return maxTries;
|
||||
public long getTimeoutMillis() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public Boolean getShowstmts() {
|
||||
return showstmnts;
|
||||
private void setClientScope(ClientScope clientScope) {
|
||||
this.clientScope = clientScope;
|
||||
}
|
||||
|
||||
public String[] getHosts() {
|
||||
return hosts;
|
||||
public ClientScope getClientScope() {
|
||||
return clientScope;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
public synchronized Function<Thread, HttpClient> getClient() {
|
||||
switch (getClientScope()) {
|
||||
case thread:
|
||||
return t -> newClient();
|
||||
case activity:
|
||||
if (this.activityClient == null) {
|
||||
this.activityClient = newClient();
|
||||
}
|
||||
return t -> this.activityClient;
|
||||
default: throw new RuntimeException("unable to recoginize client scope: " + getClientScope());
|
||||
}
|
||||
}
|
||||
|
||||
public OpSequence<ReadyHttpRequest> getOpSequence() {
|
||||
return opSequence;
|
||||
public HttpClient newClient() {
|
||||
HttpClient.Builder builder = HttpClient.newBuilder();
|
||||
getParams().getOptionalString("follow_redirects")
|
||||
.map(String::toUpperCase)
|
||||
.map(HttpClient.Redirect::valueOf)
|
||||
.map(r -> {
|
||||
logger.debug("follow_redirects=>" + r);
|
||||
return r;
|
||||
})
|
||||
.ifPresent(builder::followRedirects);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public long getTimeoutMs() {
|
||||
return timeout_ms;
|
||||
public OpSequence<ReadyHttpOp> getSequencer() {
|
||||
return sequencer;
|
||||
}
|
||||
|
||||
public boolean isDiagnosticMode() {
|
||||
return diagnosticsEnabled;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,93 @@
|
||||
package io.nosqlbench.activitytype.http;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpHeaders;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class HttpConsoleFormats {
|
||||
|
||||
private final Set<String> includes;
|
||||
private final long modulo;
|
||||
|
||||
public HttpConsoleFormats(Set<String> includes) {
|
||||
long mod = 1L;
|
||||
Set<String> incl = new HashSet<>();
|
||||
|
||||
for (String include : includes) {
|
||||
if (include.matches("[0-9]+")) {
|
||||
mod = Long.parseLong(include);
|
||||
} else if (include.toLowerCase().equals("all")) {
|
||||
incl.add("headers");
|
||||
incl.add("stats");
|
||||
incl.add("content");
|
||||
} {
|
||||
incl.add(include);
|
||||
}
|
||||
}
|
||||
this.includes = incl;
|
||||
this.modulo = mod;
|
||||
}
|
||||
|
||||
public void summarizeRequest(HttpRequest request, PrintStream out, long cycle) {
|
||||
if ((cycle%modulo)!=0) {
|
||||
return;
|
||||
}
|
||||
out.println("---- REQUEST cycle=" + cycle);
|
||||
out.println(" --- " + request.method() + " " + request.uri() + " " + request.version().orElse(HttpClient.Version.HTTP_2));
|
||||
|
||||
if (includes.contains("headers")) {
|
||||
out.println(" -- headers:");
|
||||
summariseHeaders(request.headers(),out);
|
||||
}
|
||||
|
||||
out.println(" -- body length:" + request.bodyPublisher().get().contentLength());
|
||||
}
|
||||
|
||||
public void summarizeResponse(HttpResponse<String> response, PrintStream out, long cycle, long nanos) {
|
||||
if ((cycle%modulo)!=0) {
|
||||
return;
|
||||
}
|
||||
out.println("---- RESPONSE for cycle=" + cycle + " status=" + response.statusCode() + " took=" + (nanos/1_000_000) + "ms");
|
||||
|
||||
if (includes.contains("stats")) {
|
||||
int redirects=0;
|
||||
Optional<HttpResponse<String>> walkResponses = response.previousResponse();
|
||||
while (walkResponses.isPresent()) {
|
||||
walkResponses=walkResponses.get().previousResponse();
|
||||
redirects++;
|
||||
}
|
||||
System.out.println(" redirects = " + redirects);
|
||||
}
|
||||
|
||||
summariseHeaders(response.headers(),out);
|
||||
|
||||
if (this.includes.contains("content")) {
|
||||
System.out.println(" -- body:");
|
||||
System.out.println(response.body());
|
||||
}
|
||||
}
|
||||
|
||||
private static void summariseHeaders(HttpHeaders headers, PrintStream out) {
|
||||
out.println(" --- headers:");
|
||||
headers.map().forEach((k,v) -> {
|
||||
out.print(" --- " + k + ":");
|
||||
if (v.size()>1) {
|
||||
out.println();
|
||||
v.forEach( h -> {
|
||||
out.println(" - " + h);
|
||||
});
|
||||
} else {
|
||||
out.println(" " + v.get(0));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isDiagnosticMode() {
|
||||
return this.includes.size()>0;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package io.nosqlbench.activitytype.http;
|
||||
|
||||
public class InvalidResponseBodyException extends RuntimeException {
|
||||
private final long cycleValue;
|
||||
private final String ok_body;
|
||||
private final String body;
|
||||
|
||||
public InvalidResponseBodyException(long cycleValue, String ok_body, String body) {
|
||||
this.cycleValue = cycleValue;
|
||||
this.ok_body = ok_body;
|
||||
this.body = body;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package io.nosqlbench.activitytype.http;
|
||||
|
||||
public class InvalidStatusCodeException extends RuntimeException {
|
||||
private final long cycleValue;
|
||||
private final String ok_status;
|
||||
private final int statusCode;
|
||||
|
||||
public InvalidStatusCodeException(long cycleValue, String ok_status, int statusCode) {
|
||||
this.cycleValue = cycleValue;
|
||||
this.ok_status = ok_status;
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package io.nosqlbench.activitytype.http.async;
|
||||
|
||||
import io.nosqlbench.activitytype.cmds.HttpAsyncOp;
|
||||
import io.nosqlbench.activitytype.cmds.HttpOp;
|
||||
import io.nosqlbench.activitytype.cmds.ReadyHttpOp;
|
||||
import io.nosqlbench.activitytype.http.HttpActivity;
|
||||
import io.nosqlbench.engine.api.activityapi.core.BaseAsyncAction;
|
||||
import io.nosqlbench.engine.api.activityapi.core.ops.fluent.opfacets.TrackedOp;
|
||||
import io.nosqlbench.engine.api.activityapi.planning.OpSequence;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class HttpAsyncAction extends BaseAsyncAction<HttpAsyncOp, HttpActivity> {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(HttpAsyncAction.class);
|
||||
|
||||
private OpSequence<ReadyHttpOp> sequencer;
|
||||
private HttpClient client;
|
||||
|
||||
private CompletableFuture<HttpResponse<Void>> future;
|
||||
|
||||
|
||||
public HttpAsyncAction(HttpActivity httpActivity, int slot) {
|
||||
super(httpActivity,slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startOpCycle(TrackedOp<HttpAsyncOp> opc) {
|
||||
HttpAsyncOp opdata = opc.getOpData();
|
||||
HttpOp op = opdata.getOp();
|
||||
|
||||
opc.start();
|
||||
future = opdata.getAction().client.sendAsync(op.request, HttpResponse.BodyHandlers.discarding());
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.sequencer = activity.getSequencer();
|
||||
this.client = activity.getClient().apply(Thread.currentThread());
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongFunction<HttpAsyncOp> getOpInitFunction() {
|
||||
return l -> {
|
||||
ReadyHttpOp readyHttpOp = sequencer.get(l);
|
||||
return new HttpAsyncOp(this,readyHttpOp,l,client);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// @Override
|
||||
// public boolean enqueue(TrackedOp<HttpAsyncOp> opc) {
|
||||
// HttpAsyncOp opData = opc.getOpData();
|
||||
// opData.op.
|
||||
// return false;
|
||||
// }
|
||||
}
|
@ -41,7 +41,7 @@ bindings:
|
||||
You can even make a detailed request with custom headers and result verification conditions:
|
||||
|
||||
```yaml
|
||||
# Require that the result be status code 200-299 match regex "OK, account id is .*" in the body
|
||||
# Require that the result be status code 200-299 match regex "OK, account id is .*" in the body
|
||||
statements:
|
||||
- method: GET
|
||||
uri: https://google.com/
|
||||
@ -62,7 +62,7 @@ statements:
|
||||
GET https://google.com/ HTTP/1.1
|
||||
Content-Type: application/json
|
||||
ok-status: 2[0-9][0-9]
|
||||
ok-body: ^(OK, account id is.*)$
|
||||
ok-body: ^(OK, account id is.*)$
|
||||
```
|
||||
|
||||
Of course, in the above form, the response validators are still separate parameters.
|
||||
@ -78,8 +78,8 @@ statements:
|
||||
{method} {scheme}://{host}:{port}/{path}?{query} {version}
|
||||
Content-Type: {content_type}
|
||||
Token: {mybearertoken}
|
||||
|
||||
{body}
|
||||
|
||||
{body}
|
||||
```
|
||||
|
||||
The above example is in the inline request form. It is parsed and interpreted internally as if you
|
||||
@ -157,3 +157,25 @@ the defaults for the current HttpClient library that is bundled within the JVM.
|
||||
Presently, this driver only does basic request-response style requests. Thus, adding headers which
|
||||
take TCP socket control away from the HttpClient will likely yield inconsistent (or undefined)
|
||||
results. Support may be added for long-lived connections in a future release.
|
||||
|
||||
## HTTP Activity Parameters
|
||||
|
||||
- **client_scope** - default: activity - One of activity, or thread. This controls how many
|
||||
clients instances you use with an HTTP activity. By default, all threads will use the same
|
||||
client instance.
|
||||
- **follow_redirects** - default: normal - One of never, always, or normal. Normal redirects
|
||||
are those which do not redirect from HTTPS to HTTP.
|
||||
- **diagnostics** - default: none -
|
||||
This setting is a selector for what level of verbosity you will get on console. If you set
|
||||
this to true, you'll get every request and response logged to console. This is only for
|
||||
verifying that a test is configured and to spot check services before running higher scale
|
||||
tests.
|
||||
If you want finer control over how much information diagnostics provides, you can specify
|
||||
a comma separated list of the below.
|
||||
- all - Includes all of the below categories
|
||||
- stats - Counts of redirects, headers, body length, etc
|
||||
- headers - include header details
|
||||
- content - include
|
||||
- a number, like 3000 - causes the diagnostics to be reported only on this cycle modulo
|
||||
- **timeout** - default: tbd -
|
||||
Sets the
|
||||
|
@ -10,7 +10,7 @@ import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ReadyHttpRequestTest {
|
||||
public class ReadyHttpOpTest {
|
||||
|
||||
@Test
|
||||
public void testOnelineSpec() {
|
||||
@ -19,8 +19,8 @@ public class ReadyHttpRequestTest {
|
||||
" - s1: method=get uri=http://localhost/\n");
|
||||
OpTemplate stmtDef = docs.getStmts().get(0);
|
||||
|
||||
ReadyHttpRequest readyReq = new ReadyHttpRequest(stmtDef);
|
||||
HttpRequest staticReq = readyReq.apply(3);
|
||||
ReadyHttpOp readyReq = new ReadyHttpOp(stmtDef);
|
||||
HttpOp staticReq = readyReq.apply(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -30,8 +30,8 @@ public class ReadyHttpRequestTest {
|
||||
" - s1: get http://localhost/");
|
||||
OpTemplate stmtDef = docs.getStmts().get(0);
|
||||
|
||||
ReadyHttpRequest readyReq = new ReadyHttpRequest(stmtDef);
|
||||
HttpRequest staticReq = readyReq.apply(3);
|
||||
ReadyHttpOp readyReq = new ReadyHttpOp(stmtDef);
|
||||
HttpOp staticReq = readyReq.apply(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -41,8 +41,8 @@ public class ReadyHttpRequestTest {
|
||||
" - s1: get http://localhost/ HTTP/1.1");
|
||||
OpTemplate stmtDef = docs.getStmts().get(0);
|
||||
|
||||
ReadyHttpRequest readyReq = new ReadyHttpRequest(stmtDef);
|
||||
HttpRequest staticReq = readyReq.apply(3);
|
||||
ReadyHttpOp readyReq = new ReadyHttpOp(stmtDef);
|
||||
HttpOp staticReq = readyReq.apply(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -55,8 +55,8 @@ public class ReadyHttpRequestTest {
|
||||
"");
|
||||
OpTemplate stmtDef = docs.getStmts().get(0);
|
||||
|
||||
ReadyHttpRequest readyReq = new ReadyHttpRequest(stmtDef);
|
||||
HttpRequest staticReq = readyReq.apply(3);
|
||||
ReadyHttpOp readyReq = new ReadyHttpOp(stmtDef);
|
||||
HttpOp staticReq = readyReq.apply(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -69,8 +69,8 @@ public class ReadyHttpRequestTest {
|
||||
" body1");
|
||||
OpTemplate stmtDef = docs.getStmts().get(0);
|
||||
|
||||
ReadyHttpRequest readyReq = new ReadyHttpRequest(stmtDef);
|
||||
HttpRequest staticReq = readyReq.apply(3);
|
||||
ReadyHttpOp readyReq = new ReadyHttpOp(stmtDef);
|
||||
HttpOp staticReq = readyReq.apply(3);
|
||||
}
|
||||
|
||||
@Test
|
@ -4,7 +4,7 @@ import io.nosqlbench.engine.api.activityapi.core.Action;
|
||||
import io.nosqlbench.engine.api.activityapi.core.ActionDispenser;
|
||||
|
||||
public class JMXActionDispenser implements ActionDispenser {
|
||||
private JMXActivity activity;
|
||||
private final JMXActivity activity;
|
||||
|
||||
public JMXActionDispenser(JMXActivity activity) {
|
||||
this.activity = activity;
|
||||
|
@ -5,7 +5,7 @@ import java.util.Map;
|
||||
|
||||
public class MBeanInfoConsoleFormat {
|
||||
|
||||
private static Map<Integer,String> MbeanOpImpacts = Map.of(
|
||||
private static final Map<Integer,String> MbeanOpImpacts = Map.of(
|
||||
MBeanOperationInfo.ACTION,"ACTION",
|
||||
MBeanOperationInfo.ACTION_INFO,"ACTION_INFO",
|
||||
MBeanOperationInfo.UNKNOWN,"UNKNOWN",
|
||||
|
@ -46,7 +46,7 @@ public class AsyncStdoutAction extends BaseAsyncAction<StdoutOpContext, StdoutAc
|
||||
StartedOp<StdoutOpContext> started = opc.start();
|
||||
int result=0;
|
||||
try (Timer.Context executeTime = activity.executeTimer.time()) {
|
||||
activity.write(opc.getData().statement);
|
||||
activity.write(opc.getOpData().statement);
|
||||
} catch (Exception e) {
|
||||
result=1;
|
||||
started.fail(result);
|
||||
|
@ -56,7 +56,7 @@ public class StdoutActivity extends SimpleActivity implements ActivityDefObserve
|
||||
public Timer resultTimer;
|
||||
public Histogram triesHisto;
|
||||
private Writer pw;
|
||||
private String fileName;
|
||||
private final String fileName;
|
||||
private ExceptionMeterMetrics exceptionMeterMetrics;
|
||||
private int retry_delay = 0;
|
||||
private int retries;
|
||||
|
@ -100,7 +100,7 @@ public class OpImpl<D> implements OpFacets<D> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public D getData() {
|
||||
public D getOpData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,6 @@ package io.nosqlbench.engine.api.activityapi.core.ops.fluent.opfacets;
|
||||
* @param <D> The type of delegate needed for the implementing protocol
|
||||
*/
|
||||
public interface Payload<D> {
|
||||
D getData();
|
||||
D getOpData();
|
||||
void setData(D data);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import org.yaml.snakeyaml.Yaml;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
@ -32,9 +33,9 @@ import java.util.Optional;
|
||||
public class SysPerf {
|
||||
public final static Logger logger = LoggerFactory.getLogger(SysPerf.class);
|
||||
|
||||
private static final Charset CHARSET = Charset.forName("UTF8");
|
||||
private static final Charset CHARSET = StandardCharsets.UTF_8;
|
||||
private static SysPerfData cachedData;
|
||||
private static long currentImplVersion = 1L;
|
||||
private static final long currentImplVersion = 1L;
|
||||
private static SysPerf instance;
|
||||
|
||||
private SysPerf() {
|
||||
@ -112,7 +113,7 @@ public class SysPerf {
|
||||
String perfdata = new String(bytes, CHARSET);
|
||||
|
||||
Yaml yaml = new Yaml();
|
||||
SysPerfData perfinfo = (SysPerfData) yaml.load(perfdata);
|
||||
SysPerfData perfinfo = yaml.load(perfdata);
|
||||
cachedData = perfinfo;
|
||||
logger.info("Loaded previously cached system timing data from " + cache.getCanonicalPath());
|
||||
return cachedData;
|
||||
|
@ -33,7 +33,7 @@ import java.util.Map;
|
||||
public class RawStmtsDoc extends StatementsOwner {
|
||||
|
||||
private RawScenarios scenarios = new RawScenarios();
|
||||
private List<RawStmtsBlock> blocks = new ArrayList<>();
|
||||
private final List<RawStmtsBlock> blocks = new ArrayList<>();
|
||||
|
||||
// no-args ctor is required
|
||||
public RawStmtsDoc() {
|
||||
|
@ -21,7 +21,7 @@ import java.util.List;
|
||||
|
||||
public class RawStmtsDocList {
|
||||
|
||||
private List<RawStmtsDoc> rawStmtsDocList;
|
||||
private final List<RawStmtsDoc> rawStmtsDocList;
|
||||
|
||||
public RawStmtsDocList(List<RawStmtsDoc> rawStmtsDocList) {
|
||||
this.rawStmtsDocList = rawStmtsDocList;
|
||||
|
@ -166,9 +166,9 @@ public class ParameterMap extends ConcurrentHashMap<String,Object> implements Bi
|
||||
markMutation();
|
||||
}
|
||||
|
||||
private static Pattern encodedParamsSquote = Pattern.compile("(?<param>\\w+?)='(?<value>[^']+?);");
|
||||
private static Pattern encodedParamsDquote = Pattern.compile("(?<param>\\w+?)=\"(?<value>[^\"]+?);");
|
||||
private static Pattern encodedParamsPattern = Pattern.compile("(?<param>\\w+?)=(?<value>.+?);");
|
||||
private static final Pattern encodedParamsSquote = Pattern.compile("(?<param>\\w+?)='(?<value>[^']+?);");
|
||||
private static final Pattern encodedParamsDquote = Pattern.compile("(?<param>\\w+?)=\"(?<value>[^\"]+?);");
|
||||
private static final Pattern encodedParamsPattern = Pattern.compile("(?<param>\\w+?)=(?<value>.+?);");
|
||||
|
||||
@Override
|
||||
public Object put(String name, Object value) {
|
||||
@ -345,7 +345,7 @@ public class ParameterMap extends ConcurrentHashMap<String,Object> implements Bi
|
||||
// return parameterMap;
|
||||
// }
|
||||
|
||||
public static interface Listener {
|
||||
public interface Listener {
|
||||
void handleParameterMapUpdate(ParameterMap parameterMap);
|
||||
}
|
||||
|
||||
|
@ -2,22 +2,22 @@ package io.nosqlbench.engine.api.clireader.dsl;
|
||||
|
||||
public interface CLIFacets {
|
||||
|
||||
public static interface WantsAnyOption
|
||||
interface WantsAnyOption
|
||||
extends WantsGlobalOption {
|
||||
}
|
||||
|
||||
public static interface WantsParameterizedCommand {
|
||||
public WantsAnyOption namedParams();
|
||||
interface WantsParameterizedCommand {
|
||||
WantsAnyOption namedParams();
|
||||
}
|
||||
|
||||
public static interface WantsGlobalOption {
|
||||
public WantsOptionType global(String optionName);
|
||||
interface WantsGlobalOption {
|
||||
WantsOptionType global(String optionName);
|
||||
}
|
||||
|
||||
public static interface WantsOptionType {
|
||||
public WantsAnyOption toggle();
|
||||
public WantsAnyOption string();
|
||||
public WantsAnyOption number();
|
||||
interface WantsOptionType {
|
||||
WantsAnyOption toggle();
|
||||
WantsAnyOption string();
|
||||
WantsAnyOption number();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public class NashornEvaluator<T> implements Evaluator<T> {
|
||||
private final ScriptEngine scriptEngine;
|
||||
private final SimpleBindings bindings = new SimpleBindings();
|
||||
private String script = "";
|
||||
private Class<? extends T> resultType;
|
||||
private final Class<? extends T> resultType;
|
||||
private CompiledScript compiled;
|
||||
|
||||
/**
|
||||
|
@ -92,7 +92,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class TagFilter {
|
||||
public static TagFilter MATCH_ALL = new TagFilter("");
|
||||
private Map<String, String> filter = new LinkedHashMap<>();
|
||||
private final Map<String, String> filter = new LinkedHashMap<>();
|
||||
private Conjugate conjugate = Conjugate.all;
|
||||
|
||||
private final static Pattern conjugateForm = Pattern.compile("^(?<conjugate>\\w+)\\((?<filter>.+)\\)$",Pattern.DOTALL|Pattern.MULTILINE);
|
||||
@ -217,8 +217,8 @@ public class TagFilter {
|
||||
}
|
||||
|
||||
public static class Result {
|
||||
private boolean matched;
|
||||
private List<String> matchLog;
|
||||
private final boolean matched;
|
||||
private final List<String> matchLog;
|
||||
|
||||
public Result(boolean matched, List<String> log) {
|
||||
this.matched = matched;
|
||||
|
@ -157,7 +157,7 @@ public class ScenarioLogger {
|
||||
}
|
||||
}
|
||||
|
||||
private static Comparator<File> fileTimeComparator = new Comparator<File>() {
|
||||
private static final Comparator<File> fileTimeComparator = new Comparator<File>() {
|
||||
@Override
|
||||
public int compare(File o1, File o2) {
|
||||
return Long.compare(o1.lastModified(),o2.lastModified());
|
||||
|
@ -32,7 +32,7 @@ public class ScenarioResult {
|
||||
private final static Logger logger = LoggerFactory.getLogger(ScenarioResult.class);
|
||||
|
||||
private Exception exception;
|
||||
private String iolog;
|
||||
private final String iolog;
|
||||
|
||||
public ScenarioResult(String iolog) {
|
||||
this.iolog = iolog;
|
||||
|
@ -128,7 +128,7 @@ public class ScriptParams extends HashMap<String, String> implements ProxyObject
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return gson.toJson(this, Map.class).toString();
|
||||
return gson.toJson(this, Map.class);
|
||||
}
|
||||
|
||||
private static String valueOf(Object o) {
|
||||
@ -172,10 +172,7 @@ public class ScriptParams extends HashMap<String, String> implements ProxyObject
|
||||
if (super.containsKey(key)) {
|
||||
return true;
|
||||
}
|
||||
if (key.equals("withOverrides") || key.equals("withDefaults")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return key.equals("withOverrides") || key.equals("withDefaults");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -9,7 +9,7 @@ import java.util.List;
|
||||
|
||||
public class WorkspacesView {
|
||||
|
||||
private Path workspacesRoot;
|
||||
private final Path workspacesRoot;
|
||||
public WorkspacesView(Path workspacesRoot) {
|
||||
this.workspacesRoot = workspacesRoot;
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ public class PathFinder {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
logger.debug("Found path in classpath: " + candidatePath + ": " + candidatePath.toString());
|
||||
logger.debug("Found path in classpath: " + candidatePath + ": " + candidatePath);
|
||||
return Optional.of(Path.of(uri));
|
||||
}
|
||||
return Optional.empty();
|
||||
|
@ -9,7 +9,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class CompositeMarkdownInfo implements MarkdownInfo {
|
||||
private List<MarkdownInfo> elements = new LinkedList<>();
|
||||
private final List<MarkdownInfo> elements = new LinkedList<>();
|
||||
private boolean isSorted=false;
|
||||
|
||||
@Override
|
||||
|
@ -204,7 +204,7 @@ public class MarkdownDocs {
|
||||
|
||||
private final int from;
|
||||
private final int to;
|
||||
private T edgeProps;
|
||||
private final T edgeProps;
|
||||
|
||||
public Edge(int from, int to, Supplier<T> forT) {
|
||||
this.from = from;
|
||||
|
@ -316,7 +316,7 @@ function find_max() {
|
||||
accepted_count++;
|
||||
highest_acceptable_iteration = highest_acceptable_of(results, highest_acceptable_iteration, iteration);
|
||||
printf(" ---> accepting iteration %d\n",iteration);
|
||||
continue;
|
||||
|
||||
} else {
|
||||
rejected_count++;
|
||||
printf(" !!! rejecting iteration %d\n",iteration);
|
||||
|
@ -48,7 +48,7 @@ public class NBCliIntegrationTests {
|
||||
assertThat(result.exitStatus).isEqualTo(0);
|
||||
}
|
||||
// disabled till after release
|
||||
// This is not disabled on testbranch, only on master
|
||||
// This is not disabled on testbranch, only on main
|
||||
// @Test
|
||||
// public void dockerMetrics() {
|
||||
// ProcessInvoker invoker = new ProcessInvoker();
|
||||
|
@ -26,7 +26,7 @@ public class ToUUID implements LongFunction<UUID> {
|
||||
}
|
||||
|
||||
public ToUUID(long msbs) {
|
||||
this.msbs = (msbs & 0xFFFFFFFFFFFF0FFFL) | 0x0000000000004000L;;
|
||||
this.msbs = (msbs & 0xFFFFFFFFFFFF0FFFL) | 0x0000000000004000L;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -24,7 +24,7 @@ import java.util.stream.Collectors;
|
||||
public class AutoDocsWebService implements WebServiceObject {
|
||||
|
||||
private final static Logger logger = LogManager.getLogger(AutoDocsWebService.class);
|
||||
private List<DocFuncData> _docs = VirtDataDocs.getAllDocs();
|
||||
private final List<DocFuncData> _docs = VirtDataDocs.getAllDocs();
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
|
Loading…
Reference in New Issue
Block a user