blob: 8b083fbd799e9fac07c6ee57814442aa87d36c11 [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.
*/
#include "iggy.hpp"
namespace iggy {
IggyBlockingClient::IggyBlockingClient(IggyBlockingClient &&other) noexcept
: client_(std::exchange(other.client_, nullptr)) {}
IggyBlockingClient &IggyBlockingClient::operator=(IggyBlockingClient &&other) noexcept {
if (this != &other) {
Reset();
client_ = std::exchange(other.client_, nullptr);
}
return *this;
}
IggyBlockingClient::~IggyBlockingClient() {
Reset();
}
IggyBlockingClient IggyBlockingClient::FromConnectionString(std::string connection_string) {
return RethrowAsIggyException(
[&connection_string] { return IggyBlockingClient(ffi::from_connection_string(connection_string)); });
}
void IggyBlockingClient::Connect() {
RethrowAsIggyException([this] { Handle()->connect(); });
}
void IggyBlockingClient::Disconnect() {
RethrowAsIggyException([this] { Handle()->disconnect(); });
}
void IggyBlockingClient::Shutdown() {
RethrowAsIggyException([this] { Handle()->shutdown(); });
}
LoginInfo IggyBlockingClient::Login(std::string username, std::string password) {
return RethrowAsIggyException([this, &username, &password] {
return LoginInfo::FromFfi(Handle()->login_user(std::move(username), std::move(password)));
});
}
void IggyBlockingClient::Logout() {
RethrowAsIggyException([this] { Handle()->logout_user(); });
}
StreamDetails IggyBlockingClient::CreateStream(std::string name) {
return RethrowAsIggyException(
[this, &name] { return StreamDetails::FromFfi(Handle()->create_stream(std::move(name))); });
}
void IggyBlockingClient::UpdateStream(const Identifier &stream, std::string name) {
return RethrowAsIggyException([this, &stream, &name] { Handle()->update_stream(stream.ToFfi(), std::move(name)); });
}
std::vector<Stream> IggyBlockingClient::GetStreams() {
return RethrowAsIggyException([this] {
std::vector<Stream> streams;
auto ffi_streams = Handle()->get_streams();
streams.reserve(ffi_streams.size());
for (auto &stream : ffi_streams) {
streams.push_back(Stream::FromFfi(std::move(stream)));
}
return streams;
});
}
StreamDetails IggyBlockingClient::GetStream(const Identifier &stream) {
return RethrowAsIggyException(
[this, &stream] { return StreamDetails::FromFfi(Handle()->get_stream(stream.ToFfi())); });
}
void IggyBlockingClient::DeleteStream(const Identifier &stream) {
return RethrowAsIggyException([this, &stream] { Handle()->delete_stream(stream.ToFfi()); });
}
void IggyBlockingClient::PurgeStream(const Identifier &stream) {
return RethrowAsIggyException([this, &stream] { Handle()->purge_stream(stream.ToFfi()); });
}
TopicDetails IggyBlockingClient::CreateTopic(const Identifier &stream,
std::string name,
const std::uint32_t partitions_count,
const CompressionAlgorithm compression_algorithm,
const Expiry message_expiry,
const MaxTopicSize max_topic_size,
ResourceOptions options) {
return RethrowAsIggyException(
[this, &stream, &name, partitions_count, &compression_algorithm, &message_expiry, &max_topic_size, &options] {
return TopicDetails::FromFfi(Handle()->create_topic(
stream.ToFfi(), std::move(name), partitions_count,
std::string(compression_algorithm.CompressionAlgorithmValue()),
std::string(message_expiry.ExpiryKind()), message_expiry.ExpiryValue(),
std::string(max_topic_size.MaxTopicSizeValue()), ResourceOptions::ToFfi(std::move(options))));
});
}
void IggyBlockingClient::UpdateTopic(const Identifier &stream,
const Identifier &topic,
std::string name,
const CompressionAlgorithm compression_algorithm,
const Expiry message_expiry,
const MaxTopicSize max_topic_size,
ResourceOptions options) {
return RethrowAsIggyException(
[this, &stream, &topic, &name, &compression_algorithm, &message_expiry, &max_topic_size, &options] {
Handle()->update_topic(stream.ToFfi(), topic.ToFfi(), std::move(name),
std::string(compression_algorithm.CompressionAlgorithmValue()),
std::string(message_expiry.ExpiryKind()), message_expiry.ExpiryValue(),
std::string(max_topic_size.MaxTopicSizeValue()),
ResourceOptions::ToFfi(std::move(options)));
});
}
std::vector<Topic> IggyBlockingClient::GetTopics(const Identifier &stream) {
return RethrowAsIggyException([this, &stream] {
std::vector<Topic> topics;
auto ffi_topics = Handle()->get_topics(stream.ToFfi());
topics.reserve(ffi_topics.size());
for (auto &topic : ffi_topics) {
topics.push_back(Topic::FromFfi(std::move(topic)));
}
return topics;
});
}
TopicDetails IggyBlockingClient::GetTopic(const Identifier &stream, const Identifier &topic) {
return RethrowAsIggyException(
[this, &stream, &topic] { return TopicDetails::FromFfi(Handle()->get_topic(stream.ToFfi(), topic.ToFfi())); });
}
void IggyBlockingClient::DeleteTopic(const Identifier &stream, const Identifier &topic) {
return RethrowAsIggyException([this, &stream, &topic] { Handle()->delete_topic(stream.ToFfi(), topic.ToFfi()); });
}
void IggyBlockingClient::PurgeTopic(const Identifier &stream, const Identifier &topic) {
return RethrowAsIggyException([this, &stream, &topic] { Handle()->purge_topic(stream.ToFfi(), topic.ToFfi()); });
}
void IggyBlockingClient::CreatePartitions(const Identifier &stream,
const Identifier &topic,
const std::uint32_t partitions_count) {
return RethrowAsIggyException([this, &stream, &topic, partitions_count] {
Handle()->create_partitions(stream.ToFfi(), topic.ToFfi(), partitions_count);
});
}
void IggyBlockingClient::DeletePartitions(const Identifier &stream,
const Identifier &topic,
const std::uint32_t partitions_count) {
return RethrowAsIggyException([this, &stream, &topic, partitions_count] {
Handle()->delete_partitions(stream.ToFfi(), topic.ToFfi(), partitions_count);
});
}
IggyBlockingClient::IggyBlockingClient(ffi::Client *client) : client_(client) {
if (client_ == nullptr) {
throw IggyException("Could not create Iggy client");
}
}
ffi::Client *IggyBlockingClient::Handle() const {
if (client_ == nullptr) {
throw IggyException("Cannot use a moved-from IggyBlockingClient");
}
return client_;
}
void IggyBlockingClient::Reset() noexcept {
if (client_ == nullptr) {
return;
}
ffi::Client *client{std::exchange(client_, nullptr)};
ffi::delete_client(client);
}
IggyBlockingClient::Builder::Builder() = default;
IggyBlockingClient::Builder &IggyBlockingClient::Builder::WithServerAddress(std::string server_address) {
if (server_address.empty()) {
throw IggyException("Server address cannot be empty");
}
server_address_ = std::move(server_address);
return *this;
}
IggyBlockingClient::Builder &IggyBlockingClient::Builder::WithAutoLogin(std::string username, std::string password) {
if (username.empty() || password.empty()) {
throw IggyException("Automatic login username and password cannot be empty");
}
auto_login_kind_ = ffi::AutoLoginKind::UsernamePassword;
auto_login_username_ = std::move(username);
auto_login_password_ = std::move(password);
personal_access_token_.clear();
return *this;
}
IggyBlockingClient::Builder &IggyBlockingClient::Builder::WithPersonalAccessToken(std::string token) {
if (token.empty()) {
throw IggyException("Personal access token cannot be empty");
}
auto_login_kind_ = ffi::AutoLoginKind::PersonalAccessToken;
personal_access_token_ = std::move(token);
auto_login_username_.clear();
auto_login_password_.clear();
return *this;
}
IggyBlockingClient::Builder &IggyBlockingClient::Builder::WithReconnectionMaxRetries(std::uint32_t retries) {
reconnection_max_retries_ = retries;
return *this;
}
IggyBlockingClient::Builder &IggyBlockingClient::Builder::WithoutReconnectionLimit() {
reconnection_max_retries_.reset();
return *this;
}
IggyBlockingClient::Builder &IggyBlockingClient::Builder::WithReconnectionInterval(std::chrono::microseconds interval) {
if (interval.count() < 0) {
throw IggyException("Reconnection interval cannot be negative");
}
reconnection_interval_micros_ = static_cast<std::uint64_t>(interval.count());
return *this;
}
IggyBlockingClient::Builder &IggyBlockingClient::Builder::WithReestablishAfter(std::chrono::microseconds duration) {
if (duration.count() < 0) {
throw IggyException("Reestablish duration cannot be negative");
}
reestablish_after_micros_ = static_cast<std::uint64_t>(duration.count());
return *this;
}
IggyBlockingClient::Builder &IggyBlockingClient::Builder::WithTlsEnabled(bool enabled) {
tls_enabled_ = enabled;
return *this;
}
IggyBlockingClient::Builder &IggyBlockingClient::Builder::WithTlsDomain(std::string domain) {
if (domain.empty()) {
throw IggyException("TLS domain cannot be empty");
}
tls_domain_ = std::move(domain);
return *this;
}
IggyBlockingClient::Builder &IggyBlockingClient::Builder::WithTlsCaFile(std::string path) {
if (path.empty()) {
throw IggyException("TLS CA file cannot be empty");
}
tls_ca_file_ = std::move(path);
return *this;
}
IggyBlockingClient::Builder &IggyBlockingClient::Builder::WithTlsCertificateValidation(bool enabled) {
tls_validate_certificate_ = enabled;
return *this;
}
IggyBlockingClient::Builder &IggyBlockingClient::Builder::WithNoDelay() {
no_delay_ = true;
return *this;
}
IggyBlockingClient IggyBlockingClient::Builder::Build() const {
return IggyBlockingClient::RethrowAsIggyException([this] {
ffi::IggyClientConfig config{};
config.server_address = server_address_;
config.auto_login_kind = auto_login_kind_;
config.username = auto_login_username_;
config.password = auto_login_password_;
config.personal_access_token = personal_access_token_;
config.has_reconnection_max_retries = reconnection_max_retries_.has_value();
config.reconnection_max_retries = reconnection_max_retries_.value_or(0);
config.has_reconnection_interval = reconnection_interval_micros_.has_value();
config.reconnection_interval_micros = reconnection_interval_micros_.value_or(0);
config.has_reestablish_after = reestablish_after_micros_.has_value();
config.reestablish_after_micros = reestablish_after_micros_.value_or(0);
config.tls_enabled = tls_enabled_;
config.tls_domain = tls_domain_;
config.tls_ca_file = tls_ca_file_;
config.has_tls_validate_certificate = tls_validate_certificate_.has_value();
config.tls_validate_certificate = tls_validate_certificate_.value_or(false);
config.no_delay = no_delay_;
return IggyBlockingClient(ffi::new_connection(std::move(config)));
});
}
} // namespace iggy