Skip to content

Commit

Permalink
Allow compiling protos from other workspaces
Browse files Browse the repository at this point in the history
Ref #4573
Ref #4587
  • Loading branch information
tiziano88 committed Jan 3, 2024
1 parent d2788f6 commit 91e7fe7
Show file tree
Hide file tree
Showing 8 changed files with 1,640 additions and 154 deletions.
1,659 changes: 1,512 additions & 147 deletions micro_rpc_workspace_test/Cargo.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions micro_rpc_workspace_test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ edition = "2021"
license = "Apache-2.0"

[dependencies]
oak_crypto = { path = "../oak_crypto" }
micro_rpc = { path = "../micro_rpc" }
prost = "*"
tonic = "*"

[build-dependencies]
oak_grpc_utils = { path = "../oak_grpc_utils" }

[workspace]
33 changes: 33 additions & 0 deletions micro_rpc_workspace_test/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Copyright 2024 The Project Oak Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

use oak_grpc_utils::{generate_grpc_code, CodegenOptions, ExternPath};

fn main() -> Result<(), Box<dyn std::error::Error>> {
generate_grpc_code(
"proto",
&["test.proto", "stubs.proto"],
CodegenOptions {
extern_paths: vec![ExternPath::new(
".oak.crypto.v1",
"::oak_crypto::proto::oak::crypto::v1",
)],
..Default::default()
},
)?;

Ok(())
}
1 change: 1 addition & 0 deletions micro_rpc_workspace_test/deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ unknown-git = "allow"
allow = [
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"BSD-3-Clause",
"MIT",
"Unicode-DFS-2016",
]
Expand Down
26 changes: 26 additions & 0 deletions micro_rpc_workspace_test/proto/stubs.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Copyright 2024 The Project Oak Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

syntax = "proto3";

// This file contains empty proto message stubs to make protoc happy when compiling code that
// depends on Oak protos that are not available in other repos.
// The actual implementations are provided in Rust using the `extern_paths` option of
// tonic: https://docs.rs/tonic-build/0.10.2/tonic_build/struct.Builder.html#method.extern_path
// See also the `build.rs` file in this crate.
package oak.crypto.v1;

message EncryptedRequest {}
25 changes: 25 additions & 0 deletions micro_rpc_workspace_test/proto/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// Copyright 2024 The Project Oak Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

syntax = "proto3";

import "stubs.proto";

package oak.test;

message TestRequestWrapper {
.oak.crypto.v1.EncryptedRequest encrypted_request = 1;
}
28 changes: 28 additions & 0 deletions micro_rpc_workspace_test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
// limitations under the License.
//

mod proto {
pub mod oak {
pub mod test {
tonic::include_proto!("oak.test");
}
}
}

// Test to confirm that the dependency on micro_rpc and its own protobuf types works correctly.
#[test]
fn micro_rpc_dep_test() {
Expand All @@ -27,3 +35,23 @@ fn micro_rpc_dep_test() {
r##"ResponseWrapper { response: Some(Error(Status { code: 3, message: "error" })) }"##
);
}

// Test to confirm that the dependency on oak_crypto and its own protobuf types works correctly.
#[test]
fn oak_crypto_dep_test() {
let request_wrapper = proto::oak::test::TestRequestWrapper {
encrypted_request: Some(oak_crypto::proto::oak::crypto::v1::EncryptedRequest {
encrypted_message: Some(oak_crypto::proto::oak::crypto::v1::AeadEncryptedMessage {
associated_data: vec![],
nonce: vec![],
ciphertext: vec![],
}),
serialized_encapsulated_public_key: Some(vec![]),
}),
};

assert_eq!(
format!("{request_wrapper:?}"),
r##"TestRequestWrapper { encrypted_request: Some(EncryptedRequest { encrypted_message: Some(AeadEncryptedMessage { ciphertext: [], associated_data: [], nonce: [] }), serialized_encapsulated_public_key: Some([]) }) }"##
);
}
16 changes: 9 additions & 7 deletions oak_grpc_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,23 @@ impl ExternPath {

/// Generate gRPC code from Protobuf using `tonic` library.
///
/// The path to the root repository must be passed as `proto_path`. All paths to `.proto` files
/// The path to the root repository must be passed as `include`. All paths to `.proto` files
/// must be specified relative to this path. Likewise, all imported paths in `.proto` files must
/// be specified relative to this path.
// TODO(#4588): Swap the include and protos arguments, so they match the order of the
// corresponding arguments in the `tonic_build::configure()` function.
pub fn generate_grpc_code(
proto_path: &str,
file_paths: &[&str],
include: &str,
protos: &[&str],
options: CodegenOptions,
) -> std::io::Result<()> {
set_protoc_env_if_unset();

// TODO(#1093): Move all proto generation to a common crate.
let proto_path = std::path::Path::new(proto_path);
let file_paths: Vec<std::path::PathBuf> = file_paths
let include = std::path::Path::new(include);
let file_paths: Vec<std::path::PathBuf> = protos
.iter()
.map(|file_path| proto_path.join(file_path))
.map(|file_path| include.join(file_path))
.collect();

// Generate the normal (non-Oak) server and client code for the gRPC service,
Expand All @@ -80,7 +82,7 @@ pub fn generate_grpc_code(
for extern_path in options.extern_paths {
config = config.extern_path(extern_path.proto_path, extern_path.rust_path);
}
config.compile(&file_paths, &[proto_path.to_path_buf()])
config.compile(&file_paths, &[include])
}

fn set_protoc_env_if_unset() {
Expand Down

0 comments on commit 91e7fe7

Please sign in to comment.