cluster/Backend: Make backend event processing customizable

This allows configurability at the code level to decide what to do with
a received remote events and events produced by a backend. For now, only
enqueue events into the process's script layer, but for the WebSocket
interface, the action would be to send out the event on a WebSocket
connection instead.
This commit is contained in:
Arne Welzel 2025-01-09 09:58:32 +01:00
parent 337b62960b
commit 0b7a660a34
10 changed files with 139 additions and 27 deletions

View file

@ -53,6 +53,75 @@ public:
const EventHandlerPtr& Handler() const { return handler; }
};
/**
* Interface for processing cluster::Event instances received
* on a given topic.
*
* An instances is injected into Backend instances to allow
* modifying the behavior for received events. For instance,
* for backends instantiated for WebSocket clients, events
* should not be raised as Zeek events locally and instead
* transmitted to the WebSocket client.
*/
class EventHandlingStrategy {
public:
virtual ~EventHandlingStrategy() = default;
/**
* Method for processing a remote event received on the given topic.
*
* When handling the remote event fails, this method should return false.
*
* @param topic The topic on which the event was received.
* @param ev The parsed event that was received.
*
* @return true if the remote event was handled successfully, else false.
*/
bool HandleRemoteEvent(std::string_view topic, Event e) { return DoHandleRemoteEvent(topic, std::move(e)); }
/**
* Method for enquing backend specific events.
*
* Some backend's may raise events destined for the local
* scripting layer. That's usually wanted, but not always.
* When the backend is instantiated for a WebSocket client,
* local scripting layer should not raise events for the
* WebSocket client.
* @param h The event handler to use.
* @param args The event arguments.
*/
void EnqueueLocalEvent(EventHandlerPtr h, zeek::Args args) { DoEnqueueLocalEvent(h, std::move(args)); }
private:
/**
* Hook method for implementing HandleRemoteEvent().
*
* @param topic The topic on which the event was received.
* @param ev The parsed event that was received.
*
* @return true if the remote event was handled successfully, else false.
*/
virtual bool DoHandleRemoteEvent(std::string_view topic, Event e) = 0;
/**
* Hook method for implementing EnqueueLocalEvent().
*
* @param h The event handler to use.
* @param args The event arguments.
*/
virtual void DoEnqueueLocalEvent(EventHandlerPtr h, zeek::Args args) = 0;
};
/**
* Strategy enqueueing events into this process's Zeek event loop.
*/
class LocalEventHandlingStrategy : public EventHandlingStrategy {
private:
bool DoHandleRemoteEvent(std::string_view topic, Event e) override;
void DoEnqueueLocalEvent(EventHandlerPtr h, zeek::Args args) override;
};
/**
* Validate that the provided args are suitable for handler.
*
@ -143,9 +212,24 @@ public:
protected:
/**
* Constructor.
*
* @param es The event serializer to use.
* @param ls The log batch serializer to use.
* @param ehs The event handling strategy to use for this backend.
*/
Backend(std::unique_ptr<EventSerializer> es, std::unique_ptr<LogSerializer> ls)
: event_serializer(std::move(es)), log_serializer(std::move(ls)) {}
Backend(std::unique_ptr<EventSerializer> es, std::unique_ptr<LogSerializer> ls,
std::unique_ptr<detail::EventHandlingStrategy> ehs);
/**
* Enqueue an event to be raised to this process Zeek scripting layer.
*
* When a backend is used for a WebSocket client connection, events
* raised through this method are blackholed.
*
* @param h The event handler.
* @param args The event arguments.
*/
void EnqueueEvent(EventHandlerPtr h, zeek::Args args);
/**
* Process an incoming event message.
@ -277,6 +361,7 @@ private:
std::unique_ptr<EventSerializer> event_serializer;
std::unique_ptr<LogSerializer> log_serializer;
std::unique_ptr<detail::EventHandlingStrategy> event_handling_strategy;
};
/**