Skip to content

Commit

Permalink
fix: accept version in query param for all get config apis
Browse files Browse the repository at this point in the history
  • Loading branch information
pratikmishra356 committed Apr 29, 2024
1 parent 71dd5a9 commit b7c93df
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 44 deletions.
67 changes: 38 additions & 29 deletions crates/context_aware_config/src/api/config/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,38 @@ fn is_not_modified(max_created_at: Option<NaiveDateTime>, req: &HttpRequest) ->
max_created_at.is_some() && parsed_max <= last_modified
}

pub fn generate_config_from_version(
version: Option<Value>,
conn: &mut PooledConnection<ConnectionManager<PgConnection>>,
) -> superposition::Result<Config> {
let config_version = match version {
None => config_versions::config_versions
.select(config_versions::config)
.order_by(config_versions::created_at.desc())
.first::<Value>(conn)
.map_err(|err| {
log::error!("failed to fetch config with error: {}", err);
db_error!(err)
}),
Some(Value::String(version_id)) => config_versions::config_versions
.select(config_versions::config)
.filter(config_versions::id.eq(version_id))
.get_result::<Value>(conn)
.map_err(|err| {
log::error!("failed to fetch config with error: {}", err);
db_error!(err)
}),
Some(val) => {
log::error!("failed to decode version_id as string: {}", val);
return Err(bad_argument!("version_id is not of type string"));
}
}?;

serde_json::from_value::<Config>(config_version).map_err(|err| {
log::error!("failed to decode config: {}", err);
unexpected_error!("failed to decode config")
})
}
pub fn generate_cac(
conn: &mut PooledConnection<ConnectionManager<PgConnection>>,
) -> superposition::Result<Config> {
Expand Down Expand Up @@ -161,8 +193,6 @@ async fn get(
req: HttpRequest,
db_conn: DbConnection,
) -> superposition::Result<HttpResponse> {
// let DbConnection(mut conn) = db_conn;
// let mut conn: PooledConnection<ConnectionManager<PgConnection>> = db_conn;
let DbConnection(mut conn) = db_conn;

let max_created_at = get_max_created_at(&mut conn)
Expand Down Expand Up @@ -193,31 +223,8 @@ async fn get(
);
}

let mut config_version = json!({});
if let Some(Value::String(version_id)) = query_params_map.get("version") {
config_version = config_versions::config_versions
.select(config_versions::config)
.filter(config_versions::id.eq(version_id))
.get_result::<Value>(&mut conn)
.map_err(|err| {
log::error!("failed to fetch config with error: {}", err);
db_error!(err)
})?;
} else {
config_version = config_versions::config_versions
.select(config_versions::config)
.order_by(config_versions::created_at.desc())
.first::<Value>(&mut conn)
.map_err(|err| {
log::error!("failed to fetch config with error: {}", err);
db_error!(err)
})?;
};
let mut config = serde_json::from_value::<Config>(config_version).map_err(|err| {
log::error!("failed to decode config: {}", err);
unexpected_error!("failed to decode config")
})?;
query_params_map.remove("version");
let mut config =
generate_config_from_version(query_params_map.remove("version"), &mut conn)?;
if let Some(prefix) = query_params_map.get("prefix") {
let prefix_list: HashSet<&str> = prefix
.as_str()
Expand Down Expand Up @@ -275,7 +282,8 @@ async fn get_resolved_config(
return Ok(HttpResponse::NotModified().finish());
}

let res = generate_cac(&mut conn)?;
let res =
generate_config_from_version(query_params_map.remove("version"), &mut conn)?;

let cac_client_contexts = res
.contexts
Expand Down Expand Up @@ -348,7 +356,8 @@ async fn get_filtered_config(
.map_or_else(|_| json!(value), |int_val| json!(int_val)),
);
}
let config = generate_cac(&mut conn)?;
let config =
generate_config_from_version(query_params_map.remove("version"), &mut conn)?;
let contexts = config.contexts;

let filtered_context = filter_context(&contexts, &query_params_map)?;
Expand Down
14 changes: 5 additions & 9 deletions crates/context_aware_config/src/api/context/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
},
};
use actix_web::web::Data;
use service_utils::service::types::AppState;
use service_utils::{helpers::generate_snowflake_id, service::types::AppState};

use actix_web::{
delete, get, put,
Expand Down Expand Up @@ -284,8 +284,7 @@ async fn put_handler(
mut db_conn: DbConnection,
user: User,
) -> superposition::Result<Json<PutResp>> {
let mut snowflake_generator = state.snowflake_generator.lock().unwrap();
let version_id = snowflake_generator.real_time_generate();
let version_id = generate_snowflake_id(&state)?.to_string();
db_conn.transaction::<_, superposition::AppError, _>(|transaction_conn| {
let put_response = put(req, transaction_conn, &user)
.map(|resp| Json(resp))
Expand Down Expand Up @@ -371,8 +370,7 @@ async fn move_handler(
mut db_conn: DbConnection,
user: User,
) -> superposition::Result<Json<PutResp>> {
let mut snowflake_generator = state.snowflake_generator.lock().unwrap();
let version_id = snowflake_generator.real_time_generate();
let version_id = generate_snowflake_id(&state)?.to_string();
db_conn.transaction::<_, superposition::AppError, _>(|transaction_conn| {
let move_reponse = r#move(path.into_inner(), req, transaction_conn, &user)
.map(|resp| Json(resp))
Expand Down Expand Up @@ -445,8 +443,7 @@ async fn delete_context(
let DbConnection(mut conn) = db_conn;

let ctx_id = path.into_inner();
let mut snowflake_generator = state.snowflake_generator.lock().unwrap();
let version_id = snowflake_generator.real_time_generate();
let version_id = generate_snowflake_id(&state)?.to_string();
conn.transaction::<_, superposition::AppError, _>(|transaction_conn| {
let deleted_row =
delete(dsl::contexts.filter(dsl::id.eq(&ctx_id))).execute(transaction_conn);
Expand Down Expand Up @@ -474,8 +471,7 @@ async fn bulk_operations(
) -> superposition::Result<Json<Vec<ContextBulkResponse>>> {
use contexts::dsl::contexts;
let DbConnection(mut conn) = db_conn;
let mut snowflake_generator = state.snowflake_generator.lock().unwrap();
let version_id = snowflake_generator.real_time_generate();
let version_id = generate_snowflake_id(&state)?.to_string();

let mut response = Vec::<ContextBulkResponse>::new();
conn.transaction::<_, superposition::AppError, _>(|transaction_conn| {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
extern crate base64;
use super::types::CreateReq;
use service_utils::{bad_argument, unexpected_error, validation_error};
use service_utils::{
bad_argument, helpers::generate_snowflake_id, unexpected_error, validation_error,
};

use superposition_types::{SuperpositionUser, User};

Expand Down Expand Up @@ -140,8 +142,7 @@ async fn create(
)?;
}
}
let mut snowflake_generator = state.snowflake_generator.lock().unwrap();
let version_id = snowflake_generator.real_time_generate();
let version_id = generate_snowflake_id(&state)?.to_string();
conn.transaction::<_, superposition::AppError, _>(|transaction_conn| {
let upsert = diesel::insert_into(default_configs)
.values(&default_config)
Expand Down
4 changes: 2 additions & 2 deletions crates/context_aware_config/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,14 +255,14 @@ pub fn json_to_sorted_string(v: &Value) -> String {
}

pub fn add_config_version(
version_id: i64,
version_id: String,
db_conn: &mut PooledConnection<ConnectionManager<PgConnection>>,
) -> superposition::Result<()> {
use config_versions::dsl::config_versions;
let config = generate_cac(db_conn)?;

let config_version = ConfigVersion {
id: version_id.to_string(),
id: version_id,
config: json!(config),
created_at: Utc::now().naive_utc(),
};
Expand Down
15 changes: 14 additions & 1 deletion crates/service_utils/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use actix_web::{error::ErrorInternalServerError, Error};
use actix_web::{error::ErrorInternalServerError, web::Data, Error};
use anyhow::anyhow;
use log::info;
use serde::de::{self, IntoDeserializer};
use std::{
Expand All @@ -8,6 +9,7 @@ use std::{
};

use super::result;
use crate::service::types::AppState;
use serde_json::{Map, Value};

//WARN Do NOT use this fxn inside api requests, instead add the required
Expand Down Expand Up @@ -198,3 +200,14 @@ pub fn get_variable_name_and_value(

Ok((variable_name, variable_value))
}

pub fn generate_snowflake_id(state: &Data<AppState>) -> result::Result<i64> {
let mut snowflake_generator = state.snowflake_generator.lock().map_err(|e| {
log::error!("snowflake_id generation failed {}", e);
result::AppError::UnexpectedError(anyhow!("snowflake_id generation failed {}", e))
})?;
let id = snowflake_generator.real_time_generate();
// explicitly dropping snowflake_generator so that lock is released and it can be acquired in bulk-operations handler
drop(snowflake_generator);
Ok(id)
}

0 comments on commit b7c93df

Please sign in to comment.