Skip to content

Commit

Permalink
Upgrade axum to 0.7.4 (#121)
Browse files Browse the repository at this point in the history
* Upgrade Axum to 0.7.4

Signed-off-by: Cyril Scetbon <cscetbon@gmail.com>

* Export Axum crate

Signed-off-by: Cyril Scetbon <cscetbon@gmail.com>

* Upgrade Axum in macros as well

Signed-off-by: Cyril Scetbon <cscetbon@gmail.com>

* Upgrade crates that depend on Axum

Signed-off-by: Cyril Scetbon <cscetbon@gmail.com>

* Use axum from dapr::server::actor

Signed-off-by: Cyril Scetbon <cscetbon@gmail.com>

* Remove trailing spaces and fix typos

Signed-off-by: Cyril Scetbon <cscetbon@gmail.com>

* Format file

Signed-off-by: Cyril Scetbon <cscetbon@gmail.com>

* Upgrade env_logger and toolchain

Signed-off-by: Cyril Scetbon <cscetbon@gmail.com>

* Trim spaces and remove useless quotes

Signed-off-by: Cyril Scetbon <cscetbon@gmail.com>

* Use named parameter

Signed-off-by: Cyril Scetbon <cscetbon@gmail.com>

* Run cargo fmt

Signed-off-by: Cyril Scetbon <cscetbon@gmail.com>

---------

Signed-off-by: Cyril Scetbon <cscetbon@gmail.com>
  • Loading branch information
cscetbon committed Feb 23, 2024
1 parent a9df2d9 commit bef6e3b
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 69 deletions.
12 changes: 5 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ on:
env:
CARGO_TERM_COLOR: always
CARGO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
PROTOC_VERSION: '3.x'
RUST_TOOLCHAIN: '1.70.0'
PROTOC_VERSION: 3.x
RUST_TOOLCHAIN: 1.76.0

jobs:
lint:
name: Lint
name: Lint
runs-on: ubuntu-latest

steps:
Expand All @@ -42,7 +42,7 @@ jobs:


build:
name: Build
name: Build
runs-on: ubuntu-latest

steps:
Expand All @@ -63,7 +63,7 @@ jobs:
run: cargo build --examples
- name: Run Tests
run: cargo test --all-targets

publish:
name: Publish
runs-on: ubuntu-latest
Expand All @@ -86,5 +86,3 @@ jobs:
run: cargo publish --manifest-path macros/Cargo.toml --token ${{ env.CARGO_TOKEN }}
- name: cargo publish
run: cargo publish --token ${{ env.CARGO_TOKEN }}


15 changes: 7 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,27 @@ description = "Rust SDK for dapr"
readme = "README.md"
keywords = ["microservices", "dapr"]


[dependencies]
dapr-macros = {version="0.14.0", path = "macros" }
futures = "0.3"
tonic = "0.8"
prost = "0.11"
tonic = "0.11.0"
prost = "0.12.3"
bytes = "1"
prost-types = "0.11"
prost-types = "0.12.3"
async-trait = "0.1"
env_logger = "0.10"
env_logger = "0.11.2"
log = "0.4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
axum = {version = "0.6.19", features = ["default", "headers"] }
axum = "0.7.4"
tokio = { version = "1.29", features = ["sync"] }
chrono = "0.4.24"

[build-dependencies]
tonic-build = "0.8"
tonic-build = "0.11.0"

[dev-dependencies]
axum-test = "12.1.0"
axum-test = "14.3.0"
once_cell = "1.18.0"
tokio = { version = "1", features = ["full"] }
uuid = { version = "1.4.0", features = ["v4"] }
Expand Down
32 changes: 16 additions & 16 deletions examples/actors/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Actor Example

This example demonstrates the Dapr actor framework. To author an actor,
This example demonstrates the Dapr actor framework. To author an actor,

1. Create a struc decorated with the `#[dapr::actor]` macro to house your custom actor methods that map to [Axum handlers](https://docs.rs/axum/latest/axum/handler/index.html), use [Axum extractors](https://docs.rs/axum/latest/axum/extract/index.html) to access the incoming request and return an [`impl IntoResponse`](https://docs.rs/axum/latest/axum/response/trait.IntoResponse.html).
Use the `DaprJson` extractor to deserialize the request from Json coming from a Dapr sidecar.
Expand All @@ -10,24 +10,24 @@ Use the `DaprJson` extractor to deserialize the request from Json coming from a
id: String,
client: ActorContextClient
}

#[derive(Serialize, Deserialize)]
pub struct MyRequest {
pub name: String,
}

#[derive(Serialize, Deserialize)]
pub struct MyResponse {
pub available: bool,
}
}

impl MyActor {
fn do_stuff(&self, DaprJson(data): DaprJson<MyRequest>) -> Json<MyResponse> {
println!("doing stuff with {}", data.name);
Json(MyResponse {
available: true
fn do_stuff(&self, DaprJson(data): DaprJson<MyRequest>) -> Json<MyResponse> {
println!("doing stuff with {}", data.name);
Json(MyResponse {
available: true
})
}
}
}
```

Expand All @@ -40,14 +40,14 @@ Use the `DaprJson` extractor to deserialize the request from Json coming from a
1. Implement the `Actor` trait. This trait exposes the following methods:
- `on_activate` - Called when an actor is activated on a host
- `on_deactivate` - Called when an actor is deactivated on a host
- `on_reminder` - Called when a reminder is recieved from the Dapr sidecar
- `on_timer` - Called when a timer is recieved from the Dapr sidecar
- `on_reminder` - Called when a reminder is received from the Dapr sidecar
- `on_timer` - Called when a timer is received from the Dapr sidecar


```rust
#[async_trait]
impl Actor for MyActor {

async fn on_activate(&self) -> Result<(), ActorError> {
println!("on_activate {}", self.id);
Ok(())
Expand All @@ -60,18 +60,18 @@ Use the `DaprJson` extractor to deserialize the request from Json coming from a
}
```

1. An actor host requires an Http server to recieve callbacks from the Dapr sidecar. The `DaprHttpServer` object implements this functionality and also encapsulates the actor runtime to service any hosted actors. Use the `register_actor` method to register an actor type to be serviced, this method takes an `ActorTypeRegistration` which specifies
1. An actor host requires an Http server to receive callbacks from the Dapr sidecar. The `DaprHttpServer` object implements this functionality and also encapsulates the actor runtime to service any hosted actors. Use the `register_actor` method to register an actor type to be serviced, this method takes an `ActorTypeRegistration` which specifies
- The actor type name (used by Actor clients), and concrete struct
- A factory to construct a new instance of that actor type when one is required to be activated by the runtime. The parameters passed to the factory will be the actor type, actor ID, and a Dapr client for managing state, timers and reminders for the actor.
- The methods that you would like to expose to external clients.

```rust
let mut dapr_server = dapr::server::DaprHttpServer::new();

dapr_server.register_actor(ActorTypeRegistration::new::<MyActor>("MyActor",
dapr_server.register_actor(ActorTypeRegistration::new::<MyActor>("MyActor",
Box::new(|actor_type, id, client| Arc::new(MyActor{
actor_type,
id,
actor_type,
id,
client
})))
.register_method("do_stuff", MyActor::do_stuff)
Expand Down
4 changes: 2 additions & 2 deletions examples/actors/server.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use async_trait::async_trait;
use axum::Json;
use dapr::server::{
actor::{
context_client::ActorContextClient, runtime::ActorTypeRegistration, Actor, ActorError,
axum::Json, context_client::ActorContextClient, runtime::ActorTypeRegistration, Actor,
ActorError,
},
utils::DaprJson,
};
Expand Down
2 changes: 1 addition & 1 deletion macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ proc-macro = true
[dependencies]
async-trait = "0.1"
log = "0.4"
axum = "0.6.19"
axum = "0.7.4"
syn = {version="2.0.29",features=["full"]}
quote = "1.0.8"
6 changes: 3 additions & 3 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ pub fn actor(_attr: TokenStream, item: TokenStream) -> TokenStream {

let mut result = TokenStream::from(quote!(
#[async_trait::async_trait]
impl axum::extract::FromRequestParts<dapr::server::actor::runtime::ActorState> for &#actor_struct_name {
impl dapr::server::actor::axum::extract::FromRequestParts<dapr::server::actor::runtime::ActorState> for &#actor_struct_name {
type Rejection = dapr::server::actor::ActorRejection;

async fn from_request_parts(
parts: &mut axum::http::request::Parts,
parts: &mut dapr::server::actor::axum::http::request::Parts,
state: &dapr::server::actor::runtime::ActorState,
) -> Result<Self, Self::Rejection> {
let path = match axum::extract::Path::<dapr::server::actor::ActorPath>::from_request_parts(parts, state).await {
let path = match dapr::server::actor::axum::extract::Path::<dapr::server::actor::ActorPath>::from_request_parts(parts, state).await {
Ok(path) => path,
Err(e) => {
log::error!("Error getting path: {}", e);
Expand Down
2 changes: 2 additions & 0 deletions src/server/actor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::{error::Error, fmt::Display, sync::Arc};

use self::context_client::ActorContextClient;

pub use axum;

pub mod context_client;
pub mod runtime;

Expand Down
38 changes: 16 additions & 22 deletions src/server/actor/tests.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
use std::{
collections::HashMap,
net::{SocketAddr, TcpListener},
sync::Arc,
};
use std::{collections::HashMap, sync::Arc};

use async_trait::async_trait;
use axum::{Json, Router};
Expand All @@ -15,7 +11,7 @@ use dapr_macros::actor;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use serde_json::json;
use tokio::sync::Mutex;
use tokio::{net::TcpListener, sync::Mutex};
use uuid::Uuid;

#[derive(Serialize, Deserialize, Debug, PartialEq)]
Expand Down Expand Up @@ -68,13 +64,13 @@ impl MyActor {

#[tokio::test]
async fn test_actor_invoke() {
let dapr_port = get_available_port().unwrap();
let dapr_port = get_available_port().await.unwrap();

let fake_sidecar = tokio::spawn(async move {
let sidecar = Router::new();
_ = axum::Server::bind(&SocketAddr::from(([127, 0, 0, 1], dapr_port)))
.serve(sidecar.into_make_service())
.await;
let address = format!("127.0.0.1:{dapr_port}");
let listener = TcpListener::bind(address).await.unwrap();
_ = axum::serve(listener, sidecar.into_make_service()).await;
});
tokio::task::yield_now().await;

Expand Down Expand Up @@ -140,13 +136,13 @@ async fn test_actor_invoke() {

#[tokio::test]
async fn test_actor_deactivate() {
let dapr_port = get_available_port().unwrap();
let dapr_port = get_available_port().await.unwrap();

let fake_sidecar = tokio::spawn(async move {
let sidecar = Router::new();
_ = axum::Server::bind(&SocketAddr::from(([127, 0, 0, 1], dapr_port)))
.serve(sidecar.into_make_service())
.await;
let address = format!("127.0.0.1:{dapr_port}");
let listener = TcpListener::bind(address).await.unwrap();
_ = axum::serve(listener, sidecar.into_make_service()).await;
});
tokio::task::yield_now().await;

Expand Down Expand Up @@ -246,13 +242,11 @@ impl TestState {

static TEST_STATE: Lazy<TestState> = Lazy::new(TestState::new);

fn get_available_port() -> Option<u16> {
(8000..9000).find(|port| port_is_available(*port))
}

fn port_is_available(port: u16) -> bool {
match TcpListener::bind(("127.0.0.1", port)) {
Ok(_) => true,
Err(_) => false,
async fn get_available_port() -> Option<u16> {
for port in 8000..9000 {
if TcpListener::bind(format!("127.0.0.1:{port}")).await.is_ok() {
return Some(port);
}
}
None
}
8 changes: 5 additions & 3 deletions src/server/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use axum::{
Json, Router,
};
use futures::{Future, FutureExt};
use std::{net::SocketAddr, pin::Pin, sync::Arc};
use std::{pin::Pin, sync::Arc};
use tokio::net::TcpListener;

use super::super::client::TonicClient;
use super::actor::runtime::{ActorRuntime, ActorTypeRegistration};
Expand Down Expand Up @@ -136,9 +137,10 @@ impl DaprHttpServer {
.parse()
.unwrap_or(8080);

let addr = SocketAddr::from(([127, 0, 0, 1], port.unwrap_or(default_port)));
let address = format!("127.0.0.1:{}", port.unwrap_or(default_port));
let listener = TcpListener::bind(address).await.unwrap();

let server = axum::Server::bind(&addr).serve(app.into_make_service());
let server = axum::serve(listener, app.into_make_service());

let final_result = match self.shutdown_signal.take() {
Some(signal) => {
Expand Down
10 changes: 3 additions & 7 deletions src/server/utils.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use async_trait::async_trait;
use axum::{
body::HttpBody,
body::Body,
extract::FromRequest,
http::{Request, StatusCode},
response::IntoResponse,
BoxError,
};
use serde::de::DeserializeOwned;

Expand All @@ -18,17 +17,14 @@ pub enum JsonRejection {
}

#[async_trait]
impl<T, S, B> FromRequest<S, B> for DaprJson<T>
impl<T, S> FromRequest<S> for DaprJson<T>
where
T: DeserializeOwned,
B: HttpBody + Send + 'static,
B::Data: Send,
B::Error: Into<BoxError>,
S: Send + Sync,
{
type Rejection = JsonRejection;

async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
let bytes = match axum::body::Bytes::from_request(req, state).await {
Ok(bytes) => bytes,
Err(e) => {
Expand Down

0 comments on commit bef6e3b

Please sign in to comment.