Skip to content
11 changes: 11 additions & 0 deletions src/atomdb/AtomDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ using namespace atoms;

namespace atomdb {

enum class AtomDBType { RedisMongoDB, MorkDB, InMemoryDB, RemoteAtomDB, AdapterDB };

inline AtomDBType parse_atomdb_type(const string& type) {
Comment thread
marcocapozzoli marked this conversation as resolved.
Outdated
if (type == "redismongodb") return AtomDBType::RedisMongoDB;
if (type == "morkdb") return AtomDBType::MorkDB;
if (type == "inmemorydb") return AtomDBType::InMemoryDB;
if (type == "remotedb") return AtomDBType::RemoteAtomDB;
if (type == "adapterdb") return AtomDBType::AdapterDB;
RAISE_ERROR("Unsupported atomdb.type: " + type);
}

class AtomDB : public HandleDecoder {
public:
AtomDB() = default;
Expand Down
123 changes: 123 additions & 0 deletions src/atomdb/AtomDBFactory.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#include "AtomDBFactory.h"

#include "AdapterDB.h"
#include "InMemoryDB.h"
#include "MorkDB.h"
#include "RedisMongoDB.h"
#include "RemoteAtomDB.h"
#include "Utils.h"

using namespace atomdb;
using namespace commons;

// --------------------------------------------------------------------------------
// Public methods

shared_ptr<AtomDB> AtomDBFactory::create(const JsonConfig& config,
const string& context,
bool should_wrap) {
auto atomdb = create_atomdb(config, context);
if (should_wrap) {
return wrap_if_protected(atomdb);
}
return atomdb;
}

// --------------------------------------------------------------------------------
// Private methods

shared_ptr<AtomDB> AtomDBFactory::create_atomdb(const JsonConfig& config, const string& context) {
Comment thread
marcocapozzoli marked this conversation as resolved.
Outdated
auto atomdb_type = config.at_path("type").get_or<string>("");

AtomDBType type = parse_atomdb_type(atomdb_type);

if (type == AtomDBType::RedisMongoDB || type == AtomDBType::MorkDB ||
type == AtomDBType::InMemoryDB) {
return create_basic_atomdb(config, context);
}

if (type == AtomDBType::RemoteAtomDB || type == AtomDBType::AdapterDB) {
return create_composite_atomdb(config, context);
}

RAISE_ERROR("AtomDBFactory: unsupported AtomDB type: " + atomdb_type);

return shared_ptr<AtomDB>{};
Comment thread
marcocapozzoli marked this conversation as resolved.
Outdated
}

shared_ptr<AtomDB> AtomDBFactory::create_basic_atomdb(const JsonConfig& config, const string& context) {
auto atomdb_type = config.at_path("type").get_or<string>("");

AtomDBType type = parse_atomdb_type(atomdb_type);

if (type == AtomDBType::RedisMongoDB) {
Comment thread
marcocapozzoli marked this conversation as resolved.
Outdated
return shared_ptr<AtomDB>(new RedisMongoDB(context, false, config));
Comment thread
andre-senna marked this conversation as resolved.
Outdated
}

if (type == AtomDBType::MorkDB) {
return shared_ptr<AtomDB>(new MorkDB(context, config));
}

if (type == AtomDBType::InMemoryDB) {
return shared_ptr<AtomDB>(new InMemoryDB(context.empty() ? "inmemorydb_" : context));
}

RAISE_ERROR("AtomDBFactory: '" + atomdb_type + "' is not a basic AtomDB type");

return shared_ptr<AtomDB>{};
}

shared_ptr<AtomDB> AtomDBFactory::create_composite_atomdb(const JsonConfig& config,
const string& context) {
auto atomdb_type = config.at_path("type").get_or<string>("");

AtomDBType type = parse_atomdb_type(atomdb_type);

if (type == AtomDBType::RemoteAtomDB) {
auto remote_peers_config = config.at_path("remote_peers").get_or<JsonConfig>(JsonConfig());

map<string, shared_ptr<RemoteAtomDBPeer>> remote_peers;

for (auto& entry : remote_peers_config) {
auto peer_config = JsonConfig(entry);
string uid = peer_config.at_path("uid").get_or<string>("");
if (uid.empty()) continue;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

string peer_context = peer_config.at_path("context").get_or<string>("");
if (peer_context.empty()) {
peer_context = "remotedb_" + uid;
}

shared_ptr<AtomDB> local_persistence = nullptr;
auto local_persistence_config =
peer_config.at_path("local_persistence").get_or<JsonConfig>(JsonConfig());
if (!local_persistence_config.empty()) {
string local_context =
local_persistence_config.at_path("context").get_or<string>(peer_context);
if (local_context.empty()) {
local_context = peer_context;
}
local_persistence = create_basic_atomdb(local_persistence_config, local_context);
}
remote_peers[uid] = make_shared<RemoteAtomDBPeer>(
create_basic_atomdb(peer_config, peer_context), local_persistence, uid);
}

return shared_ptr<AtomDB>(new RemoteAtomDB(remote_peers));
}

if (type == AtomDBType::AdapterDB) {
// The backend AtomDB in AdapterDB could be RemoteAtomDB ?
auto atomdb_backend_config =
config.at_path("adapterdb.atomdb_backend").get_or<JsonConfig>(JsonConfig());
auto basic_atomdb = create_basic_atomdb(atomdb_backend_config, context);
return shared_ptr<AtomDB>(new AdapterDB(config, basic_atomdb));
}

return shared_ptr<AtomDB>{};
}

shared_ptr<AtomDB> AtomDBFactory::wrap_if_protected(shared_ptr<AtomDB> backend) {
// AtomDBFactory::wrap_if_protected() is not implemented yet.
return backend;
}
47 changes: 47 additions & 0 deletions src/atomdb/AtomDBFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#pragma once

#include <memory>
#include <string>

#include "AtomDB.h"
#include "JsonConfig.h"

using namespace std;
using namespace commons;

namespace atomdb {

/**
* @brief Single entry point to construct concrete AtomDB backends.
*
* Use this instead of calling RedisMongoDB/MorkDB/InMemoryDB constructors directly.
Comment thread
marcocapozzoli marked this conversation as resolved.
Outdated
*/
class AtomDBFactory {
public:
/**
* @brief Creates a AtomDB and wraps it with ProtectedAtomDB when is_protected().
Comment thread
marcocapozzoli marked this conversation as resolved.
Outdated
*/
static shared_ptr<AtomDB> create(const JsonConfig& config,
const string& context = "",
bool should_wrap = true);

private:
/**
* @brief Creates a concrete AtomDB without authorization wrapping.
*/
static shared_ptr<AtomDB> create_atomdb(const JsonConfig& config, const string& context = "");

// Supported types: redismongodb, morkdb, inmemorydb.
static shared_ptr<AtomDB> create_basic_atomdb(const JsonConfig& config, const string& context = "");

// Supported types: remotedb, adapterdb.
static shared_ptr<AtomDB> create_composite_atomdb(const JsonConfig& config,
const string& context = "");

/**
* @brief Wraps backend with ProtectedAtomDB when protected and not already wrapped.
*/
static shared_ptr<AtomDB> wrap_if_protected(shared_ptr<AtomDB> backend);
};

} // namespace atomdb
33 changes: 12 additions & 21 deletions src/atomdb/AtomDBSingleton.cc
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#include "AtomDBSingleton.h"

#include "AdapterDB.h"
#include "MorkDB.h"
#include "RedisMongoDB.h"
#include "RemoteAtomDB.h"
#include "AtomDBFactory.h"
#include "Utils.h"

using namespace atomdb;
Expand All @@ -19,24 +16,18 @@ void AtomDBSingleton::init(const JsonConfig& atomdb_config) {
if (AtomDBSingleton::initialized) {
RAISE_ERROR(
"AtomDBSingleton already initialized. AtomDBSingleton::init() should be called only once.");
} else {
auto atomdb_type = atomdb_config.at_path("type").get_or<string>("");
if (atomdb_type == "morkdb") {
AtomDBSingleton::atom_db = shared_ptr<AtomDB>(new MorkDB("", atomdb_config));
} else if (atomdb_type == "redismongodb") {
AtomDBSingleton::atom_db = shared_ptr<AtomDB>(new RedisMongoDB("", false, atomdb_config));
} else if (atomdb_type == "remotedb") {
auto remote_peers_config =
atomdb_config.at_path("remote_peers").get_or<JsonConfig>(JsonConfig());
AtomDBSingleton::atom_db = shared_ptr<AtomDB>(new RemoteAtomDB(remote_peers_config));
} else if (atomdb_type == "adapterdb") {
AtomDBSingleton::atom_db = shared_ptr<AtomDB>(new AdapterDB(atomdb_config));
} else {
RAISE_ERROR("Invalid AtomDB type: " + atomdb_type);
}

AtomDBSingleton::initialized = true;
}

shared_ptr<AtomDB> atomdb;

try {
Comment thread
marcocapozzoli marked this conversation as resolved.
Outdated
atomdb = AtomDBFactory::create(atomdb_config);
} catch (const exception& e) {
RAISE_ERROR("AtomDBSingleton::init() failed to create AtomDB: " + string(e.what()));
}

AtomDBSingleton::atom_db = atomdb;
AtomDBSingleton::initialized = true;
}

shared_ptr<AtomDB> AtomDBSingleton::get_instance() {
Expand Down
22 changes: 18 additions & 4 deletions src/atomdb/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ cc_library(
deps = [
":atomdb",
":atomdb_api_types",
":atomdb_factory",
":atomdb_singleton",
":atomdbutils",
"//atomdb/adapterdb:adapterdb_lib",
Expand All @@ -18,6 +19,22 @@ cc_library(
],
)

cc_library(
name = "atomdb_factory",
srcs = ["AtomDBFactory.cc"],
hdrs = ["AtomDBFactory.h"],
includes = ["."],
deps = [
":atomdb",
"//atomdb/adapterdb",
"//atomdb/inmemorydb",
"//atomdb/morkdb",
"//atomdb/redis_mongodb",
"//atomdb/remotedb:remotedb_lib",
"//commons:commons_lib",
],
)

cc_library(
name = "atomdb",
hdrs = ["AtomDB.h"],
Expand Down Expand Up @@ -56,11 +73,8 @@ cc_library(
hdrs = ["AtomDBSingleton.h"],
includes = ["."],
deps = [
":atomdb_factory",
"//atomdb:atomdb_api_types",
"//atomdb/adapterdb",
"//atomdb/morkdb",
"//atomdb/redis_mongodb",
"//atomdb/remotedb:remotedb_lib",
"//commons:commons_lib",
],
)
39 changes: 18 additions & 21 deletions src/atomdb/adapterdb/AdapterDB.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,10 @@
#include "DatabaseOrchestrator.h"
#include "DedicatedThread.h"
#include "MongoInitializer.h"
#include "MorkDB.h"
#include "MorkMappingStrategy.h"
#include "PostgresMappingStrategy.h"
#include "PostgresWrapper.h"
#include "Processor.h"
#include "RedisMongoDB.h"
#include "RemoteAtomDB.h"
#include "Utils.h"
#include "expression_hasher.h"
#include "processor/ThreadPool.h"
Expand All @@ -33,10 +30,10 @@ string AdapterDB::MONGODB_ADAPTER_COLLECTION_NAME = "adapterdb";
// Construction / destruction
// ==============================

AdapterDB::AdapterDB(const JsonConfig& config) : config(config) {
this->atomdb_backend_setup();
this->initialize();
}
// AdapterDB::AdapterDB(const JsonConfig& config) : config(config) {
// this->atomdb_backend_setup();
// this->initialize();
// }

atomdb::AdapterDB::AdapterDB(const JsonConfig& config, std::shared_ptr<AtomDB> backend)
: config(config), atomdb_backend(backend) {
Expand Down Expand Up @@ -310,20 +307,20 @@ void AdapterDB::persistence_setup() {
}
}

void AdapterDB::atomdb_backend_setup() {
auto atomdb_backend_config =
this->config.at_path("adapterdb.atomdb_backend").get_or<JsonConfig>(JsonConfig());
string atomdb_backend_type = atomdb_backend_config.at_path("type").get_or<string>("");
if (atomdb_backend_type == "morkdb") {
this->atomdb_backend = shared_ptr<AtomDB>(new MorkDB("", atomdb_backend_config));
} else if (atomdb_backend_type == "redismongodb") {
this->atomdb_backend = shared_ptr<AtomDB>(new RedisMongoDB("", false, atomdb_backend_config));
} else if (atomdb_backend_type == "remotedb") {
this->atomdb_backend = shared_ptr<AtomDB>(new RemoteAtomDB(atomdb_backend_config));
} else {
RAISE_ERROR("Invalid AtomDB type: " + atomdb_backend_type);
}
}
// void AdapterDB::atomdb_backend_setup() {
// auto atomdb_backend_config =
// this->config.at_path("adapterdb.atomdb_backend").get_or<JsonConfig>(JsonConfig());
// string atomdb_backend_type = atomdb_backend_config.at_path("type").get_or<string>("");
// if (atomdb_backend_type == "morkdb") {
// this->atomdb_backend = shared_ptr<AtomDB>(new MorkDB("", atomdb_backend_config));
// } else if (atomdb_backend_type == "redismongodb") {
// this->atomdb_backend = shared_ptr<AtomDB>(new RedisMongoDB("", false, atomdb_backend_config));
// } else if (atomdb_backend_type == "remotedb") {
// this->atomdb_backend = shared_ptr<AtomDB>(new RemoteAtomDB(atomdb_backend_config));
// } else {
// RAISE_ERROR("Invalid AtomDB type: " + atomdb_backend_type);
// }
// }

bool AdapterDB::is_backend_ready() const { return this->backend_ready.load(); }

Expand Down
10 changes: 5 additions & 5 deletions src/atomdb/adapterdb/AdapterDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ inline AdapterDbType parse_adapter_db_type(const string& value) {

class AdapterDB : public AtomDB {
public:
explicit AdapterDB(const JsonConfig& config);
// explicit AdapterDB(const JsonConfig& config);
AdapterDB(const JsonConfig& config, shared_ptr<AtomDB> backend); // for testing
~AdapterDB() override;

Expand Down Expand Up @@ -128,10 +128,10 @@ class AdapterDB : public AtomDB {
*/
void persistence_setup();

/**
* @brief Initializes the AtomDB backend according to the configuration.
*/
void atomdb_backend_setup();
// /**
// * @brief Initializes the AtomDB backend according to the configuration.
// */
// void atomdb_backend_setup();

bool is_backend_ready() const;

Expand Down
3 changes: 0 additions & 3 deletions src/atomdb/adapterdb/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ cc_library(
includes = ["."],
deps = [
"//atomdb",
"//atomdb/morkdb",
"//atomdb/redis_mongodb",
"//atomdb/remotedb:remotedb_lib",
"//commons:commons_lib",
"//commons/atoms:atoms_lib",
"//db_adapter:db_adapter_lib",
Expand Down
6 changes: 5 additions & 1 deletion src/atomdb/redis_mongodb/RedisMongoDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ enum MONGODB_FIELD { ID = 0, NAME, TARGETS, NAMED_TYPE, size };

class RedisMongoDB : public AtomDB {
public:
RedisMongoDB(const string& context, bool skip_redis, const JsonConfig& config);
~RedisMongoDB();

bool allow_nested_indexing() override;
Expand Down Expand Up @@ -146,6 +145,11 @@ class RedisMongoDB : public AtomDB {
map<string, vector<string>>& composite_type_entries_map);

private:
friend class AtomDBFactory;
friend class MorkDB;
Comment thread
marcocapozzoli marked this conversation as resolved.
Outdated

RedisMongoDB(const string& context, bool skip_redis, const JsonConfig& config);

string context;
bool skip_redis_;
bool composite_type_enabled_;
Expand Down
Loading
Loading