use crate::server::route_catalog::{
RouteAudience, RouteAuth, RouteEntry, RouteGroupDefaults, RouteMethod, RouteRegistry,
RouteRequest, RouteStability,
};
use crate::server::routes::common::{PUBLIC_SURFACES, STANDARD_MIDDLEWARE};
use crate::server::*;
const LEFTOVERS_USER: RouteGroupDefaults = RouteGroupDefaults {
family: "leftovers",
audience: RouteAudience::Internal,
auth: RouteAuth::UserRequired,
surfaces: PUBLIC_SURFACES,
stability: RouteStability::Internal,
middlewares: STANDARD_MIDDLEWARE,
};
const LEFTOVER_ROUTES: &[RouteEntry] = &[
RouteEntry::new("root.index", RouteMethod::Get, "/", root_index),
RouteEntry::new("config.export", RouteMethod::Get, "/config", config_export),
RouteEntry::new("config.import", RouteMethod::Post, "/config", config_import),
RouteEntry::new("config.key", RouteMethod::Any, "/config/*", config_key),
RouteEntry::new("keyed.v1.kv", RouteMethod::Any, "/v1/kv/*", keyed_v1_kv),
RouteEntry::new(
"keyed.v1.config",
RouteMethod::Any,
"/v1/config/*",
keyed_v1_kv,
),
RouteEntry::new(
"keyed.v1.vault",
RouteMethod::Any,
"/v1/vault/*",
keyed_v1_kv,
),
RouteEntry::new(
"kv.dynamic.kvs",
RouteMethod::Any,
"/collections/:collection/kvs/*",
kv_dynamic_kvs,
),
RouteEntry::new(
"kv.dynamic.kv",
RouteMethod::Any,
"/collections/:collection/kv/*",
kv_dynamic_kvs,
),
RouteEntry::new(
"logs.dynamic",
RouteMethod::Any,
"/logs/:name/:action",
logs_dynamic,
),
RouteEntry::new(
"indexes.action",
RouteMethod::Any,
"/indexes/:name/:action",
indexes_action,
),
RouteEntry::new(
"vectors.cluster",
RouteMethod::Post,
"/vectors/cluster",
vectors_cluster,
),
RouteEntry::new(
"serverless.attach",
RouteMethod::Post,
"/serverless/attach",
serverless_attach,
),
RouteEntry::new(
"serverless.warmup",
RouteMethod::Post,
"/serverless/warmup",
serverless_warmup,
),
RouteEntry::new(
"serverless.reclaim",
RouteMethod::Post,
"/serverless/reclaim",
serverless_reclaim,
),
RouteEntry::new(
"serverless.tick",
RouteMethod::Post,
"/tick",
serverless_reclaim,
),
RouteEntry::new(
"physical.native_vector_artifacts.by_collection",
RouteMethod::Get,
"/physical/native-vector-artifacts/:collection",
physical_native_vector_artifacts_by_collection,
),
RouteEntry::new(
"physical.native_vector_artifacts.by_collection.warmup",
RouteMethod::Post,
"/physical/native-vector-artifacts/:collection/warmup",
physical_native_vector_artifacts_by_collection_warmup,
),
];
pub(crate) fn register(registry: &mut RouteRegistry) {
registry.routes(LEFTOVERS_USER, LEFTOVER_ROUTES);
}
fn root_index(server: &RedDBServer, _req: &RouteRequest<'_>) -> Option<HttpResponse> {
Some(match server.ui_dir() {
Some(ui_dir) => crate::server::ui_static::serve_bundle_asset(ui_dir, "/")
.unwrap_or_else(|| server.handle_root_discovery()),
None => server.handle_root_discovery(),
})
}
fn config_export(server: &RedDBServer, _req: &RouteRequest<'_>) -> Option<HttpResponse> {
Some(server.handle_config_export())
}
fn config_import(server: &RedDBServer, req: &RouteRequest<'_>) -> Option<HttpResponse> {
Some(server.handle_config_import(req.body.to_vec()))
}
fn config_key(server: &RedDBServer, req: &RouteRequest<'_>) -> Option<HttpResponse> {
server.handle_config_key_route(req.method, req.path, req.body)
}
fn keyed_v1_kv(server: &RedDBServer, req: &RouteRequest<'_>) -> Option<HttpResponse> {
server.handle_v1_keyed_route(req.method, req.path, req.query, req.body)
}
fn kv_dynamic_kvs(server: &RedDBServer, req: &RouteRequest<'_>) -> Option<HttpResponse> {
server.handle_collection_kv_route(req.method, req.path, req.query, req.headers, req.body)
}
fn logs_dynamic(server: &RedDBServer, req: &RouteRequest<'_>) -> Option<HttpResponse> {
let name = req.matched.params.get("name")?;
let action = req.matched.params.get("action")?;
Some(match (req.method, action.as_str()) {
("POST", "append") => {
handlers_log::handle_log_append(&server.runtime, name, req.body.to_vec())
}
("GET", "query") => handlers_log::handle_log_query(&server.runtime, name, req.query),
("POST", "retention") => handlers_log::handle_log_retention(&server.runtime, name),
_ => json_error(405, "method not allowed for log endpoint"),
})
}
fn indexes_action(server: &RedDBServer, req: &RouteRequest<'_>) -> Option<HttpResponse> {
let name = req.matched.params.get("name")?;
let action = req.matched.params.get("action")?;
server.handle_index_action_route(req.method, name, action)
}
fn vectors_cluster(server: &RedDBServer, req: &RouteRequest<'_>) -> Option<HttpResponse> {
Some(handlers_vector::handle_vector_cluster(
&server.runtime,
req.body.to_vec(),
))
}
fn serverless_attach(server: &RedDBServer, req: &RouteRequest<'_>) -> Option<HttpResponse> {
Some(server.handle_serverless_attach(req.body.to_vec()))
}
fn serverless_warmup(server: &RedDBServer, req: &RouteRequest<'_>) -> Option<HttpResponse> {
Some(server.handle_serverless_warmup(req.body.to_vec()))
}
fn serverless_reclaim(server: &RedDBServer, req: &RouteRequest<'_>) -> Option<HttpResponse> {
Some(server.handle_serverless_reclaim(req.body.to_vec()))
}
fn physical_native_vector_artifacts_by_collection(
server: &RedDBServer,
req: &RouteRequest<'_>,
) -> Option<HttpResponse> {
let collection = req.matched.params.get("collection")?;
Some(
match server
.native_use_cases()
.inspect_vector_artifact(InspectNativeArtifactInput {
collection: collection.to_string(),
artifact_kind: req.query.get("kind").cloned(),
}) {
Ok(artifact) => json_response(
200,
crate::presentation::native_state_json::native_vector_artifact_inspection_json(
&artifact,
),
),
Err(err) => json_error(404, err.to_string()),
},
)
}
fn physical_native_vector_artifacts_by_collection_warmup(
server: &RedDBServer,
req: &RouteRequest<'_>,
) -> Option<HttpResponse> {
let collection = req.matched.params.get("collection")?;
Some(
match server
.native_use_cases()
.warmup_vector_artifact(InspectNativeArtifactInput {
collection: collection.to_string(),
artifact_kind: req.query.get("kind").cloned(),
}) {
Ok(artifact) => json_response(
200,
crate::presentation::native_state_json::native_vector_artifact_inspection_json(
&artifact,
),
),
Err(err) => json_error(404, err.to_string()),
},
)
}