mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-29 16:24:26 +01:00
Improve the health route by ensuring lmdb is not down
And refactorize slightly the auth controller.
This commit is contained in:
parent
b4c01581cd
commit
4d308d5237
@ -429,6 +429,13 @@ impl IndexScheduler {
|
|||||||
Ok(this)
|
Ok(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return `Ok(())` if the index scheduler is able to access one of its database.
|
||||||
|
pub fn health(&self) -> Result<()> {
|
||||||
|
let rtxn = self.env.read_txn()?;
|
||||||
|
self.all_tasks.first(&rtxn)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn index_budget(
|
fn index_budget(
|
||||||
tasks_path: &Path,
|
tasks_path: &Path,
|
||||||
base_map_size: usize,
|
base_map_size: usize,
|
||||||
|
@ -34,6 +34,12 @@ impl AuthController {
|
|||||||
Ok(Self { store: Arc::new(store), master_key: master_key.clone() })
|
Ok(Self { store: Arc::new(store), master_key: master_key.clone() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return `Ok(())` if the auth controller is able to access one of its database.
|
||||||
|
pub fn health(&self) -> Result<()> {
|
||||||
|
self.store.health()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the size of the `AuthController` database in bytes.
|
/// Return the size of the `AuthController` database in bytes.
|
||||||
pub fn size(&self) -> Result<u64> {
|
pub fn size(&self) -> Result<u64> {
|
||||||
self.store.size()
|
self.store.size()
|
||||||
|
@ -61,6 +61,13 @@ impl HeedAuthStore {
|
|||||||
Ok(Self { env, keys, action_keyid_index_expiration, should_close_on_drop: true })
|
Ok(Self { env, keys, action_keyid_index_expiration, should_close_on_drop: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return `Ok(())` if the auth store is able to access one of its database.
|
||||||
|
pub fn health(&self) -> Result<()> {
|
||||||
|
let rtxn = self.env.read_txn()?;
|
||||||
|
self.keys.first(&rtxn)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the size in bytes of database
|
/// Return the size in bytes of database
|
||||||
pub fn size(&self) -> Result<u64> {
|
pub fn size(&self) -> Result<u64> {
|
||||||
Ok(self.env.real_disk_size()?)
|
Ok(self.env.real_disk_size()?)
|
||||||
|
@ -86,7 +86,7 @@ impl SegmentAnalytics {
|
|||||||
pub async fn new(
|
pub async fn new(
|
||||||
opt: &Opt,
|
opt: &Opt,
|
||||||
index_scheduler: Arc<IndexScheduler>,
|
index_scheduler: Arc<IndexScheduler>,
|
||||||
auth_controller: AuthController,
|
auth_controller: Arc<AuthController>,
|
||||||
) -> Arc<dyn Analytics> {
|
) -> Arc<dyn Analytics> {
|
||||||
let instance_uid = super::find_user_id(&opt.db_path);
|
let instance_uid = super::find_user_id(&opt.db_path);
|
||||||
let first_time_run = instance_uid.is_none();
|
let first_time_run = instance_uid.is_none();
|
||||||
@ -376,7 +376,11 @@ impl Segment {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(mut self, index_scheduler: Arc<IndexScheduler>, auth_controller: AuthController) {
|
async fn run(
|
||||||
|
mut self,
|
||||||
|
index_scheduler: Arc<IndexScheduler>,
|
||||||
|
auth_controller: Arc<AuthController>,
|
||||||
|
) {
|
||||||
const INTERVAL: Duration = Duration::from_secs(60 * 60); // one hour
|
const INTERVAL: Duration = Duration::from_secs(60 * 60); // one hour
|
||||||
// The first batch must be sent after one hour.
|
// The first batch must be sent after one hour.
|
||||||
let mut interval =
|
let mut interval =
|
||||||
@ -408,10 +412,10 @@ impl Segment {
|
|||||||
async fn tick(
|
async fn tick(
|
||||||
&mut self,
|
&mut self,
|
||||||
index_scheduler: Arc<IndexScheduler>,
|
index_scheduler: Arc<IndexScheduler>,
|
||||||
auth_controller: AuthController,
|
auth_controller: Arc<AuthController>,
|
||||||
) {
|
) {
|
||||||
if let Ok(stats) =
|
if let Ok(stats) =
|
||||||
create_all_stats(index_scheduler.into(), auth_controller, &AuthFilter::default())
|
create_all_stats(index_scheduler.into(), auth_controller.into(), &AuthFilter::default())
|
||||||
{
|
{
|
||||||
// Replace the version number with the prototype name if any.
|
// Replace the version number with the prototype name if any.
|
||||||
let version = if let Some(prototype) = crate::prototype_name() {
|
let version = if let Some(prototype) = crate::prototype_name() {
|
||||||
|
@ -4,6 +4,7 @@ use std::marker::PhantomData;
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
use actix_web::web::Data;
|
||||||
use actix_web::FromRequest;
|
use actix_web::FromRequest;
|
||||||
pub use error::AuthenticationError;
|
pub use error::AuthenticationError;
|
||||||
use futures::future::err;
|
use futures::future::err;
|
||||||
@ -23,7 +24,7 @@ impl<P, D> GuardedData<P, D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn auth_bearer(
|
async fn auth_bearer(
|
||||||
auth: AuthController,
|
auth: Data<AuthController>,
|
||||||
token: String,
|
token: String,
|
||||||
index: Option<String>,
|
index: Option<String>,
|
||||||
data: Option<D>,
|
data: Option<D>,
|
||||||
@ -43,7 +44,7 @@ impl<P, D> GuardedData<P, D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn auth_token(auth: AuthController, data: Option<D>) -> Result<Self, ResponseError>
|
async fn auth_token(auth: Data<AuthController>, data: Option<D>) -> Result<Self, ResponseError>
|
||||||
where
|
where
|
||||||
P: Policy + 'static,
|
P: Policy + 'static,
|
||||||
{
|
{
|
||||||
@ -60,7 +61,7 @@ impl<P, D> GuardedData<P, D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn authenticate(
|
async fn authenticate(
|
||||||
auth: AuthController,
|
auth: Data<AuthController>,
|
||||||
token: String,
|
token: String,
|
||||||
index: Option<String>,
|
index: Option<String>,
|
||||||
) -> Result<Option<AuthFilter>, ResponseError>
|
) -> Result<Option<AuthFilter>, ResponseError>
|
||||||
@ -90,7 +91,7 @@ impl<P: Policy + 'static, D: 'static + Clone> FromRequest for GuardedData<P, D>
|
|||||||
req: &actix_web::HttpRequest,
|
req: &actix_web::HttpRequest,
|
||||||
_payload: &mut actix_web::dev::Payload,
|
_payload: &mut actix_web::dev::Payload,
|
||||||
) -> Self::Future {
|
) -> Self::Future {
|
||||||
match req.app_data::<AuthController>().cloned() {
|
match req.app_data::<Data<AuthController>>().cloned() {
|
||||||
Some(auth) => match req
|
Some(auth) => match req
|
||||||
.headers()
|
.headers()
|
||||||
.get("Authorization")
|
.get("Authorization")
|
||||||
@ -122,10 +123,15 @@ impl<P: Policy + 'static, D: 'static + Clone> FromRequest for GuardedData<P, D>
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Policy {
|
pub trait Policy {
|
||||||
fn authenticate(auth: AuthController, token: &str, index: Option<&str>) -> Option<AuthFilter>;
|
fn authenticate(
|
||||||
|
auth: Data<AuthController>,
|
||||||
|
token: &str,
|
||||||
|
index: Option<&str>,
|
||||||
|
) -> Option<AuthFilter>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod policies {
|
pub mod policies {
|
||||||
|
use actix_web::web::Data;
|
||||||
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
|
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
|
||||||
use meilisearch_auth::{AuthController, AuthFilter, SearchRules};
|
use meilisearch_auth::{AuthController, AuthFilter, SearchRules};
|
||||||
// reexport actions in policies in order to be used in routes configuration.
|
// reexport actions in policies in order to be used in routes configuration.
|
||||||
@ -178,7 +184,7 @@ pub mod policies {
|
|||||||
/// Otherwise, returns an object containing the generated permissions: the search filters to add to a search, and the list of allowed indexes
|
/// Otherwise, returns an object containing the generated permissions: the search filters to add to a search, and the list of allowed indexes
|
||||||
/// (that may contain more indexes than requested).
|
/// (that may contain more indexes than requested).
|
||||||
fn authenticate(
|
fn authenticate(
|
||||||
auth: AuthController,
|
auth: Data<AuthController>,
|
||||||
token: &str,
|
token: &str,
|
||||||
index: Option<&str>,
|
index: Option<&str>,
|
||||||
) -> Option<AuthFilter> {
|
) -> Option<AuthFilter> {
|
||||||
|
@ -88,7 +88,7 @@ fn is_empty_db(db_path: impl AsRef<Path>) -> bool {
|
|||||||
|
|
||||||
pub fn create_app(
|
pub fn create_app(
|
||||||
index_scheduler: Data<IndexScheduler>,
|
index_scheduler: Data<IndexScheduler>,
|
||||||
auth_controller: AuthController,
|
auth_controller: Data<AuthController>,
|
||||||
opt: Opt,
|
opt: Opt,
|
||||||
analytics: Arc<dyn Analytics>,
|
analytics: Arc<dyn Analytics>,
|
||||||
enable_dashboard: bool,
|
enable_dashboard: bool,
|
||||||
@ -136,7 +136,7 @@ enum OnFailure {
|
|||||||
KeepDb,
|
KeepDb,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_meilisearch(opt: &Opt) -> anyhow::Result<(Arc<IndexScheduler>, AuthController)> {
|
pub fn setup_meilisearch(opt: &Opt) -> anyhow::Result<(Arc<IndexScheduler>, Arc<AuthController>)> {
|
||||||
let empty_db = is_empty_db(&opt.db_path);
|
let empty_db = is_empty_db(&opt.db_path);
|
||||||
let (index_scheduler, auth_controller) = if let Some(ref snapshot_path) = opt.import_snapshot {
|
let (index_scheduler, auth_controller) = if let Some(ref snapshot_path) = opt.import_snapshot {
|
||||||
let snapshot_path_exists = snapshot_path.exists();
|
let snapshot_path_exists = snapshot_path.exists();
|
||||||
@ -195,6 +195,7 @@ pub fn setup_meilisearch(opt: &Opt) -> anyhow::Result<(Arc<IndexScheduler>, Auth
|
|||||||
|
|
||||||
// We create a loop in a thread that registers snapshotCreation tasks
|
// We create a loop in a thread that registers snapshotCreation tasks
|
||||||
let index_scheduler = Arc::new(index_scheduler);
|
let index_scheduler = Arc::new(index_scheduler);
|
||||||
|
let auth_controller = Arc::new(auth_controller);
|
||||||
if let ScheduleSnapshot::Enabled(snapshot_delay) = opt.schedule_snapshot {
|
if let ScheduleSnapshot::Enabled(snapshot_delay) = opt.schedule_snapshot {
|
||||||
let snapshot_delay = Duration::from_secs(snapshot_delay);
|
let snapshot_delay = Duration::from_secs(snapshot_delay);
|
||||||
let index_scheduler = index_scheduler.clone();
|
let index_scheduler = index_scheduler.clone();
|
||||||
@ -380,7 +381,7 @@ fn import_dump(
|
|||||||
pub fn configure_data(
|
pub fn configure_data(
|
||||||
config: &mut web::ServiceConfig,
|
config: &mut web::ServiceConfig,
|
||||||
index_scheduler: Data<IndexScheduler>,
|
index_scheduler: Data<IndexScheduler>,
|
||||||
auth: AuthController,
|
auth: Data<AuthController>,
|
||||||
opt: &Opt,
|
opt: &Opt,
|
||||||
analytics: Arc<dyn Analytics>,
|
analytics: Arc<dyn Analytics>,
|
||||||
) {
|
) {
|
||||||
|
@ -74,13 +74,14 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
async fn run_http(
|
async fn run_http(
|
||||||
index_scheduler: Arc<IndexScheduler>,
|
index_scheduler: Arc<IndexScheduler>,
|
||||||
auth_controller: AuthController,
|
auth_controller: Arc<AuthController>,
|
||||||
opt: Opt,
|
opt: Opt,
|
||||||
analytics: Arc<dyn Analytics>,
|
analytics: Arc<dyn Analytics>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let enable_dashboard = &opt.env == "development";
|
let enable_dashboard = &opt.env == "development";
|
||||||
let opt_clone = opt.clone();
|
let opt_clone = opt.clone();
|
||||||
let index_scheduler = Data::from(index_scheduler);
|
let index_scheduler = Data::from(index_scheduler);
|
||||||
|
let auth_controller = Data::from(auth_controller);
|
||||||
|
|
||||||
let http_server = HttpServer::new(move || {
|
let http_server = HttpServer::new(move || {
|
||||||
create_app(
|
create_app(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
|
use actix_web::web::Data;
|
||||||
use actix_web::{web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use deserr::actix_web::{AwebJson, AwebQueryParameter};
|
use deserr::actix_web::{AwebJson, AwebQueryParameter};
|
||||||
use deserr::Deserr;
|
use deserr::Deserr;
|
||||||
@ -35,7 +36,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_api_key(
|
pub async fn create_api_key(
|
||||||
auth_controller: GuardedData<ActionPolicy<{ actions::KEYS_CREATE }>, AuthController>,
|
auth_controller: GuardedData<ActionPolicy<{ actions::KEYS_CREATE }>, Data<AuthController>>,
|
||||||
body: AwebJson<CreateApiKey, DeserrJsonError>,
|
body: AwebJson<CreateApiKey, DeserrJsonError>,
|
||||||
_req: HttpRequest,
|
_req: HttpRequest,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
@ -66,7 +67,7 @@ impl ListApiKeys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list_api_keys(
|
pub async fn list_api_keys(
|
||||||
auth_controller: GuardedData<ActionPolicy<{ actions::KEYS_GET }>, AuthController>,
|
auth_controller: GuardedData<ActionPolicy<{ actions::KEYS_GET }>, Data<AuthController>>,
|
||||||
list_api_keys: AwebQueryParameter<ListApiKeys, DeserrQueryParamError>,
|
list_api_keys: AwebQueryParameter<ListApiKeys, DeserrQueryParamError>,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let paginate = list_api_keys.into_inner().as_pagination();
|
let paginate = list_api_keys.into_inner().as_pagination();
|
||||||
@ -84,7 +85,7 @@ pub async fn list_api_keys(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_api_key(
|
pub async fn get_api_key(
|
||||||
auth_controller: GuardedData<ActionPolicy<{ actions::KEYS_GET }>, AuthController>,
|
auth_controller: GuardedData<ActionPolicy<{ actions::KEYS_GET }>, Data<AuthController>>,
|
||||||
path: web::Path<AuthParam>,
|
path: web::Path<AuthParam>,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let key = path.into_inner().key;
|
let key = path.into_inner().key;
|
||||||
@ -103,7 +104,7 @@ pub async fn get_api_key(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn patch_api_key(
|
pub async fn patch_api_key(
|
||||||
auth_controller: GuardedData<ActionPolicy<{ actions::KEYS_UPDATE }>, AuthController>,
|
auth_controller: GuardedData<ActionPolicy<{ actions::KEYS_UPDATE }>, Data<AuthController>>,
|
||||||
body: AwebJson<PatchApiKey, DeserrJsonError>,
|
body: AwebJson<PatchApiKey, DeserrJsonError>,
|
||||||
path: web::Path<AuthParam>,
|
path: web::Path<AuthParam>,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
@ -123,7 +124,7 @@ pub async fn patch_api_key(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_api_key(
|
pub async fn delete_api_key(
|
||||||
auth_controller: GuardedData<ActionPolicy<{ actions::KEYS_DELETE }>, AuthController>,
|
auth_controller: GuardedData<ActionPolicy<{ actions::KEYS_DELETE }>, Data<AuthController>>,
|
||||||
path: web::Path<AuthParam>,
|
path: web::Path<AuthParam>,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let key = path.into_inner().key;
|
let key = path.into_inner().key;
|
||||||
|
@ -19,7 +19,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
|
|||||||
|
|
||||||
pub async fn create_dump(
|
pub async fn create_dump(
|
||||||
index_scheduler: GuardedData<ActionPolicy<{ actions::DUMPS_CREATE }>, Data<IndexScheduler>>,
|
index_scheduler: GuardedData<ActionPolicy<{ actions::DUMPS_CREATE }>, Data<IndexScheduler>>,
|
||||||
auth_controller: GuardedData<ActionPolicy<{ actions::DUMPS_CREATE }>, AuthController>,
|
auth_controller: GuardedData<ActionPolicy<{ actions::DUMPS_CREATE }>, Data<AuthController>>,
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
analytics: web::Data<dyn Analytics>,
|
analytics: web::Data<dyn Analytics>,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
|
@ -17,7 +17,7 @@ pub fn configure(config: &mut web::ServiceConfig) {
|
|||||||
|
|
||||||
pub async fn get_metrics(
|
pub async fn get_metrics(
|
||||||
index_scheduler: GuardedData<ActionPolicy<{ actions::METRICS_GET }>, Data<IndexScheduler>>,
|
index_scheduler: GuardedData<ActionPolicy<{ actions::METRICS_GET }>, Data<IndexScheduler>>,
|
||||||
auth_controller: GuardedData<ActionPolicy<{ actions::METRICS_GET }>, AuthController>,
|
auth_controller: GuardedData<ActionPolicy<{ actions::METRICS_GET }>, Data<AuthController>>,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let auth_filters = index_scheduler.filters();
|
let auth_filters = index_scheduler.filters();
|
||||||
if !auth_filters.all_indexes_authorized() {
|
if !auth_filters.all_indexes_authorized() {
|
||||||
|
@ -238,7 +238,7 @@ pub struct Stats {
|
|||||||
|
|
||||||
async fn get_stats(
|
async fn get_stats(
|
||||||
index_scheduler: GuardedData<ActionPolicy<{ actions::STATS_GET }>, Data<IndexScheduler>>,
|
index_scheduler: GuardedData<ActionPolicy<{ actions::STATS_GET }>, Data<IndexScheduler>>,
|
||||||
auth_controller: GuardedData<ActionPolicy<{ actions::STATS_GET }>, AuthController>,
|
auth_controller: GuardedData<ActionPolicy<{ actions::STATS_GET }>, Data<AuthController>>,
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
analytics: web::Data<dyn Analytics>,
|
analytics: web::Data<dyn Analytics>,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
@ -253,7 +253,7 @@ async fn get_stats(
|
|||||||
|
|
||||||
pub fn create_all_stats(
|
pub fn create_all_stats(
|
||||||
index_scheduler: Data<IndexScheduler>,
|
index_scheduler: Data<IndexScheduler>,
|
||||||
auth_controller: AuthController,
|
auth_controller: Data<AuthController>,
|
||||||
filters: &meilisearch_auth::AuthFilter,
|
filters: &meilisearch_auth::AuthFilter,
|
||||||
) -> Result<Stats, ResponseError> {
|
) -> Result<Stats, ResponseError> {
|
||||||
let mut last_task: Option<OffsetDateTime> = None;
|
let mut last_task: Option<OffsetDateTime> = None;
|
||||||
@ -318,9 +318,14 @@ struct KeysResponse {
|
|||||||
|
|
||||||
pub async fn get_health(
|
pub async fn get_health(
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
|
index_scheduler: Data<IndexScheduler>,
|
||||||
|
auth_controller: Data<AuthController>,
|
||||||
analytics: web::Data<dyn Analytics>,
|
analytics: web::Data<dyn Analytics>,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
analytics.health_seen(&req);
|
analytics.health_seen(&req);
|
||||||
|
|
||||||
|
index_scheduler.health().unwrap();
|
||||||
|
auth_controller.health().unwrap();
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().json(serde_json::json!({ "status": "available" })))
|
Ok(HttpResponse::Ok().json(serde_json::json!({ "status": "available" })))
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ impl Server {
|
|||||||
> {
|
> {
|
||||||
actix_web::test::init_service(create_app(
|
actix_web::test::init_service(create_app(
|
||||||
self.service.index_scheduler.clone().into(),
|
self.service.index_scheduler.clone().into(),
|
||||||
self.service.auth.clone(),
|
self.service.auth.clone().into(),
|
||||||
self.service.options.clone(),
|
self.service.options.clone(),
|
||||||
analytics::MockAnalytics::new(&self.service.options),
|
analytics::MockAnalytics::new(&self.service.options),
|
||||||
true,
|
true,
|
||||||
|
@ -13,7 +13,7 @@ use crate::common::encoder::Encoder;
|
|||||||
|
|
||||||
pub struct Service {
|
pub struct Service {
|
||||||
pub index_scheduler: Arc<IndexScheduler>,
|
pub index_scheduler: Arc<IndexScheduler>,
|
||||||
pub auth: AuthController,
|
pub auth: Arc<AuthController>,
|
||||||
pub options: Opt,
|
pub options: Opt,
|
||||||
pub api_key: Option<String>,
|
pub api_key: Option<String>,
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ impl Service {
|
|||||||
pub async fn request(&self, mut req: test::TestRequest) -> (Value, StatusCode) {
|
pub async fn request(&self, mut req: test::TestRequest) -> (Value, StatusCode) {
|
||||||
let app = test::init_service(create_app(
|
let app = test::init_service(create_app(
|
||||||
self.index_scheduler.clone().into(),
|
self.index_scheduler.clone().into(),
|
||||||
self.auth.clone(),
|
self.auth.clone().into(),
|
||||||
self.options.clone(),
|
self.options.clone(),
|
||||||
analytics::MockAnalytics::new(&self.options),
|
analytics::MockAnalytics::new(&self.options),
|
||||||
true,
|
true,
|
||||||
|
Loading…
Reference in New Issue
Block a user