Skip to content
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ serde_with = "3.12"

getset = "0.1"
lazy_static = "1.4"
serial_test = "3.0"

# Internal dependencies
swss-common = { version = "0.1.0", path = "crates/swss-common" }
Expand Down
4 changes: 3 additions & 1 deletion common/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ common_libswsscommon_la_SOURCES = \
common/interface.h \
common/c-api/util.cpp \
common/c-api/dbconnector.cpp \
common/c-api/configdbconnector.cpp \
common/c-api/consumerstatetable.cpp \
common/c-api/producerstatetable.cpp \
common/c-api/subscriberstatetable.cpp \
Expand All @@ -80,7 +81,8 @@ common_libswsscommon_la_SOURCES = \
common/c-api/zmqconsumerstatetable.cpp \
common/c-api/zmqproducerstatetable.cpp \
common/c-api/table.cpp \
common/c-api/logger.cpp \
common/c-api/logger.cpp \
common/c-api/events.cpp \
common/performancetimer.cpp

common_libswsscommon_la_CXXFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(LIBNL_CFLAGS) $(CODE_COVERAGE_CXXFLAGS)
Expand Down
185 changes: 185 additions & 0 deletions common/c-api/configdbconnector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#include <cstring>
#include <string>
#include <utility>
#include <map>
#include <vector>

#include "../configdb.h"
#include "configdbconnector.h"
#include "util.h"

using namespace swss;
using namespace std;

SWSSResult SWSSConfigDBConnector_new(uint8_t use_unix_socket_path, const char *netns, SWSSConfigDBConnector *outConfigDb) {
SWSSTry({
string netns_str = netns ? string(netns) : "";
*outConfigDb = (SWSSConfigDBConnector) new ConfigDBConnector_Native(use_unix_socket_path != 0, netns_str.c_str());
});
}

SWSSResult SWSSConfigDBConnector_free(SWSSConfigDBConnector configDb) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
SWSSTry(delete (ConfigDBConnector_Native *)configDb);
#pragma GCC diagnostic pop
}

SWSSResult SWSSConfigDBConnector_connect(SWSSConfigDBConnector configDb, uint8_t wait_for_init, uint8_t retry_on) {
SWSSTry(((ConfigDBConnector_Native *)configDb)->connect(wait_for_init != 0, retry_on != 0));
}

SWSSResult SWSSConfigDBConnector_get_entry(SWSSConfigDBConnector configDb, const char *table, const char *key, SWSSFieldValueArray *outEntry) {
SWSSTry({
auto entry_map = ((ConfigDBConnector_Native *)configDb)->get_entry(string(table), string(key));
// Convert map<string, string> to vector<pair<string, string>> for makeFieldValueArray
vector<pair<string, string>> pairs;
pairs.reserve(entry_map.size());
for (auto &pair : entry_map) {
pairs.push_back(make_pair(pair.first, move(pair.second)));
}

*outEntry = makeFieldValueArray(std::move(pairs));
});
}

SWSSResult SWSSConfigDBConnector_get_keys(SWSSConfigDBConnector configDb, const char *table, uint8_t split, SWSSStringArray *outKeys) {
SWSSTry({
auto keys = ((ConfigDBConnector_Native *)configDb)->get_keys(string(table), split != 0);
*outKeys = makeStringArray(std::move(keys));
});
}

SWSSResult SWSSConfigDBConnector_get_table(SWSSConfigDBConnector configDb, const char *table, SWSSKeyOpFieldValuesArray *outTable) {
SWSSTry({
auto table_map = ((ConfigDBConnector_Native *)configDb)->get_table(string(table));

// Convert map<string, map<string, string>> to vector<SWSSKeyOpFieldValues>
vector<SWSSKeyOpFieldValues> table_entries;
table_entries.reserve(table_map.size());

for (auto &entry : table_map) {
SWSSKeyOpFieldValues kfv_entry;
kfv_entry.key = strdup(entry.first.c_str());
kfv_entry.operation = SWSSKeyOperation_SET; // ConfigDB entries are always SET operations

// Convert inner map to field-value array
vector<pair<string, string>> pairs;
pairs.reserve(entry.second.size());
for (auto &field_pair : entry.second) {
pairs.push_back(make_pair(field_pair.first, move(field_pair.second)));
}
kfv_entry.fieldValues = makeFieldValueArray(std::move(pairs));

table_entries.push_back(kfv_entry);
}

// Convert to SWSSKeyOpFieldValuesArray
SWSSKeyOpFieldValues *data = new SWSSKeyOpFieldValues[table_entries.size()];
for (size_t i = 0; i < table_entries.size(); i++) {
data[i] = table_entries[i];
}

SWSSKeyOpFieldValuesArray out;
out.len = (uint64_t)table_entries.size();
out.data = data;
*outTable = out;
});
}

SWSSResult SWSSConfigDBConnector_set_entry(SWSSConfigDBConnector configDb, const char *table, const char *key, const SWSSFieldValueArray *data) {
SWSSTry({
// Convert SWSSFieldValueArray to map<string, string>
map<string, string> data_map;
auto field_values = takeFieldValueArray(*data);
for (auto &fv : field_values) {
data_map[fv.first] = fv.second;
}

((ConfigDBConnector_Native *)configDb)->set_entry(string(table), string(key), data_map);
});
}

SWSSResult SWSSConfigDBConnector_mod_entry(SWSSConfigDBConnector configDb, const char *table, const char *key, const SWSSFieldValueArray *data) {
SWSSTry({
// Convert SWSSFieldValueArray to map<string, string>
map<string, string> data_map;
auto field_values = takeFieldValueArray(*data);
for (auto &fv : field_values) {
data_map[fv.first] = fv.second;
}

((ConfigDBConnector_Native *)configDb)->mod_entry(string(table), string(key), data_map);
});
}

SWSSResult SWSSConfigDBConnector_delete_table(SWSSConfigDBConnector configDb, const char *table) {
SWSSTry(((ConfigDBConnector_Native *)configDb)->delete_table(string(table)));
}

SWSSResult SWSSConfigDBConnector_get_redis_client(SWSSConfigDBConnector configDb, const char *db_name, SWSSDBConnector *outDbConnector) {
SWSSTry({
// Get the Redis client from the ConfigDBConnector's parent SonicV2Connector_Native
DBConnector& redis_client = ((ConfigDBConnector_Native *)configDb)->get_redis_client(string(db_name));

// Return a pointer to the existing DBConnector
// Note: This returns a reference to the existing connector, not a new one
*outDbConnector = (SWSSDBConnector)&redis_client;
});
}

SWSSResult SWSSConfigDBConnector_get_config(SWSSConfigDBConnector configDb, SWSSConfigMap *outConfig) {
SWSSTry({
// Get the entire configuration as a nested map structure
auto config_map = ((ConfigDBConnector_Native *)configDb)->get_config();

// Convert map<string, map<string, map<string, string>>> to SWSSConfigMap
vector<SWSSConfigTable> config_tables;
config_tables.reserve(config_map.size());

for (auto &table_entry : config_map) {
SWSSConfigTable config_table;
config_table.table_name = strdup(table_entry.first.c_str());

// Convert map<string, map<string, string>> to SWSSKeyOpFieldValuesArray
vector<SWSSKeyOpFieldValues> table_entries;
table_entries.reserve(table_entry.second.size());

for (auto &key_entry : table_entry.second) {
SWSSKeyOpFieldValues kfv_entry;
kfv_entry.key = strdup(key_entry.first.c_str());
kfv_entry.operation = SWSSKeyOperation_SET; // Config entries are always SET operations

// Convert map<string, string> to SWSSFieldValueArray
vector<pair<string, string>> pairs;
pairs.reserve(key_entry.second.size());
for (auto &field_pair : key_entry.second) {
pairs.push_back(make_pair(field_pair.first, move(field_pair.second)));
}
kfv_entry.fieldValues = makeFieldValueArray(std::move(pairs));

table_entries.push_back(kfv_entry);
}

// Convert vector to array
SWSSKeyOpFieldValues *data = new SWSSKeyOpFieldValues[table_entries.size()];
for (size_t i = 0; i < table_entries.size(); i++) {
data[i] = table_entries[i];
}

config_table.entries.len = (uint64_t)table_entries.size();
config_table.entries.data = data;

config_tables.push_back(config_table);
}

// Convert vector to final array
SWSSConfigTable *config_data = new SWSSConfigTable[config_tables.size()];
for (size_t i = 0; i < config_tables.size(); i++) {
config_data[i] = config_tables[i];
}

outConfig->len = (uint64_t)config_tables.size();
outConfig->data = config_data;
});
}
63 changes: 63 additions & 0 deletions common/c-api/configdbconnector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#ifndef SWSS_COMMON_C_API_CONFIGDBCONNECTOR_H
#define SWSS_COMMON_C_API_CONFIGDBCONNECTOR_H

#include "result.h"
#include "util.h"
#include "dbconnector.h"

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

typedef struct SWSSConfigDBConnectorOpaque *SWSSConfigDBConnector;

// Create a new ConfigDBConnector
// Pass 0 to use TCP connection, 1 to use Unix socket
SWSSResult SWSSConfigDBConnector_new(uint8_t use_unix_socket_path, const char *netns, SWSSConfigDBConnector *outConfigDb);

// Free the ConfigDBConnector
SWSSResult SWSSConfigDBConnector_free(SWSSConfigDBConnector configDb);

// Connect to ConfigDB
// wait_for_init: wait for CONFIG_DB_INITIALIZED flag if true
// retry_on: retry connection on failure if true
SWSSResult SWSSConfigDBConnector_connect(SWSSConfigDBConnector configDb, uint8_t wait_for_init, uint8_t retry_on);

// Get a single entry from a table
// Result array must be freed using SWSSFieldValueArray_free()
SWSSResult SWSSConfigDBConnector_get_entry(SWSSConfigDBConnector configDb, const char *table, const char *key, SWSSFieldValueArray *outEntry);

// Get all keys from a table
// Result array and all of its elements must be freed using appropriate free functions
SWSSResult SWSSConfigDBConnector_get_keys(SWSSConfigDBConnector configDb, const char *table, uint8_t split, SWSSStringArray *outKeys);

// Get entire table as key-value pairs
// Result is a map-like structure where each entry contains a key and its field-value pairs
// Result array and all of its elements must be freed using appropriate free functions
SWSSResult SWSSConfigDBConnector_get_table(SWSSConfigDBConnector configDb, const char *table, SWSSKeyOpFieldValuesArray *outTable);

// Set an entry in a table
SWSSResult SWSSConfigDBConnector_set_entry(SWSSConfigDBConnector configDb, const char *table, const char *key, const SWSSFieldValueArray *data);

// Modify an entry in a table (update existing fields, add new ones)
SWSSResult SWSSConfigDBConnector_mod_entry(SWSSConfigDBConnector configDb, const char *table, const char *key, const SWSSFieldValueArray *data);

// Delete an entire table
SWSSResult SWSSConfigDBConnector_delete_table(SWSSConfigDBConnector configDb, const char *table);

// Get the Redis client for the specified database
// Returns a SWSSDBConnector that can be used to perform direct Redis operations
SWSSResult SWSSConfigDBConnector_get_redis_client(SWSSConfigDBConnector configDb, const char *db_name, SWSSDBConnector *outDbConnector);

// Get the entire configuration as a nested structure
// Returns a nested table structure containing all configuration data
// The result represents a map of table_name -> (key -> (field -> value))
SWSSResult SWSSConfigDBConnector_get_config(SWSSConfigDBConnector configDb, SWSSConfigMap *outConfig);

#ifdef __cplusplus
}
#endif

#endif
71 changes: 71 additions & 0 deletions common/c-api/events.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <cstring>
#include <string>
#include <map>

#include "../events.h"
#include "events.h"
#include "util.h"

using namespace std;

struct SWSSEventPublisherOpaque {
event_handle_t handle;

SWSSEventPublisherOpaque(event_handle_t h) : handle(h) {}
};

SWSSResult SWSSEventPublisher_new(const char *event_source, SWSSEventPublisher *outPublisher) {
SWSSTry({
string source_str = event_source ? string(event_source) : "";
event_handle_t handle = events_init_publisher(source_str);
if (handle == nullptr) {
throw std::runtime_error("Failed to initialize event publisher");
}
*outPublisher = new SWSSEventPublisherOpaque(handle);
});
}

SWSSResult SWSSEventPublisher_deinit(SWSSEventPublisher publisher) {
SWSSTry({
if (publisher) {
events_deinit_publisher(publisher->handle);
publisher->handle = nullptr;
}
});
}

SWSSResult SWSSEventPublisher_free(SWSSEventPublisher publisher) {
SWSSTry({
if (publisher) {
if (publisher->handle) {
events_deinit_publisher(publisher->handle);
}
delete publisher;
}
});
}

SWSSResult SWSSEventPublisher_publish(SWSSEventPublisher publisher, const char *event_tag, const SWSSFieldValueArray *params) {
SWSSTry({
if (!publisher || !event_tag) {
throw std::invalid_argument("Invalid publisher or event_tag");
}

string tag_str(event_tag);
event_params_t event_params;

// Convert SWSSFieldValueArray to event_params_t if params provided
if (params) {
for (uint64_t i = 0; i < params->len; i++) {
string key(params->data[i].field);
string value = takeString(std::move(params->data[i].value));
event_params[key] = value;
}
}

int result = event_publish(publisher->handle, tag_str, params ? &event_params : nullptr);
if (result != 0) {
throw std::runtime_error("Failed to publish event, error code: " + std::to_string(result));
}
});
}
35 changes: 35 additions & 0 deletions common/c-api/events.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef SWSS_COMMON_C_API_EVENTS_H
#define SWSS_COMMON_C_API_EVENTS_H

#include "result.h"
#include "util.h"

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

typedef struct SWSSEventPublisherOpaque *SWSSEventPublisher;

// Initialize an event publisher for a given source
// event_source: The YANG module name for the event source
SWSSResult SWSSEventPublisher_new(const char *event_source, SWSSEventPublisher *outPublisher);

// Deinitialize the event publisher (without freeing the handle)
SWSSResult SWSSEventPublisher_deinit(SWSSEventPublisher publisher);

// Free the event publisher
SWSSResult SWSSEventPublisher_free(SWSSEventPublisher publisher);

// Publish an event with the given tag and parameters
// publisher: Event publisher handle
// event_tag: Name of the YANG container that defines this event
// params: Parameters associated with the event (can be NULL)
SWSSResult SWSSEventPublisher_publish(SWSSEventPublisher publisher, const char *event_tag, const SWSSFieldValueArray *params);

#ifdef __cplusplus
}
#endif

#endif
Loading
Loading