forked from awsdocs/aws-doc-sdk-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rust/cross service/rest aurora ses actix (awsdocs#3874)
* Actix web healthz * App create w/ deserialization * Break out files in mod. * Create item integration test. * Comments * Tracing! * tmp unstash later * Round trip to database! * Finish repository & collection * Add SES & send report * Docs pass * Top level comments * Ignore environment specific files * Refactored tests; mock tests * Archived deserializer * Clippy * Formatted * SPDX ID and comments review. * Install libclang-dev for libxsmlwriter dependency * sudo install me a dep * Add placeholder test config * Editorial * Respond to Laren review. Full archive test workflow. Nits and fixes. Spec diversions. README! * Add elwing item tracker readme * Last comments * Remove debugging line * Laren editorial pass v2 * Editorial Co-authored-by: Irene Smith <[email protected]>
- Loading branch information
1 parent
d31d3a9
commit 4248c8b
Showing
33 changed files
with
1,980 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
resources/clients/react/elwing/src/plugins/item-tracker/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# Work item tracker Elwing Plugin | ||
|
||
## Overview | ||
|
||
Shows how to use [React](https://reactjs.org/) to create a web page that connects to a REST service that lets you do the following: | ||
|
||
- Get a list of active or archived work items. | ||
- Mark active work items as archived. | ||
- Add new work items to the list of active items. | ||
- Send a report of work items to a specified email recipient. | ||
|
||
## Sample REST applications | ||
|
||
The web client is designed to send requests to one of the following sample applications. | ||
Each sample application shows you how to use an AWS SDK to store work items using AWS | ||
resources: | ||
|
||
- [Create a React and Spring REST application that queries Amazon Aurora Serverless data](/javav2/usecases/Creating_Spring_RDS_%20Rest) | ||
- [Create the Amazon Aurora Serverless backend using the AWS SDK for PHP](/php/cross_service/aurora_item_tracker) | ||
- [Track work items in an Aurora Serverless database with the SDK for Python](/python/cross_service/aurora_item_tracker) | ||
|
||
## Run the Item Tracker UI | ||
|
||
1. Run Elwing by following the instructions in the [Elwing README](/resources/clients/react/elwing/README.md). | ||
1. When Elwing starts, a web browser opens http://localhost:3000/. | ||
1. Run the item tracker plugin by selecting **Item Tracker** in the left navigation bar. | ||
1. This sends a request to the REST service to get any existing active items: | ||
``` | ||
GET http://localhost:8080/api/items?archived=false | ||
``` | ||
1. At first, the table is empty. | ||
![Work item tracker](images/item-tracker-start.png) | ||
1. Select **Add item**, fill in the values, and select **Add** to add an item. | ||
![Add item](images/item-tracker-add-item.png) | ||
This sends a POST request to the REST service with a JSON payload that contains the | ||
work item. | ||
``` | ||
POST http://localhost:8080/api/items | ||
{"name":"Me", | ||
"guide":"Rust", | ||
"description":"Show how to add an item", | ||
"status":"In progress", | ||
"archived":false} | ||
``` | ||
1. After you add items, they display in the table. | ||
You can archive an active item by selecting the **Archive** button next to the item. | ||
![Work item tracker with items](images/item-tracker-all-items.png) | ||
This sends a PUT request to the REST service, specifying the item ID and the `archive` action. | ||
``` | ||
PUT http://localhost:8080/api/items/8db8aaa4-6f04-4467-bd60-EXAMPLEGUID:archive | ||
``` | ||
1. To get and display items with a specific status, select a filter in the dropdown list, such as **Archived**. | ||
![Work item tracker Archived items](images/item-tracker-archived-items.png) | ||
This sends a GET request to the REST service with an `archived` query parameter. | ||
``` | ||
GET http://localhost:8080/api/items?archived=true | ||
``` | ||
1. Enter an email recipient and select **Send report** to send an email of active items. | ||
![Work item tracker send report](images/item-tracker-send-report.png) | ||
This sends a POST request to the REST service with a `report` action. | ||
``` | ||
POST http://localhost:8080/api/items:report | ||
``` | ||
When your Amazon Simple Email Service (Amazon SES) account is in the sandbox, both the sender and recipient email addresses must be registered with Amazon SES. | ||
## Additional resources | ||
<!-- | ||
- [.NET cross-service examples](/dotnetv3/cross-service/README.md) | ||
- [Go cross-service examples](/gov2/cross_service) | ||
- [JavaScript cross-service examples](/javascriptv3/example_code/cross-services) | ||
- [Java cross-service examples](/javav2/usecases) | ||
- [Kotlin cross-service examples](/kotlin/usecases/Readme.md) | ||
- [Python cross-service examples](/python/cross_service/README.md) | ||
--> | ||
- [Rust cross-service examples](/rust_dev_preview/cross_service/rest_ses/README.md) | ||
--- | ||
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 |
Binary file added
BIN
+21.1 KB
.../clients/react/elwing/src/plugins/item-tracker/images/item-tracker-add-item.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+35.5 KB
...clients/react/elwing/src/plugins/item-tracker/images/item-tracker-all-items.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+29.3 KB
...ts/react/elwing/src/plugins/item-tracker/images/item-tracker-archived-items.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+35.8 KB
...ients/react/elwing/src/plugins/item-tracker/images/item-tracker-send-report.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+27.3 KB
...ces/clients/react/elwing/src/plugins/item-tracker/images/item-tracker-start.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
. | ||
!configuration | ||
!src | ||
!tests | ||
!Cargo.toml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
[package] | ||
name = "rest_ses" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
|
||
[lib] | ||
path = "src/lib.rs" | ||
|
||
[[bin]] | ||
path = "src/main.rs" | ||
name = "rest_ses" | ||
|
||
[dependencies] | ||
actix-web = "4" | ||
actix-web-prom = "0.6.0" | ||
aws-config = { git = "https://github.com/awslabs/aws-sdk-rust", branch = "main" } | ||
aws-sdk-cloudwatchlogs = { git = "https://github.com/awslabs/aws-sdk-rust", branch = "main" } | ||
aws-sdk-rdsdata = { git = "https://github.com/awslabs/aws-sdk-rust", branch = "main" } | ||
aws-sdk-ses = { git = "https://github.com/awslabs/aws-sdk-rust", branch = "main" } | ||
chrono = { version = "0.4.22", default-features = false, features = ["clock", "serde"] } | ||
color-eyre = "0.6.2" | ||
config = "0.13.2" | ||
derive_more = "0.99.17" | ||
futures = "0.3.24" | ||
mail-builder = "0.2.2" | ||
reqwest = "0.11.12" | ||
secrecy = { version = "0.8.0", features = ["serde"] } | ||
serde = { version = "1", features = ["derive"] } | ||
serde_json = "1.0.86" | ||
thiserror = "1.0.37" | ||
tokio = {version = "1", features = ["macros", "rt-multi-thread"]} | ||
tracing = "0.1.37" | ||
tracing-actix-web = "0.6.1" | ||
tracing-bunyan-formatter = "0.3.4" | ||
tracing-log = "0.1.3" | ||
tracing-subscriber = { version = "0.3", features = ["registry", "env-filter"] } | ||
uuid = { version = "1.2.1", features = ["v4", "serde"] } | ||
xlsxwriter = "0.3.1" | ||
|
||
[dev-dependencies] | ||
aws-smithy-http = { git = "https://github.com/awslabs/aws-sdk-rust", branch = "main" } | ||
fake = { version = "2.5.0", features = ["uuid"] } | ||
once_cell = "1.15.0" | ||
rand = "0.8.5" | ||
tokio-test = "0.4.2" | ||
wiremock = "0.5.15" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# chef and planner steps pre-compile the upstream create dependencies. | ||
FROM lukemathwalker/cargo-chef:latest-rust-1.59.0 as chef | ||
WORKDIR /app | ||
RUN apt update && apt install lld clang -y | ||
|
||
FROM chef as planner | ||
COPY Cargo.toml . | ||
# Compute a lock-like file for our project. | ||
RUN cargo chef prepare --recipe-path recipe.json | ||
|
||
# After pre-building the crates, build the app binary. | ||
FROM chef as builder | ||
COPY --from=planner /app/recipe.json recipe.json | ||
# Build our project dependencies, not our application. | ||
RUN cargo chef cook --release --recipe-path recipe.json | ||
COPY . . | ||
# Build our project. | ||
RUN cargo build --release --bin rest_ses | ||
|
||
# Take the final binary from the builder, and the local configuration files. | ||
FROM debian:bullseye-slim AS runtime | ||
WORKDIR /app | ||
RUN apt-get update -y \ | ||
&& apt-get install -y --no-install-recommends openssl ca-certificates \ | ||
# Clean up. | ||
&& apt-get autoremove -y \ | ||
&& apt-get clean -y \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
COPY --from=builder /app/target/release/rest_ses rest_ses | ||
COPY configuration configuration | ||
ENV APP_ENVIRONMENT production | ||
ENTRYPOINT ["./rest_ses"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
# Track work items in an Aurora Serverless database with the SDK for Rust | ||
|
||
## Overview | ||
|
||
This example shows you how to use the AWS SDK for Rust to create a REST service that lets you do the following: | ||
|
||
- Build an Actix Web REST service that integrates with AWS services. | ||
- Read, write, and update work items that are stored in an Amazon Aurora Serverless database. | ||
- Create an AWS Secrets Manager secret that contains database credentials and use it to authenticate calls to the database. | ||
- Use Amazon Simple Email Service (Amazon SES) to send email reports of work items. | ||
|
||
The REST service is used in conjunction with the [Elwing React client](../../../resources/clients/react/elwing) | ||
to present a fully functional web application. | ||
|
||
### ⚠️ Important | ||
|
||
- Running this code might result in charges to your AWS account. | ||
- Running the tests might result in charges to your AWS account. | ||
- We recommend that you grant your code least privilege. At most, grant only the minimum | ||
permissions required to perform the task. For more information, see | ||
[Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege). | ||
- This code is not tested in every AWS Region. For more information, see | ||
[AWS Regional Services](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services). | ||
|
||
### Prerequisites | ||
|
||
Prerequisites for running examples can be found in the [README](../../README.md#Prerequisites) in the Rust folder. | ||
|
||
## Create the resources | ||
|
||
Follow the instructions in the [README for the Aurora Serverless application](/resources/cdk/aurora_serverless_app/README.md) to use the AWS Cloud Development Kit (AWS CDK) or AWS Command Line Interface (AWS CLI) to create and manage the resources. | ||
|
||
## Run the example | ||
|
||
### REST service | ||
|
||
#### Configure the service | ||
|
||
Before you run the service, enter your AWS resource values and verified email address | ||
in `configuration/local.yaml`, similar to the following: | ||
|
||
```yaml | ||
rds: | ||
db_instance: auroraappdb | ||
secret_arn: "arn:aws:secretsmanager:us-east-1:1111222233334444:secret:docexampleauroraappsecret8B-EXAMPLE-Dz2N2y" | ||
cluster_arn: "arn:aws:rds:us-east-1:1111222233334444:cluster:docexampleauroraapp-docexampleauroraappclustereb7e-EXAMPLE" | ||
ses: | ||
source: "[email protected]" # Replace with an email address that is registered with Amazon SES. | ||
``` | ||
#### Run the service | ||
This example uses [Actix Web](https://actix.rs/) to host a local web server and REST service. | ||
With the web server running, you can send HTTP requests to the service endpoint to list, add, and update work items and to send email reports. | ||
``` | ||
cargo run | ||
``` | ||
|
||
### Webpage | ||
|
||
The REST service is designed to work with the item tracker plugin in the Elwing web client. | ||
The item tracker plugin is a JavaScript application that lets you manage work items, send requests to the REST service, and see the results. | ||
|
||
#### Run Elwing and select the item tracker | ||
|
||
1. Run Elwing by following the instructions in the [Elwing README](/resources/clients/react/elwing/README.md). | ||
1. When Elwing starts, a web browser opens http://localhost:3000/. | ||
1. Run the item tracker plugin by selecting **Item Tracker** in the left navigation bar. | ||
1. Follow the Elwing [Item Tracker instructions](/resources/clients/react/elwing/src/plugins/item-tracker/README.md). | ||
|
||
## Understand the example | ||
|
||
This example uses the Actix Web framework to host a local REST service and respond to HTTP requests. | ||
|
||
### Start up | ||
|
||
When the program first starts, it loads environment and configuration information from `src/configuration.rs`. | ||
It then prepares its Actix Web resources and SDK clients in `src/startup.rs`. | ||
These helpers are also used in `test/startup.rs` to ensure the application is running in a consistent environment in development, testing, and production. | ||
|
||
### Routing | ||
|
||
Top level routing happens when creating the HTTP server in `src/startup.rs`, with specific routes registered in `src/healthz.rs`, `src/collection.rs`, and `src/report.rs`. | ||
All routes are instrumented, and primarily serve as a facade between Actix's HTTP tooling and the SDK resources. | ||
|
||
```Rust | ||
/// Retrieve a single WorkItem, in a JSON body, specified by a URL parameter. | ||
#[actix_web::get("/{id}")] | ||
#[tracing::instrument(name = "Request Retrieve single WorkItem", skip(client))] | ||
async fn retrieve( | ||
itemid: Path<String>, | ||
client: Data<crate::client::RdsClient>, | ||
) -> Result<Json<crate::work_item::WorkItem>, crate::work_item::WorkItemError> { | ||
crate::work_item::repository::retrieve(itemid.to_string(), &client) | ||
.await | ||
.map(Json) | ||
} | ||
``` | ||
|
||
### Aurora Serverless repository | ||
|
||
The [repository.rs](src/work_item/repository.rs) file contains functions that get and set data in an Aurora Serverless database by using an Amazon Relational Database Service (Amazon RDS) Data Service client. | ||
|
||
For example, the `retrieve` function constructs a `SELECT` statement and parameters and sends them to the data client to get a single work item. | ||
|
||
```Rust | ||
pub async fn retrieve(id: String, client: &crate::client::RdsClient) -> Result<crate::work_item::WorkItem, crate::work_item::WorkItemError> { | ||
let statement = client | ||
.execute_statement() | ||
.sql(format!( | ||
r#"SELECT {FIELDS} FROM Work WHERE idwork = :idwork;"# | ||
)) | ||
.set_parameters(params![("idwork", id)]) | ||
.format_records_as(RecordsFormatType::Json) | ||
.send() | ||
.await; | ||
|
||
let items = parse_rds_output(statement)?; | ||
todo!("Further checks to ensure a single item was retrieved") | ||
} | ||
``` | ||
|
||
### Amazon SES report | ||
|
||
The [report.rs](src/report.rs) file contains functions that route the report HTTP request and send an email report of work items to a specified email address. | ||
|
||
The report is send as an XSLX Excel spreadsheet. | ||
When you use Amazon SES to send an attachment, you must use the `send_raw_email` service action and send the email in MIME format. | ||
|
||
## Delete the resources | ||
|
||
To avoid charges, delete all the resources that you created for this tutorial. | ||
|
||
If you created the example resources by using the AWS CDK or AWS CLI, you can destroy the resources by following the instructions in the [README for the Aurora Serverless application](/resources/cdk/aurora_serverless_app/README.md). | ||
|
||
If you created your resources through the AWS Management Console, or modified them by running the app, you must use the console to delete them. | ||
|
||
## Next steps | ||
|
||
Congratulations! | ||
You have built a REST service that reads, writes, and archives work items that are stored in an Aurora Serverless database, and that uses Amazon SES to send email to a registered user. | ||
|
||
## Additional information | ||
|
||
- [Amazon Aurora User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/CHAP_AuroraOverview.html) | ||
- [Amazon RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Welcome.html) | ||
- [Amazon SES Developer Guide](https://docs.aws.amazon.com/ses/latest/dg/Welcome.html) | ||
- [Amazon RDS Data Service Rust SDK API Reference](https://crates.io/crates/aws-sdk-rdsdata) | ||
|
||
--- | ||
|
||
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
|
||
SPDX-License-Identifier: Apache-2.0 |
2 changes: 2 additions & 0 deletions
2
rust_dev_preview/cross_service/rest_ses/configuration/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
local.yaml | ||
production.yaml |
Oops, something went wrong.