cluster: Add Components and ComponentManager for new components

This commit is contained in:
Arne Welzel 2024-11-13 11:24:08 +01:00
parent fb23a06f6f
commit 23ca625c03
6 changed files with 311 additions and 0 deletions

View file

@ -0,0 +1,9 @@
zeek_add_subdir_library(
cluster
INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
SOURCES
Component.cc
Backend.cc
Manager.cc)

56
src/cluster/Component.cc Normal file
View file

@ -0,0 +1,56 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/cluster/Component.h"
#include "zeek/Desc.h"
#include "zeek/Tag.h"
#include "zeek/cluster/Manager.h"
#include "zeek/util.h"
using namespace zeek::cluster;
BackendComponent::BackendComponent(const std::string& name, factory_callback arg_factory)
: plugin::Component(plugin::component::CLUSTER_BACKEND, name, 0, cluster::manager->Backends().GetTagType()) {
factory = arg_factory;
}
void BackendComponent::Initialize() {
InitializeTag();
cluster::manager->Backends().RegisterComponent(this, "CLUSTER_BACKEND_");
}
void BackendComponent::DoDescribe(ODesc* d) const {
d->Add("Cluster::CLUSTER_BACKEND_");
d->Add(CanonicalName());
}
EventSerializerComponent::EventSerializerComponent(const std::string& name, factory_callback arg_factory)
: plugin::Component(plugin::component::EVENT_SERIALIZER, name, 0,
cluster::manager->EventSerializers().GetTagType()) {
factory = arg_factory;
}
void EventSerializerComponent::Initialize() {
InitializeTag();
cluster::manager->EventSerializers().RegisterComponent(this, "EVENT_SERIALIZER_");
}
void EventSerializerComponent::DoDescribe(ODesc* d) const {
d->Add("Cluster::EVENT_SERIALIZER_");
d->Add(CanonicalName());
}
LogSerializerComponent::LogSerializerComponent(const std::string& name, factory_callback arg_factory)
: plugin::Component(plugin::component::LOG_SERIALIZER, name, 0, cluster::manager->LogSerializers().GetTagType()) {
factory = arg_factory;
}
void LogSerializerComponent::Initialize() {
InitializeTag();
cluster::manager->LogSerializers().RegisterComponent(this, "LOG_SERIALIZER_");
}
void LogSerializerComponent::DoDescribe(ODesc* d) const {
d->Add("Cluster::LOG_SERIALIZER_");
d->Add(CanonicalName());
}

131
src/cluster/Component.h Normal file
View file

@ -0,0 +1,131 @@
// See the file "COPYING" in the main distribution directory for copyright.
#pragma once
#include <memory>
#include "zeek/cluster/Backend.h"
#include "zeek/cluster/Serializer.h"
#include "zeek/plugin/Component.h"
namespace zeek::cluster {
class BackendComponent : public plugin::Component {
public:
using factory_callback = std::unique_ptr<Backend> (*)(std::unique_ptr<EventSerializer>,
std::unique_ptr<LogSerializer>);
/**
* Constructor.
*
* @param name The name of the cluster backend. A Zeek script-level enum
* with the name Cluster::CLUSTER_BACKEND_<NAME> will be created.
*
* @param factory A factory function to instantiate instances of the
* cluster backend.
*/
BackendComponent(const std::string& name, factory_callback factory);
/**
* Destructor.
*/
~BackendComponent() override = default;
/**
* Initialization function. This function has to be called before any
* plugin component functionality is used; it is used to add the
* plugin component to the list of components and to initialize tags
*/
void Initialize() override;
/**
* Returns the analyzer's factory function.
*/
factory_callback Factory() const { return factory; }
protected:
void DoDescribe(ODesc* d) const override;
private:
factory_callback factory;
};
class EventSerializerComponent : public plugin::Component {
public:
using factory_callback = std::unique_ptr<EventSerializer> (*)();
/**
* Constructor.
*
* @param name The name of the event serializer. A Zeek script-level enum
* with the name Cluster::EVENT_SERIALIZER_<NAME> will be created.
*
* @param factory A factory function to instantiate instances of the
* event serializer.
*/
EventSerializerComponent(const std::string& name, factory_callback factory);
/**
* Destructor.
*/
~EventSerializerComponent() override = default;
/**
* Initialization function. This function has to be called before any
* plugin component functionality is used; it is used to add the
* plugin component to the list of components and to initialize tags
*/
void Initialize() override;
/**
* Returns the analyzer's factory function.
*/
factory_callback Factory() const { return factory; }
protected:
void DoDescribe(ODesc* d) const override;
private:
factory_callback factory;
};
class LogSerializerComponent : public plugin::Component {
public:
using factory_callback = std::unique_ptr<LogSerializer> (*)();
/**
* Constructor.
*
* @param name The name of the log serializer. A Zeek script-level enum
* with the name Cluster::LOG_SERIALIZER_<NAME> will be created.
*
* @param factory A factory function to instantiate instances of the
* log serializer.
*/
LogSerializerComponent(const std::string& name, factory_callback factory);
/**
* Destructor.
*/
~LogSerializerComponent() override = default;
/**
* Initialization function. This function has to be called before any
* plugin component functionality is used; it is used to add the
* plugin component to the list of components and to initialize tags
*/
void Initialize() override;
/**
* Returns the analyzer's factory function.
*/
factory_callback Factory() const { return factory; }
protected:
void DoDescribe(ODesc* d) const override;
private:
factory_callback factory;
};
} // namespace zeek::cluster

27
src/cluster/Manager.cc Normal file
View file

@ -0,0 +1,27 @@
#include "zeek/cluster/Manager.h"
#include "zeek/cluster/Serializer.h"
using namespace zeek::cluster;
Manager::Manager()
: backends(plugin::ComponentManager<BackendComponent>("Cluster", "BackendTag")),
event_serializers(plugin::ComponentManager<EventSerializerComponent>("Cluster", "EventSerializerTag")),
log_serializers(plugin::ComponentManager<LogSerializerComponent>("Cluster", "LogSerializerTag")) {}
std::unique_ptr<Backend> Manager::InstantiateBackend(const zeek::EnumValPtr& tag,
std::unique_ptr<EventSerializer> event_serializer,
std::unique_ptr<LogSerializer> log_serializer) {
const BackendComponent* c = Backends().Lookup(tag);
return c ? c->Factory()(std::move(event_serializer), std::move(log_serializer)) : nullptr;
}
std::unique_ptr<EventSerializer> Manager::InstantiateEventSerializer(const zeek::EnumValPtr& tag) {
const EventSerializerComponent* c = EventSerializers().Lookup(tag);
return c ? c->Factory()() : nullptr;
}
std::unique_ptr<LogSerializer> Manager::InstantiateLogSerializer(const zeek::EnumValPtr& tag) {
const LogSerializerComponent* c = LogSerializers().Lookup(tag);
return c ? c->Factory()() : nullptr;
}

80
src/cluster/Manager.h Normal file
View file

@ -0,0 +1,80 @@
// See the file "COPYING" in the main distribution directory for copyright.
#pragma once
#include <memory>
#include "zeek/cluster/Component.h"
#include "zeek/cluster/Serializer.h"
#include "zeek/plugin/ComponentManager.h"
namespace zeek::cluster {
/**
* Manager to allow registration of cluster components.
*
* This manager holds three component manager for event and log serializers
* components, as well as backend components themselves.
*/
class Manager {
public:
Manager();
/**
* Instantiate a cluster backend with the given enum value and
* pre-instantiated event and log serializers.
*
* @param tag The enum value identifying the backend.
* @param event_serializer The event serializer to inject.
* @param log_serializer The log serializer to inject.
*
* @return New ClusterBackend instance, or null if there's no such component.
*/
std::unique_ptr<Backend> InstantiateBackend(const EnumValPtr& tag,
std::unique_ptr<EventSerializer> event_serializer,
std::unique_ptr<LogSerializer> log_serializer);
/**
* Instantiate a event serializer with the given enum value.
*
* @param tag The enum value identifying a serializer.
*
* @return New Serializer instance, or null if there's no such component.
*/
std::unique_ptr<EventSerializer> InstantiateEventSerializer(const EnumValPtr& tag);
/**
* Instantiate a log serializer with the given enum value.
*
* @param tag The enum value identifying a serializer.
*
* @return New Serializer instance, or null if there's no such component.
*/
std::unique_ptr<LogSerializer> InstantiateLogSerializer(const EnumValPtr& tag);
/**
* @return The ComponentManager for backends.
*/
plugin::ComponentManager<BackendComponent>& Backends() { return backends; };
/**
* @return The ComponentManager for event serializers.
*/
plugin::ComponentManager<EventSerializerComponent>& EventSerializers() { return event_serializers; };
/**
* @return The ComponentManager for serializers.
*/
plugin::ComponentManager<LogSerializerComponent>& LogSerializers() { return log_serializers; };
private:
plugin::ComponentManager<BackendComponent> backends;
plugin::ComponentManager<EventSerializerComponent> event_serializers;
plugin::ComponentManager<LogSerializerComponent> log_serializers;
};
// This manager instance only exists for plugins to register components,
// not for actual cluster functionality.
extern Manager* manager;
} // namespace zeek::cluster

View file

@ -313,6 +313,14 @@ void ScriptInfo::DoInitPostScript() {
const auto& id = zeek::detail::global_scope()->Find("Log::Writer"); const auto& id = zeek::detail::global_scope()->Find("Log::Writer");
types.push_back(new IdentifierInfo(id, this)); types.push_back(new IdentifierInfo(id, this));
} }
else if ( name == "base/frameworks/cluster/main.zeek" ) {
const auto& backend_id = zeek::detail::global_scope()->Find("Cluster::BackendTag");
types.push_back(new IdentifierInfo(backend_id, this));
const auto& event_serializer_id = zeek::detail::global_scope()->Find("Cluster::EventSerializerTag");
types.push_back(new IdentifierInfo(event_serializer_id, this));
const auto& log_serializer_id = zeek::detail::global_scope()->Find("Cluster::LogSerializerTag");
types.push_back(new IdentifierInfo(log_serializer_id, this));
}
} }
vector<string> ScriptInfo::GetComments() const { return comments; } vector<string> ScriptInfo::GetComments() const { return comments; }