blob: 5c258b314b6266d38382680ab3a0747294673758 [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.
*/
use bytes::Bytes;
use iggy::prelude::*;
use std::collections::HashMap;
// The compression and decompression utilities are shared between the producer and consumer compression examples.
// Hence, we import them here.
use iggy_examples::shared::codec::{Codec, NUM_MESSAGES, STREAM_NAME, TOPIC_NAME};
#[tokio::main]
async fn main() -> Result<(), IggyError> {
// Setup a client to connect to the iggy-server via TCP.
let client = IggyClientBuilder::new().with_tcp().build()?;
client.connect().await?;
// Login using default credentials.
client
.login_user(DEFAULT_ROOT_USERNAME, DEFAULT_ROOT_PASSWORD)
.await?;
// Create a Stream.
client
.create_stream(STREAM_NAME)
.await
.expect("Stream was NOT created! Remove /local_data or start a fresh server with the --fresh flag to run this example.");
// Create a Topic on that Stream.
client
.create_topic(
&Identifier::named(STREAM_NAME).unwrap(),
TOPIC_NAME,
1, // Number of partitions.
CompressionAlgorithm::None, // NOTE: This configures the compression on the server, not the actual messages in transit!
None, // Replication factor.
IggyExpiry::NeverExpire, // Time until messages expire on the server.
MaxTopicSize::ServerDefault, // Defined in server/config.toml. Defaults to "unlimited".
)
.await
.expect("Topic was NOT created! Start a fresh server to run this example.");
// The Codec from ../compression.rs implements the compression and decompression utilities.
let codec = Codec::Lz4;
// NOTE: This is where the Codec is used to prepare the compression user-header for the IggyMessage.
let key = Codec::header_key();
let value = codec.to_header_value();
let compression_headers = HashMap::from([(key, value)]);
// Generate artificial example messages to send to the server.
let mut messages = Vec::new();
for i in 0..NUM_MESSAGES {
// For illustration purposes a log-like pattern is resembled.
let payload = format!(
r#"{{"ts": "2000-01-{:02}T{:02}:{:02}:{:02}Z", "level": "info", "trace":{}, "command": "command-{}", "status": 200, "latency_ms": {}}}"#,
i % 28,
i % 24,
i % 60,
i % 60,
i,
i % 1000,
i % 120
);
let payload = Bytes::from(payload);
let compressed_payload = codec.compress(&payload);
let compressed_bytes = Bytes::from(compressed_payload);
let msg = IggyMessage::builder()
.payload(compressed_bytes)
// NOTE: This is where the user_headers of IggyMessages are used to indicate, that a payload is compressed.
.user_headers(compression_headers.clone())
.build()
.expect("IggyMessage should be buildable.");
messages.push(msg);
}
// Send all compressed messages to the server.
let producer = client.producer(STREAM_NAME, TOPIC_NAME)?.build();
producer
.send(messages)
.await
.expect("Message sending failed.");
println!("All messages sent to server.");
Ok(())
}