endpoint updates for nbui

This commit is contained in:
Jonathan Shook 2020-08-28 12:33:32 -05:00
parent 1b81f43227
commit 6db06818fd
10 changed files with 455 additions and 119 deletions

View File

@ -5,20 +5,25 @@ import io.nosqlbench.engine.cli.BasicScriptBuffer;
import io.nosqlbench.engine.cli.Cmd;
import io.nosqlbench.engine.cli.NBCLICommandParser;
import io.nosqlbench.engine.cli.ScriptBuffer;
import io.nosqlbench.engine.core.ScenarioLogger;
import io.nosqlbench.engine.core.ScenarioResult;
import io.nosqlbench.engine.core.script.Scenario;
import io.nosqlbench.engine.core.script.ScenariosExecutor;
import io.nosqlbench.engine.rest.domain.WorkSpace;
import io.nosqlbench.engine.rest.services.WorkspaceService;
import io.nosqlbench.engine.rest.services.WorkSpace;
import io.nosqlbench.engine.rest.services.WorkspaceFinder;
import io.nosqlbench.engine.rest.transfertypes.LiveScenarioView;
import io.nosqlbench.engine.rest.transfertypes.RunScenarioRequest;
import io.nosqlbench.nb.annotations.Service;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import javax.inject.Singleton;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import java.io.CharArrayWriter;
import java.io.PrintWriter;
import java.util.*;
@Service(WebServiceObject.class)
@ -33,6 +38,33 @@ public class ScenarioExecutorEndpoint implements WebServiceObject {
private Configuration config;
@DELETE
@Path("scenario/{scenario}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public synchronized Response cancelScenario(@PathParam("scenario") String scenario) {
try {
executor.deleteScenario(scenario);
return Response.ok("canceled '" + scenario +"' and removed it").build();
} catch (Exception e) {
return Response.serverError().entity(e.getMessage()).build();
}
}
@POST
@Path("stop/{scenario}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public synchronized Response stopScenario(@PathParam("scenario") String scenario) {
try {
executor.stopScenario(scenario,false);
return Response.ok("stopped '" + scenario +"' without removing it").build();
} catch (Exception e) {
return Response.serverError().entity(e.getMessage()).build();
}
}
@POST
@Path("cli")
@Consumes(MediaType.APPLICATION_JSON)
@ -40,9 +72,17 @@ public class ScenarioExecutorEndpoint implements WebServiceObject {
public synchronized Response invokeCommand(RunScenarioRequest rq) {
String name = rq.getScenarioName();
if (name.equals("auto")) {
rq.setScenarioName("scenario"+ System.currentTimeMillis());
rq.setScenarioName("scenario" + System.currentTimeMillis());
}
org.joda.time.format.DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyyMMddHHmmssSSS");
name=name.replaceAll("EPOCHMS", String.valueOf(System.currentTimeMillis()));
name=name.replaceAll("DATESTAMP", dtf.print(new DateTime()));
name=name.replaceAll("[:/ ]","");
rq.setScenarioName(name);
WorkSpace workspace = new WorkspaceFinder(config).getWorkspace(rq.getWorkspace());
// First, virtualize files provided
storeFiles(rq);
@ -56,26 +96,31 @@ public class ScenarioExecutorEndpoint implements WebServiceObject {
}
}
args = substituteFilenames(rq, args);
NBCLICommandParser.parse(args, cmdList);
NBCLICommandParser.parse(args, cmdList, workspace.asIncludes());
ScriptBuffer buffer = new BasicScriptBuffer();
buffer.add(cmdList.toArray(new Cmd[0]));
Scenario scenario = new Scenario(
rq.getScenarioName(),
"",
Scenario.Engine.Graalvm,
"disabled",
false,
true,
false
rq.getScenarioName(),
"",
Scenario.Engine.Graalvm,
"disabled",
false,
true,
false
);
scenario.addScriptText(buffer.getParsedScript());
executor.execute(scenario);
ScenarioLogger logger = new ScenarioLogger(scenario)
.setLogDir(workspace.getWorkspacePath().resolve("logs").toString());
executor.execute(scenario, logger);
return Response.created(UriBuilder.fromResource(ScenarioExecutorEndpoint.class).path(
"scenario/" + rq.getScenarioName()).build()).build();
"scenario/" + rq.getScenarioName()).build()).entity("started").build();
}
@ -83,26 +128,26 @@ public class ScenarioExecutorEndpoint implements WebServiceObject {
LinkedList<String> newargs = new LinkedList<>();
for (String arg : args) {
for (String s : rq.getFilemap().keySet()) {
arg = arg.replaceAll(s,rq.getFilemap().get(s));
newargs.add(arg);
arg = arg.replaceAll(s, rq.getFilemap().get(s));
}
newargs.add(arg);
}
return newargs;
}
private void storeFiles(RunScenarioRequest rq) {
Map<String, String> filemap = rq.getFilemap();
if (filemap==null) {
if (filemap == null) {
return;
}
WorkspaceService ws = new WorkspaceService(config);
WorkspaceFinder ws = new WorkspaceFinder(config);
WorkSpace workspace = ws.getWorkspace(rq.getWorkspace());
Map<String,String> replacements = new HashMap<>();
Map<String, String> replacements = new HashMap<>();
for (String filename : filemap.keySet()) {
java.nio.file.Path targetPath = workspace.storeFile(filename, filemap.get(filename), replacements);
java.nio.file.Path targetPath = workspace.storeFile(filename, filemap.get(filename), replacements);
}
rq.setFileMap(replacements);
}
@ -157,7 +202,7 @@ public class ScenarioExecutorEndpoint implements WebServiceObject {
if (pendingScenario.isPresent()) {
Optional<ScenarioResult> pendingResult = executor.getPendingResult(scenarioName);
return new LiveScenarioView(pendingScenario.get(),pendingResult.orElse(null));
return new LiveScenarioView(pendingScenario.get(), pendingResult.orElse(null));
} else {
throw new RuntimeException("Scenario name '" + scenarioName + "' not found.");
}
@ -166,16 +211,25 @@ public class ScenarioExecutorEndpoint implements WebServiceObject {
@GET
@Path("scenarios")
@Produces(MediaType.APPLICATION_JSON)
public synchronized List<LiveScenarioView> getScenarios() {
public synchronized Response getScenarios() {
List<LiveScenarioView> liveScenarioViews = new ArrayList<>();
List<String> pendingScenarios = executor.getPendingScenarios();
try {
List<LiveScenarioView> liveScenarioViews = new ArrayList<>();
List<String> pendingScenarios = executor.getPendingScenarios();
for (String pendingScenario : pendingScenarios) {
LiveScenarioView liveScenarioView = getScenario(pendingScenario);
liveScenarioViews.add(liveScenarioView);
for (String pendingScenario : pendingScenarios) {
LiveScenarioView liveScenarioView = getScenario(pendingScenario);
liveScenarioViews.add(liveScenarioView);
}
return Response.ok(liveScenarioViews).build();
} catch (Exception e) {
CharArrayWriter caw = new CharArrayWriter();
PrintWriter pw = new PrintWriter(caw);
e.printStackTrace(pw);
String trace = caw.toString();
return Response.serverError().entity(trace).build();
}
return liveScenarioViews;
}

View File

@ -3,7 +3,7 @@ package io.nosqlbench.engine.rest.resources;
import io.nosqlbench.docsys.api.WebServiceObject;
import io.nosqlbench.engine.api.scenarios.NBCLIScenarioParser;
import io.nosqlbench.engine.api.scenarios.WorkloadDesc;
import io.nosqlbench.engine.rest.services.WorkspaceService;
import io.nosqlbench.engine.rest.services.WorkspaceFinder;
import io.nosqlbench.nb.annotations.Service;
import io.nosqlbench.virtdata.userlibs.apps.docsapp.AutoDocsWebService;
import org.apache.logging.log4j.LogManager;
@ -18,9 +18,7 @@ import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
@Service(WebServiceObject.class)
@ -32,30 +30,39 @@ public class WorkloadFinderEndpoint implements WebServiceObject {
@Context
private Configuration config;
public List<WorkloadDesc> getWorkloads(String search) {
return getWorkloads(Set.of(search!=null ? search.split(",") : new String[0]));
}
public List<WorkloadDesc> getWorkloads(Set<String> search) {
List<WorkloadDesc> workloads = new ArrayList<>();
WorkspaceFinder ws = new WorkspaceFinder(config);
for (String include : search) {
if (include.equals("builtins")) {
List<WorkloadDesc> activities = NBCLIScenarioParser.getWorkloadsWithScenarioScripts(true, "activities");
for (WorkloadDesc desc : activities) {
workloads.add(desc);
}
} else {
List<WorkloadDesc> descInWorkspace = ws.getWorkspace(include).getWorkloadsWithScenarioScripts();
for (WorkloadDesc workload : descInWorkspace) {
workloads.add(workload);
}
}
}
return workloads;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getWorkloadDescriptions(@QueryParam("searchin") String searchin) {
// WorkloadsView workloads = new WorkloadsView();
List<WorkloadDesc> workloads = new ArrayList<>();
WorkspaceService ws = new WorkspaceService(config);
WorkspaceFinder ws = new WorkspaceFinder(config);
Set<String> searchIn = Set.of(searchin != null ? searchin.split(",") : new String[]{});
try {
String[] includes = (searchin != null ? searchin.split(",") : new String[]{});
for (String include : includes) {
if (include.equals("builtins")) {
List<WorkloadDesc> activities = NBCLIScenarioParser.getWorkloadsWithScenarioScripts(true, "activities");
for (WorkloadDesc desc : activities) {
workloads.add(desc);
}
} else {
List<WorkloadDesc> descInWorkspace = ws.getWorkspace(include).getWorkloadsWithScenarioScripts();
for (WorkloadDesc workload : descInWorkspace) {
workloads.add(workload);
}
}
}
List<WorkloadDesc> workloads = getWorkloads(searchIn);
return Response.ok(workloads).build();
} catch (Exception e) {
return Response.serverError().entity(e.getMessage()).build();
@ -65,8 +72,11 @@ public class WorkloadFinderEndpoint implements WebServiceObject {
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("parameters")
public Map<String, String> getParametersByWorkload(@QueryParam("workloadName") String workloadName) {
List<WorkloadDesc> workloads = NBCLIScenarioParser.getWorkloadsWithScenarioScripts(true);
public Map<String, String> getParametersByWorkload(
@QueryParam("workloadName") String workloadName,
@QueryParam("searchin") String searchin
) {
List<WorkloadDesc> workloads = getWorkloads(searchin);
Map<String, String> templates = null;

View File

@ -1,7 +1,9 @@
package io.nosqlbench.engine.rest.resources;
import io.nosqlbench.docsys.api.WebServiceObject;
import io.nosqlbench.engine.rest.services.WorkspaceService;
import io.nosqlbench.engine.rest.services.WorkSpace;
import io.nosqlbench.engine.rest.services.WorkspaceFinder;
import io.nosqlbench.engine.rest.transfertypes.WorkspaceItemView;
import io.nosqlbench.engine.rest.transfertypes.WorkspaceView;
import io.nosqlbench.nb.annotations.Service;
import org.apache.logging.log4j.LogManager;
@ -15,7 +17,7 @@ import java.nio.ByteBuffer;
import java.nio.file.Paths;
import java.util.List;
@Path("/services/workspaces/")
@Path("/services/workspaces")
@Singleton
@Service(WebServiceObject.class)
public class WorkspacesEndpoint implements WebServiceObject {
@ -26,7 +28,7 @@ public class WorkspacesEndpoint implements WebServiceObject {
private Configuration config;
private final static java.nio.file.Path workspacesRoot = Paths.get("workspaces");
private WorkspaceService svc;
private WorkspaceFinder svc;
/**
* @return A list of workspaces as a
@ -40,13 +42,13 @@ public class WorkspacesEndpoint implements WebServiceObject {
}
@DELETE
@Path("{workspace}")
@Path("/{workspace}")
@Produces(MediaType.APPLICATION_JSON)
public Response deleteWorkspace(@PathParam("workspace") String workspace,
@QueryParam("deleteCount") String deleteCount) {
try {
int dc = deleteCount!=null ? Integer.valueOf(deleteCount):0;
getSvc().purgeWorkspace(workspace,dc);
int dc = deleteCount != null ? Integer.valueOf(deleteCount) : 0;
getSvc().purgeWorkspace(workspace, dc);
return Response.ok("removed workspace " + workspace).build();
} catch (Exception e) {
return Response.serverError().entity(e.getMessage()).build();
@ -54,19 +56,23 @@ public class WorkspacesEndpoint implements WebServiceObject {
}
@GET
@Path("{workspace}")
@Produces(MediaType.APPLICATION_JSON)
public Response getWorkspaceInfo(@PathParam("workspace") String workspace) {
@Path("/{workspaceName}/{filepath:.+}")
public Response listFilesInWorkspace(
@PathParam("workspaceName") String workspaceName,
@PathParam("filepath") String filepath
) {
try {
WorkspaceView workpaceView = getSvc().getWorkspaceView(workspace);
return Response.ok(workpaceView).build();
WorkSpace w = getSvc().getWorkspace(workspaceName);
List<WorkspaceItemView> listing = w.getWorkspaceListingView(filepath);
return Response.ok(listing).build();
} catch (Exception e) {
return Response.serverError().entity(e.getMessage()).build();
}
}
@POST
@Path("{workspaceName}/upload/{filepath}")
@Path("/{workspaceName}/upload/{filepath}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFileIntoWorkspace(
) {
@ -74,7 +80,7 @@ public class WorkspacesEndpoint implements WebServiceObject {
}
@POST
@Path("{workspaceName}/{filepath}")
@Path("/{workspaceName}/{filepath:.*}")
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.WILDCARD)
public Response doSomething(@Context HttpServletRequest request, byte[] input) {
@ -83,8 +89,8 @@ public class WorkspacesEndpoint implements WebServiceObject {
try {
String pathInfo = request.getPathInfo();
String[] parts = pathInfo.split("/");
String workspaceName = parts[parts.length-2];
String filename = parts[parts.length-1];
String workspaceName = parts[parts.length - 2];
String filename = parts[parts.length - 1];
getSvc().putFile(workspaceName, filename, ByteBuffer.wrap(input));
return Response.ok().build();
} catch (Exception e) {
@ -93,26 +99,56 @@ public class WorkspacesEndpoint implements WebServiceObject {
}
@GET
@Path("{workspaceName}/{filename}")
public Response getFileInWorkspace(
@PathParam("workspaceName") String workspaceName,
@PathParam("filename") String filename) {
@Path("/{workspace}")
@Produces(MediaType.APPLICATION_JSON)
public Response getWorkspaceInfo(
@PathParam("workspace") String workspace,
@QueryParam("ls") String ls
) {
try {
WorkspaceService.FileInfo fileinfo = getSvc().readFile(workspaceName, filename);
if (fileinfo != null) {
return Response.ok(fileinfo.getPath().toFile(), fileinfo.getMediaType()).build();
if (ls!=null && !ls.toLowerCase().equals("false")) {
WorkSpace ws = getSvc().getWorkspace(workspace);
List<WorkspaceItemView> listing = ws.getWorkspaceListingView("");
return Response.ok(listing).build();
} else {
return Response.noContent().status(Response.Status.NOT_FOUND).build();
WorkspaceView workpaceView = getSvc().getWorkspaceView(workspace);
return Response.ok(workpaceView).build();
}
} catch (Exception e) {
return Response.serverError().entity(e.getMessage()).build();
}
}
private WorkspaceService getSvc() {
@GET
@Path("/{workspace}/{filename}")
public Response getFileInWorkspace(
@PathParam("workspace") String workspace,
@PathParam("filename") String filename,
@QueryParam("ls") String ls) {
try {
if (ls!=null && !ls.toLowerCase().equals("false")) {
WorkSpace ws = getSvc().getWorkspace(workspace);
List<WorkspaceItemView> listing = ws.getWorkspaceListingView(filename);
return Response.ok(listing).build();
} else {
WorkspaceFinder.FileInfo fileinfo = getSvc().readFile(workspace, filename);
if (fileinfo != null) {
return Response.ok(fileinfo.getPath().toFile(), fileinfo.getMediaType()).build();
} else {
return Response.noContent().status(Response.Status.NOT_FOUND).build();
}
}
} catch (Exception e) {
return Response.serverError().entity(e.getMessage()).build();
}
}
private WorkspaceFinder getSvc() {
if (svc == null) {
svc = new WorkspaceService(config);
svc = new WorkspaceFinder(config);
}
return svc;
}

View File

@ -1,7 +1,8 @@
package io.nosqlbench.engine.rest.domain;
package io.nosqlbench.engine.rest.services;
import io.nosqlbench.engine.api.scenarios.NBCLIScenarioParser;
import io.nosqlbench.engine.api.scenarios.WorkloadDesc;
import io.nosqlbench.engine.rest.transfertypes.WorkspaceItemView;
import io.nosqlbench.engine.rest.transfertypes.WorkspaceView;
import io.nosqlbench.nb.api.content.Content;
import io.nosqlbench.nb.api.content.NBIO;
@ -78,6 +79,8 @@ public class WorkSpace {
}
Path targetPath = Paths.get(filename);
assertLegalWorkspacePath(targetPath);
if (targetPath.isAbsolute()) {
throw new RuntimeException("You may not use absolute paths in workspaces: '" + targetPath.toString() + "'");
}
@ -111,4 +114,40 @@ public class WorkSpace {
}
}
public List<WorkspaceItemView> getWorkspaceListingView(String filepath) {
Path target = this.workspacePath.resolve(filepath);
assertLegalWorkspacePath(target);
List<WorkspaceItemView> items = new ArrayList<>();
try {
DirectoryStream<Path> elementPaths = Files.newDirectoryStream(target);
for (Path elementPath : elementPaths) {
items.add(new WorkspaceItemView(this.workspacePath,elementPath));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return items;
}
private void assertLegalWorkspacePath(Path target) {
if (target.toString().contains("..")) {
throw new RuntimeException("Possible path injection:" + target.toString());
}
}
@Override
public String toString() {
return this.workspaceName;
}
public String[] asIncludes() {
Path relativePath =
this.workspacesRoot.toAbsolutePath().getParent().relativize(this.workspacePath.toAbsolutePath());
return new String[]{ relativePath.toString() };
}
}

View File

@ -1,6 +1,5 @@
package io.nosqlbench.engine.rest.services;
import io.nosqlbench.engine.rest.domain.WorkSpace;
import io.nosqlbench.engine.rest.transfertypes.WorkspaceView;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -15,15 +14,15 @@ import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;
public class WorkspaceService {
private final static Logger logger = LogManager.getLogger(WorkspaceService.class);
public class WorkspaceFinder {
private final static Logger logger = LogManager.getLogger(WorkspaceFinder.class);
public static String DEFAULT = "default";
public static final String WORKSPACE_ROOT = "workspaces_root";
private final Path root;
public WorkspaceService(Configuration config) {
public WorkspaceFinder(Configuration config) {
Object root = config.getProperties().get(WORKSPACE_ROOT);
if (root instanceof Path) {
this.root = (Path) root;
@ -46,7 +45,7 @@ public class WorkspaceService {
createDefaultIfNotExist();
}
public WorkspaceService(Path root) {
public WorkspaceFinder(Path root) {
this.root = root;
createDefaultIfNotExist();
}

View File

@ -1,12 +1,14 @@
package io.nosqlbench.engine.rest.transfertypes;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import io.nosqlbench.engine.api.activityapi.core.ProgressMeter;
import io.nosqlbench.engine.core.ScenarioResult;
import io.nosqlbench.engine.core.script.Scenario;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
public class LiveScenarioView {
@ -18,6 +20,9 @@ public class LiveScenarioView {
this.result = result;
}
@JsonProperty
@JsonPropertyDescription("Optionally populated result, "+
" present only if there was an error or the scenario is complete")
public ResultView getResult() {
if (result==null) {
return null;
@ -40,12 +45,24 @@ public class LiveScenarioView {
return scenario.getEndedAtMillis();
}
public Scenario.State getState() {
return scenario.getScenarioState();
}
@JsonProperty("progress")
public List<ProgressView> getProgress() {
List<ProgressView> progress = new ArrayList<>();
List<ProgressView> progressView = new ArrayList<>();
if (scenario.getScenarioController()==null) {
return progressView;
}
return scenario.getScenarioController().getProgressMeters()
.stream().map(ProgressView::new).collect(Collectors.toList());
Collection<? extends ProgressMeter> meters = scenario.getScenarioController().getProgressMeters();
for (ProgressMeter progressMeter : meters) {
ProgressView meterView = new ProgressView(progressMeter);
progressView.add(meterView);
}
return progressView;
}
}

View File

@ -2,19 +2,53 @@ package io.nosqlbench.engine.rest.transfertypes;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.nosqlbench.engine.api.activityapi.core.ProgressMeter;
import io.nosqlbench.engine.api.activityimpl.input.StateCapable;
public class ProgressView {
private final ProgressMeter progressMeter;
public ProgressView(ProgressMeter progressMeter) {
if (progressMeter==null) {
throw new RuntimeException("Unable to create a view with a null progressMeter");
}
this.progressMeter = progressMeter;
}
@JsonProperty("details")
@JsonProperty("summary")
public String getProgressDetails() {
return progressMeter.getProgressDetails();
return progressMeter.getProgressSummary();
}
@JsonProperty("min")
public long getMin() {
return progressMeter.getProgressMin();
}
@JsonProperty("current")
public long getCurrent() {
return progressMeter.getProgressCurrent();
}
@JsonProperty("max")
public long getMax() {
return progressMeter.getProgressMax();
}
@JsonProperty("recycles_max")
public long getRecyclesMax() {
return progressMeter.getRecyclesMax();
}
@JsonProperty("recycles_current")
public long getRecyclesCurrent() {
return progressMeter.getRecyclesCurrent();
}
@JsonProperty("eta_millis")
public double getEtaMills() {
return progressMeter.getProgressETAMillis();
}
@JsonProperty("name")
@ -22,14 +56,18 @@ public class ProgressView {
return progressMeter.getProgressName();
}
@JsonProperty("state")
public String getState() {
return progressMeter.getProgressState().toString();
}
@JsonProperty("completed")
public double getProgress() {
return progressMeter.getProgress();
return progressMeter.getProgressRatio();
}
@JsonProperty("state")
public String getState() {
if (progressMeter instanceof StateCapable) {
return ((StateCapable)progressMeter).getRunState().toString();
} else {
return "unknown";
}
}

View File

@ -5,36 +5,18 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import java.util.Map;
/**
* A CliRequest is what the user sends when they want to invoke NoSQLBench via web request in the
* same way they may on the command line.
*
* <pre>{@code
* {
* "workspace" : "",
* "name" : "auto",
* "basedir" : "/tmp/nosqlbench",
* "filemap" : {
* "file1.yaml": "bindings:\n i: Identity()\n",
* "myscb:base64" : "base64encodeddata.."
* },
* "commands": [
* "run", "workload=file1.yaml", "driver=stdout", "cycles=10M", "cyclerate=100", "scb=myscb"
* ]
* }
* }</pre>
*/
public class RunScenarioRequest {
@JsonProperty("commands")
private List<String> commands;
private List<String> commands = List.of();
@JsonProperty("filemap")
private Map<String, String> filemap;
private Map<String, String> filemap = Map.of();
@JsonProperty("console")
private String stdout;
@JsonProperty("name")
@JsonProperty("scenario_name")
private String scenarioName = "auto";
@JsonProperty("workspace")

View File

@ -0,0 +1,158 @@
package io.nosqlbench.engine.rest.transfertypes;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileOwnerAttributeView;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class WorkspaceItemView {
private String type;
private String perms;
private String owner;
private String group;
private long size;
private long mtime;
private final static List<String> fields = List.of(
"type",
"perms",
"owner",
"group",
"size",
"mtime",
"name"
);
public WorkspaceItemView(Path wspath, Path path) {
try {
PosixFileAttributeView posix = Files.getFileAttributeView(path, PosixFileAttributeView.class);
PosixFileAttributes attrs = posix.readAttributes();
setPerms(fromPerms(attrs.permissions()));
setType(typeOf(path));
setOwner(attrs.owner().getName());
setGroup(attrs.group().getName());
setSize(attrs.size());
setMtimeMillis(attrs.lastModifiedTime().to(TimeUnit.MILLISECONDS));
setName(wspath.relativize(path).toString());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void setOwner(FileOwnerAttributeView fileAttributeView) {
try {
this.setOwner(fileAttributeView.getOwner().getName());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private String typeOf(Path path) {
if (Files.isRegularFile(path)) {
return "F";
}
if (Files.isDirectory(path)) {
return "D";
}
return "U";
}
@JsonProperty("fields")
public List<List<String>> getAsFields() {
return List.of(
fields,
List.of(
this.type,
this.perms,
this.owner,
this.group,
String.valueOf(this.size),
"mtime",
this.name
)
);
}
private String fromPerms(Set<PosixFilePermission> perms) {
StringBuilder sb = new StringBuilder();
String img = "rwxrwxrwx";
String not = "---------";
int step = 0;
for (PosixFilePermission perm : PosixFilePermission.values()) {
String src = perms.contains(perm) ? img : not;
sb.append(src.charAt(step));
step++;
}
return sb.toString();
}
public String getPerms() {
return perms;
}
public void setPerms(String perms) {
this.perms = perms;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public long getMtimeMillis() {
return mtime;
}
public void setMtimeMillis(long mtime) {
this.mtime = mtime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String name;
}

View File

@ -1,5 +1,6 @@
package io.nosqlbench.engine.rest.transfertypes;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.joda.time.Period;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
@ -32,6 +33,7 @@ public class WorkspaceView {
return workspaceRoot.getFileName().toString();
}
@JsonProperty("modified")
public long getModified() {
try {
return Files.getLastModifiedTime(workspaceRoot).toMillis();
@ -40,6 +42,7 @@ public class WorkspaceView {
}
}
@JsonProperty("summary")
public Summary getSummary() {
if (this.summary == null) {
Summary v = new Summary(this.workspaceRoot);