summaryrefslogtreecommitdiffstats
path: root/tests/testcontainers/echoserver/src/main.rs
blob: 1ea917179b7b082b0e632108f7114b9b0580d7bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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<PD> PluginBuilder<PD> 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<tedge_api::plugin::BuiltPlugin, tedge_api::PluginError> {
        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<Body>) -> Result<Response<Body>, 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
}