Skip to content
This repository has been archived by the owner on Jun 10, 2024. It is now read-only.

Commit

Permalink
Update echo example with step by step instructions (#32)
Browse files Browse the repository at this point in the history
* Update echo example with step by step instructions

* Update extras example

* Apply requested changes

* Apply the second round of change requests
  • Loading branch information
snnsnn authored Mar 25, 2021
1 parent 1fe3439 commit 6d75ad7
Show file tree
Hide file tree
Showing 12 changed files with 445 additions and 53 deletions.
28 changes: 14 additions & 14 deletions echo/Cargo.lock

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

6 changes: 3 additions & 3 deletions echo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ edition = "2018"
crate-type = ["cdylib"]

[dependencies]
serde = {version = "1.0.118", features = ["derive"]}
serde_json ="1.0.60"
wapc-guest = "0.4.0"
wasmcloud-actor-core = { version = "0.2.2", features = ["guest"] }
wasmcloud-actor-http-server = { version = "0.1.1", features = ["guest"]}
serde_json ="1.0.60"
serde = {version = "1.0.118", features = ["derive"]}

[profile.release]
# Optimize for small code size
opt-level = "s"
lto = true
opt-level = "s"
34 changes: 34 additions & 0 deletions echo/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
COLOR ?= always # Valid COLOR options: {always, auto, never}
CARGO = cargo --color $(COLOR)
TARGET = target/wasm32-unknown-unknown
DEBUG = $(TARGET)/debug
RELEASE = $(TARGET)/release
KEYDIR ?= .keys
VERSION = $(shell cargo metadata --no-deps --format-version 1 | jq -r '.packages[].version')

.PHONY: all build check clean doc test update

all: build

build:
@$(CARGO) build
wash claims sign $(DEBUG)/echo.wasm -c wasmcloud:httpserver --name "echo" --ver $(VERSION) --rev 0

check:
@$(CARGO) check

clean:
@$(CARGO) clean

doc:
@$(CARGO) doc

test: build
@$(CARGO) test

update:
@$(CARGO) update

release:
@$(CARGO) build --release
wash claims sign $(RELEASE)/echo.wasm -c wasmcloud:httpserver --name "echo" --ver $(VERSION) --rev 0
232 changes: 230 additions & 2 deletions echo/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,233 @@
# Echo Example

This example is designed to illustrate a few simple aspects of coding an actor module with wasmCloud. The first shows how to respond to simple HTTP requests, but this sample also shows how to use `serde` for JSON serialization.
An actor is the smallest unit of deployable, portable compute within the wasmcloud ecosystem.

This actor module responds to all incoming HTTP requests by returning a JSON object describing the inbound request.
Actors are small WebAssembly modules that can handle messages delivered to them by the host runtime and can invoke functions on capability providers, provided they have been granted the appropriate privileges.

Check out [https://wasmcloud.dev/reference/host-runtime/actors/](https://wasmcloud.dev/reference/host-runtime/actors/) for more.

In this example our actor responds to all incoming HTTP requests by returning the HTTP request as a JSON object.

We will have a two part tutorial, starting with running a precompiled actor stored in a remote OCI registry, then we will write our own actor and swap it with the remote one. We will use a manifest file to run our actor declaratively via `wasmcloud`.

In the second part, we will spin up a NATS server and a local docker registry to store our WebAssembly module. We'll use the wasmcloud shell, `wash`, a feature-rich cli tool that provides an interactive REPL environment to run our actor and interact with it.

## Running an echo server

1. Please install `wasmcloud` and `wash` binaries if you do not have them installed already. `wasmcloud` will provide the runtime environment for our actor while `wash` will be used for development later in the tutorial:

[https://wasmcloud.dev/overview/installation/](https://wasmcloud.dev/overview/installation/)

```bash
$ wasmcloud --version
$ wash --version
```

2. Locate manifest.yaml file here in the project folder and run it with `--manifest` flag:

```bash
$ wasmcloud -m manifest.yaml
```

Here are the contents of the file:

```bash
labels:
sample: "wasmcloud echo"
actors:
- "wasmcloud.azurecr.io/echo:0.2.0"
capabilities:
- image_ref: wasmcloud.azurecr.io/httpserver:0.11.1
link_name: default
links:
- actor: ${ECHO_ACTOR:MBCFOPM6JW2APJLXJD3Z5O4CN7CPYJ2B4FTKLJUR5YR5MITIU7HD3WD5}
provider_id: "VAG3QITQQ2ODAOWB5TTQSDJ53XK3SHBEIFNK4AYJ5RKAX2UNSCAPHA5M"
contract_id: "wasmcloud:httpserver"
link_name: default
values:
PORT: 8080
```

3. Visit `http://localhost:8080` to see the result:

```bash
curl http://localhost:8080/
```

That is it, you are running a highly secure HTTP server powered by a WebAssembly module.

4. Now lets build our own actor and swap with the remote one:

```bash
$ cargo build --release
```

5. To be able to use it, we need to sign it:

```bash
$ wash claims sign ./target/wasm32-unknown-unknown/release/echo.wasm -c wasmcloud:httpserver --name "echo" --ver 0.2.2
```

Read more on the security aspects at https://wasmcloud.dev/reference/host-runtime/security/.

6. Actors are signed with unique module keys, so the echo actor ID will be different for everyone. We'll need to inspect the actor to find its public key (module) for the next step:
```bash
$ wash claims inspect ./target/wasm32-unknown-unknown/release/echo_s.wasm
```
This will output something like:
```bash
Account ACPVJRHMJ5GM2EOQWRPAQVKL75NBOCTZC52TAYPDCDA2GLXJ6TVJOPDN
Module MCUDTMOOZCVAM5EBNN4U3X2OGHNIY3BKPEW66HY4RTCYYVWXOE7ESVDQ
Expires never
Can Be Used immediately
Version 0.2.2 (0)
Call Alias (Not set)
```
We are after the module ID: `MCUDTMOOZCVAM5EBNN4U3X2OGHNIY3BKPEW66HY4RTCYYVWXOE7ESVDQ`
7. Swap the remote actor with our newly created one in the manifest file and don't forget to change the actor ID:

```yaml
actors:
- "./target/wasm32-unknown-unknown/release/echo_s.wasm"
# ...
actor: ${ECHO_ACTOR:MCUDTMOOZCVAM5EBNN4U3X2OGHNIY3BKPEW66HY4RTCYYVWXOE7ESVDQ}
# ...
```

8. Now it's time to run our actor:
```bash
$ wasmcloud -m manifest.yaml
```
9. As a final step we will send another request to `http://localhost:8080`:
```bash
curl http://localhost:8080/
```
## Using `wash` for better developer experience
Previously we were using a declarative deployment model that did not allow us to modify resources at runtime. In this section, we will use `NATS` to allow `wasmcloud` to utilize self-managing [lattice network](https://wasmcloud.dev/reference/lattice/), and we can use `wash` to interact with the `wasmcloud` host via the lattice control interface (`ctl`).
We will also use a local docker registry to store our echo actor to illustrate interacting with a local development version of an OCI registry.
1. Since we are going to use `docker-compose` to run NATS server and image registry, you need to have `wasmcloud`, `wash`, `docker` and `docker-compose` installed on your machine.
2. You can either use `docker-compose.yml` file in the project's directory or create one with the following content:

```yaml
version: "3"
services:
registry:
image: registry:2
ports:
- "5000:5000"
nats:
image: nats:2.1.9
ports:
- "6222:6222"
- "4222:4222"
- "8222:8222"
```

We will run our containers in detached mode to reduce clutter.

```bash
$ docker-compose up -d
```

Start a REPL session using `wash up` command:

```bash
$ wash up
```

Check if session is running:

```bash
$ ctl get hosts
```

It will output something like:

```bash
Host ID Uptime (seconds)
NDGPVEOZKAYT6JRL2C4BDVSW3PBBOYTWRLC2QFCSLXWDX4KCIRHM6WCZ 1357
```

3. Please open a new terminal, as the REPL is running in the current one. We will build our actor first, then will sign it:

```bash
$ cargo build --release
$ wash claims sign ./target/wasm32-unknown-unknown/release/echo.wasm -c wasmcloud:httpserver --name "echo" --ver 0.2.2
```

Or you can use `make` file in project's directory for convenience:
```bash
make release VERSION=0.2.2
```
Now we have our actor, `echo.wasm` and its signed version `echo_s.wasm` in `./target/wasm32-unknown-unknown/release` directory.
3. Now it's time to push signed our actor into to local registry using `wash`:

```bash
wash reg push localhost:5000/echo:0.2.2 ./target/wasm32-unknown-unknown/release/echo_s.wasm --insecure
```

4. Now, please go back to REPL terminal and run the actor from the local image registry:

```bash
ctl start actor localhost:5000/echo:0.2.2
```

The steps from now on are independent of our current example, but we've kept it for completeness:
5. Start your capability provider that runs an HTML server:
```bash
ctl start provider wasmcloud.azurecr.io/httpserver:0.11.1
```
Check out https://wasmcloud.dev/app-dev/create-provider for how to write your own:
6. Link the actor with capability using `wash`:
```bash
// Get actor and capability provider IDs using:
// ctl get inventory «HOST_ID»
$ ctl get inventory NDGPVEOZKAYT6JRL2C4BDVSW3PBBOYTWRLC2QFCSLXWDX4KCIRHM6WCZ
// Establish a contract between them using link command
// Pass along environment variables required by the capability provider using:
// ctl link «ACTOR_ID» «PROVIDER_ID» «CONTRACT_ID» PORT=8080
$ ctl link MCUDTMOOZCVAM5EBNN4U3X2OGHNIY3BKPEW66HY4RTCYYVWXOE7ESVDQ VAG3QITQQ2ODAOWB5TTQSDJ53XK3SHBEIFNK4A YJ5RKAX2UNSCAPHA5M wasmcloud:httpserver PORT=8080
```
7. You can use `ctl call` command in the REPL window to test out our actor:
```bash
ctl call «ACTOR_ID» HandleRequest {"method": "GET", "path": "/", "body": "", "queryString":"","header":{}}
```
This will output response JSON along with some raw bytes which our REPL terminal does not know how to interpret:
```bash
Call response (raw): ��statusCode�Ȧstatus�OK�header��body�D{"method":"GET","path":"/","query_string":"","headers":{},"body":[]}
```
Or you can query `http://localhost:8080` via `curl` from a seperate terminal window:
```bash
curl http://localhost:8080/
```
Or just visit `http://localhost:8080/` address via browser:
12 changes: 12 additions & 0 deletions echo/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: "3"
services:
registry:
image: registry:2
ports:
- "5000:5000"
nats:
image: nats:2.1.9
ports:
- "6222:6222"
- "4222:4222"
- "8222:8222"
Loading

0 comments on commit 6d75ad7

Please sign in to comment.