mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2024-12-22 15:13:41 -06:00
workspaces incremental progress
This commit is contained in:
parent
4e8370a6a3
commit
1b96f8876d
@ -4,11 +4,18 @@ package io.nosqlbench.docsys.api;
|
||||
* Any class which is annotated with <pre>{@code @Service(WebServiceObject.class)}</pre>
|
||||
* will be found and loaded as a service.
|
||||
*
|
||||
* For the methods used to configure these objects, consult
|
||||
* <A href="https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/jaxrs-resources.html#d0e2040">jax-rs resources documentation</A>
|
||||
* For the methods used to configure these objects, consult the
|
||||
* references below:
|
||||
*
|
||||
* and
|
||||
* <A href="https://jax-rs.github.io/apidocs/2.1/">Jax-RS API Docs</A>
|
||||
* @see <A href="https://eclipse-ee4j.github.io/jersey.github
|
||||
* .io/documentation/latest/jaxrs-resources.html#d0e2040">Jersey jax-rs
|
||||
* resources documentation</A>
|
||||
*
|
||||
* @see <A href="https://github.com/jax-rs/spec/blob/master/spec
|
||||
* .pdf">JAX-RS: Java™ API for RESTful Web Services Version 2.1
|
||||
* Proposed Final Draft June 9, 2017</A>
|
||||
**
|
||||
* @see <A href="https://jax-rs.github.io/apidocs/2.1/">Jax-RS API Docs</A>
|
||||
*/
|
||||
public interface WebServiceObject {
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import javax.ws.rs.core.MediaType;
|
||||
@Singleton
|
||||
@Path("_")
|
||||
public class DocServerStatusEndpoint implements WebServiceObject {
|
||||
|
||||
private final static Logger logger =
|
||||
LogManager.getLogger(DocServerStatusEndpoint.class);
|
||||
|
||||
|
32
docsys/src/main/node/docsys/pages/ui/workspaces/index.vue
Normal file
32
docsys/src/main/node/docsys/pages/ui/workspaces/index.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<v-app>
|
||||
<v-app-bar app dark color="secondary">
|
||||
<v-toolbar-title>NoSQLBench - Workspaces</v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-toolbar-items>
|
||||
<v-btn text href="https://github.com/nosqlbench/nosqlbench/wiki/Submitting-Feedback">SUBMIT FEEDBACK</v-btn>
|
||||
</v-toolbar-items>
|
||||
</v-app-bar>
|
||||
|
||||
<v-layout justify-center align-center>
|
||||
<v-content>
|
||||
<v-card max-width="344">
|
||||
<v-card-title>workspace-name</v-card-title>
|
||||
<v-card-text>workspace details go here</v-card-text>
|
||||
</v-card>
|
||||
|
||||
</v-content>
|
||||
</v-layout>
|
||||
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "workspaces.vue"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -1,93 +1,103 @@
|
||||
package io.nosqlbench.engine.rest.resources;
|
||||
|
||||
import io.nosqlbench.docsys.api.WebServiceObject;
|
||||
import io.nosqlbench.engine.rest.domain.WorkSpace;
|
||||
import io.nosqlbench.engine.rest.services.WorkspaceService;
|
||||
import io.nosqlbench.engine.rest.transfertypes.WorkspaceView;
|
||||
import io.nosqlbench.engine.rest.transfertypes.WorkspacesInfo;
|
||||
import io.nosqlbench.nb.annotations.Service;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.*;
|
||||
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.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
import java.util.List;
|
||||
|
||||
@Path("/services/workspaces")
|
||||
@Path("/services/workspaces/")
|
||||
@Singleton
|
||||
@Service(WebServiceObject.class)
|
||||
public class WorkspacesEndpoint implements WebServiceObject {
|
||||
|
||||
private final static java.nio.file.Path workspacesRoot = Paths.get("workspaces");
|
||||
private final static Logger logger =
|
||||
LogManager.getLogger(WorkspacesEndpoint.class);
|
||||
|
||||
public static final String WORKSPACE_ROOT = "workspace_root";
|
||||
|
||||
@Context
|
||||
private Configuration config;
|
||||
|
||||
private final static java.nio.file.Path workspacesRoot = Paths.get("workspaces");
|
||||
private WorkspaceService svc;
|
||||
|
||||
/**
|
||||
* @return A list of workspaces as a
|
||||
* {@link List} of {@link WorkspaceView}
|
||||
*/
|
||||
@GET
|
||||
@Path("")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response listWorkspaces() {
|
||||
WorkspacesInfo info = new WorkspacesInfo(workspacesRoot);
|
||||
return Response.ok(info).build();
|
||||
public Response getWorkspacesInfo() {
|
||||
List<WorkspaceView> wsviews = getSvc().getWorkspaceViews();
|
||||
return Response.ok(wsviews).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{workspace}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response listWorkspace(@PathParam("workspace") String workspace) {
|
||||
WorkspaceView view = new WorkspaceView(workspace);
|
||||
return Response.ok(view).build();
|
||||
public Response getWorkspaceInfo(@PathParam("workspace") String workspace) {
|
||||
WorkspaceView workpaceView = getSvc().getWorkspaceView(workspace);
|
||||
return Response.ok(workpaceView).build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{workspaceName}/upload/{filepath}")
|
||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||
public Response uploadFileIntoWorkspace(
|
||||
) {
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{workspaceName}/{filepath}")
|
||||
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
|
||||
public Response putFile(
|
||||
@PathParam("workspaceName") String workspaceName,
|
||||
@PathParam("filepath") String filename
|
||||
public Response putFileInWorkspace(
|
||||
@PathParam("workspaceName") String workspaceName,
|
||||
@PathParam("filepath") String filename,
|
||||
ByteBuffer content
|
||||
) {
|
||||
WorkSpace workspace = getWorkspace(workspaceName);
|
||||
Optional<Path> puttedFile = workspace.put(workspace);
|
||||
if (puttedFile.isPresent()) {
|
||||
try {
|
||||
getSvc().putFile(workspaceName, filename, content);
|
||||
return Response.ok().build();
|
||||
} else {
|
||||
} catch (Exception e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{workspaceName}/{filename}")
|
||||
public Response getFile(
|
||||
@PathParam("workspaceName") String workspaceName,
|
||||
@PathParam("filename") String filename) {
|
||||
public Response getFileInWorkspace(
|
||||
@PathParam("workspaceName") String workspaceName,
|
||||
@PathParam("filename") String filename) {
|
||||
|
||||
WorkSpace workSpace = new WorkSpace(workspacesRoot, workspaceName);
|
||||
Optional<java.nio.file.Path> optFile = workSpace.get(filename);
|
||||
|
||||
if (optFile.isPresent()) {
|
||||
try {
|
||||
java.nio.file.Path filepath = optFile.get();
|
||||
String contentType = Files.probeContentType(filepath);
|
||||
MediaType mediaType = MediaType.valueOf(contentType);
|
||||
|
||||
byte[] bytes = Files.readAllBytes(filepath);
|
||||
return Response.ok(bytes, mediaType).build();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
try {
|
||||
WorkspaceService.FileInfo fileinfo = getSvc().readFile(workspaceName, filename);
|
||||
if (fileinfo != null) {
|
||||
return Response.ok(fileinfo.getContent(), fileinfo.getMediaType()).build();
|
||||
} else {
|
||||
return Response.noContent().status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
} else {
|
||||
return Response.noContent().status(Response.Status.NOT_FOUND).build();
|
||||
} catch (Exception e) {
|
||||
return Response.serverError().entity(e.getMessage()).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private WorkSpace getWorkspace(String workspace) {
|
||||
if (!workspace.matches("[a-zA-Z][a-zA-Z0-9]+")) {
|
||||
throw new RuntimeException("Workspaces must start with an alphabetic" +
|
||||
" character, and contain only letters and numbers.");
|
||||
private WorkspaceService getSvc() {
|
||||
if (svc == null) {
|
||||
svc = new WorkspaceService(config.getProperties().get(WORKSPACE_ROOT));
|
||||
}
|
||||
WorkSpace workSpace = new WorkSpace(workspacesRoot, workspace);
|
||||
return workSpace;
|
||||
return svc;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,134 @@
|
||||
package io.nosqlbench.engine.rest.services;
|
||||
|
||||
import io.nosqlbench.engine.rest.transfertypes.WorkspaceView;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WorkspaceService {
|
||||
private final Path root;
|
||||
public static String DEFAULT = "default";
|
||||
|
||||
public WorkspaceService(Object root) {
|
||||
if (root instanceof Path) {
|
||||
this.root = (Path) root;
|
||||
} else if (root instanceof CharSequence) {
|
||||
this.root = Paths.get(((CharSequence) root).toString());
|
||||
} else if (root == null) {
|
||||
this.root = Paths.get(System.getProperty("user.dir"),
|
||||
"workspaces");
|
||||
try {
|
||||
Files.createDirectories(this.root);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Unable to use workspaces root " +
|
||||
"path of type " + root.getClass().getCanonicalName());
|
||||
}
|
||||
createDefaultIfNotExist();
|
||||
}
|
||||
|
||||
private void createDefaultIfNotExist() {
|
||||
getWorkspaceView(DEFAULT);
|
||||
}
|
||||
|
||||
public List<WorkspaceView> getWorkspaceViews() {
|
||||
List<WorkspaceView> views = new ArrayList<>();
|
||||
DirectoryStream<Path> wsrEntries = null;
|
||||
try {
|
||||
wsrEntries = Files.newDirectoryStream(root);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
for (Path entry : wsrEntries) {
|
||||
views.add(new WorkspaceView(entry));
|
||||
}
|
||||
return views;
|
||||
}
|
||||
|
||||
public WorkspaceView getWorkspaceView(String workspace) {
|
||||
if (!workspace.matches("[a-zA-Z][a-zA-Z0-9]+")) {
|
||||
throw new RuntimeException("Workspaces must start with an alphabetic" +
|
||||
" character, and contain only letters and numbers.");
|
||||
}
|
||||
|
||||
Path wspath = root.resolve(Paths.get(workspace));
|
||||
if (!Files.exists(wspath)) {
|
||||
try {
|
||||
Files.createDirectories(wspath);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return new WorkspaceView(wspath);
|
||||
}
|
||||
|
||||
public void putFile(String workspaceName, String filename, ByteBuffer content) {
|
||||
Path toWrite = root.resolve(workspaceName).resolve(filename);
|
||||
try {
|
||||
Files.write(toWrite, content.array(),
|
||||
StandardOpenOption.TRUNCATE_EXISTING,
|
||||
StandardOpenOption.CREATE,
|
||||
StandardOpenOption.WRITE);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the bytes of the named file in the named workspace.
|
||||
*
|
||||
* @param workspaceName The workspace name to look in for the file
|
||||
* @param filename The filename within the workspace to read
|
||||
* @return null if the file is not found
|
||||
* @throws RuntimeException if the file was found but could not be
|
||||
* read.
|
||||
*/
|
||||
public FileInfo readFile(String workspaceName, String filename) {
|
||||
Path filePath = workspacePath(workspaceName).resolve(filename);
|
||||
if (Files.exists(filePath)) {
|
||||
return new FileInfo(filePath);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Path workspacePath(String workspaceName) {
|
||||
return root.resolve(workspaceName);
|
||||
}
|
||||
|
||||
public final static class FileInfo {
|
||||
private final Path path;
|
||||
|
||||
public FileInfo(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public MediaType getMediaType() {
|
||||
try {
|
||||
String contentType = Files.probeContentType(path);
|
||||
MediaType mediaType = MediaType.valueOf(contentType);
|
||||
return mediaType;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public ByteBuffer getContent() {
|
||||
byte[] bytes = new byte[0];
|
||||
try {
|
||||
bytes = Files.readAllBytes(path);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return ByteBuffer.wrap(bytes);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Classes in this package are meant to provide a basic
|
||||
* internal service facade to be used by endpoints.
|
||||
* This simplifies endpoint implementations and facilitates DRY
|
||||
* implementations.
|
||||
*
|
||||
* These implementations should only expose primitive types,
|
||||
* collections of primitive types, or views of transfer types
|
||||
* as implemented in that package.
|
||||
*/
|
||||
package io.nosqlbench.engine.rest.services;
|
@ -1,10 +1,16 @@
|
||||
package io.nosqlbench.engine.rest.transfertypes;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class WorkspaceView {
|
||||
|
||||
private final String workspace;
|
||||
private final Path workspaceRoot;
|
||||
|
||||
public WorkspaceView(String workspace) {
|
||||
this.workspace = workspace;
|
||||
public WorkspaceView(Path workspaceRoot) {
|
||||
this.workspaceRoot = workspaceRoot;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return workspaceRoot.getFileName().toString();
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,10 @@ import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WorkspacesInfo {
|
||||
public class WorkspacesView {
|
||||
|
||||
private Path workspacesRoot;
|
||||
public WorkspacesInfo(Path workspacesRoot) {
|
||||
public WorkspacesView(Path workspacesRoot) {
|
||||
this.workspacesRoot = workspacesRoot;
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Types in this package are meant to provide a mapping
|
||||
* between internal state and external views. Specifically,
|
||||
* these types should only include details which are meant to
|
||||
* be shared by endpoints. This can be achieved by wrapping
|
||||
* internal state and exposing only the visible properties, or
|
||||
* it can be done by implementing types which are built from
|
||||
* common internal types.
|
||||
*
|
||||
* Service objects in the services package should only provide
|
||||
* primitive values or the view types from this package.
|
||||
*/
|
||||
package io.nosqlbench.engine.rest.transfertypes;
|
@ -27,3 +27,6 @@ echo "Do mvn release:prepare..."
|
||||
#mvn $MAVEN_REPO_LOCAL --batch-mode --global-settings release.xml -Dusername=$GITHUB_ACCESS_TOKEN release:prepare
|
||||
mvn --batch-mode --global-settings release.xml -Dusername=$GITHUB_ACCESS_TOKEN clean release:prepare -DdevelopmentVersion=${NEXT_SNAPSHOT} -DreleaseVersion=${RELEASE_VERSION}
|
||||
|
||||
echo "files after release:prepare..."
|
||||
pwd
|
||||
ls -l
|
||||
|
Loading…
Reference in New Issue
Block a user