Skip to content

Commit 05015f4

Browse files
committed
feat: add update_toggles endpoint
1 parent e5f5058 commit 05015f4

5 files changed

Lines changed: 65 additions & 19 deletions

File tree

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ tracing-subscriber = { version = "0.3", features = [
5151
] }
5252
url = "2.3"
5353
socketio-rs = { optional = true, version = "0.1.7", default-features = false, features = ["server"] }
54-
feature-probe-server-sdk = { version = "1.2.6", features = [
54+
feature-probe-server-sdk = { version = "1.2.9", features = [
5555
"internal",
5656
"use_tokio",
5757
], default-features = false }

src/http/handler.rs

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use super::{cors_headers, ClientParams, SdkAuthorization};
1+
use super::{cors_headers, ClientParams, SdkAuthorization, ToggleUpdateParams};
22
#[cfg(feature = "unstable")]
3-
use super::{SecretsParams, SegmentUpdateParams, ToggleUpdateParams};
3+
use super::{SecretsParams, SegmentUpdateParams};
44
use crate::FPServerError::{NotFound, NotReady};
55
use crate::{repo::SdkRepository, FPServerError};
66
use axum::{
@@ -14,7 +14,7 @@ use feature_probe_event::{
1414
collector::{EventHandler, FPEventError},
1515
event::PackedData,
1616
};
17-
use feature_probe_server_sdk::{FPUser, Repository, Url};
17+
use feature_probe_server_sdk::{FPUser, Repository, SyncType, Url};
1818
use parking_lot::Mutex;
1919
use reqwest::{
2020
header::{self, AUTHORIZATION, USER_AGENT},
@@ -42,7 +42,6 @@ pub trait HttpHandler {
4242
TypedHeader(SdkAuthorization(sdk_key)): TypedHeader<SdkAuthorization>,
4343
) -> Result<Response, FPServerError>;
4444

45-
#[cfg(feature = "unstable")]
4645
async fn update_toggles(
4746
&self,
4847
Json(params): Json<ToggleUpdateParams>,
@@ -128,6 +127,25 @@ impl HttpHandler for FpHttpHandler {
128127
}
129128
}
130129

130+
async fn update_toggles(
131+
&self,
132+
Json(params): Json<ToggleUpdateParams>,
133+
) -> Result<Response, FPServerError> {
134+
let sdk_key = params.sdk_key;
135+
match self.repo.client_sync_now(&sdk_key, SyncType::Realtime) {
136+
Ok(_sdk_key) => Ok((StatusCode::OK, cors_headers(), "{}").into_response()),
137+
Err(e) => match e {
138+
NotFound(_) => Ok((
139+
StatusCode::BAD_REQUEST,
140+
[(header::CONTENT_TYPE, "application/json")],
141+
"{}",
142+
)
143+
.into_response()),
144+
_ => Err(e),
145+
},
146+
}
147+
}
148+
131149
#[cfg(feature = "unstable")]
132150
async fn update_toggles(
133151
&self,
@@ -272,14 +290,17 @@ impl HttpHandler for LocalFileHttpHandlerForTest {
272290
.into_response())
273291
}
274292

275-
#[cfg(feature = "unstable")]
276293
async fn update_toggles(
277294
&self,
278295
Json(_params): Json<ToggleUpdateParams>,
279296
) -> Result<Response, FPServerError> {
280-
let status = StatusCode::OK;
281-
let body = "";
282-
Ok((status, body).into_response())
297+
let body = "{}".to_owned();
298+
Ok((
299+
StatusCode::OK,
300+
[(header::CONTENT_TYPE, "application/json")],
301+
body,
302+
)
303+
.into_response())
283304
}
284305

285306
#[cfg(feature = "unstable")]

src/http/mod.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ use crate::FPServerError;
1515
use feature_probe_event::collector::{post_events, EventHandler};
1616
use feature_probe_server_sdk::SdkAuthorization;
1717
#[cfg(feature = "unstable")]
18-
use feature_probe_server_sdk::{Segment, Toggle};
18+
use feature_probe_server_sdk::Segment;
19+
use feature_probe_server_sdk::Toggle;
1920
pub use handler::{FpHttpHandler, HttpHandler, LocalFileHttpHandlerForTest};
2021
use serde::Deserialize;
2122
use serde_json::json;
@@ -35,14 +36,14 @@ where
3536
.route("/api/server-sdk/toggles", get(server_sdk_toggles::<T>))
3637
.route("/api/events", post(post_events::<T>).options(client_cors))
3738
.route("/internal/all_secrets", get(all_secrets::<T>)) // not for public network
39+
.route("/internal/update_toggles", post(update_toggles::<T>))
3840
.layer(Extension(handler))
3941
.fallback(handler_404.into_service());
4042

4143
#[cfg(feature = "unstable")]
4244
let app = app
43-
.route("/api/server/toggles", post(update_toggles::<T>))
44-
.route("/api/server/segments", post(update_segments::<T>))
45-
.route("/api/server/check_secrets", post(check_secrets::<T>));
45+
.route("/internal/server/segments", post(update_segments::<T>))
46+
.route("/intelnal/server/check_secrets", post(check_secrets::<T>));
4647

4748
let addr = SocketAddr::from(([0, 0, 0, 0], port));
4849
axum::Server::bind(&addr)
@@ -76,7 +77,6 @@ where
7677
handler.server_sdk_toggles(sdk_key).await
7778
}
7879

79-
#[cfg(feature = "unstable")]
8080
async fn update_toggles<T>(
8181
params: Json<ToggleUpdateParams>,
8282
Extension(handler): Extension<T>,
@@ -131,11 +131,14 @@ pub struct ClientParams {
131131
user: String,
132132
}
133133

134-
#[cfg(feature = "unstable")]
134+
#[allow(unused)]
135135
#[derive(Debug, Deserialize)]
136136
pub struct ToggleUpdateParams {
137137
sdk_key: String,
138+
#[serde(default)]
138139
toggles: HashMap<String, Toggle>,
140+
#[serde(default)]
141+
version: Option<String>,
139142
}
140143

141144
#[cfg(feature = "unstable")]
@@ -190,6 +193,13 @@ mod tests {
190193
use serde_json::Value;
191194
use std::{fs, path::PathBuf, sync::Arc, time::Duration};
192195

196+
#[test]
197+
fn deserialize_toggle_udpate_param() {
198+
let toggle_update_param = r#"{"sdk_key": "key1"}"#;
199+
let p: ToggleUpdateParams = serde_json::from_str(toggle_update_param).unwrap();
200+
assert_eq!(p.sdk_key, "key1");
201+
}
202+
193203
#[tokio::test]
194204
async fn test_fp_server_connect_fp_api() {
195205
let server_sdk_key = "server-sdk-key1".to_owned();

src/repo.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
use crate::realtime::RealtimeSocket;
33
use crate::FPServerError;
44
use crate::{base::ServerConfig, secrets::SecretMapping};
5-
use feature_probe_server_sdk::{EvalDetail, FPConfig, FPUser, FeatureProbe as FPClient, Url};
5+
use feature_probe_server_sdk::{
6+
EvalDetail, FPConfig, FPUser, FeatureProbe as FPClient, SyncType, Url,
7+
};
68
#[cfg(feature = "unstable")]
79
use feature_probe_server_sdk::{Segment, Toggle};
810
use parking_lot::RwLock;
@@ -145,6 +147,16 @@ impl SdkRepository {
145147
self.inner.all_evaluated_string(server_sdk_key, user)
146148
}
147149

150+
pub fn client_sync_now(&self, sdk_key: &str, t: SyncType) -> Result<String, FPServerError> {
151+
let sdk_clients = self.inner.sdk_clients.write();
152+
let client = match sdk_clients.get(sdk_key) {
153+
Some(client) => client,
154+
None => return Err(FPServerError::NotFound(sdk_key.to_string())),
155+
};
156+
client.sync_now(t);
157+
Ok(sdk_key.to_string())
158+
}
159+
148160
#[cfg(test)]
149161
#[cfg(feature = "unstable")]
150162
fn sdk_client(&self, sdk_key: &str) -> Option<FPClient> {
@@ -226,7 +238,7 @@ impl Inner {
226238
mapping.client_sdk_key(server_sdk_key).cloned()
227239
};
228240

229-
client.set_update_callback(Box::new(move |_old, _new| {
241+
client.set_update_callback(Box::new(move |_old, _new, _type| {
230242
let server_key = sdk_key.clone();
231243
let client_key = client_sdk_key.clone();
232244
let socket = realtime_socket.clone();
@@ -323,6 +335,9 @@ mod tests {
323335
let clients = { (repository.inner.sdk_clients.read()).clone() };
324336
assert!(!clients.contains_key(&server_sdk_key));
325337
assert!(clients.contains_key(&server_sdk_key2));
338+
339+
let sdk_key = repository.client_sync_now(&server_sdk_key2, SyncType::Polling);
340+
assert!(sdk_key.is_ok());
326341
}
327342

328343
#[tokio::test]

0 commit comments

Comments
 (0)