fix requested changes

This commit is contained in:
Quentin de Quelen 2020-04-24 15:00:52 +02:00 committed by qdequele
parent ea308eb798
commit 36c7fd0cf1
No known key found for this signature in database
GPG Key ID: B3F0A000EBF11745
12 changed files with 68 additions and 63 deletions

View File

@ -14,6 +14,13 @@ name = "meilisearch"
path = "src/main.rs"
[dependencies]
actix-cors = "0.2.0"
actix-files = "0.2.1"
actix-http = "1"
actix-rt = "1"
actix-service = "1.0.5"
actix-web = "2"
actix-web-macros = "0.1.0"
chrono = { version = "0.4.11", features = ["serde"] }
crossbeam-channel = "0.4.2"
env_logger = "0.7.1"
@ -34,20 +41,13 @@ serde_json = { version = "1.0.50", features = ["preserve_order"] }
serde_qs = "0.5.2"
sha2 = "0.8.1"
siphasher = "0.3.2"
slice-group-by = "0.2.6"
structopt = "0.3.12"
sysinfo = "0.12.0"
tokio = { version = "0.2.18", features = ["macros"] }
ureq = { version = "0.12.0", features = ["tls"], default-features = false }
walkdir = "2.3.1"
whoami = "0.8.1"
slice-group-by = "0.2.6"
actix-rt = "1"
actix-web = "2"
actix-http = "1"
actix-files = "0.2.1"
actix-cors = "0.2.0"
actix-service = "1.0.5"
actix-web-macros = "0.1.0"
tokio = { version = "0.2.18", features = ["macros"] }
[dev-dependencies]
http-service = "0.4.0"

View File

@ -37,7 +37,7 @@ pub struct DataInner {
pub server_pid: Pid,
}
#[derive(Default, Clone)]
#[derive(Clone)]
pub struct ApiKeys {
pub public: Option<String>,
pub private: Option<String>,

View File

@ -91,11 +91,11 @@ impl fmt::Display for ResponseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::BadParameter(param, err) => write!(f, "Url parameter {} error: {}", param, err),
Self::BadRequest(err) => write!(f, "{}", err),
Self::BadRequest(err) => f.write_str(err),
Self::CreateIndex(err) => write!(f, "Impossible to create index; {}", err),
Self::DocumentNotFound(document_id) => write!(f, "Document with id {} not found", document_id),
Self::IndexNotFound(index_uid) => write!(f, "Index {} not found", index_uid),
Self::Internal(err) => write!(f, "{}", err),
Self::Internal(err) => f.write_str(err),
Self::InvalidIndexUid => f.write_str("Index must have a valid uid; Index uid can be of type integer or string only composed of alphanumeric characters, hyphens (-) and underscores (_)."),
Self::InvalidToken(err) => write!(f, "Invalid API key: {}", err),
Self::Maintenance => f.write_str("Server is in maintenance, please try again later"),

View File

@ -33,7 +33,7 @@ where
fn new_transform(&self, service: S) -> Self::Future {
ok(LoggingMiddleware {
acl: (*self).clone(),
acl: self.clone(),
service: Rc::new(RefCell::new(service)),
})
}
@ -61,6 +61,8 @@ where
fn call(&mut self, req: ServiceRequest) -> Self::Future {
let mut svc = self.service.clone();
// This unwrap is left because this error should never appear. If that's the case, then
// it means that actix-web has an issue or someone changes the type `Data`.
let data = req.app_data::<Data>().unwrap();
if data.api_keys.master.is_none() {

View File

@ -18,8 +18,6 @@ static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
#[actix_rt::main]
async fn main() -> Result<(), MainError> {
let opt = Opt::from_args();
// let local = tokio::task::LocalSet::new();
// let _sys = actix_rt::System::run_in_tokio("server", &local);
match opt.env.as_ref() {
"production" => {

View File

@ -13,7 +13,7 @@ use crate::Data;
type Document = IndexMap<String, Value>;
#[derive(Default, Deserialize)]
#[derive(Deserialize)]
struct DocumentParam {
index_uid: String,
document_id: String,
@ -46,7 +46,7 @@ async fn get_document(
let reader = data.db.main_read_txn()?;
let response = index
.document::<Document>(&reader, None, document_id)?
.document(&reader, None, document_id)?
.ok_or(ResponseError::document_not_found(&path.document_id))?;
Ok(HttpResponse::Ok().json(response))
@ -78,7 +78,7 @@ async fn delete_document(
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
#[derive(Default, Deserialize)]
#[derive(Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct BrowseQuery {
offset: Option<usize>,
@ -116,9 +116,11 @@ async fn get_all_documents(
.as_ref()
.map(|a| a.split(',').collect());
let mut response = Vec::<Document>::new();
let mut response = Vec::new();
for document_id in documents_ids {
if let Ok(Some(document)) = index.document(&reader, attributes.as_ref(), document_id) {
if let Ok(Some(document)) =
index.document::<Document>(&reader, attributes.as_ref(), document_id)
{
response.push(document);
}
}
@ -135,7 +137,7 @@ fn find_primary_key(document: &IndexMap<String, Value>) -> Option<String> {
None
}
#[derive(Default, Deserialize)]
#[derive(Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct UpdateDocumentsQuery {
primary_key: Option<String>,
@ -171,7 +173,9 @@ async fn update_multiple_documents(
let mut writer = data.db.main_write_txn()?;
schema.set_primary_key(&id)?;
schema
.set_primary_key(&id)
.map_err(ResponseError::bad_request)?;
index.main.put_schema(&mut writer, &schema)?;
writer.commit()?;
}

View File

@ -157,13 +157,13 @@ async fn create_index(
));
}
let uid = match body.uid.clone() {
let uid = match &body.uid {
Some(uid) => {
if uid
.chars()
.all(|x| x.is_ascii_alphanumeric() || x == '-' || x == '_')
{
uid
uid.to_owned()
} else {
return Err(ResponseError::InvalidIndexUid);
}
@ -183,8 +183,8 @@ async fn create_index(
let mut writer = data.db.main_write_txn()?;
let name = body.name.clone().unwrap_or(uid.clone());
created_index.main.put_name(&mut writer, &name)?;
let name = body.name.as_ref().unwrap_or(&uid);
created_index.main.put_name(&mut writer, name)?;
let created_at = created_index
.main
@ -208,7 +208,7 @@ async fn create_index(
writer.commit()?;
Ok(HttpResponse::Created().json(IndexResponse {
name,
name: name.to_string(),
uid,
created_at,
updated_at,
@ -246,8 +246,8 @@ async fn update_index(
let mut writer = data.db.main_write_txn()?;
if let Some(name) = body.name.clone() {
index.main.put_name(&mut writer, &name)?;
if let Some(name) = &body.name {
index.main.put_name(&mut writer, name)?;
}
if let Some(id) = body.primary_key.clone() {
@ -314,7 +314,7 @@ async fn delete_index(
Ok(HttpResponse::NoContent().finish())
}
#[derive(Default, Deserialize)]
#[derive(Deserialize)]
struct UpdateParam {
index_uid: String,
update_id: u64,

View File

@ -1,4 +1,5 @@
use actix_web::web;
use actix_web::HttpResponse;
use actix_web_macros::get;
use serde::Serialize;
@ -9,16 +10,16 @@ pub fn services(cfg: &mut web::ServiceConfig) {
cfg.service(list);
}
#[derive(Default, Serialize)]
#[derive(Serialize)]
struct KeysResponse {
private: Option<String>,
public: Option<String>,
}
#[get("/keys", wrap = "Authentication::Admin")]
async fn list(data: web::Data<Data>) -> web::Json<KeysResponse> {
async fn list(data: web::Data<Data>) -> HttpResponse {
let api_keys = data.api_keys.clone();
web::Json(KeysResponse {
HttpResponse::Ok().json(KeysResponse {
private: api_keys.private,
public: api_keys.public,
})

View File

@ -11,12 +11,12 @@ pub mod stats;
pub mod stop_words;
pub mod synonym;
#[derive(Default, Deserialize)]
#[derive(Deserialize)]
pub struct IndexParam {
index_uid: String,
}
#[derive(Default, Serialize)]
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct IndexUpdateResponse {
pub update_id: u64,

View File

@ -2,11 +2,12 @@ use std::collections::{HashSet, HashMap};
use log::warn;
use actix_web::web;
use actix_web::HttpResponse;
use actix_web_macros::get;
use serde::Deserialize;
use crate::error::ResponseError;
use crate::helpers::meilisearch::{IndexSearchExt, SearchResult};
use crate::helpers::meilisearch::IndexSearchExt;
use crate::helpers::Authentication;
use crate::routes::IndexParam;
use crate::Data;
@ -34,7 +35,7 @@ async fn search_with_url_query(
data: web::Data<Data>,
path: web::Path<IndexParam>,
params: web::Query<SearchQuery>,
) -> Result<web::Json<SearchResult>, ResponseError> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
@ -137,5 +138,5 @@ async fn search_with_url_query(
}
}
Ok(web::Json(search_builder.search(&reader)?))
Ok(HttpResponse::Ok().json(search_builder.search(&reader)?))
}

View File

@ -94,14 +94,14 @@ async fn get_all(
let searchable_attributes = schema.clone().map(|s| {
s.indexed_name()
.iter()
.map(|s| (*s).to_string())
.map(|s| s.to_string())
.collect::<Vec<String>>()
});
let displayed_attributes = schema.clone().map(|s| {
s.displayed_name()
.iter()
.map(|s| (*s).to_string())
.map(|s| s.to_string())
.collect::<HashSet<String>>()
});
@ -312,7 +312,7 @@ async fn get_searchable(
let reader = data.db.main_read_txn()?;
let schema = index.main.schema(&reader)?;
let searchable_attributes: Option<Vec<String>> =
schema.map(|s| s.indexed_name().iter().map(|i| (*i).to_string()).collect());
schema.map(|s| s.indexed_name().iter().map(|i| i.to_string()).collect());
Ok(HttpResponse::Ok().json(searchable_attributes))
}
@ -385,12 +385,8 @@ async fn get_displayed(
let schema = index.main.schema(&reader)?;
let displayed_attributes: Option<HashSet<String>> = schema.map(|s| {
s.displayed_name()
.iter()
.map(|i| (*i).to_string())
.collect()
});
let displayed_attributes: Option<HashSet<String>> =
schema.map(|s| s.displayed_name().iter().map(|i| i.to_string()).collect());
Ok(HttpResponse::Ok().json(displayed_attributes))
}

View File

@ -1,6 +1,7 @@
use std::collections::HashMap;
use actix_web::web;
use actix_web::HttpResponse;
use actix_web_macros::get;
use chrono::{DateTime, Utc};
use log::error;
@ -34,7 +35,7 @@ struct IndexStatsResponse {
async fn index_stats(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> Result<web::Json<IndexStatsResponse>, ResponseError> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
@ -48,11 +49,13 @@ async fn index_stats(
let update_reader = data.db.update_read_txn()?;
let is_indexing = data
.is_indexing(&update_reader, &path.index_uid)?
.unwrap_or_default();
let is_indexing =
data.is_indexing(&update_reader, &path.index_uid)?
.ok_or(ResponseError::internal(
"Impossible to know if the database is indexing",
))?;
Ok(web::Json(IndexStatsResponse {
Ok(HttpResponse::Ok().json(IndexStatsResponse {
number_of_documents,
is_indexing,
fields_frequency,
@ -68,7 +71,7 @@ struct StatsResult {
}
#[get("/stats", wrap = "Authentication::Private")]
async fn get_stats(data: web::Data<Data>) -> Result<web::Json<StatsResult>, ResponseError> {
async fn get_stats(data: web::Data<Data>) -> Result<HttpResponse, ResponseError> {
let mut index_list = HashMap::new();
let reader = data.db.main_read_txn()?;
@ -83,9 +86,9 @@ async fn get_stats(data: web::Data<Data>) -> Result<web::Json<StatsResult>, Resp
let fields_frequency = index.main.fields_frequency(&reader)?.unwrap_or_default();
let is_indexing = data
.is_indexing(&update_reader, &index_uid)?
.unwrap_or_default();
let is_indexing = data.is_indexing(&update_reader, &index_uid)?.ok_or(
ResponseError::internal("Impossible to know if the database is indexing"),
)?;
let response = IndexStatsResponse {
number_of_documents,
@ -110,7 +113,7 @@ async fn get_stats(data: web::Data<Data>) -> Result<web::Json<StatsResult>, Resp
let last_update = data.last_update(&reader)?;
Ok(web::Json(StatsResult {
Ok(HttpResponse::Ok().json(StatsResult {
database_size,
last_update,
indexes: index_list,
@ -126,8 +129,8 @@ struct VersionResponse {
}
#[get("/version", wrap = "Authentication::Private")]
async fn get_version() -> web::Json<VersionResponse> {
web::Json(VersionResponse {
async fn get_version() -> HttpResponse {
HttpResponse::Ok().json(VersionResponse {
commit_sha: env!("VERGEN_SHA").to_string(),
build_date: env!("VERGEN_BUILD_TIMESTAMP").to_string(),
pkg_version: env!("CARGO_PKG_VERSION").to_string(),
@ -195,7 +198,7 @@ impl SysInfo {
}
#[get("/sys-info", wrap = "Authentication::Private")]
async fn get_sys_info(data: web::Data<Data>) -> web::Json<SysInfo> {
async fn get_sys_info(data: web::Data<Data>) -> HttpResponse {
let mut sys = System::new();
let mut info = SysInfo::new();
@ -226,7 +229,7 @@ async fn get_sys_info(data: web::Data<Data>) -> web::Json<SysInfo> {
}
sys.refresh_all();
web::Json(info)
HttpResponse::Ok().json(info)
}
#[derive(Serialize)]
@ -290,7 +293,7 @@ impl SysInfoPretty {
}
#[get("/sys-info/pretty", wrap = "Authentication::Private")]
async fn get_sys_info_pretty(data: web::Data<Data>) -> web::Json<SysInfoPretty> {
async fn get_sys_info_pretty(data: web::Data<Data>) -> HttpResponse {
let mut sys = System::new();
let mut info = SysInfoPretty::new();
@ -328,5 +331,5 @@ async fn get_sys_info_pretty(data: web::Data<Data>) -> web::Json<SysInfoPretty>
sys.refresh_all();
web::Json(info)
HttpResponse::Ok().json(info)
}