From 23ca625c039d31e3c1a6088a38c88ab1d44d240b Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Wed, 13 Nov 2024 11:24:08 +0100 Subject: [PATCH] cluster: Add Components and ComponentManager for new components --- src/cluster/CMakeLists.txt | 9 +++ src/cluster/Component.cc | 56 ++++++++++++++++ src/cluster/Component.h | 131 +++++++++++++++++++++++++++++++++++++ src/cluster/Manager.cc | 27 ++++++++ src/cluster/Manager.h | 80 ++++++++++++++++++++++ src/zeekygen/ScriptInfo.cc | 8 +++ 6 files changed, 311 insertions(+) create mode 100644 src/cluster/CMakeLists.txt create mode 100644 src/cluster/Component.cc create mode 100644 src/cluster/Component.h create mode 100644 src/cluster/Manager.cc create mode 100644 src/cluster/Manager.h diff --git a/src/cluster/CMakeLists.txt b/src/cluster/CMakeLists.txt new file mode 100644 index 0000000000..0395d28786 --- /dev/null +++ b/src/cluster/CMakeLists.txt @@ -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) diff --git a/src/cluster/Component.cc b/src/cluster/Component.cc new file mode 100644 index 0000000000..09dd74c938 --- /dev/null +++ b/src/cluster/Component.cc @@ -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()); +} diff --git a/src/cluster/Component.h b/src/cluster/Component.h new file mode 100644 index 0000000000..944557feae --- /dev/null +++ b/src/cluster/Component.h @@ -0,0 +1,131 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include + +#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 (*)(std::unique_ptr, + std::unique_ptr); + + /** + * Constructor. + * + * @param name The name of the cluster backend. A Zeek script-level enum + * with the name Cluster::CLUSTER_BACKEND_ 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 (*)(); + + /** + * Constructor. + * + * @param name The name of the event serializer. A Zeek script-level enum + * with the name Cluster::EVENT_SERIALIZER_ 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 (*)(); + + /** + * Constructor. + * + * @param name The name of the log serializer. A Zeek script-level enum + * with the name Cluster::LOG_SERIALIZER_ 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 diff --git a/src/cluster/Manager.cc b/src/cluster/Manager.cc new file mode 100644 index 0000000000..eff6196164 --- /dev/null +++ b/src/cluster/Manager.cc @@ -0,0 +1,27 @@ +#include "zeek/cluster/Manager.h" + +#include "zeek/cluster/Serializer.h" + +using namespace zeek::cluster; + +Manager::Manager() + : backends(plugin::ComponentManager("Cluster", "BackendTag")), + event_serializers(plugin::ComponentManager("Cluster", "EventSerializerTag")), + log_serializers(plugin::ComponentManager("Cluster", "LogSerializerTag")) {} + +std::unique_ptr Manager::InstantiateBackend(const zeek::EnumValPtr& tag, + std::unique_ptr event_serializer, + std::unique_ptr log_serializer) { + const BackendComponent* c = Backends().Lookup(tag); + return c ? c->Factory()(std::move(event_serializer), std::move(log_serializer)) : nullptr; +} + +std::unique_ptr Manager::InstantiateEventSerializer(const zeek::EnumValPtr& tag) { + const EventSerializerComponent* c = EventSerializers().Lookup(tag); + return c ? c->Factory()() : nullptr; +} + +std::unique_ptr Manager::InstantiateLogSerializer(const zeek::EnumValPtr& tag) { + const LogSerializerComponent* c = LogSerializers().Lookup(tag); + return c ? c->Factory()() : nullptr; +} diff --git a/src/cluster/Manager.h b/src/cluster/Manager.h new file mode 100644 index 0000000000..fd4a44f31c --- /dev/null +++ b/src/cluster/Manager.h @@ -0,0 +1,80 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include + +#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 InstantiateBackend(const EnumValPtr& tag, + std::unique_ptr event_serializer, + std::unique_ptr 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 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 InstantiateLogSerializer(const EnumValPtr& tag); + + /** + * @return The ComponentManager for backends. + */ + plugin::ComponentManager& Backends() { return backends; }; + + /** + * @return The ComponentManager for event serializers. + */ + plugin::ComponentManager& EventSerializers() { return event_serializers; }; + + /** + * @return The ComponentManager for serializers. + */ + plugin::ComponentManager& LogSerializers() { return log_serializers; }; + +private: + plugin::ComponentManager backends; + plugin::ComponentManager event_serializers; + plugin::ComponentManager log_serializers; +}; + +// This manager instance only exists for plugins to register components, +// not for actual cluster functionality. +extern Manager* manager; + +} // namespace zeek::cluster diff --git a/src/zeekygen/ScriptInfo.cc b/src/zeekygen/ScriptInfo.cc index 817174cca9..70347baa88 100644 --- a/src/zeekygen/ScriptInfo.cc +++ b/src/zeekygen/ScriptInfo.cc @@ -313,6 +313,14 @@ void ScriptInfo::DoInitPostScript() { const auto& id = zeek::detail::global_scope()->Find("Log::Writer"); 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 ScriptInfo::GetComments() const { return comments; }