Skip to content

Commit

Permalink
Introduce opaque service endpoint id (#413)
Browse files Browse the repository at this point in the history
  • Loading branch information
slinkydeveloper authored May 17, 2023
1 parent 06ab1e3 commit c334c6e
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ description = "Restate makes distributed applications easy!"
anyhow = "1.0.68"
arc-swap = "1.6"
assert2 = "0.3.10"
base64 = "0.21"
bytes = { version = "1.3", features = ["serde"] }
bytestring = { version = "1.2", features = ["serde"] }
bytes-utils = "0.1.3"
Expand Down
1 change: 1 addition & 0 deletions src/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ serde = ["dep:serde", "dep:serde_with"]
options_schema = ["serde", "dep:schemars"]

[dependencies]
base64 = { workspace = true }
bytes = { workspace = true }
bytestring = { workspace = true }
schemars = { workspace = true, optional = true }
Expand Down
1 change: 1 addition & 0 deletions src/common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod errors;
pub mod opaque;
pub mod partitioner;
pub mod retry_policy;
pub mod traits;
Expand Down
95 changes: 95 additions & 0 deletions src/common/src/opaque.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use crate::types;
use crate::utils::GenericError;
use base64::engine::general_purpose::STANDARD;
use base64::prelude::*;
use std::error::Error;
use std::fmt;
use uuid::Uuid;

#[derive(Debug, Default, thiserror::Error)]
#[error("cannot parse the opaque id, bad format")]
pub struct ParseError {
#[source]
cause: Option<GenericError>,
}

impl ParseError {
pub fn from_cause(cause: impl Error + Send + Sync + 'static) -> Self {
Self {
cause: Some(Box::new(cause)),
}
}
}

#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[cfg_attr(feature = "options_schema", derive(schemars::JsonSchema))]
pub struct ServiceInvocationId(String);

impl fmt::Display for ServiceInvocationId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}

impl From<types::ServiceInvocationId> for ServiceInvocationId {
fn from(value: types::ServiceInvocationId) -> Self {
ServiceInvocationId(format!(
"{}-{}-{}",
value.invocation_id.as_simple(),
value.service_id.service_name,
STANDARD.encode(value.service_id.key)
))
}
}

impl TryFrom<ServiceInvocationId> for types::ServiceInvocationId {
type Error = ParseError;

fn try_from(value: ServiceInvocationId) -> Result<Self, Self::Error> {
let ServiceInvocationId(str) = value;

// This encoding is based on the fact that neither invocation_id
// nor service_name can contain the '-' character
// Invocation id is serialized as simple
// Service name follows the fullIdent ABNF here:
// https://protobuf.dev/reference/protobuf/proto3-spec/#identifiers
let mut splits: Vec<&str> = str.splitn(3, '-').collect();
if splits.len() != 3 {
return Err(ParseError::default());
}
let key = STANDARD
.decode(splits.pop().unwrap())
.map_err(ParseError::from_cause)?;
let service_name = splits.pop().unwrap().to_string();
let invocation_id: Uuid = splits
.pop()
.unwrap()
.parse()
.map_err(ParseError::from_cause)?;

Ok(types::ServiceInvocationId::new(
service_name,
key,
invocation_id,
))
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn roundtrip_service_invocation_id() {
let expected_sid = types::ServiceInvocationId::new(
"my.example.Service",
"-------stuff------".as_bytes().to_vec(),
Uuid::now_v7(),
);
let opaque_sid: ServiceInvocationId = expected_sid.clone().into();
let actual_sid: types::ServiceInvocationId = opaque_sid.try_into().unwrap();
assert_eq!(expected_sid, actual_sid);
}
}
2 changes: 1 addition & 1 deletion src/service_metadata/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ serde_schema = ["serde", "dep:schemars", "restate_common/options_schema"]

[dependencies]
arc-swap = { workspace = true }
base64 = "0.21"
base64 = { workspace = true }
restate_common = { workspace = true }
schemars = { workspace = true, optional = true }
serde = { workspace = true, optional = true }
Expand Down

0 comments on commit c334c6e

Please sign in to comment.