mirror of
https://github.com/MarginaliaSearch/MarginaliaSearch.git
synced 2025-02-23 13:09:00 +00:00
(control) New list and form for index nodes.
This commit is contained in:
parent
108b4cb648
commit
eacbf87979
@ -215,10 +215,10 @@ public class FileStorageService {
|
||||
return null;
|
||||
}
|
||||
public FileStorageBase createStorageBase(String name, Path path, FileStorageBaseType type) throws SQLException, FileNotFoundException {
|
||||
return createStorageBase(name, path, node, type);
|
||||
}
|
||||
|
||||
if (!Files.exists(path)) {
|
||||
throw new FileNotFoundException("Storage base path does not exist: " + path);
|
||||
}
|
||||
public FileStorageBase createStorageBase(String name, Path path, int node, FileStorageBaseType type) throws SQLException, FileNotFoundException {
|
||||
|
||||
try (var conn = dataSource.getConnection();
|
||||
var stmt = conn.prepareStatement("""
|
||||
@ -238,7 +238,6 @@ public class FileStorageService {
|
||||
|
||||
return getStorageBase(type);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private Path allocateDirectory(Path basePath, String prefix) throws IOException {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
@ -25,6 +25,7 @@ import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Spark;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -64,6 +65,7 @@ public class ControlNodeService {
|
||||
}
|
||||
|
||||
public void register() throws IOException {
|
||||
var nodeListRenderer = rendererFactory.renderer("control/node/nodes-list");
|
||||
var overviewRenderer = rendererFactory.renderer("control/node/node-overview");
|
||||
var actionsRenderer = rendererFactory.renderer("control/node/node-actions");
|
||||
var actorsRenderer = rendererFactory.renderer("control/node/node-actors");
|
||||
@ -74,6 +76,8 @@ public class ControlNodeService {
|
||||
|
||||
var newSpecsFormRenderer = rendererFactory.renderer("control/node/node-new-specs-form");
|
||||
|
||||
Spark.get("/public/nodes", this::nodeListModel, nodeListRenderer::render);
|
||||
Spark.post("/public/nodes", this::createNode);
|
||||
Spark.get("/public/nodes/:id", this::nodeOverviewModel, overviewRenderer::render);
|
||||
Spark.get("/public/nodes/:id/", this::nodeOverviewModel, overviewRenderer::render);
|
||||
Spark.get("/public/nodes/:id/actors", this::nodeActorsModel, actorsRenderer::render);
|
||||
@ -102,6 +106,27 @@ public class ControlNodeService {
|
||||
|
||||
}
|
||||
|
||||
private Object createNode(Request request, Response response) throws SQLException, FileNotFoundException {
|
||||
var newConfig = nodeConfigurationService.create(request.queryParams("description"), "on".equalsIgnoreCase(request.queryParams("acceptQueries")));
|
||||
int id = newConfig.node();
|
||||
|
||||
fileStorageService.createStorageBase("Index Data", Path.of("/idx"), id, FileStorageBaseType.CURRENT);
|
||||
fileStorageService.createStorageBase("Index Backups", Path.of("/backup"), id, FileStorageBaseType.BACKUP);
|
||||
fileStorageService.createStorageBase("Crawl Data", Path.of("/storage"), id, FileStorageBaseType.STORAGE);
|
||||
fileStorageService.createStorageBase("Work Area", Path.of("/work"), id, FileStorageBaseType.WORK);
|
||||
|
||||
return redirectToOverview(id);
|
||||
}
|
||||
|
||||
private Object nodeListModel(Request request, Response response) throws SQLException {
|
||||
var configs = nodeConfigurationService.getAll();
|
||||
|
||||
int nextId = configs.stream().mapToInt(NodeConfiguration::node).map(i -> i+1).max().orElse(1);
|
||||
|
||||
return Map.of("nodes", nodeConfigurationService.getAll(),
|
||||
"nextNodeId", nextId);
|
||||
}
|
||||
|
||||
private Object triggerCrawl(Request request, Response response) throws Exception {
|
||||
int nodeId = Integer.parseInt(request.params("id"));
|
||||
|
||||
@ -117,10 +142,14 @@ public class ControlNodeService {
|
||||
|
||||
return redirectToOverview(request);
|
||||
}
|
||||
@SneakyThrows
|
||||
public String redirectToOverview(int nodeId) {
|
||||
return new Redirects.HtmlRedirect("/nodes/"+nodeId).render(null);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public String redirectToOverview(Request request) {
|
||||
return new Redirects.HtmlRedirect("/nodes/"+request.params("id")).render(null);
|
||||
return redirectToOverview(Integer.parseInt(request.params("id")));
|
||||
}
|
||||
|
||||
private Object createNewSpecsAction(Request request, Response response) {
|
||||
|
@ -0,0 +1,62 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
{{> control/partials/head-includes }}
|
||||
<head><title>Control Service</title></head>
|
||||
<body>
|
||||
{{> control/partials/nav}}
|
||||
|
||||
<div class="container">
|
||||
<h1 class="my-5">Index Nodes</h1>
|
||||
|
||||
{{#unless nodes}}
|
||||
It appears no nodes have been configured! This is necessary before any index or executor services
|
||||
can be started. At least a single node needs to be configured to serve search queries.
|
||||
{{/unless}}
|
||||
|
||||
{{#if nodes}}
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Node ID</th>
|
||||
<th>Description</th>
|
||||
<th>Accept Queries</th>
|
||||
</tr>
|
||||
{{#each nodes}}
|
||||
<tr>
|
||||
<td><a href="/nodes/{{node}}">node-{{node}}</a></td>
|
||||
<td>{{description}}</td>
|
||||
<td>{{acceptQueries}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</table>
|
||||
|
||||
|
||||
<div class="m-3 p-3 border">
|
||||
<h2>Add Node</h2>
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">ID</label>
|
||||
<input class="form-control" type="text" name="id" id="id" value="{{nextNodeId}}" disabled aria-disabled="true" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Description</label>
|
||||
<input class="form-control" type="text" name="description" id="description" />
|
||||
</div>
|
||||
|
||||
<div class="form-check form-switch mb-3">
|
||||
<input class="form-check-input" type="checkbox" role="switch" name="acceptQueries">
|
||||
<label class="form-check-label" for="acceptQueries">Accept queries</label>
|
||||
|
||||
<div class="form-text">Sets whether queries will be routed to this node. This can be modified later.</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Create</button>
|
||||
</form>
|
||||
</div>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
{{> control/partials/foot-includes }}
|
||||
</html>
|
@ -21,6 +21,7 @@
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false">System</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="/nodes" title="View and configure index nodes">Nodes</a></li>
|
||||
<li><a class="dropdown-item" href="/events" title="View the event log">Events</a></li>
|
||||
<li><a class="dropdown-item" href="/message-queue" title="View or manipulate the system message queue">Message Queue</a></li>
|
||||
</ul>
|
||||
|
Loading…
Reference in New Issue
Block a user