From 513dd60d718f186c4e57d633d9e2ba3fe4dbfe64 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Mon, 25 Nov 2024 15:15:57 +0100 Subject: [PATCH 1/3] impl in progress --- applications/tari_swarm_daemon/Cargo.toml | 2 +- .../src/webserver/templates.rs | 81 +++++++++++++------ 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/applications/tari_swarm_daemon/Cargo.toml b/applications/tari_swarm_daemon/Cargo.toml index c8bd01c1e..84e7ed14d 100644 --- a/applications/tari_swarm_daemon/Cargo.toml +++ b/applications/tari_swarm_daemon/Cargo.toml @@ -44,7 +44,7 @@ tokio = { workspace = true, features = ["rt-multi-thread", "macros", "signal", " toml = "0.8.12" tonic = { workspace = true } tower-http = { workspace = true, features = ["fs", "cors"] } -url = { workspace = true } +url = { workspace = true, features = ["default", "serde"] } [target.'cfg(unix)'.dependencies] nix = { version = "0.28.0", default-features = false, features = ["signal"] } diff --git a/applications/tari_swarm_daemon/src/webserver/templates.rs b/applications/tari_swarm_daemon/src/webserver/templates.rs index 0d0329160..d745b08ae 100644 --- a/applications/tari_swarm_daemon/src/webserver/templates.rs +++ b/applications/tari_swarm_daemon/src/webserver/templates.rs @@ -3,6 +3,7 @@ use std::{io, sync::Arc}; +use axum::extract::Query; use axum::{ extract::{multipart::MultipartError, Multipart}, http::StatusCode, @@ -10,6 +11,7 @@ use axum::{ Extension, }; use log::{error, info}; +use serde::{Deserialize, Serialize}; use tari_crypto::tari_utilities::hex; use tari_dan_engine::wasm::WasmModule; use tari_engine_types::calculate_template_binary_hash; @@ -18,14 +20,35 @@ use url::Url; use crate::{process_manager::TemplateData, webserver::context::HandlerContext}; +fn register_template_default() -> bool { + true +} + +#[derive(Deserialize)] +struct UploadQueryParams { + #[serde(default = "register_template_default")] + register_template: bool, +} + +#[derive(Serialize)] +struct UploadResponse { + success: bool, + template_url: Option, + error: String, +} + pub async fn upload( Extension(context): Extension>, mut value: Multipart, -) -> Result<(), UploadError> { + query_params: Query, +) -> Result { let Some(field) = value.next_field().await? else { error!("🌐 Upload template: no field found"); - // TODO: return error - return Ok(()); + return Ok(UploadResponse { + success: false, + template_url: None, + error: "No multipart file field found".to_string(), + }); }; let name = field.file_name().unwrap_or("unnamed-template").to_string(); @@ -41,28 +64,38 @@ pub async fn upload( file.write_all(&bytes).await?; info!("🌐 Upload template {} bytes", bytes.len()); - let data = TemplateData { - name, - version: 0, - contents_hash: hash, - contents_url: Url::parse(&format!( - "http://localhost:{}/templates/{}", - context.config().webserver.bind_address.port(), - dest_file - )) - .unwrap(), - }; + let template_url = Url::parse(&format!( + "http://localhost:{}/templates/{}", + context.config().webserver.bind_address.port(), + dest_file + )) + .unwrap(); - match context.process_manager().register_template(data).await { - Ok(()) => { - info!("🌐 Registered template"); - Ok(()) - }, - Err(err) => { - error!("🌐 Registering template failed: {}", err); - Err(err.into()) - }, + if query_params.register_template { + let data = TemplateData { + name, + version: 0, + contents_hash: hash, + contents_url: template_url, + }; + + return match context.process_manager().register_template(data).await { + Ok(()) => { + info!("🌐 Registered template"); + Ok(UploadResponse { + success: true, + template_url: Some(template_url.clone()), + error: String::new(), + }) + } + Err(err) => { + error!("🌐 Registering template failed: {}", err); + Err(err.into()) + } + }; } + + Ok(UploadResponse { template_url }) } #[derive(Debug, thiserror::Error)] @@ -91,7 +124,7 @@ impl IntoResponse for UploadError { UploadError::MultiPartError(err) => err.into_response(), UploadError::Other(err) => { (StatusCode::INTERNAL_SERVER_ERROR, format!("Upload error: {}", err)).into_response() - }, + } } } } From 2cd743b422099651a892c6ff3aacd852655579ea Mon Sep 17 00:00:00 2001 From: ksrichard Date: Tue, 26 Nov 2024 15:08:15 +0100 Subject: [PATCH 2/3] Modified endpoint to allow uploading templates without registering --- .../tari_swarm_daemon/src/webserver/server.rs | 6 +- .../src/webserver/templates.rs | 63 ++++++++++++------- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/applications/tari_swarm_daemon/src/webserver/server.rs b/applications/tari_swarm_daemon/src/webserver/server.rs index 8bc14afc9..03301adfc 100644 --- a/applications/tari_swarm_daemon/src/webserver/server.rs +++ b/applications/tari_swarm_daemon/src/webserver/server.rs @@ -132,16 +132,16 @@ async fn call_handler( where TReq: DeserializeOwned, TResp: Serialize, - H: for<'a> JrpcHandler<'a, TReq, Response = TResp>, + H: for<'a> JrpcHandler<'a, TReq, Response=TResp>, { let answer_id = value.get_answer_id(); let params = value.parse_params().inspect_err(|e| match &e.result { JsonRpcAnswer::Result(_) => { unreachable!("parse_params() error should not return a result") - }, + } JsonRpcAnswer::Error(e) => { warn!(target: LOG_TARGET, "🌐 JSON-RPC params error: {}", e); - }, + } })?; let resp = handler .handle(&context, params) diff --git a/applications/tari_swarm_daemon/src/webserver/templates.rs b/applications/tari_swarm_daemon/src/webserver/templates.rs index d745b08ae..376ccb54e 100644 --- a/applications/tari_swarm_daemon/src/webserver/templates.rs +++ b/applications/tari_swarm_daemon/src/webserver/templates.rs @@ -4,12 +4,7 @@ use std::{io, sync::Arc}; use axum::extract::Query; -use axum::{ - extract::{multipart::MultipartError, Multipart}, - http::StatusCode, - response::IntoResponse, - Extension, -}; +use axum::{extract::{multipart::MultipartError, Multipart}, http::StatusCode, response::IntoResponse, Extension, Json}; use log::{error, info}; use serde::{Deserialize, Serialize}; use tari_crypto::tari_utilities::hex; @@ -25,30 +20,48 @@ fn register_template_default() -> bool { } #[derive(Deserialize)] -struct UploadQueryParams { +pub struct UploadQueryParams { #[serde(default = "register_template_default")] register_template: bool, } -#[derive(Serialize)] -struct UploadResponse { +#[derive(Serialize, Deserialize)] +pub struct UploadResponse { success: bool, template_url: Option, error: String, } +impl UploadResponse { + pub fn success(template_url: Url) -> Self { + Self { + success: true, + template_url: Some(template_url), + error: String::new(), + } + } + + pub fn failure(error: String) -> Self { + Self { + success: false, + template_url: None, + error, + } + } +} + pub async fn upload( Extension(context): Extension>, - mut value: Multipart, query_params: Query, -) -> Result { + mut value: Multipart, +) -> Result, UploadError> { let Some(field) = value.next_field().await? else { error!("🌐 Upload template: no field found"); - return Ok(UploadResponse { - success: false, - template_url: None, - error: "No multipart file field found".to_string(), - }); + return Ok( + Json( + UploadResponse::failure("No multipart file field found".to_string()) + ) + ); }; let name = field.file_name().unwrap_or("unnamed-template").to_string(); @@ -76,17 +89,17 @@ pub async fn upload( name, version: 0, contents_hash: hash, - contents_url: template_url, + contents_url: template_url.clone(), }; return match context.process_manager().register_template(data).await { Ok(()) => { info!("🌐 Registered template"); - Ok(UploadResponse { - success: true, - template_url: Some(template_url.clone()), - error: String::new(), - }) + Ok( + Json( + UploadResponse::success(template_url) + ) + ) } Err(err) => { error!("🌐 Registering template failed: {}", err); @@ -95,7 +108,11 @@ pub async fn upload( }; } - Ok(UploadResponse { template_url }) + Ok( + Json( + UploadResponse::success(template_url) + ) + ) } #[derive(Debug, thiserror::Error)] From 4357336fc08fb7bb27f9beeb2ca68a2912bb037f Mon Sep 17 00:00:00 2001 From: ksrichard Date: Wed, 27 Nov 2024 15:05:45 +0100 Subject: [PATCH 3/3] format --- .../tari_swarm_daemon/src/webserver/server.rs | 6 ++-- .../src/webserver/templates.rs | 29 +++++++++---------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/applications/tari_swarm_daemon/src/webserver/server.rs b/applications/tari_swarm_daemon/src/webserver/server.rs index 03301adfc..8bc14afc9 100644 --- a/applications/tari_swarm_daemon/src/webserver/server.rs +++ b/applications/tari_swarm_daemon/src/webserver/server.rs @@ -132,16 +132,16 @@ async fn call_handler( where TReq: DeserializeOwned, TResp: Serialize, - H: for<'a> JrpcHandler<'a, TReq, Response=TResp>, + H: for<'a> JrpcHandler<'a, TReq, Response = TResp>, { let answer_id = value.get_answer_id(); let params = value.parse_params().inspect_err(|e| match &e.result { JsonRpcAnswer::Result(_) => { unreachable!("parse_params() error should not return a result") - } + }, JsonRpcAnswer::Error(e) => { warn!(target: LOG_TARGET, "🌐 JSON-RPC params error: {}", e); - } + }, })?; let resp = handler .handle(&context, params) diff --git a/applications/tari_swarm_daemon/src/webserver/templates.rs b/applications/tari_swarm_daemon/src/webserver/templates.rs index 376ccb54e..d3b720470 100644 --- a/applications/tari_swarm_daemon/src/webserver/templates.rs +++ b/applications/tari_swarm_daemon/src/webserver/templates.rs @@ -3,8 +3,13 @@ use std::{io, sync::Arc}; -use axum::extract::Query; -use axum::{extract::{multipart::MultipartError, Multipart}, http::StatusCode, response::IntoResponse, Extension, Json}; +use axum::{ + extract::{multipart::MultipartError, Multipart, Query}, + http::StatusCode, + response::IntoResponse, + Extension, + Json, +}; use log::{error, info}; use serde::{Deserialize, Serialize}; use tari_crypto::tari_utilities::hex; @@ -82,7 +87,7 @@ pub async fn upload( context.config().webserver.bind_address.port(), dest_file )) - .unwrap(); + .unwrap(); if query_params.register_template { let data = TemplateData { @@ -95,24 +100,16 @@ pub async fn upload( return match context.process_manager().register_template(data).await { Ok(()) => { info!("🌐 Registered template"); - Ok( - Json( - UploadResponse::success(template_url) - ) - ) - } + Ok(Json(UploadResponse::success(template_url))) + }, Err(err) => { error!("🌐 Registering template failed: {}", err); Err(err.into()) - } + }, }; } - Ok( - Json( - UploadResponse::success(template_url) - ) - ) + Ok(Json(UploadResponse::success(template_url))) } #[derive(Debug, thiserror::Error)] @@ -141,7 +138,7 @@ impl IntoResponse for UploadError { UploadError::MultiPartError(err) => err.into_response(), UploadError::Other(err) => { (StatusCode::INTERNAL_SERVER_ERROR, format!("Upload error: {}", err)).into_response() - } + }, } } }