Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade axum to 0.7.4 #121

Merged
merged 11 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
cscetbon marked this conversation as resolved.
Show resolved Hide resolved
_ = 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 {
cscetbon marked this conversation as resolved.
Show resolved Hide resolved
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,
{
cscetbon marked this conversation as resolved.
Show resolved Hide resolved
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
Loading