Skip to main content

opensearch_client/
lib.rs

1//! # OpenSearch Client for Rust
2//!
3//! A comprehensive Rust client library for OpenSearch with strongly typed APIs and async support.
4//!
5//! ## Features
6//!
7//! - **Strongly Typed**: Type-safe APIs with compile-time guarantees
8//! - **Async/Await**: Built on tokio for high-performance async operations
9//! - **Comprehensive Coverage**: Support for search, indices, cluster management, and more
10//! - **Modular Design**: Feature flags for optional functionality
11//! - **Production Ready**: Includes retry logic, connection pooling, and error handling
12//!
13//! ## Quick Start
14//!
15//! ```rust
16//! use opensearch_client::{ConfigurationBuilder, OsClient};
17//! use opensearch_dsl::*;
18//! use url::Url;
19//!
20//! #[tokio::main]
21//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
22//!     // Create client configuration
23//!     let config = ConfigurationBuilder::new()
24//!         .base_url(Url::parse("http://localhost:9200")?)
25//!         .basic_auth("admin".to_string(), "admin".to_string())
26//!         .build();
27//!     
28//!     let client = OsClient::new(config);
29//!     
30//!     // Perform a search
31//!     let search = Search::new()
32//!         .query(Query::match_("title", "opensearch"))
33//!         .size(10);
34//!     
35//!     let response = client.search(&search).index("my_index").await?;
36//!     
37//!     for hit in response.hits.hits {
38//!         println!("Document: {:?}", hit.source);
39//!     }
40//!     
41//!     Ok(())
42//! }
43//! ```
44//!
45//! ## Module Organization
46//!
47//! - [`search`] - Search operations and query building
48//! - [`indices`] - Index management and operations
49//! - [`cluster`] - Cluster health and management
50//! - [`bulk`] - Bulk operations for efficient data processing
51//! - [`dsl`] - Re-export of opensearch-dsl for query building
52//!
53//! ## Feature Flags
54//!
55//! Enable only the features you need:
56//!
57//! ```toml
58//! [dependencies]
59//! opensearch-client = { version = "0.3", features = [
60//!     "search",
61//!     "indices",
62//!     "cluster"
63//! ] }
64//! ```
65
66#![allow(unused_imports)]
67#![allow(clippy::too_many_arguments)]
68
69pub extern crate opensearch_dsl;
70extern crate reqwest;
71extern crate serde;
72extern crate serde_json;
73extern crate serde_repr;
74extern crate url;
75use std::sync::OnceLock;
76
77/// Re-export of opensearch-dsl for convenient access to query building types.
78///
79/// This allows users to access DSL types like `Query`, `Search`, and `Aggregation`
80/// without needing a separate import.
81pub use opensearch_dsl as dsl;
82
83mod bulk;
84mod bulker;
85
86pub use bulk::*;
87pub use bulker::*;
88
89/// Asynchronous search operations for long-running queries.
90#[cfg(feature = "asynchronous_search")]
91pub mod asynchronous_search;
92
93/// Cluster and index information in a compact, tabular format.
94#[cfg(feature = "cat")]
95pub mod cat;
96
97/// Cluster-level operations including health monitoring and settings management.
98#[cfg(feature = "cluster")]
99pub mod cluster;
100
101/// Common types and utilities used across the client.
102pub mod common;
103
104/// Core client functionality and configuration.
105pub mod core;
106
107/// Operations for managing dangling indices.
108#[cfg(feature = "dangling_indices")]
109pub mod dangling_indices;
110#[cfg(feature = "indices")]
111pub mod indices;
112#[cfg(feature = "ingest")]
113pub mod ingest;
114#[cfg(feature = "insights")]
115pub mod insights;
116#[cfg(feature = "ism")]
117pub mod ism;
118#[cfg(feature = "knn")]
119pub mod knn;
120#[cfg(feature = "ml")]
121pub mod ml;
122#[cfg(feature = "nodes")]
123pub mod nodes;
124#[cfg(feature = "notifications")]
125pub mod notifications;
126#[cfg(feature = "observability")]
127pub mod observability;
128#[cfg(feature = "ppl")]
129pub mod ppl;
130// #[cfg(feature = "query")]
131pub mod query;
132#[cfg(feature = "remote_store")]
133pub mod remote_store;
134#[cfg(feature = "replication")]
135pub mod replication;
136#[cfg(feature = "rollups")]
137pub mod rollups;
138pub mod search;
139#[cfg(feature = "security")]
140pub mod security;
141#[cfg(feature = "snapshot")]
142pub mod snapshot;
143#[cfg(feature = "sql")]
144pub mod sql;
145// #[cfg(feature = "tasks")]
146pub mod tasks;
147#[cfg(feature = "transforms")]
148pub mod transforms;
149
150mod client;
151#[cfg(feature = "tools")]
152pub mod tools;
153
154pub use client::configuration::Configuration;
155pub use client::configuration::ConfigurationBuilder;
156pub use client::Error;
157pub use client::OsClient;
158pub use client::ResponseContent;
159
160mod document;
161pub use document::*;
162pub use opensearch_macro::OpenSearch;
163static OPENSEARCH: OnceLock<OsClient> = OnceLock::new();
164
165pub fn set_opensearch(client: OsClient) -> Result<(), OsClient> {
166    OPENSEARCH
167        .set(client)
168        .map_err(|_| OsClient::from_environment().unwrap())
169}
170
171pub fn get_opensearch() -> &'static OsClient {
172    OPENSEARCH.get_or_init(|| {
173        OsClient::from_environment().expect("Failed to load OPENSEARCH configuration")
174    })
175}
176
177#[cfg(test)]
178mod tests {
179
180    use std::path::PathBuf;
181
182    use serde::de::DeserializeOwned;
183
184    use super::*;
185    fn load_entity<T: DeserializeOwned>(name: &str) -> T {
186        let filename = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(format!("tests/base/{name}"));
187        let text = std::fs::read_to_string(filename).unwrap();
188        serde_json::from_str(&text).unwrap()
189    }
190
191    #[test]
192    fn test_document_delete_response() {
193        let decoded: crate::common::DocumentDeleteResponse =
194            load_entity("document_delete.response.json");
195        assert_eq!(decoded.id, String::from("MzcIJX8BA7mbufL6DOwl"));
196    }
197}