From 562ca0e2f5cb606415937268832f9b500bd628c7 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 19 Sep 2022 09:04:46 +0200 Subject: Add echoserver tedge binary for testcontainer example setup Signed-off-by: Matthias Beyer --- Cargo.lock | 20 +++++ Cargo.toml | 3 +- tests/testcontainers/echoserver/Cargo.toml | 26 ++++++ tests/testcontainers/echoserver/Dockerfile | 12 +++ tests/testcontainers/echoserver/config.toml | 7 ++ tests/testcontainers/echoserver/src/main.rs | 122 ++++++++++++++++++++++++++++ 6 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 tests/testcontainers/echoserver/Cargo.toml create mode 100644 tests/testcontainers/echoserver/Dockerfile create mode 100644 tests/testcontainers/echoserver/config.toml create mode 100644 tests/testcontainers/echoserver/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 0aa66dcb..d3798e4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1107,6 +1107,26 @@ dependencies = [ "rand", ] +[[package]] +name = "echoserver" +version = "0.1.0" +dependencies = [ + "async-trait", + "cfg-if 1.0.0", + "clap 3.2.18", + "env_logger 0.9.0", + "hyper", + "miette", + "tedge-cli", + "tedge_api", + "tedge_core", + "thiserror", + "tokio", + "toml", + "tracing", + "tracing-subscriber", +] + [[package]] name = "either" version = "1.8.0" diff --git a/Cargo.toml b/Cargo.toml index c2a5b5f6..8b591518 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,8 @@ members = [ "plugins/tedge_apama_plugin", "plugins/tedge_apt_plugin", "plugins/tedge_dummy_plugin", - "tedge" + "tedge", + "tests/testcontainers/echoserver", ] resolver = "2" diff --git a/tests/testcontainers/echoserver/Cargo.toml b/tests/testcontainers/echoserver/Cargo.toml new file mode 100644 index 00000000..20584c3c --- /dev/null +++ b/tests/testcontainers/echoserver/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "echoserver" +version = "0.1.0" +edition = "2021" + +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +async-trait = "0.1" +cfg-if = "1" +clap = { version = "3", features = ["derive", "cargo", "suggestions"] } +env_logger = { version = "0.9", optional = true } +miette = { version = "4.7", features = ["fancy"] } +hyper = { version = "0.14", features = ["server", "tcp", "http1"] } +thiserror = "1" +tokio = { version = "1", features = ["fs", "macros", "rt-multi-thread", "signal"] } +toml = "0.5.8" +tracing = "0.1" +tracing-subscriber = { version = "0.3.11", features = ["env-filter"] } + +tedge_api = { path = "../../../crates/core/tedge_api" } +tedge_core = { path = "../../../crates/core/tedge_core" } +tedge-cli = { path = "../../../tedge/" } + diff --git a/tests/testcontainers/echoserver/Dockerfile b/tests/testcontainers/echoserver/Dockerfile new file mode 100644 index 00000000..5c4d8572 --- /dev/null +++ b/tests/testcontainers/echoserver/Dockerfile @@ -0,0 +1,12 @@ +FROM rust:1.63.0-buster AS builder +WORKDIR /usr/src/app +COPY . . +COPY tests/testcontainers/echoserver/config.toml / +RUN cargo build -p echoserver + +FROM debian:buster AS runtime +WORKDIR /app +COPY --from=builder /usr/src/app/target/debug/echoserver . +COPY --from=builder /config.toml . + +CMD ["/app/echoserver", "run", "/app/config.toml"] diff --git a/tests/testcontainers/echoserver/config.toml b/tests/testcontainers/echoserver/config.toml new file mode 100644 index 00000000..12fd4ac6 --- /dev/null +++ b/tests/testcontainers/echoserver/config.toml @@ -0,0 +1,7 @@ +max_concurrency = 10 +plugin_shutdown_timeout_ms = 10000 + +[plugins] +[plugins.e] +kind = "echo" +[plugins.e.configuration] diff --git a/tests/testcontainers/echoserver/src/main.rs b/tests/testcontainers/echoserver/src/main.rs new file mode 100644 index 00000000..1ea91717 --- /dev/null +++ b/tests/testcontainers/echoserver/src/main.rs @@ -0,0 +1,122 @@ +use std::convert::Infallible; +use std::net::SocketAddr; + +use clap::Parser; +use hyper::Body; +use hyper::Request; +use hyper::Response; +use hyper::Server; +use tedge_api::PluginBuilder; +use tedge_api::PluginExt; +use tracing::debug; +use tracing::info; + +use tedge_cli::Registry; + +#[derive(Debug, miette::Diagnostic, thiserror::Error)] +enum Error { + #[error("Failed to parse configuration")] + ConfigParseFailed(#[from] toml::de::Error), + + #[error("Hyper error")] + Hyper(#[from] hyper::Error), +} + +pub struct EchoServerPluginBuilder; + +#[async_trait::async_trait] +impl PluginBuilder for EchoServerPluginBuilder +where + PD: tedge_api::PluginDirectory, +{ + fn kind_name() -> &'static str + where + Self: Sized, + { + "echo" + } + + fn kind_message_types() -> tedge_api::plugin::HandleTypes + where + Self: Sized, + { + EchoServerPlugin::get_handled_types() + } + + async fn verify_configuration( + &self, + _config: &tedge_api::PluginConfiguration, + ) -> Result<(), tedge_api::PluginError> { + Ok(()) + } + + async fn instantiate( + &self, + _config: tedge_api::PluginConfiguration, + cancellation_token: tedge_api::CancellationToken, + _core_comms: &PD, + ) -> Result { + Ok(EchoServerPlugin { cancellation_token }.finish()) + } +} + +pub struct EchoServerPlugin { + cancellation_token: tedge_api::CancellationToken, +} + +#[async_trait::async_trait] +impl tedge_api::Plugin for EchoServerPlugin { + async fn main(&self) -> Result<(), tedge_api::PluginError> { + let svc = hyper::service::make_service_fn(move |_conn| { + let service = hyper::service::service_fn(move |req| request_handler(req)); + + async move { Ok::<_, Infallible>(service) } + }); + + let cancellation_token = self.cancellation_token.clone(); + let addr: SocketAddr = "0.0.0.0:8080".parse().unwrap(); + Server::bind(&addr) + .serve(svc) + .with_graceful_shutdown(async move { + cancellation_token.cancelled().await; + }) + .await + .map(|_| ()) + .map_err(Error::from) + .map_err(tedge_api::PluginError::from) + } +} + +async fn request_handler(_: Request) -> Result, Infallible> { + Ok(Response::new("Pong".into())) +} + +impl tedge_api::plugin::PluginDeclaration for EchoServerPlugin { + type HandledMessages = (); +} + +#[tokio::main] +#[tracing::instrument] +async fn main() -> miette::Result<()> { + let args = tedge_cli::cli::Cli::parse(); + let _guard = tedge_cli::logging::setup_logging( + args.logging, + args.chrome_logging.as_ref(), + args.tracy_logging, + )?; + info!("Tedge booting..."); + debug!(?args, "Tedge CLI"); + + let registry = tedge_cli::Registry::default(); + info!("Building application"); + + let registry = Registry { + app_builder: registry + .app_builder + .with_plugin_builder(EchoServerPluginBuilder), + plugin_kinds: registry.plugin_kinds, + doc_printers: registry.doc_printers, + }; + + tedge_cli::run_app(args, registry).await +} -- cgit v1.2.3