Skip to content

Commit

Permalink
feat: start using instance_id argument for instance_id header (#616)
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswk authored Jan 8, 2025
1 parent 2421d09 commit cb2df01
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 47 deletions.
33 changes: 26 additions & 7 deletions server/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use unleash_yggdrasil::EngineState;
use crate::cli::RedisMode;
use crate::feature_cache::FeatureCache;
use crate::http::feature_refresher::{FeatureRefreshConfig, FeatureRefresherMode};
use crate::http::unleash_client::new_reqwest_client;
use crate::http::unleash_client::{new_reqwest_client, ClientMetaInformation};
use crate::offline::offline_hotload::{load_bootstrap, load_offline_engine_cache};
use crate::persistence::file::FilePersister;
use crate::persistence::redis::RedisPersister;
Expand Down Expand Up @@ -218,7 +218,10 @@ async fn get_data_source(args: &EdgeArgs) -> Option<Arc<dyn EdgePersistence>> {
None
}

async fn build_edge(args: &EdgeArgs, app_name: &str) -> EdgeResult<EdgeInfo> {
async fn build_edge(
args: &EdgeArgs,
client_meta_information: ClientMetaInformation,
) -> EdgeResult<EdgeInfo> {
if !args.strict {
if !args.dynamic {
error!("You should explicitly opt into either strict or dynamic behavior. Edge has defaulted to dynamic to preserve legacy behavior, however we recommend using strict from now on. Not explicitly opting into a behavior will return an error on startup in a future release");
Expand All @@ -237,13 +240,12 @@ async fn build_edge(args: &EdgeArgs, app_name: &str) -> EdgeResult<EdgeInfo> {
let persistence = get_data_source(args).await;

let http_client = new_reqwest_client(
"unleash_edge".into(),
args.skip_ssl_verification,
args.client_identity.clone(),
args.upstream_certificate_file.clone(),
Duration::seconds(args.upstream_request_timeout),
Duration::seconds(args.upstream_socket_timeout),
app_name.into(),
client_meta_information.clone(),
)?;

let unleash_client = Url::parse(&args.upstream_url.clone())
Expand All @@ -267,7 +269,7 @@ async fn build_edge(args: &EdgeArgs, app_name: &str) -> EdgeResult<EdgeInfo> {
let feature_config = FeatureRefreshConfig::new(
Duration::seconds(args.features_refresh_interval_seconds as i64),
refresher_mode,
app_name.to_string(),
client_meta_information,
);
let feature_refresher = Arc::new(FeatureRefresher::new(
unleash_client,
Expand Down Expand Up @@ -315,7 +317,16 @@ pub async fn build_caches_and_refreshers(args: CliArgs) -> EdgeResult<EdgeInfo>
EdgeMode::Offline(offline_args) => {
build_offline(offline_args).map(|cache| (cache, None, None, None))
}
EdgeMode::Edge(edge_args) => build_edge(&edge_args, &args.app_name).await,
EdgeMode::Edge(edge_args) => {
build_edge(
&edge_args,
ClientMetaInformation {
app_name: args.app_name,
instance_id: args.instance_id,
},
)
.await
}
_ => unreachable!(),
}
}
Expand All @@ -325,6 +336,7 @@ mod tests {
use crate::{
builder::{build_edge, build_offline},
cli::{EdgeArgs, OfflineArgs, TokenHeader},
http::unleash_client::ClientMetaInformation,
};

#[test]
Expand Down Expand Up @@ -375,7 +387,14 @@ mod tests {
streaming: false,
};

let result = build_edge(&args, "test-app").await;
let result = build_edge(
&args,
ClientMetaInformation {
app_name: "test-app".into(),
instance_id: "test-instance-id".into(),
},
)
.await;
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
Expand Down
2 changes: 1 addition & 1 deletion server/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ pub struct CliArgs {
pub mode: EdgeMode,

/// Instance id. Used for metrics reporting.
#[clap(long, env, default_value_t = ulid::Ulid::new().to_string())]
#[clap(long, env, default_value_t = format!("unleash-edge@{}", ulid::Ulid::new()))]
pub instance_id: String,

/// App name. Used for metrics reporting.
Expand Down
4 changes: 2 additions & 2 deletions server/src/client_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ mod tests {

use crate::auth::token_validator::TokenValidator;
use crate::cli::{OfflineArgs, TokenHeader};
use crate::http::unleash_client::UnleashClient;
use crate::http::unleash_client::{UnleashClient, ClientMetaInformation};
use crate::middleware;
use crate::tests::{features_from_disk, upstream_server};
use actix_http::{Request, StatusCode};
Expand Down Expand Up @@ -1011,7 +1011,7 @@ mod tests {
persistence: None,
strict: false,
streaming: false,
app_name: "test-app".into(),
client_meta_information: ClientMetaInformation::test_config(),
});
let token_validator = Arc::new(TokenValidator {
unleash_client: unleash_client.clone(),
Expand Down
36 changes: 19 additions & 17 deletions server/src/http/feature_refresher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::{
types::{ClientFeaturesRequest, ClientFeaturesResponse, EdgeToken, TokenRefresh},
};

use super::unleash_client::UnleashClient;
use super::unleash_client::{ClientMetaInformation, UnleashClient};

fn frontend_token_is_covered_by_tokens(
frontend_token: &EdgeToken,
Expand All @@ -48,7 +48,7 @@ pub struct FeatureRefresher {
pub persistence: Option<Arc<dyn EdgePersistence>>,
pub strict: bool,
pub streaming: bool,
pub app_name: String,
pub client_meta_information: ClientMetaInformation,
}

impl Default for FeatureRefresher {
Expand All @@ -62,21 +62,21 @@ impl Default for FeatureRefresher {
persistence: None,
strict: true,
streaming: false,
app_name: "unleash_edge".into(),
client_meta_information: Default::default(),
}
}
}

fn client_application_from_token_and_name(
token: EdgeToken,
refresh_interval: i64,
app_name: &str,
client_meta_information: ClientMetaInformation,
) -> ClientApplication {
ClientApplication {
app_name: app_name.into(),
app_name: client_meta_information.app_name,
connect_via: None,
environment: token.environment,
instance_id: None,
instance_id: Some(client_meta_information.instance_id),
interval: refresh_interval as u32,
started: Utc::now(),
strategies: vec![],
Expand All @@ -99,19 +99,19 @@ pub enum FeatureRefresherMode {
pub struct FeatureRefreshConfig {
features_refresh_interval: chrono::Duration,
mode: FeatureRefresherMode,
app_name: String,
client_meta_information: ClientMetaInformation,
}

impl FeatureRefreshConfig {
pub fn new(
features_refresh_interval: chrono::Duration,
mode: FeatureRefresherMode,
app_name: String,
client_meta_information: ClientMetaInformation,
) -> Self {
Self {
features_refresh_interval,
mode,
app_name,
client_meta_information,
}
}
}
Expand All @@ -133,7 +133,7 @@ impl FeatureRefresher {
persistence,
strict: config.mode != FeatureRefresherMode::Dynamic,
streaming: config.mode == FeatureRefresherMode::Streaming,
app_name: config.app_name,
client_meta_information: config.client_meta_information,
}
}

Expand Down Expand Up @@ -254,7 +254,7 @@ impl FeatureRefresher {
client_application_from_token_and_name(
token.clone(),
self.refresh_interval.num_seconds(),
&self.app_name,
self.client_meta_information.clone(),
),
)
.await
Expand All @@ -276,7 +276,7 @@ impl FeatureRefresher {
/// This is where we set up a listener per token.
pub async fn start_streaming_features_background_task(
&self,
app_name: String,
client_meta_information: ClientMetaInformation,
custom_headers: Vec<(String, String)>,
) -> anyhow::Result<()> {
use anyhow::Context;
Expand All @@ -289,8 +289,11 @@ impl FeatureRefresher {
let mut es_client_builder = eventsource_client::ClientBuilder::for_url(streaming_url)
.context("Failed to create EventSource client for streaming")?
.header("Authorization", &token.token)?
.header(UNLEASH_APPNAME_HEADER, &app_name)?
.header(UNLEASH_INSTANCE_ID_HEADER, "unleash_edge")?
.header(UNLEASH_APPNAME_HEADER, &client_meta_information.app_name)?
.header(
UNLEASH_INSTANCE_ID_HEADER,
&client_meta_information.instance_id,
)?
.header(
UNLEASH_CLIENT_SPEC_HEADER,
unleash_yggdrasil::SUPPORTED_SPEC_VERSION,
Expand Down Expand Up @@ -557,7 +560,7 @@ mod tests {

use crate::feature_cache::{update_projects_from_feature_update, FeatureCache};
use crate::filters::{project_filter, FeatureFilterSet};
use crate::http::unleash_client::new_reqwest_client;
use crate::http::unleash_client::{new_reqwest_client, ClientMetaInformation};
use crate::tests::features_from_disk;
use crate::tokens::cache_key;
use crate::types::TokenValidationStatus::Validated;
Expand All @@ -580,13 +583,12 @@ mod tests {

fn create_test_client() -> UnleashClient {
let http_client = new_reqwest_client(
"unleash_edge".into(),
false,
None,
None,
Duration::seconds(5),
Duration::seconds(5),
"test-client".into(),
ClientMetaInformation::test_config(),
)
.expect("Failed to create client");

Expand Down
Loading

0 comments on commit cb2df01

Please sign in to comment.