Skip to content

Commit

Permalink
feat: get rid of PublishedMessage derive (#18)
Browse files Browse the repository at this point in the history
* feat: get rid of PublishedMessage derive

* fix

* fixes
  • Loading branch information
hseeberger authored Oct 12, 2023
1 parent 840c38d commit 8bc7c4d
Show file tree
Hide file tree
Showing 20 changed files with 139 additions and 251 deletions.
2 changes: 1 addition & 1 deletion .blackbox/blackbox-files.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub-sub-client-tests/secrets/active-road-365118-2eca6b7b8fd9.json
secrets/active-road-365118-2eca6b7b8fd9.json
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ jobs:
env:
GCP_SERVICE_ACCOUNT: ${{ secrets.GCP_SERVICE_ACCOUNT }}
run: |
printenv GCP_SERVICE_ACCOUNT > pub-sub-client-tests/secrets/active-road-365118-2eca6b7b8fd9.json
printenv GCP_SERVICE_ACCOUNT > secrets/active-road-365118-2eca6b7b8fd9.json
just test
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ target
/.blackbox/pubring.gpg~
/.blackbox/pubring.kbx~
/.blackbox/secring.gpg
/pub-sub-client-tests/secrets/active-road-365118-2eca6b7b8fd9.json
active-road-365118-2eca6b7b8fd9.json
44 changes: 17 additions & 27 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
[workspace]
members = [
"pub-sub-client",
"pub-sub-client-derive",
"pub-sub-client-tests",
]
resolver = "2"

[workspace.package]
# No use to define version here, because cargo release ignores it!
# version = "0.10.1-alpha.0"
[package]
name = "pub-sub-client"
version = "0.11.1-alpha.0"
edition = "2021"
description = "Google Cloud Pub/Sub client library"
authors = [ "Heiko Seeberger <[email protected]>" ]
Expand All @@ -17,23 +9,21 @@ readme = "README.md"
homepage = "https://github.com/hseeberger/pub-sub-client"
repository = "https://github.com/hseeberger/pub-sub-client"
documentation = "https://github.com/hseeberger/pub-sub-client"
publish = true

[workspace.dependencies]
[dependencies]
base64 = { version = "0.21" }
goauth = { version = "0.13" }
reqwest = { version = "0.11", features = [ "json" ] }
serde = { version = "1.0", features = [ "derive" ] }
serde_json = { version = "1.0" }
smpl_jwt = { version = "0.7" }
thiserror = { version = "1.0" }
time = { version = "0.3", features = [ "serde-well-known" ] }
tracing = { version = "0.1" }

[dev-dependencies]
anyhow = { version = "1.0" }
base64 = { version = "0.21" }
goauth = { version = "0.13" }
proc-macro2 = { version = "1.0" }
quote = { version = "1.0" }
reqwest = { version = "0.11" }
serde = { version = "1.0" }
serde_json = { version = "1.0" }
smpl_jwt = { version = "0.7" }
syn = { version = "2.0" }
testcontainers = { version = "0.15" }
testcontainers-modules = { version = "0.1", features = [ "google_cloud_sdk_emulators" ] }
thiserror = { version = "1.0" }
time = { version = "0.3" }
tokio = { version = "1" }
tracing = { version = "0.1" }
tracing-subscriber = { version = "0.3" }
tokio = { version = "1", features = [ "macros", "rt-multi-thread" ] }
tracing-subscriber = { version = "0.3", features = [ "env-filter", "fmt", "json" ] }
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

Google Cloud Pub/Sub client library in [Rust](https://www.rust-lang.org/). Currently publishing, pulling and acknowledging are supported, but no management tasks like creating topics or subscriptions.

Messages can either be published/pulled as raw or, if the payload is JSON data, serialized from/deserialized into domain messages (structs or enums) via [Serde](https://serde.rs/) and [Serde JSON](https://docs.serde.rs/serde_json). Both raw `ReceivedMessages` and "typed" `PulledMessages` expose metadata like message ID, acknowledge ID, attributes, etc.
Messages can either be published/pulled as raw or, if the payload is JSON data, serialized from/deserialized into domain messages (structs or enums) via [Serde](https://serde.rs/) and [Serde JSON](https://docs.serde.rs/serde_json). Both raw `RawPulledMessage`s and "typed" `PulledMessage`s expose metadata like message ID, acknowledge ID, attributes, etc.

Aside from straight forward deserialization it is also possible to first transform the pulled JSON values before deserizlizing into domain messages which allows for generally adjusting the JSON structure as well as schema evolution.

Expand All @@ -22,13 +22,13 @@ Aside from straight forward deserialization it is also possible to first transfo
Typically we want to use domain message:

``` rust
#[derive(Debug, Deserialize, Serialize, PublishedMessage)]
#[derive(Debug, Serialize, Deserialize)]
struct Message {
text: String,
}
```

In order to publish `Message`, we need to derive `Serialize` and `PublishedMessage` and to pull it we need to derive `Deserialize`.
To publish `Message` we need to derive `Serialize` and to pull it we need to derive `Deserialize`.

First create a `PubSubClient`, giving the path to a service account key file and the duration to refresh access tokens before they expire:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use pub_sub_client::{Error, PubSubClient, PublishedMessage};
use pub_sub_client::{Error, PubSubClient};
use serde::{Deserialize, Serialize};
use std::{env, error::Error as _, time::Duration};

const TOPIC_ID: &str = "test";
const SUBSCRIPTION_ID: &str = "test";

#[derive(Debug, Deserialize, Serialize, PublishedMessage)]
#[derive(Debug, Serialize, Deserialize)]
struct Message {
text: String,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use anyhow::anyhow;
use base64::{engine::general_purpose::STANDARD, Engine};
use pub_sub_client::{
Error, PubSubClient, PublishedMessage, PulledMessage, RawPublishedMessage,
RawPulledMessageEnvelope,
Error, PubSubClient, PulledMessage, RawPublishedMessage, RawPulledMessageEnvelope,
};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
Expand All @@ -11,7 +10,7 @@ use std::{collections::HashMap, env, error::Error as _, time::Duration};
const TOPIC_ID: &str = "test";
const SUBSCRIPTION_ID: &str = "test";

#[derive(Debug, Deserialize, Serialize, PublishedMessage)]
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
#[allow(dead_code)]
enum Message {
Expand Down
20 changes: 0 additions & 20 deletions pub-sub-client-derive/Cargo.toml

This file was deleted.

27 changes: 0 additions & 27 deletions pub-sub-client-derive/src/lib.rs

This file was deleted.

24 changes: 0 additions & 24 deletions pub-sub-client-tests/Cargo.toml

This file was deleted.

31 changes: 0 additions & 31 deletions pub-sub-client/Cargo.toml

This file was deleted.

54 changes: 0 additions & 54 deletions pub-sub-client/src/error/mod.rs

This file was deleted.

4 changes: 1 addition & 3 deletions release.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
pre-release-commit-message = "release: released {{crate_name}} v{{version}}"
post-release-commit-message = "release: bumping {{crate_name}} to v{{next_version}}"
dev-version = true
pre-release-commit-message = "release: v{{version}}"
52 changes: 52 additions & 0 deletions src/error/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use reqwest::Response;
use serde_json::Value;
use std::{convert::identity, error::Error as StdError};
use thiserror::Error;

#[derive(Debug, Error)]
pub enum Error {
#[error("initialization error: {reason}")]
Initialization {
reason: String,
source: Box<dyn StdError + Send + Sync + 'static>,
},

#[error("getting authentication token failed")]
TokenFetch(#[from] Box<goauth::GoErr>),

#[error("HTTP communication with Pub/Sub service failed")]
HttpServiceCommunication(#[source] reqwest::Error),
#[error("unexpected HTTP status code `{0}` from Pub/Sub service: {1}")]
UnexpectedHttpStatusCode(reqwest::StatusCode, String),
#[error("unexpected HTTP response from Pub/Sub service")]
UnexpectedHttpResponse(#[source] reqwest::Error),

#[error("decoding data of received message as Base64 failed")]
DecodeBase64(#[source] base64::DecodeError),
#[error("message contains no data")]
NoData,
#[error("deserializing data of received message failed")]
Deserialize(#[source] serde_json::Error),
#[error("serializing of message to be published failed")]
Serialize(#[source] serde_json::Error),
#[error("failed to transform JSON value")]
Transform(#[source] Box<dyn StdError + Send + Sync + 'static>),
}

impl Error {
pub async fn unexpected_http_status_code(response: Response) -> Error {
Error::UnexpectedHttpStatusCode(
response.status(),
response
.text()
.await
.map_err(|e| format!("failed to get response body as text: {e}"))
.and_then(|text| {
serde_json::from_str::<Value>(&text)
.map_err(|e| format!("failed to parse error response: {e}"))
.map(|v| v["error"]["message"].to_string())
})
.unwrap_or_else(identity),
)
}
}
Loading

0 comments on commit 8bc7c4d

Please sign in to comment.