Skip to content

Commit a45175a

Browse files
committed
Add experimental thrift API client
1 parent a050bca commit a45175a

File tree

15 files changed

+94471
-1
lines changed

15 files changed

+94471
-1
lines changed

Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rbfrt"
3-
version = "0.1.8"
3+
version = "0.1.9"
44
authors = ["Steffen Lindner", "Fabian Ihle", "Etienne Zink"]
55
edition = "2021"
66
license = "Apache-2.0"
@@ -25,7 +25,13 @@ async-stream = "0.3.6"
2525
crossbeam-channel = "0.5.15"
2626
prettytable-rs = "^0.10"
2727
futures-core = "0.3.31"
28+
# Thrift support
29+
thrift = { version = "0.17", optional = true }
2830

2931
[build-dependencies]
3032
tonic-prost-build = "0.14.2"
3133
prost-build = "0.14.1"
34+
35+
[features]
36+
default = []
37+
thrift-support = ["thrift"]

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
- [Rust BF Runtime Interface (RBFRT)](#rust-bf-runtime-interface-rbfrt)
1414
- [Overview](#overview)
15+
- [Features](#features)
1516
- [Documentation](#documentation)
1617
- [Cite](#cite)
1718

@@ -24,6 +25,15 @@ The RBFRT is a Rust-based control plane library.
2425
It provides a fast and memory-safe interface to configure the Intel Tofino.
2526
It uses gRPC and the official Protobuf definitions of the [Open-Tofino](https://github.com/barefootnetworks/Open-Tofino) GitHub repository.
2627

28+
## Features
29+
30+
- **BFRuntime gRPC Interface** - High-level table, register, and digest operations
31+
- **Thrift PD API Support** (optional) - Low-level platform-dependent operations
32+
- Port MTU configuration
33+
- Traffic Manager (TM) APIs
34+
- Multicast and pipeline management
35+
- See [THRIFT.md](THRIFT.md) for setup and usage
36+
2737
## Documentation
2838

2939
The documentation of this crate is deployed as a [GitHub page](https://uni-tue-kn.github.io/rbfrt/rbfrt/).

src/lib.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,31 @@ pub mod error;
6363
mod protos;
6464
pub mod register;
6565
pub mod table;
66+
#[cfg(feature = "thrift-support")]
67+
pub mod thrift_client;
68+
69+
// Generated Thrift code wrappers
70+
#[cfg(feature = "thrift-support")]
71+
#[allow(warnings)]
72+
mod thrift_gen;
73+
74+
// Re-export generated Thrift modules
75+
#[cfg(feature = "thrift-support")]
76+
pub use thrift_gen::res;
77+
78+
#[cfg(feature = "thrift-support")]
79+
pub mod thrift_generated {
80+
pub use super::res;
81+
pub use super::thrift_gen::conn_mgr_pd_rpc as conn_mgr;
82+
pub use super::thrift_gen::devport_mgr_pd_rpc as devport_mgr;
83+
pub use super::thrift_gen::mc_pd_rpc as mc;
84+
pub use super::thrift_gen::mirror_pd_rpc as mirror;
85+
pub use super::thrift_gen::pal_rpc as pal;
86+
pub use super::thrift_gen::pipemgr_api as pipemgr;
87+
pub use super::thrift_gen::port_mgr_pd_rpc as port_mgr;
88+
pub use super::thrift_gen::tm_api as tm;
89+
pub use super::thrift_gen::ts_pd_rpc as ts;
90+
}
6691
pub mod util;
6792

6893
use crate::bfrt_proto::forwarding_pipeline_config::Profile;

src/thrift_client/mod.rs

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/* Copyright 2023-present University of Tuebingen, Chair of Communication Networks
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
//! Thrift client helpers
17+
//!
18+
//! This module provides convenience functions for connecting to Thrift services.
19+
//!
20+
//! # Example - Using Timestamp Service
21+
//! ```no_run
22+
//! use rbfrt::thrift_client;
23+
//! use rbfrt::thrift_generated::ts::{TsSyncClient, TTsSyncClient};
24+
//!
25+
//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
26+
//! // Create Thrift client with all protocol setup done
27+
//! let mut ts_client: TsSyncClient<_, _> = thrift_client::connect("localhost:9090")?;
28+
//!
29+
//! // Use ALL Thrift APIs directly
30+
//! ts_client.ts_global_ts_value_set(0, 1_000_000_000)?;
31+
//! # Ok(())
32+
//! # }
33+
//! ```
34+
35+
use thrift::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol};
36+
use thrift::transport::{
37+
ReadHalf, TFramedReadTransport, TFramedWriteTransport, TIoChannel, TTcpChannel, WriteHalf,
38+
};
39+
40+
use crate::error::RBFRTError;
41+
42+
/// Type alias for Thrift input protocol
43+
pub type ThriftInputProtocol = TBinaryInputProtocol<TFramedReadTransport<ReadHalf<TTcpChannel>>>;
44+
45+
/// Type alias for Thrift output protocol
46+
pub type ThriftOutputProtocol =
47+
TBinaryOutputProtocol<TFramedWriteTransport<WriteHalf<TTcpChannel>>>;
48+
49+
/// Connect to a Thrift service and return protocol layers
50+
///
51+
/// This function handles all the boilerplate of creating a TCP connection
52+
/// and setting up the Thrift protocol layers.
53+
///
54+
/// # Arguments
55+
/// * `address` - Server address in format "host:port" (e.g., "localhost:9090")
56+
///
57+
/// # Returns
58+
/// Returns a tuple of (InputProtocol, OutputProtocol) that can be passed to any Thrift client's new() method
59+
///
60+
/// # Example
61+
/// ```no_run
62+
/// use rbfrt::thrift_client;
63+
/// use rbfrt::thrift_generated::ts::{TsSyncClient, TTsSyncClient};
64+
///
65+
/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
66+
/// // Create timestamp client
67+
/// let (i_prot, o_prot) = thrift_client::connect("localhost:9090")?;
68+
/// let mut ts_client = TsSyncClient::new(i_prot, o_prot);
69+
/// ts_client.ts_global_ts_value_set(0, 1_000_000_000)?;
70+
///
71+
/// // Create port manager client
72+
/// use rbfrt::thrift_generated::port_mgr::PortMgrSyncClient;
73+
/// let (i_prot, o_prot) = thrift_client::connect("localhost:9090")?;
74+
/// let mut port_client = PortMgrSyncClient::new(i_prot, o_prot);
75+
/// port_client.port_mgr_mtu_set(0, 128, 9000, 9000)?;
76+
/// # Ok(())
77+
/// # }
78+
/// ```
79+
pub fn connect(address: &str) -> Result<(ThriftInputProtocol, ThriftOutputProtocol), RBFRTError> {
80+
// Create TCP connection
81+
let mut channel = TTcpChannel::new();
82+
channel
83+
.open(address)
84+
.map_err(|e| RBFRTError::GenericError {
85+
message: format!("Thrift connection to {} failed: {}", address, e),
86+
})?;
87+
88+
// Split channel for bidirectional communication
89+
let (i_chan, o_chan) = channel.split().map_err(|e| RBFRTError::GenericError {
90+
message: format!("Failed to split channel: {}", e),
91+
})?;
92+
93+
// Create protocol layers
94+
let i_prot = TBinaryInputProtocol::new(TFramedReadTransport::new(i_chan), true);
95+
let o_prot = TBinaryOutputProtocol::new(TFramedWriteTransport::new(o_chan), true);
96+
97+
Ok((i_prot, o_prot))
98+
}
99+
100+
#[cfg(test)]
101+
mod tests {
102+
use super::*;
103+
use crate::thrift_generated::ts::TsSyncClient;
104+
105+
#[test]
106+
fn test_connect_signature() {
107+
// This test ensures the types compile correctly
108+
// Actual connection would require a running Thrift server
109+
fn _example() -> Result<(), RBFRTError> {
110+
let (i_prot, o_prot) = connect("localhost:9090")?;
111+
let _client = TsSyncClient::new(i_prot, o_prot);
112+
Ok(())
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)