Skip to content

Commit 86bc1ed

Browse files
authored
docs: make cloud-sink examples runnable standalone via docker-compose (#947)
1 parent fcb60cc commit 86bc1ed

19 files changed

Lines changed: 281 additions & 37 deletions

File tree

examples/aws_lambda/README.md

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,44 @@ flowchart LR
1313
- **Filters**
1414
- `SplitBlock`: breaks each block into individual transactions.
1515
- `ParseCbor`: decodes the raw transaction CBOR into structured records.
16-
- **Sink**`AwsLambda`: invokes `function_name` in `region` with each event as the payload.
16+
- **Sink**`AwsLambda`: invokes `function_name` in `region` with each event as the
17+
JSON payload.
1718

1819
## Prerequisites
1920

2021
- Built with the `aws` feature.
21-
- AWS credentials available to the process (env vars, profile, or instance role) with
22-
permission to invoke the function.
23-
- Edit `region` and `function_name` in `daemon.toml` to match your function.
22+
- A running Docker engine — LocalStack runs each Lambda invocation in its own container
23+
(the compose file mounts the Docker socket for this).
2424

25-
## Run
25+
## Run standalone (LocalStack)
26+
27+
The included `docker-compose.yml` starts [LocalStack](https://www.localstack.cloud/) and
28+
deploys `my-lambda` (a tiny function in `localstack/handler.py` that logs each event), so
29+
the example runs without a real AWS account:
2630

2731
```sh
2832
cd examples/aws_lambda
33+
docker compose up -d
34+
```
35+
36+
Point the AWS SDK at LocalStack with dummy credentials, then run Oura:
37+
38+
```sh
39+
export AWS_ENDPOINT_URL=http://localhost.localstack.cloud:4566
40+
export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test AWS_REGION=us-east-1
2941
cargo run --features aws --bin oura -- daemon --config daemon.toml
3042
```
3143

3244
(or `oura daemon --config daemon.toml` with a binary built with the `aws` feature.)
45+
46+
Watch the function get invoked — one `lambda.Invoke => 200` per event:
47+
48+
```sh
49+
docker compose logs -f localstack | grep "lambda.Invoke"
50+
```
51+
52+
## Run against real AWS
53+
54+
Skip the compose step and the `AWS_ENDPOINT_URL` export. Provide real credentials (env
55+
vars, profile, or instance role) with permission to invoke the function, and set `region`
56+
and `function_name` in `daemon.toml` to match it.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
version: "3"
2+
services:
3+
# LocalStack emulates AWS locally, so the example runs without a real AWS account.
4+
# The init script under ./localstack deploys a tiny function named `my-lambda`
5+
# that logs each event it receives.
6+
localstack:
7+
image: localstack/localstack:3
8+
container_name: localstack-lambda
9+
ports:
10+
- "4566:4566"
11+
environment:
12+
- SERVICES=lambda
13+
volumes:
14+
- ./localstack:/etc/localstack/init/ready.d
15+
# LocalStack runs each Lambda invocation in its own container.
16+
- /var/run/docker.sock:/var/run/docker.sock
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
def handler(event, context):
2+
# Oura invokes the function once per chain event; the payload is the JSON record.
3+
print("oura event:", event)
4+
return {"statusCode": 200}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/sh
2+
# Runs inside the LocalStack container once it is ready.
3+
# Packages handler.py and deploys it as the function daemon.toml invokes.
4+
cd /etc/localstack/init/ready.d
5+
python3 -c "import zipfile; zipfile.ZipFile('/tmp/fn.zip','w').write('handler.py')"
6+
awslocal lambda create-function \
7+
--function-name my-lambda \
8+
--runtime python3.12 \
9+
--handler handler.handler \
10+
--role arn:aws:iam::000000000000:role/lambda-role \
11+
--zip-file fileb:///tmp/fn.zip

examples/aws_s3/README.md

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,52 @@
11
# AWS S3 sink
22

3-
Decode transactions and write each one as an object into an S3 bucket.
3+
Write each block's raw CBOR as an object into an S3 bucket.
44

55
## Pipeline
66

77
```mermaid
88
flowchart LR
9-
src[N2N source] --> f1[ParseCbor] --> sink[AwsS3 sink]
9+
src[N2N source] --> sink[AwsS3 sink]
1010
```
1111

1212
- **Source**`N2N`: mainnet relay, starting from the chain tip.
13-
- **Filters**`ParseCbor`: decodes the raw transaction CBOR into structured records.
14-
- **Sink**`AwsS3`: writes objects under `prefix` in `bucket` (`region`).
13+
- **Sink**`AwsS3`: writes one object per block under `prefix` in `bucket` (`region`),
14+
keyed by `slot.hash`. The `AwsS3` sink stores the block CBOR as-is, so the example runs
15+
no filters — a `ParseCbor` / `SplitBlock` filter would change the record type and the
16+
sink would reject it.
1517

1618
## Prerequisites
1719

1820
- Built with the `aws` feature.
19-
- AWS credentials available to the process (env vars, profile, or instance role) with
20-
permission to write to the bucket.
21-
- Edit `region`, `bucket`, and `prefix` in `daemon.toml` to match your bucket.
2221

23-
## Run
22+
## Run standalone (LocalStack)
23+
24+
The included `docker-compose.yml` starts [LocalStack](https://www.localstack.cloud/) and
25+
provisions the `my-bucket` bucket, so the example runs without a real AWS account:
2426

2527
```sh
2628
cd examples/aws_s3
29+
docker compose up -d
30+
```
31+
32+
Point the AWS SDK at LocalStack with dummy credentials, then run Oura:
33+
34+
```sh
35+
export AWS_ENDPOINT_URL=http://s3.localhost.localstack.cloud:4566
36+
export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test AWS_REGION=us-east-1
2737
cargo run --features aws --bin oura -- daemon --config daemon.toml
2838
```
2939

3040
(or `oura daemon --config daemon.toml` with a binary built with the `aws` feature.)
41+
42+
Inspect the objects Oura wrote:
43+
44+
```sh
45+
docker exec localstack-s3 awslocal s3 ls s3://my-bucket/mainnet/
46+
```
47+
48+
## Run against real AWS
49+
50+
Skip the compose step and the `AWS_ENDPOINT_URL` export. Provide real credentials (env
51+
vars, profile, or instance role) with permission to write to the bucket, and edit
52+
`region`, `bucket`, and `prefix` in `daemon.toml` to match it.

examples/aws_s3/daemon.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ type = "mainnet"
88
[intersect]
99
type = "Tip"
1010

11-
[[filters]]
12-
type = "ParseCbor"
11+
# The AwsS3 sink stores the raw block CBOR, so the block must reach it unparsed
12+
# (no ParseCbor / SplitBlock filter).
1313

1414
[sink]
1515
type = "AwsS3"

examples/aws_s3/docker-compose.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: "3"
2+
services:
3+
# LocalStack emulates AWS locally, so the example runs without a real AWS account.
4+
# The init script under ./localstack provisions the bucket Oura writes to.
5+
localstack:
6+
image: localstack/localstack:3
7+
container_name: localstack-s3
8+
ports:
9+
- "4566:4566"
10+
environment:
11+
- SERVICES=s3
12+
volumes:
13+
- ./localstack:/etc/localstack/init/ready.d

examples/aws_s3/localstack/init.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
# Runs inside the LocalStack container once it is ready.
3+
# Creates the bucket that daemon.toml writes to.
4+
awslocal s3 mb s3://my-bucket

examples/aws_sqs/README.md

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,43 @@ flowchart LR
1313
- **Filters**
1414
- `SplitBlock`: breaks each block into individual transactions.
1515
- `ParseCbor`: decodes the raw transaction CBOR into structured records.
16-
- **Sink**`AwsSqs`: sends messages to `queue_url` (`region`) with the configured
17-
`group_id` (FIFO queues).
16+
- **Sink**`AwsSqs`: sends each event as a JSON message to `queue_url` (`region`). For a
17+
FIFO queue (`queue_url` ending in `.fifo`) the configured `group_id` is used.
1818

1919
## Prerequisites
2020

2121
- Built with the `aws` feature.
22-
- AWS credentials available to the process (env vars, profile, or instance role) with
23-
permission to send to the queue.
24-
- Edit `region`, `queue_url`, and `group_id` in `daemon.toml` to match your queue.
2522

26-
## Run
23+
## Run standalone (LocalStack)
24+
25+
The included `docker-compose.yml` starts [LocalStack](https://www.localstack.cloud/) and
26+
provisions the `my-queue` queue that `daemon.toml` points at, so the example runs without a
27+
real AWS account:
2728

2829
```sh
2930
cd examples/aws_sqs
31+
docker compose up -d
32+
```
33+
34+
Point the AWS SDK at LocalStack with dummy credentials, then run Oura:
35+
36+
```sh
37+
export AWS_ENDPOINT_URL=http://localhost.localstack.cloud:4566
38+
export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test AWS_REGION=us-east-1
3039
cargo run --features aws --bin oura -- daemon --config daemon.toml
3140
```
3241

3342
(or `oura daemon --config daemon.toml` with a binary built with the `aws` feature.)
43+
44+
Read the messages Oura enqueued:
45+
46+
```sh
47+
docker exec localstack-sqs awslocal sqs receive-message \
48+
--queue-url http://localhost:4566/000000000000/my-queue
49+
```
50+
51+
## Run against real AWS
52+
53+
Skip the compose step and the `AWS_ENDPOINT_URL` export. Provide real credentials (env
54+
vars, profile, or instance role) with permission to send to the queue, and set `region`,
55+
`queue_url`, and `group_id` in `daemon.toml` to match your queue.

examples/aws_sqs/daemon.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,7 @@ type = "ParseCbor"
1717
[sink]
1818
type = "AwsSqs"
1919
region = "us-east-1"
20-
queue_url = "https://sqs.us-east-1.amazonaws.com/*****/my-queue"
20+
# Points at the queue created by the bundled LocalStack (see README). For a real
21+
# AWS queue, use its URL: https://sqs.<region>.amazonaws.com/<account-id>/my-queue
22+
queue_url = "http://localhost.localstack.cloud:4566/queue/us-east-1/000000000000/my-queue"
2123
group_id = "my_group"

0 commit comments

Comments
 (0)