Skip to content

Commit

Permalink
Digital Twin Graph
Browse files Browse the repository at this point in the history
  • Loading branch information
ashbeitz committed May 6, 2024
1 parent 7fc6ff1 commit 7a97fc3
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 17 deletions.
43 changes: 43 additions & 0 deletions core/common/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub enum ServiceUriSource {
///
/// # Arguments
/// * `config_filename` - Name of the config file to load settings from.
/// # Returns
/// * The settings.
pub fn load_settings<T>(config_filename: &str) -> Result<T, ConfigError>
where
T: for<'de> serde::Deserialize<'de>,
Expand All @@ -65,6 +67,8 @@ where
/// * `retry_interval_ms` - The retry interval between retries in milliseconds.
/// * `function` - The function to retry.
/// * `context` - Context field to provide additional info for logging.
/// # Returns
/// * The result of the function.
pub async fn execute_with_retry<T, E, Fut, F: FnMut() -> Fut>(
max_retries: u32,
retry_interval_ms: Duration,
Expand Down Expand Up @@ -108,6 +112,8 @@ where
/// * `version` - The service's version.
/// # `expected_communication_kind` - The service's expected communication kind.
/// # `expected_communication_reference` - The service's expected communication reference.
/// # Returns
/// * The service's URI.
pub async fn discover_service_using_chariott(
chariott_uri: &str,
namespace: &str,
Expand Down Expand Up @@ -147,6 +153,8 @@ pub async fn discover_service_using_chariott(
/// * `service_uri_source` - Enum providing information on how to get the service URI.
/// # `expected_communication_kind` - The service's expected communication kind.
/// # `expected_communication_reference` - The service's expected communication reference.
/// # Returns
/// * The service's URI.
pub async fn get_service_uri(
service_uri_source: ServiceUriSource,
expected_communication_kind: &str,
Expand Down Expand Up @@ -185,6 +193,19 @@ pub async fn get_service_uri(
Ok(result)
}

/// Is the provided subset a subset of the provided superset?
///
/// # Arguments
/// * `subset` - The provided subset.
/// * `superset` - The provided superset.
/// # Returns
/// * `true` if the subset is a subset of the superset, `false` otherwise.
pub fn is_subset(subset: &[String], superset: &[String]) -> bool {
subset.iter().all(|subset_member| {
superset.iter().any(|supserset_member| subset_member == supserset_member)
})
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -229,3 +250,25 @@ mod tests {
assert!(result.is_err());
}
}

#[test]
fn is_subset_test() {
assert!(is_subset(&[], &[]));
assert!(is_subset(&[], &["one".to_string()]));
assert!(is_subset(&[], &["one".to_string(), "two".to_string()]));
assert!(is_subset(&["one".to_string()], &["one".to_string()]));
assert!(is_subset(&["one".to_string()], &["one".to_string(), "two".to_string()]));
assert!(is_subset(
&["one".to_string(), "two".to_string()],
&["one".to_string(), "two".to_string()]
));
assert!(!is_subset(
&["one".to_string(), "two".to_string(), "three".to_string()],
&["one".to_string(), "two".to_string()]
));
assert!(!is_subset(
&["one".to_string(), "two".to_string(), "three".to_string()],
&["one".to_string()]
));
assert!(!is_subset(&["one".to_string(), "two".to_string(), "three".to_string()], &[]));
}
16 changes: 3 additions & 13 deletions core/module/digital_twin_graph/src/digital_twin_graph_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT license.
// SPDX-License-Identifier: MIT

use common::utils::is_subset;
use core_protobuf_data_access::async_rpc::v1::request::{
request_client::RequestClient, AskRequest,
};
Expand Down Expand Up @@ -63,17 +64,6 @@ impl DigitalTwinGraphImpl {
}
}

/// Is the provided subset a subset of the provided superset?
///
/// # Arguments
/// * `subset` - The provided subset.
/// * `superset` - The provided superset.
fn is_subset(subset: &[String], superset: &[String]) -> bool {
subset.iter().all(|subset_member| {
superset.iter().any(|supserset_member| subset_member == supserset_member)
})
}

/// Use the Digital Twin Registery service to find the endpoints for digital twin providers that support
/// the specified model id, protocol and operations.
///
Expand Down Expand Up @@ -112,7 +102,7 @@ impl DigitalTwinGraphImpl {
.flat_map(|entity_access_info| entity_access_info.endpoint_info_list.clone())
.filter(|endpoint_info| {
endpoint_info.protocol == protocol
&& Self::is_subset(operations, &endpoint_info.operations)
&& is_subset(operations, &endpoint_info.operations)
})
.collect())
}
Expand Down Expand Up @@ -155,7 +145,7 @@ impl DigitalTwinGraphImpl {
.flat_map(|entity_access_info| entity_access_info.endpoint_info_list.clone())
.filter(|endpoint_info| {
endpoint_info.protocol == protocol
&& Self::is_subset(operations, &endpoint_info.operations)
&& is_subset(operations, &endpoint_info.operations)
})
.collect())
}
Expand Down
9 changes: 5 additions & 4 deletions docs/design/modules/digital_twin_graph/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

## <a name="introduction">Introduction</a>

Ibeji today provides the foundations for constructing and interacting with a digital twin on an edge device. These are low-level abilities and do not necessarily
provide a consumer with the best interaction experience. They can be used as building blocks to build facades that provide a consumer with an abstraction that
delivers a much better interaction experience. In the future, Ibeji may support multiple facades and the user can select the one that they prefer to use.
The initial Ibeji provided the foundations for constructing and interacting with a digital twin on an edge device. These foundations are low-level abilities
and they do not necessarily provide a consumer with the best interaction experience. However, they can be used as building blocks to build facades that
provide a consumer with an abstraction that delivers a much better interaction experience. Ibeji may support multiple facades and the user can select the one
that they prefer to use.

This design specifies a graph-based facade, which will be named the Digital Twin Graph Service. With this facade, the digital twin will be represented as a
graph of digital twin entities whose arcs represent the relationships between those entities. Instance IDs will be used to refer to entities.
Expand All @@ -26,7 +27,7 @@ We will introduce a new service named "Digital Twin Graph" that will provide a f
providers. Ideally, the consumer will not need to directly interact with provider endpoints. Instead, the consumer will interact with a graph structure that
represents the digital twin.

Ibeji's In-vehicle Digital Twin Service needs some adjustments to support the Digital Twin Graph Service. We will introduce a modified form of the service under the name "Digital Twin Registry" and keep the existing functionality intact under the original In-vehicle Digital Twin Service.
Ibeji's In-vehicle Digital Twin Service needs some adjustments to support the Digital Twin Graph Service. We will introduce a modified form of the service under the name "Digital Twin Registry" and keep the existing functionality intact, for now, under the original In-vehicle Digital Twin Service.

The Managed Subscriber Service is an optional service that provides integration with Agemo. The Managed Subscriber Service has been included in the component diagram for completeness' sake.

Expand Down

0 comments on commit 7a97fc3

Please sign in to comment.