Skip to content

Commit

Permalink
WASI example (#228)
Browse files Browse the repository at this point in the history
* feat: wasi-example

Signed-off-by: Anton Whalley <[email protected]>

* fix: remove line end

Signed-off-by: Anton Whalley <[email protected]>

---------

Signed-off-by: Anton Whalley <[email protected]>
  • Loading branch information
No9 authored May 10, 2024
1 parent 13c36fd commit 2f57c3c
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/rust_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ jobs:
env:
CARGO_TARGET_WASM32_WASI_RUNNER: wasmedge
# Build examples
- uses: actions-rs/cargo@v1
name: "Build wasi-example"
if: matrix.target == 'wasm32-wasi' && matrix.toolchain == 'stable'
with:
command: build
toolchain: ${{ matrix.toolchain }}
args: --target ${{ matrix.target }} --manifest-path ./example-projects/wasi-example/Cargo.toml

- uses: actions-rs/cargo@v1
name: "Build reqwest-wasm-example"
if: matrix.target == 'wasm32-unknown-unknown' && matrix.toolchain == 'stable'
Expand Down Expand Up @@ -170,3 +178,4 @@ jobs:
command: build
toolchain: ${{ matrix.toolchain }}
args: --target ${{ matrix.target }} --manifest-path ./example-projects/nats-example/Cargo.toml

17 changes: 17 additions & 0 deletions example-projects/wasi-example/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "wasi-example"
version = "0.1.0"
edition = "2021"

[dependencies]
anyhow = "1.0"
cloudevents-sdk = { path = "../..", features = ["http-binding", "hyper_wasi", "hyper" ] }
hyper_wasi = { version = "0.15", features = ["full"] }
log = "0.4.21"
tokio_wasi = { version = "1", features = ["io-util", "fs", "net", "time", "rt", "macros"] }
serde_json = " 1.0.116"

[dev-dependencies]
bytes = "1.6.0"
http-body-util = "0.1.1"
chrono = "*"
26 changes: 26 additions & 0 deletions example-projects/wasi-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Install WASMEdge:

https://wasmedge.org/docs/start/install/

To run the server:
```console
cargo run --target wasm32-wasi
```

To test a GET:

```console
curl -sw '%{http_code}\n' http://localhost:9000/health/readiness
```

To test a POST:

```console
curl -d '{"name": "wasi-womble"}' \
-H'content-type: application/json' \
-H'ce-specversion: 1.0' \
-H'ce-id: 1' \
-H'ce-source: http://cloudevents.io' \
-H'ce-type: dev.knative.example' \
http://localhost:9000
```
39 changes: 39 additions & 0 deletions example-projects/wasi-example/src/handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use cloudevents::{event::Data, Event, EventBuilder, EventBuilderV10};
use log::info;
use serde_json::{from_slice, from_str, json};

pub async fn handle_event(event: Event) -> Result<Event, anyhow::Error> {
info!("event: {}", event);

let input = match event.data() {
Some(Data::Binary(v)) => from_slice(v)?,
Some(Data::String(v)) => from_str(v)?,
Some(Data::Json(v)) => v.to_owned(),
None => json!({ "name": "default" }),
};

EventBuilderV10::from(event)
.source("func://handler")
.ty("func.example")
.data("application/json", json!({ "hello": input["name"] }))
.build()
.map_err(|err| err.into())
}

#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn post_test() -> Result<(), anyhow::Error> {
let reqevt = Event::default();
let respevt = handle_event(reqevt).await?;
let output = match respevt.data() {
Some(Data::Binary(v)) => from_slice(v)?,
Some(Data::String(v)) => from_str(v)?,
Some(Data::Json(v)) => v.to_owned(),
None => json!({ "name": "default" }),
};
assert_eq!(output, json!({ "hello": "default" }));
Ok(())
}
}
45 changes: 45 additions & 0 deletions example-projects/wasi-example/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use cloudevents::binding::http::builder::adapter::to_response;
use cloudevents::binding::http::to_event;

use hyper::service::{make_service_fn, service_fn};
use hyper::Server;
use hyper::{Body, Method, Request, Response, StatusCode};
use std::convert::Infallible;
use std::net::SocketAddr;
use std::result::Result;

mod handler;

#[allow(clippy::redundant_closure)]
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let addr = SocketAddr::from(([0, 0, 0, 0], 9000));
let make_svc = make_service_fn(|_| async move {
Ok::<_, Infallible>(service_fn(move |req| handle_request(req)))
});
let server = Server::bind(&addr).serve(make_svc);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
Ok(())
}
async fn handle_request(req: Request<Body>) -> Result<Response<Body>, anyhow::Error> {
match (req.method(), req.uri().path()) {
(&Method::POST, "/") => {
let headers = req.headers().clone();
let body_bytes = hyper::body::to_bytes(req.into_body()).await?;
let body = body_bytes.to_vec();
let reqevt = to_event(&headers, body)?;
let _respevt = handler::handle_event(reqevt).await?;

to_response(_respevt).map_err(|err| err.into())
}
(&Method::GET, "/health/readiness") => Ok(Response::new(Body::from(""))),
(&Method::GET, "/health/liveness") => Ok(Response::new(Body::from(""))),
_ => {
let mut not_found = Response::default();
*not_found.status_mut() = StatusCode::NOT_FOUND;
Ok(not_found)
}
}
}

0 comments on commit 2f57c3c

Please sign in to comment.