From e2686c0fce4b325fe78f669f04e843822a8439e5 Mon Sep 17 00:00:00 2001 From: Tamo Date: Thu, 26 Dec 2024 16:16:56 +0100 Subject: [PATCH] add the swap indexes --- crates/meilisearch/src/routes/mod.rs | 6 ++- crates/meilisearch/src/routes/multi_search.rs | 1 - crates/meilisearch/src/routes/swap_indexes.rs | 39 ++++++++++++++++++- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/crates/meilisearch/src/routes/mod.rs b/crates/meilisearch/src/routes/mod.rs index 0211f2151..da4cb5528 100644 --- a/crates/meilisearch/src/routes/mod.rs +++ b/crates/meilisearch/src/routes/mod.rs @@ -4,6 +4,7 @@ use crate::extractors::authentication::policies::*; use crate::extractors::authentication::GuardedData; use crate::routes::indexes::documents::DocumentEditionByFunction; use crate::routes::multi_search::SearchResults; +use crate::routes::swap_indexes::SwapIndexesPayload; use crate::search::{ FederatedSearch, FederatedSearchResult, Federation, FederationOptions, MergeFacets, SearchQueryWithIndex, SearchResultWithIndex, SimilarQuery, SimilarResult, @@ -70,13 +71,14 @@ pub mod tasks; (path = "/metrics", api = metrics::MetricApi), (path = "/logs", api = logs::LogsApi), (path = "/multi-search", api = multi_search::MultiSearchApi), + (path = "/swap-indexes", api = swap_indexes::SwapIndexesApi), ), paths(get_health, get_version, get_stats), tags( (name = "Stats", description = "Stats gives extended information and metrics about indexes and the Meilisearch database."), ), modifiers(&OpenApiAuth), - components(schemas(DocumentEditionByFunction, MergeFacets, FederationOptions, SearchQueryWithIndex, Federation, FederatedSearch, FederatedSearchResult, SearchResults, SearchResultWithIndex, SimilarQuery, SimilarResult, PaginationView, BrowseQuery, UpdateIndexRequest, IndexUid, IndexCreateRequest, KeyView, Action, CreateApiKey, UpdateStderrLogs, LogMode, GetLogs, IndexStats, Stats, HealthStatus, HealthResponse, VersionResponse, Code, ErrorType, AllTasks, TaskView, Status, DetailsView, ResponseError, Settings, Settings, TypoSettings, MinWordSizeTyposSetting, FacetingSettings, PaginationSettings, SummarizedTaskView, Kind)) + components(schemas(SwapIndexesPayload, DocumentEditionByFunction, MergeFacets, FederationOptions, SearchQueryWithIndex, Federation, FederatedSearch, FederatedSearchResult, SearchResults, SearchResultWithIndex, SimilarQuery, SimilarResult, PaginationView, BrowseQuery, UpdateIndexRequest, IndexUid, IndexCreateRequest, KeyView, Action, CreateApiKey, UpdateStderrLogs, LogMode, GetLogs, IndexStats, Stats, HealthStatus, HealthResponse, VersionResponse, Code, ErrorType, AllTasks, TaskView, Status, DetailsView, ResponseError, Settings, Settings, TypoSettings, MinWordSizeTyposSetting, FacetingSettings, PaginationSettings, SummarizedTaskView, Kind)) )] pub struct MeilisearchApi; @@ -96,7 +98,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) { .service(web::resource("/stats").route(web::get().to(get_stats))) // done .service(web::resource("/version").route(web::get().to(get_version))) // done .service(web::scope("/indexes").configure(indexes::configure)) // done - .service(web::scope("/multi-search").configure(multi_search::configure)) // TODO + .service(web::scope("/multi-search").configure(multi_search::configure)) // done .service(web::scope("/swap-indexes").configure(swap_indexes::configure)) // TODO .service(web::scope("/metrics").configure(metrics::configure)) // done .service(web::scope("/experimental-features").configure(features::configure)); diff --git a/crates/meilisearch/src/routes/multi_search.rs b/crates/meilisearch/src/routes/multi_search.rs index 1515dd707..711bdd03c 100644 --- a/crates/meilisearch/src/routes/multi_search.rs +++ b/crates/meilisearch/src/routes/multi_search.rs @@ -23,7 +23,6 @@ use crate::search::{ }; use crate::search_queue::SearchQueue; - #[derive(OpenApi)] #[openapi( paths(multi_search_with_post), diff --git a/crates/meilisearch/src/routes/swap_indexes.rs b/crates/meilisearch/src/routes/swap_indexes.rs index 9b8b67e63..2d46642c0 100644 --- a/crates/meilisearch/src/routes/swap_indexes.rs +++ b/crates/meilisearch/src/routes/swap_indexes.rs @@ -9,6 +9,7 @@ use meilisearch_types::error::ResponseError; use meilisearch_types::index_uid::IndexUid; use meilisearch_types::tasks::{IndexSwap, KindWithContent}; use serde::Serialize; +use utoipa::{OpenApi, ToSchema}; use super::{get_task_id, is_dry_run, SummarizedTaskView}; use crate::analytics::{Aggregate, Analytics}; @@ -18,13 +19,18 @@ use crate::extractors::authentication::{AuthenticationError, GuardedData}; use crate::extractors::sequential_extractor::SeqHandler; use crate::Opt; +#[derive(OpenApi)] +#[openapi(paths(swap_indexes))] +pub struct SwapIndexesApi; + pub fn configure(cfg: &mut web::ServiceConfig) { cfg.service(web::resource("").route(web::post().to(SeqHandler(swap_indexes)))); } -#[derive(Deserr, Debug, Clone, PartialEq, Eq)] +#[derive(Deserr, Debug, Clone, PartialEq, Eq, ToSchema)] #[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)] pub struct SwapIndexesPayload { + /// Array of the two indexUids to be swapped #[deserr(error = DeserrJsonError, missing_field_error = DeserrJsonError::missing_swap_indexes)] indexes: Vec, } @@ -50,6 +56,37 @@ impl Aggregate for IndexSwappedAnalytics { } } +/// Swap indexes +/// +/// Swap the documents, settings, and task history of two or more indexes. You can only swap indexes in pairs. However, a single request can swap as many index pairs as you wish. +/// Swapping indexes is an atomic transaction: either all indexes are successfully swapped, or none are. +/// Swapping indexA and indexB will also replace every mention of indexA by indexB and vice-versa in the task history. enqueued tasks are left unmodified. +#[utoipa::path( + post, + path = "/", + tag = "Indexes", + security(("Bearer" = ["search", "*"])), + request_body = Vec, + responses( + (status = OK, description = "Task successfully enqueued", body = SummarizedTaskView, content_type = "application/json", example = json!( + { + "taskUid": 3, + "indexUid": null, + "status": "enqueued", + "type": "indexSwap", + "enqueuedAt": "2021-08-12T10:00:00.000000Z" + } + )), + (status = 401, description = "The authorization header is missing", body = ResponseError, content_type = "application/json", example = json!( + { + "message": "The Authorization header is missing. It must use the bearer authorization method.", + "code": "missing_authorization_header", + "type": "auth", + "link": "https://docs.meilisearch.com/errors#missing_authorization_header" + } + )), + ) +)] pub async fn swap_indexes( index_scheduler: GuardedData, Data>, params: AwebJson, DeserrJsonError>,