mirror of
https://github.com/MarginaliaSearch/MarginaliaSearch.git
synced 2025-02-23 21:18:58 +00:00
(control) Node configuration
This commit is contained in:
parent
4baf9527d7
commit
6308a8dfcd
@ -1,5 +1,6 @@
|
||||
package nu.marginalia.nodecfg;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import nu.marginalia.nodecfg.model.NodeConfiguration;
|
||||
|
||||
@ -11,6 +12,7 @@ public class NodeConfigurationService {
|
||||
|
||||
private final HikariDataSource dataSource;
|
||||
|
||||
@Inject
|
||||
public NodeConfigurationService(HikariDataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
@ -48,7 +50,9 @@ public class NodeConfigurationService {
|
||||
FROM NODE_CONFIGURATION
|
||||
""")) {
|
||||
var rs = qs.executeQuery();
|
||||
|
||||
List<NodeConfiguration> ret = new ArrayList<>();
|
||||
|
||||
while (rs.next()) {
|
||||
ret.add(new NodeConfiguration(
|
||||
rs.getInt("ID"),
|
||||
|
@ -10,6 +10,8 @@ import nu.marginalia.control.node.model.*;
|
||||
import nu.marginalia.control.sys.model.EventLogEntry;
|
||||
import nu.marginalia.control.sys.svc.EventLogService;
|
||||
import nu.marginalia.control.sys.svc.HeartbeatService;
|
||||
import nu.marginalia.nodecfg.NodeConfigurationService;
|
||||
import nu.marginalia.nodecfg.model.NodeConfiguration;
|
||||
import nu.marginalia.storage.FileStorageService;
|
||||
import nu.marginalia.executor.client.ExecutorClient;
|
||||
import nu.marginalia.executor.model.crawl.RecrawlParameters;
|
||||
@ -37,6 +39,7 @@ public class ControlNodeService {
|
||||
private final ExecutorClient executorClient;
|
||||
private final HikariDataSource dataSource;
|
||||
private final ServiceMonitors monitors;
|
||||
private final NodeConfigurationService nodeConfigurationService;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@ -48,7 +51,7 @@ public class ControlNodeService {
|
||||
HeartbeatService heartbeatService,
|
||||
ExecutorClient executorClient,
|
||||
HikariDataSource dataSource,
|
||||
ServiceMonitors monitors)
|
||||
ServiceMonitors monitors, NodeConfigurationService nodeConfigurationService)
|
||||
{
|
||||
this.fileStorageService = fileStorageService;
|
||||
this.rendererFactory = rendererFactory;
|
||||
@ -57,6 +60,7 @@ public class ControlNodeService {
|
||||
this.executorClient = executorClient;
|
||||
this.dataSource = dataSource;
|
||||
this.monitors = monitors;
|
||||
this.nodeConfigurationService = nodeConfigurationService;
|
||||
}
|
||||
|
||||
public void register() throws IOException {
|
||||
@ -82,7 +86,9 @@ public class ControlNodeService {
|
||||
Spark.post("/public/nodes/:id/storage/new-specs", this::createNewSpecsAction);
|
||||
|
||||
Spark.get("/public/nodes/:id/storage/:view", this::nodeStorageListModel, storageListRenderer::render);
|
||||
|
||||
Spark.get("/public/nodes/:id/configuration", this::nodeConfigModel, configRenderer::render);
|
||||
Spark.post("/public/nodes/:id/configuration", this::updateConfigModel, configRenderer::render);
|
||||
|
||||
Spark.post("/public/nodes/:id/storage/recrawl-auto", this::triggerAutoRecrawl);
|
||||
Spark.post("/public/nodes/:id/storage/process-auto", this::triggerAutoProcess);
|
||||
@ -284,11 +290,45 @@ public class ControlNodeService {
|
||||
"storage", storage);
|
||||
}
|
||||
|
||||
private Object nodeConfigModel(Request request, Response response) {
|
||||
private Object nodeConfigModel(Request request, Response response) throws SQLException {
|
||||
int nodeId = Integer.parseInt(request.params("id"));
|
||||
|
||||
Map<String, Path> storage = new HashMap<>();
|
||||
|
||||
for (var baseType : List.of(FileStorageBaseType.CURRENT, FileStorageBaseType.WORK, FileStorageBaseType.BACKUP, FileStorageBaseType.STORAGE)) {
|
||||
Optional.ofNullable(fileStorageService.getStorageBase(baseType, nodeId))
|
||||
.map(FileStorageBase::asPath)
|
||||
.ifPresent(path -> storage.put(baseType.toString().toLowerCase(), path));
|
||||
}
|
||||
|
||||
return Map.of(
|
||||
"node", new IndexNode(nodeId)
|
||||
);
|
||||
"node", new IndexNode(nodeId),
|
||||
"config", Objects.requireNonNull(nodeConfigurationService.get(nodeId), "Failed to fetch configuration"),
|
||||
"storage", storage);
|
||||
}
|
||||
|
||||
private Object updateConfigModel(Request request, Response response) throws SQLException {
|
||||
int nodeId = Integer.parseInt(request.params("id"));
|
||||
String act = request.queryParams("act");
|
||||
|
||||
if ("config".equals(act)) {
|
||||
var newConfig = new NodeConfiguration(
|
||||
nodeId,
|
||||
request.queryParams("description"),
|
||||
"on".equalsIgnoreCase(request.queryParams("acceptQueries")),
|
||||
"on".equalsIgnoreCase(request.queryParams("disabled"))
|
||||
);
|
||||
|
||||
nodeConfigurationService.save(newConfig);
|
||||
}
|
||||
else if ("storage".equals(act)) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
else {
|
||||
Spark.halt(400);
|
||||
}
|
||||
|
||||
return nodeConfigModel(request, response);
|
||||
}
|
||||
|
||||
private Object nodeOverviewModel(Request request, Response response) throws SQLException {
|
||||
|
@ -29,14 +29,41 @@
|
||||
|
||||
</nav>
|
||||
|
||||
<div class="mt-2">
|
||||
{{> control/partials/processes-table }}
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
{{> control/partials/events-table-summary }}
|
||||
<h1 class="my-5">Node Configuration</h1>
|
||||
|
||||
<div class="m-4 p-4 border">
|
||||
<h2>Settings</h2>
|
||||
|
||||
<form method="post" action="?act=config">
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Description</label>
|
||||
<input class="form-control" type="text" name="description" value="{{config.description}}"/>
|
||||
</div>
|
||||
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" name="acceptQueries" {{#if config.acceptQueries}}checked{{/if}}>
|
||||
<label class="form-check-label" for="acceptQueries">Accept queries</label>
|
||||
|
||||
<div class="form-text">Sets whether queries will be routed to this node</div>
|
||||
</div>
|
||||
|
||||
<div class="form-check form-switch mb-3">
|
||||
<input class="form-check-input" type="checkbox" role="switch" name="disabled" {{#if config.disabled}}checked{{/if}}>
|
||||
<label class="form-check-label" for="disabled">Disabled</label>
|
||||
|
||||
<div class="form-text">Disabling a node is a soft delete that prevents the index and
|
||||
control service from starting</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
{{> control/partials/foot-includes }}
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user