Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Adds client features endpoint #3

Merged
merged 1 commit into from
Jan 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
name: Checkout code
with:
token: ${{ secrets.GH_PUSH_TOKEN }}
fetch-depth: 0
- name: setup git config
run: |
git config user.name "Github Release Bot"
Expand All @@ -27,7 +28,10 @@ jobs:
rustup set auto-self-update disable
rustup toolchain install stable --profile minimal
rustup show
- uses: Swatinem/rust-cache@v2
- name: Use rust cache
uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: Install cargo smart-release
run: |
cargo install cargo-smart-release
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ tokio = { version = "1.24.2", features = ["macros", "rt-multi-thread", "tracing"
tracing = { version = "0.1.37", features = ["log"] }
tracing-opentelemetry = "0.18.0"
tracing-subscriber = { version = "0.3.16", features = ["json", "env-filter"] }
unleash-types = "0.4.0"
unleash-types = "0.4.1"
unleash-yggdrasil = "0.2.0"
5 changes: 3 additions & 2 deletions server/src/client_api.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::offline_provider::OfflineProvider;
use crate::types::{EdgeJsonResult, FeaturesProvider};
use actix_web::get;
use actix_web::web::{self, Json};
use unleash_types::client_features::ClientFeatures;

#[get("/client/features")]
async fn features(features_source: web::Data<OfflineProvider>) -> EdgeJsonResult<ClientFeatures> {
async fn features(
features_source: web::Data<dyn FeaturesProvider>,
) -> EdgeJsonResult<ClientFeatures> {
let client_features = features_source.get_client_features();
Ok(Json(client_features))
}
Expand Down
3 changes: 3 additions & 0 deletions server/src/edge_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
use actix_web::web;

pub fn configure_edge_api(_cfg: &mut web::ServiceConfig) {}
10 changes: 7 additions & 3 deletions server/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use actix_web::{http::StatusCode, HttpResponseBuilder, ResponseError};

#[derive(Debug)]
pub enum EdgeError {
InvalidBackupFile(String),
InvalidBackupFile(String, String),
NoFeaturesFile,
TlsError,
}
Expand All @@ -15,7 +15,11 @@ impl Error for EdgeError {}
impl Display for EdgeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
EdgeError::InvalidBackupFile(msg) => write!(f, "{}", msg),
EdgeError::InvalidBackupFile(path, why_invalid) => write!(
f,
"file at path: {} was invalid due to {}",
path, why_invalid
),
EdgeError::TlsError => write!(f, "Could not configure TLS"),
EdgeError::NoFeaturesFile => write!(f, "No features file located"),
}
Expand All @@ -25,7 +29,7 @@ impl Display for EdgeError {
impl ResponseError for EdgeError {
fn status_code(&self) -> actix_web::http::StatusCode {
match self {
EdgeError::InvalidBackupFile(_) => StatusCode::INTERNAL_SERVER_ERROR,
EdgeError::InvalidBackupFile(_, _) => StatusCode::INTERNAL_SERVER_ERROR,
EdgeError::TlsError => StatusCode::INTERNAL_SERVER_ERROR,
EdgeError::NoFeaturesFile => StatusCode::INTERNAL_SERVER_ERROR,
}
Expand Down
3 changes: 3 additions & 0 deletions server/src/frontend_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
use actix_web::web;

pub fn configure_frontend_api(_cfg: &mut web::ServiceConfig) {}
18 changes: 11 additions & 7 deletions server/src/internal_backstage.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use actix_web::{
get,
web::{self, Json},
HttpRequest,
};
use actix_web_opentelemetry::PrometheusMetricsHandler;
use serde::Serialize;

use crate::types::EdgeJsonResult;
Expand All @@ -20,12 +20,16 @@ impl EdgeStatus {
}
}
#[get("/health")]
pub async fn health(_req: HttpRequest) -> EdgeJsonResult<EdgeStatus> {
pub async fn health() -> EdgeJsonResult<EdgeStatus> {
Ok(Json(EdgeStatus::ok()))
}

pub fn configure_internal_backstage(cfg: &mut web::ServiceConfig) {
cfg.service(health);
pub fn configure_internal_backstage(
cfg: &mut web::ServiceConfig,
metrics_handler: PrometheusMetricsHandler,
) {
cfg.service(health)
.service(web::resource("/metrics").route(web::get().to(metrics_handler)));
}

#[cfg(test)]
Expand All @@ -34,9 +38,9 @@ mod tests {

#[actix_web::test]
async fn test_health_ok() {
let app = test::init_service(App::new().service(
web::scope("/internal-backstage").configure(super::configure_internal_backstage),
))
let app = test::init_service(
App::new().service(web::scope("/internal-backstage").service(super::health)),
)
.await;
let req = test::TestRequest::get()
.uri("/internal-backstage/health")
Expand Down
25 changes: 18 additions & 7 deletions server/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
use std::sync::Arc;

use crate::cli::EdgeMode;
use crate::offline_provider::OfflineProvider;
use actix_web::{middleware, web, App, HttpServer};
use actix_web_opentelemetry::RequestTracing;
use clap::Parser;
use cli::CliArgs;
use types::FeaturesProvider;

mod cli;
mod client_api;
mod edge_api;
mod error;
mod frontend_api;
mod internal_backstage;
mod metrics;
mod offline_provider;
Expand All @@ -24,19 +29,25 @@ async fn main() -> Result<(), anyhow::Error> {
}
.map_err(anyhow::Error::new)?;
let server = HttpServer::new(move || {
let client_provider_arc: Arc<dyn FeaturesProvider> = Arc::new(client_provider.clone());
let client_provider_data = web::Data::from(client_provider_arc);
App::new()
.app_data(web::Data::new(client_provider.clone()))
.app_data(client_provider_data)
.wrap(RequestTracing::new())
.wrap(request_metrics.clone())
.wrap(middleware::Logger::default())
.service(web::scope("/internal-backstage").configure(|service_cfg| {
internal_backstage::configure_internal_backstage(
service_cfg,
metrics_handler.clone(),
)
}))
.service(
web::scope("/internal-backstage")
.configure(internal_backstage::configure_internal_backstage)
.service(
web::resource("/metrics").route(web::get().to(metrics_handler.clone())),
),
web::scope("/api")
.configure(client_api::configure_client_api)
.configure(frontend_api::configure_frontend_api),
)
.service(web::scope("/api").configure(client_api::configure_client_api))
.service(web::scope("/edge").configure(edge_api::configure_edge_api))
});
let server = if args.http.tls.tls_enable {
let config = tls::config(args.clone().http.tls)
Expand Down
14 changes: 4 additions & 10 deletions server/src/offline_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::types::FeaturesProvider;
use std::fs::File;
use std::io::BufReader;
use std::path::PathBuf;
use tracing::info;
use unleash_types::client_features::ClientFeatures;

#[derive(Debug, Clone)]
Expand All @@ -21,18 +20,13 @@ impl OfflineProvider {
pub fn instantiate_provider(
bootstrap_file: Option<PathBuf>,
) -> Result<OfflineProvider, EdgeError> {
info!("Instantiate offline provider");
if let Some(bootstrap) = bootstrap_file {
info!("Opening bootstrap file");
let file = File::open(bootstrap.clone()).map_err(|_| EdgeError::NoFeaturesFile)?;
info!("Opened");
let reader = BufReader::new(file);
info!("Buffered reader");
let client_features: ClientFeatures =
serde_json::from_reader(reader).map_err(|_| {
let path = format!("{}", bootstrap.clone().display());
EdgeError::InvalidBackupFile(path)
})?;
let client_features: ClientFeatures = serde_json::from_reader(reader).map_err(|e| {
let path = format!("{}", bootstrap.clone().display());
EdgeError::InvalidBackupFile(path, e.to_string())
})?;
Ok(OfflineProvider::new(client_features))
} else {
Err(EdgeError::NoFeaturesFile)
Expand Down