Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ApiKey additions #98

Merged
merged 2 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 44 additions & 5 deletions protocol_codegen/src/generate_messages.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::{BTreeMap, BTreeSet};
use std::collections::{BTreeMap, BTreeSet, HashMap};
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
Expand All @@ -11,13 +11,10 @@ mod generate;
mod parse;
mod spec;

use spec::SpecType;
use spec::{SpecType, VersionSpec};

pub fn run(messages_module_dir: &str, mut input_file_paths: Vec<PathBuf>) -> Result<(), Error> {
input_file_paths.sort();
let mut entity_types = BTreeSet::new();
let mut request_types = BTreeMap::new();
let mut response_types = BTreeMap::new();

let module_path = format!("{}.rs", messages_module_dir);

Expand All @@ -38,6 +35,7 @@ pub fn run(messages_module_dir: &str, mut input_file_paths: Vec<PathBuf>) -> Res
)?;
writeln!(m, "#[cfg(all(feature = \"client\", feature = \"broker\"))]")?;
writeln!(m, "use crate::protocol::Request;")?;
writeln!(m, "use crate::protocol::VersionRange;")?;
writeln!(m, "use std::convert::TryFrom;")?;
writeln!(m, "#[cfg(feature = \"messages_enums\")]")?;
writeln!(m, "#[cfg(any(feature = \"client\", feature = \"broker\"))]")?;
Expand All @@ -51,15 +49,22 @@ pub fn run(messages_module_dir: &str, mut input_file_paths: Vec<PathBuf>) -> Res
writeln!(m, "use anyhow::Context;")?;
writeln!(m)?;

let mut entity_types = BTreeSet::new();
let mut request_types = BTreeMap::new();
let mut response_types = BTreeMap::new();
let mut api_key_to_valid_version: HashMap<i16, VersionSpec> = HashMap::new();

for input_file_path in &input_file_paths {
let spec = parse::parse(input_file_path)?;
let spec_meta = (spec.type_, spec.api_key);
let valid_versions = spec.valid_versions;

let outcome = generate::generate(messages_module_dir, spec)?;
if let Some(output) = outcome {
match spec_meta {
(SpecType::Request, Some(k)) => {
request_types.insert(k, output);
api_key_to_valid_version.insert(k, valid_versions);
}
(SpecType::Response, Some(k)) => {
response_types.insert(k, output);
Expand Down Expand Up @@ -179,6 +184,40 @@ pub fn run(messages_module_dir: &str, mut input_file_paths: Vec<PathBuf>) -> Res
}
writeln!(m, " }}")?;
writeln!(m, " }}")?;

writeln!(
m,
" /// Returns the valid versions that can be used with this ApiKey"
)?;
writeln!(m, " pub fn valid_versions(&self) -> VersionRange {{")?;
writeln!(m, " match self {{")?;
for (api_key, request_type) in request_types.iter() {
let valid_versions = api_key_to_valid_version
.get(api_key)
.unwrap()
.range()
.unwrap();
writeln!(
m,
"ApiKey::{} => VersionRange {{ min: {}, max: {} }},",
request_type.replace("Request", ""),
valid_versions.start(),
valid_versions.end(),
)?;
}
writeln!(m, " }}")?;
writeln!(m, " }}")?;

writeln!(
m,
r#"
/// Iterate through every ApiKey variant in the order of the internal code.
pub fn iter() -> impl Iterator<Item = ApiKey> {{
(0..i16::MAX).map_while(|i| ApiKey::try_from(i).ok())
}}
"#
)?;

writeln!(m, "}}")?;

writeln!(m, "impl TryFrom<i16> for ApiKey {{")?;
Expand Down
87 changes: 87 additions & 0 deletions src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::protocol::Decodable;
use crate::protocol::Encodable;
#[cfg(all(feature = "client", feature = "broker"))]
use crate::protocol::Request;
use crate::protocol::VersionRange;
use crate::protocol::{HeaderVersion, NewType, StrBytes};
#[cfg(feature = "messages_enums")]
#[cfg(any(feature = "client", feature = "broker"))]
Expand Down Expand Up @@ -1324,6 +1325,92 @@ impl ApiKey {
}
}
}
/// Returns the valid versions that can be used with this ApiKey
pub fn valid_versions(&self) -> VersionRange {
match self {
ApiKey::Produce => VersionRange { min: 0, max: 11 },
ApiKey::Fetch => VersionRange { min: 0, max: 16 },
ApiKey::ListOffsets => VersionRange { min: 0, max: 8 },
ApiKey::Metadata => VersionRange { min: 0, max: 12 },
ApiKey::LeaderAndIsr => VersionRange { min: 0, max: 7 },
ApiKey::StopReplica => VersionRange { min: 0, max: 4 },
ApiKey::UpdateMetadata => VersionRange { min: 0, max: 8 },
ApiKey::ControlledShutdown => VersionRange { min: 0, max: 3 },
ApiKey::OffsetCommit => VersionRange { min: 0, max: 9 },
ApiKey::OffsetFetch => VersionRange { min: 0, max: 9 },
ApiKey::FindCoordinator => VersionRange { min: 0, max: 5 },
ApiKey::JoinGroup => VersionRange { min: 0, max: 9 },
ApiKey::Heartbeat => VersionRange { min: 0, max: 4 },
ApiKey::LeaveGroup => VersionRange { min: 0, max: 5 },
ApiKey::SyncGroup => VersionRange { min: 0, max: 5 },
ApiKey::DescribeGroups => VersionRange { min: 0, max: 5 },
ApiKey::ListGroups => VersionRange { min: 0, max: 5 },
ApiKey::SaslHandshake => VersionRange { min: 0, max: 1 },
ApiKey::ApiVersions => VersionRange { min: 0, max: 3 },
ApiKey::CreateTopics => VersionRange { min: 0, max: 7 },
ApiKey::DeleteTopics => VersionRange { min: 0, max: 6 },
ApiKey::DeleteRecords => VersionRange { min: 0, max: 2 },
ApiKey::InitProducerId => VersionRange { min: 0, max: 5 },
ApiKey::OffsetForLeaderEpoch => VersionRange { min: 0, max: 4 },
ApiKey::AddPartitionsToTxn => VersionRange { min: 0, max: 5 },
ApiKey::AddOffsetsToTxn => VersionRange { min: 0, max: 4 },
ApiKey::EndTxn => VersionRange { min: 0, max: 4 },
ApiKey::WriteTxnMarkers => VersionRange { min: 0, max: 1 },
ApiKey::TxnOffsetCommit => VersionRange { min: 0, max: 4 },
ApiKey::DescribeAcls => VersionRange { min: 0, max: 3 },
ApiKey::CreateAcls => VersionRange { min: 0, max: 3 },
ApiKey::DeleteAcls => VersionRange { min: 0, max: 3 },
ApiKey::DescribeConfigs => VersionRange { min: 0, max: 4 },
ApiKey::AlterConfigs => VersionRange { min: 0, max: 2 },
ApiKey::AlterReplicaLogDirs => VersionRange { min: 0, max: 2 },
ApiKey::DescribeLogDirs => VersionRange { min: 0, max: 4 },
ApiKey::SaslAuthenticate => VersionRange { min: 0, max: 2 },
ApiKey::CreatePartitions => VersionRange { min: 0, max: 3 },
ApiKey::CreateDelegationToken => VersionRange { min: 0, max: 3 },
ApiKey::RenewDelegationToken => VersionRange { min: 0, max: 2 },
ApiKey::ExpireDelegationToken => VersionRange { min: 0, max: 2 },
ApiKey::DescribeDelegationToken => VersionRange { min: 0, max: 3 },
ApiKey::DeleteGroups => VersionRange { min: 0, max: 2 },
ApiKey::ElectLeaders => VersionRange { min: 0, max: 2 },
ApiKey::IncrementalAlterConfigs => VersionRange { min: 0, max: 1 },
ApiKey::AlterPartitionReassignments => VersionRange { min: 0, max: 0 },
ApiKey::ListPartitionReassignments => VersionRange { min: 0, max: 0 },
ApiKey::OffsetDelete => VersionRange { min: 0, max: 0 },
ApiKey::DescribeClientQuotas => VersionRange { min: 0, max: 1 },
ApiKey::AlterClientQuotas => VersionRange { min: 0, max: 1 },
ApiKey::DescribeUserScramCredentials => VersionRange { min: 0, max: 0 },
ApiKey::AlterUserScramCredentials => VersionRange { min: 0, max: 0 },
ApiKey::Vote => VersionRange { min: 0, max: 0 },
ApiKey::BeginQuorumEpoch => VersionRange { min: 0, max: 0 },
ApiKey::EndQuorumEpoch => VersionRange { min: 0, max: 0 },
ApiKey::DescribeQuorum => VersionRange { min: 0, max: 1 },
ApiKey::AlterPartition => VersionRange { min: 0, max: 3 },
ApiKey::UpdateFeatures => VersionRange { min: 0, max: 1 },
ApiKey::Envelope => VersionRange { min: 0, max: 0 },
ApiKey::FetchSnapshot => VersionRange { min: 0, max: 0 },
ApiKey::DescribeCluster => VersionRange { min: 0, max: 1 },
ApiKey::DescribeProducers => VersionRange { min: 0, max: 0 },
ApiKey::BrokerRegistration => VersionRange { min: 0, max: 3 },
ApiKey::BrokerHeartbeat => VersionRange { min: 0, max: 1 },
ApiKey::UnregisterBroker => VersionRange { min: 0, max: 0 },
ApiKey::DescribeTransactions => VersionRange { min: 0, max: 0 },
ApiKey::ListTransactions => VersionRange { min: 0, max: 1 },
ApiKey::AllocateProducerIds => VersionRange { min: 0, max: 0 },
ApiKey::ConsumerGroupHeartbeat => VersionRange { min: 0, max: 0 },
ApiKey::ConsumerGroupDescribe => VersionRange { min: 0, max: 0 },
ApiKey::ControllerRegistration => VersionRange { min: 0, max: 0 },
ApiKey::GetTelemetrySubscriptions => VersionRange { min: 0, max: 0 },
ApiKey::PushTelemetry => VersionRange { min: 0, max: 0 },
ApiKey::AssignReplicasToDirs => VersionRange { min: 0, max: 0 },
ApiKey::ListClientMetricsResources => VersionRange { min: 0, max: 0 },
ApiKey::DescribeTopicPartitions => VersionRange { min: 0, max: 0 },
}
}

/// Iterate through every ApiKey variant in the order of the internal code.
pub fn iter() -> impl Iterator<Item = ApiKey> {
(0..i16::MAX).map_while(|i| ApiKey::try_from(i).ok())
}
}
impl TryFrom<i16> for ApiKey {
type Error = ();
Expand Down