blob: 7d4bfb9c5ac690e6ab9c26320167497fa07be0e6 [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.
mod client;
mod consumer_group;
mod identifier;
mod messages;
mod stream;
mod topic;
use client::{Client, delete_connection, new_connection};
use messages::make_message;
use std::sync::LazyLock;
static RUNTIME: LazyLock<tokio::runtime::Runtime> = LazyLock::new(|| {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap()
});
#[cxx::bridge(namespace = "iggy::ffi")]
mod ffi {
struct Identifier {
kind: String,
length: u8,
value: Vec<u8>,
}
struct Topic {
id: u32,
created_at: u64,
name: String,
size_bytes: u64,
message_expiry: u64,
compression_algorithm: String,
max_topic_size: u64,
replication_factor: u8,
messages_count: u64,
partitions_count: u32,
}
struct Partition {
id: u32,
created_at: u64,
segments_count: u32,
current_offset: u64,
size_bytes: u64,
messages_count: u64,
}
struct TopicDetails {
id: u32,
created_at: u64,
name: String,
size_bytes: u64,
message_expiry: u64,
compression_algorithm: String,
max_topic_size: u64,
replication_factor: u8,
messages_count: u64,
partitions_count: u32,
partitions: Vec<Partition>,
}
struct Stream {
id: u32,
created_at: u64,
name: String,
size_bytes: u64,
messages_count: u64,
topics_count: u32,
}
struct IggyMessageToSend {
id_lo: u64,
id_hi: u64,
payload: Vec<u8>,
user_headers: Vec<u8>,
}
struct IggyMessagePolled {
checksum: u64,
id_lo: u64,
id_hi: u64,
offset: u64,
timestamp: u64,
origin_timestamp: u64,
user_headers_length: u32,
payload_length: u32,
reserved: u64,
payload: Vec<u8>,
user_headers: Vec<u8>,
}
struct PolledMessages {
partition_id: u32,
current_offset: u64,
count: u32,
messages: Vec<IggyMessagePolled>,
}
struct StreamDetails {
id: u32,
created_at: u64,
name: String,
size_bytes: u64,
messages_count: u64,
topics_count: u32,
topics: Vec<Topic>,
}
struct ConsumerGroupMember {
id: u32,
partitions_count: u32,
partitions: Vec<u32>,
}
struct ConsumerGroupDetails {
id: u32,
name: String,
partitions_count: u32,
members_count: u32,
members: Vec<ConsumerGroupMember>,
}
struct ConsumerGroup {
id: u32,
name: String,
partitions_count: u32,
members_count: u32,
}
struct ConsumerGroupInfo {
stream_id: u32,
topic_id: u32,
group_id: u32,
}
struct ClientInfo {
client_id: u32,
has_user_id: bool,
user_id: u32,
address: String,
transport: String,
consumer_groups_count: u32,
}
struct ClientInfoDetails {
client_id: u32,
has_user_id: bool,
user_id: u32,
address: String,
transport: String,
consumer_groups_count: u32,
consumer_groups: Vec<ConsumerGroupInfo>,
}
struct CacheMetricEntry {
stream_id: u32,
topic_id: u32,
partition_id: u32,
hits: u64,
misses: u64,
hit_ratio: f32,
}
struct Stats {
process_id: u32,
cpu_usage: f32,
total_cpu_usage: f32,
memory_usage: u64,
total_memory: u64,
available_memory: u64,
run_time_micros: u64,
start_time_epoch_micros: u64,
read_bytes: u64,
written_bytes: u64,
messages_size_bytes: u64,
streams_count: u32,
topics_count: u32,
partitions_count: u32,
segments_count: u32,
messages_count: u64,
clients_count: u32,
consumer_groups_count: u32,
hostname: String,
os_name: String,
os_version: String,
kernel_version: String,
iggy_server_version: String,
// `iggy_server_semver` is only meaningful when this flag is true.
has_server_semver: bool,
// Uses `0` when the Rust `Option<u32>` is absent; check `has_server_semver`
// before reading this field.
iggy_server_semver: u32,
cache_metrics: Vec<CacheMetricEntry>,
threads_count: u32,
free_disk_space: u64,
total_disk_space: u64,
}
extern "Rust" {
type Client;
// Client functions
fn new_connection(connection_string: String) -> Result<*mut Client>;
fn login_user(self: &Client, username: String, password: String) -> Result<()>;
fn connect(self: &Client) -> Result<()>;
fn create_stream(self: &Client, stream_name: String) -> Result<StreamDetails>;
fn get_streams(self: &Client) -> Result<Vec<Stream>>;
fn get_stream(self: &Client, stream_id: Identifier) -> Result<StreamDetails>;
fn delete_stream(self: &Client, stream_id: Identifier) -> Result<()>;
fn purge_stream(self: &Client, stream_id: Identifier) -> Result<()>;
#[allow(clippy::too_many_arguments)]
fn create_topic(
self: &Client,
stream_id: Identifier,
topic_name: String,
partitions_count: u32,
compression_algorithm: String,
replication_factor: u8,
message_expiry_kind: String,
message_expiry_value: u64,
max_topic_size: String,
) -> Result<TopicDetails>;
fn get_topic(
self: &Client,
stream_id: Identifier,
topic_id: Identifier,
) -> Result<TopicDetails>;
fn get_topics(self: &Client, stream_id: Identifier) -> Result<Vec<Topic>>;
#[allow(clippy::too_many_arguments)]
fn update_topic(
self: &Client,
stream_id: Identifier,
topic_id: Identifier,
topic_name: String,
compression_algorithm: String,
replication_factor: u8,
message_expiry_kind: String,
message_expiry_value: u64,
max_topic_size: String,
) -> Result<()>;
fn delete_topic(self: &Client, stream_id: Identifier, topic_id: Identifier) -> Result<()>;
fn purge_topic(self: &Client, stream_id: Identifier, topic_id: Identifier) -> Result<()>;
fn create_partitions(
self: &Client,
stream_id: Identifier,
topic_id: Identifier,
partitions_count: u32,
) -> Result<()>;
fn delete_partitions(
self: &Client,
stream_id: Identifier,
topic_id: Identifier,
partitions_count: u32,
) -> Result<()>;
fn create_consumer_group(
self: &Client,
stream_id: Identifier,
topic_id: Identifier,
name: String,
) -> Result<ConsumerGroupDetails>;
fn get_consumer_group(
self: &Client,
stream_id: Identifier,
topic_id: Identifier,
group_id: Identifier,
) -> Result<ConsumerGroupDetails>;
fn get_consumer_groups(
self: &Client,
stream_id: Identifier,
topic_id: Identifier,
) -> Result<Vec<ConsumerGroup>>;
fn delete_consumer_group(
self: &Client,
stream_id: Identifier,
topic_id: Identifier,
group_id: Identifier,
) -> Result<()>;
fn join_consumer_group(
self: &Client,
stream_id: Identifier,
topic_id: Identifier,
group_id: Identifier,
) -> Result<()>;
fn leave_consumer_group(
self: &Client,
stream_id: Identifier,
topic_id: Identifier,
group_id: Identifier,
) -> Result<()>;
#[allow(clippy::too_many_arguments)]
fn poll_messages(
self: &Client,
stream_id: Identifier,
topic_id: Identifier,
partition_id: u32,
consumer_kind: String,
consumer_id: Identifier,
polling_strategy_kind: String,
polling_strategy_value: u64,
count: u32,
auto_commit: bool,
) -> Result<PolledMessages>;
fn make_message(payload: Vec<u8>) -> IggyMessageToSend;
#[allow(clippy::too_many_arguments)]
fn send_messages(
self: &Client,
stream_id: Identifier,
topic_id: Identifier,
partitioning_kind: String,
partitioning_value: Vec<u8>,
messages: Vec<IggyMessageToSend>,
) -> Result<()>;
fn get_stats(self: &Client) -> Result<Stats>;
fn get_me(self: &Client) -> Result<ClientInfoDetails>;
fn get_client(self: &Client, client_id: u32) -> Result<ClientInfoDetails>;
fn get_clients(self: &Client) -> Result<Vec<ClientInfo>>;
fn ping(self: &Client) -> Result<()>;
fn heartbeat_interval(self: &Client) -> u64;
fn snapshot(
self: &Client,
snapshot_compression: String,
snapshot_types: Vec<String>,
) -> Result<Vec<u8>>;
unsafe fn delete_connection(client: *mut Client) -> Result<()>;
// Identifier functions
fn set_string(self: &mut Identifier, id: String) -> Result<()>;
fn set_numeric(self: &mut Identifier, id: u32) -> Result<()>;
}
}