From 22d2a0c6ca687d1197fd3d6bb95ee39540eee10b Mon Sep 17 00:00:00 2001 From: Anthony Rubick <68485672+AnthonyMichaelTDM@users.noreply.github.com> Date: Sun, 31 Aug 2025 21:27:45 -0500 Subject: [PATCH] refactor: move event types into own submodule --- src/accesslist.go | 6 +-- src/mod/dynamicproxy/access.go | 4 +- src/mod/eventsystem/event_system.go | 21 +++++----- src/mod/eventsystem/event_system_test.go | 38 +++++++++---------- src/mod/plugins/eventlistener.go | 4 +- src/mod/plugins/lifecycle.go | 3 +- .../{event.go => events/events.go} | 2 +- .../plugins/zoraxy_plugin/zoraxy_plugin.go | 6 ++- 8 files changed, 44 insertions(+), 40 deletions(-) rename src/mod/plugins/zoraxy_plugin/{event.go => events/events.go} (99%) diff --git a/src/accesslist.go b/src/accesslist.go index f65c7b2..76ab2f8 100644 --- a/src/accesslist.go +++ b/src/accesslist.go @@ -11,7 +11,7 @@ import ( "imuslab.com/zoraxy/mod/access" "imuslab.com/zoraxy/mod/eventsystem" - "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin" + "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events" "imuslab.com/zoraxy/mod/utils" ) @@ -101,7 +101,7 @@ func handleCreateAccessRule(w http.ResponseWriter, r *http.Request) { // emit an event for the new access rule creation eventsystem.Publisher.Emit( - &zoraxy_plugin.AccessRuleCreatedEvent{ + &events.AccessRuleCreatedEvent{ ID: ruleUUID, Name: ruleName, Desc: ruleDesc, @@ -372,7 +372,7 @@ func handleBlacklistEnable(w http.ResponseWriter, r *http.Request) { return } - eventsystem.Publisher.Emit(&zoraxy_plugin.BlacklistToggledEvent{ + eventsystem.Publisher.Emit(&events.BlacklistToggledEvent{ RuleID: ruleID, Enabled: rule.BlacklistEnabled, }) diff --git a/src/mod/dynamicproxy/access.go b/src/mod/dynamicproxy/access.go index 4cb5f25..dca919c 100644 --- a/src/mod/dynamicproxy/access.go +++ b/src/mod/dynamicproxy/access.go @@ -8,7 +8,7 @@ import ( "imuslab.com/zoraxy/mod/access" "imuslab.com/zoraxy/mod/eventsystem" "imuslab.com/zoraxy/mod/netutils" - "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin" + "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events" ) // Handle access check (blacklist / whitelist), return true if request is handled (aka blocked) @@ -52,7 +52,7 @@ func accessRequestBlocked(accessRule *access.AccessRule, templateDirectory strin comment = "blacklisted" } eventsystem.Publisher.Emit( - &zoraxy_plugin.BlacklistedIPBlockedEvent{ + &events.BlacklistedIPBlockedEvent{ IP: clientIpAddr, Comment: comment, RequestedURL: r.URL.String(), diff --git a/src/mod/eventsystem/event_system.go b/src/mod/eventsystem/event_system.go index d2453b1..7c4f820 100644 --- a/src/mod/eventsystem/event_system.go +++ b/src/mod/eventsystem/event_system.go @@ -6,21 +6,22 @@ import ( "imuslab.com/zoraxy/mod/info/logger" // "imuslab.com/zoraxy/mod/plugins" - zoraxyPlugin "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin" + + "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events" ) type ListenerID string type Listener interface { - Notify(event zoraxyPlugin.Event) error + Notify(event events.Event) error GetID() ListenerID } // eventManager manages event subscriptions and dispatching events to listeners type eventManager struct { - subscriptions map[zoraxyPlugin.EventName][]ListenerID // EventType -> []Subscriber, tracks which events each listener is subscribed to - subscribers map[ListenerID]Listener // ListenerID -> Listener, tracks all registered listeners - logger *logger.Logger // Logger for the event manager - mutex sync.RWMutex // Mutex for concurrent access + subscriptions map[events.EventName][]ListenerID // EventType -> []Subscriber, tracks which events each listener is subscribed to + subscribers map[ListenerID]Listener // ListenerID -> Listener, tracks all registered listeners + logger *logger.Logger // Logger for the event manager + mutex sync.RWMutex // Mutex for concurrent access } var ( @@ -33,7 +34,7 @@ var ( func InitEventSystem(logger *logger.Logger) { once.Do(func() { Publisher = &eventManager{ - subscriptions: make(map[zoraxyPlugin.EventName][]ListenerID), + subscriptions: make(map[events.EventName][]ListenerID), subscribers: make(map[ListenerID]Listener), logger: logger, } @@ -41,7 +42,7 @@ func InitEventSystem(logger *logger.Logger) { } // RegisterSubscriberToEvent adds a listener to the subscription list for an event type -func (em *eventManager) RegisterSubscriberToEvent(subscriber Listener, eventType zoraxyPlugin.EventName) error { +func (em *eventManager) RegisterSubscriberToEvent(subscriber Listener, eventType events.EventName) error { em.mutex.Lock() defer em.mutex.Unlock() @@ -86,7 +87,7 @@ func (em *eventManager) UnregisterSubscriber(listenerID ListenerID) error { } // Emit dispatches an event to all subscribed listeners -func (em *eventManager) Emit(payload zoraxyPlugin.EventPayload) error { +func (em *eventManager) Emit(payload events.EventPayload) error { eventName := payload.GetName() em.mutex.RLock() @@ -98,7 +99,7 @@ func (em *eventManager) Emit(payload zoraxyPlugin.EventPayload) error { } // Create the event - event := zoraxyPlugin.Event{ + event := events.Event{ Name: eventName, Timestamp: time.Now().Unix(), Data: payload, diff --git a/src/mod/eventsystem/event_system_test.go b/src/mod/eventsystem/event_system_test.go index c6ecebc..432ae5a 100644 --- a/src/mod/eventsystem/event_system_test.go +++ b/src/mod/eventsystem/event_system_test.go @@ -6,14 +6,14 @@ import ( "testing" "time" - "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin" + "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events" ) // Test (de)serialization of events func TestEventDeSerialization(t *testing.T) { type SerializationTest struct { name string - event zoraxy_plugin.Event + event events.Event expectedJson string } @@ -22,10 +22,10 @@ func TestEventDeSerialization(t *testing.T) { tests := []SerializationTest{ { name: "BlacklistedIPBlocked", - event: zoraxy_plugin.Event{ - Name: zoraxy_plugin.EventBlacklistedIPBlocked, + event: events.Event{ + Name: events.EventBlacklistedIPBlocked, Timestamp: timestamp, - Data: &zoraxy_plugin.BlacklistedIPBlockedEvent{ + Data: &events.BlacklistedIPBlockedEvent{ IP: "192.168.1.1", Comment: "Test comment", RequestedURL: "http://example.com", @@ -38,10 +38,10 @@ func TestEventDeSerialization(t *testing.T) { }, { name: "BlacklistToggled", - event: zoraxy_plugin.Event{ - Name: zoraxy_plugin.EventBlacklistToggled, + event: events.Event{ + Name: events.EventBlacklistToggled, Timestamp: timestamp, - Data: &zoraxy_plugin.BlacklistToggledEvent{ + Data: &events.BlacklistToggledEvent{ RuleID: "rule123", Enabled: true, }, @@ -50,10 +50,10 @@ func TestEventDeSerialization(t *testing.T) { }, { name: "AccessRuleCreated", - event: zoraxy_plugin.Event{ - Name: zoraxy_plugin.EventAccessRuleCreated, + event: events.Event{ + Name: events.EventAccessRuleCreated, Timestamp: timestamp, - Data: &zoraxy_plugin.AccessRuleCreatedEvent{ + Data: &events.AccessRuleCreatedEvent{ ID: "rule456", Name: "New Access Rule", Desc: "A dummy access rule", @@ -79,8 +79,8 @@ func TestEventDeSerialization(t *testing.T) { } // Deserialize the JSON back into an event - var deserializedEvent zoraxy_plugin.Event - if err := zoraxy_plugin.ParseEvent(jsonData, &deserializedEvent); err != nil { + var deserializedEvent events.Event + if err := events.ParseEvent(jsonData, &deserializedEvent); err != nil { t.Fatalf("Failed to parse event: %v", err) } @@ -90,18 +90,18 @@ func TestEventDeSerialization(t *testing.T) { } switch data := deserializedEvent.Data.(type) { - case *zoraxy_plugin.BlacklistedIPBlockedEvent: - originalData, ok := test.event.Data.(*zoraxy_plugin.BlacklistedIPBlockedEvent) + case *events.BlacklistedIPBlockedEvent: + originalData, ok := test.event.Data.(*events.BlacklistedIPBlockedEvent) if !ok || *data != *originalData { t.Fatalf("Deserialized BlacklistedIPBlockedEvent does not match original.\nGot: %+v\nWant: %+v", data, originalData) } - case *zoraxy_plugin.AccessRuleCreatedEvent: - originalData, ok := test.event.Data.(*zoraxy_plugin.AccessRuleCreatedEvent) + case *events.AccessRuleCreatedEvent: + originalData, ok := test.event.Data.(*events.AccessRuleCreatedEvent) if !ok || *data != *originalData { t.Fatalf("Deserialized AccessRuleCreatedEvent does not match original.\nGot: %+v\nWant: %+v", data, originalData) } - case *zoraxy_plugin.BlacklistToggledEvent: - originalData, ok := test.event.Data.(*zoraxy_plugin.BlacklistToggledEvent) + case *events.BlacklistToggledEvent: + originalData, ok := test.event.Data.(*events.BlacklistToggledEvent) if !ok || *data != *originalData { t.Fatalf("Deserialized BlacklistToggledEvent does not match original.\nGot: %+v\nWant: %+v", data, originalData) } diff --git a/src/mod/plugins/eventlistener.go b/src/mod/plugins/eventlistener.go index 6000c35..21d3244 100644 --- a/src/mod/plugins/eventlistener.go +++ b/src/mod/plugins/eventlistener.go @@ -12,7 +12,7 @@ import ( "time" "imuslab.com/zoraxy/mod/eventsystem" - zoraxyPlugin "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin" + "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events" ) func (p *Plugin) GetID() eventsystem.ListenerID { @@ -20,7 +20,7 @@ func (p *Plugin) GetID() eventsystem.ListenerID { } // Send an event to the plugin -func (p *Plugin) Notify(event zoraxyPlugin.Event) error { +func (p *Plugin) Notify(event events.Event) error { // Handle the event notification if !p.Enabled || p.AssignedPort == 0 { return fmt.Errorf("plugin %s is not running", p.Spec.ID) diff --git a/src/mod/plugins/lifecycle.go b/src/mod/plugins/lifecycle.go index 5860694..cf8282f 100644 --- a/src/mod/plugins/lifecycle.go +++ b/src/mod/plugins/lifecycle.go @@ -16,6 +16,7 @@ import ( "imuslab.com/zoraxy/mod/dynamicproxy/dpcore" "imuslab.com/zoraxy/mod/eventsystem" zoraxyPlugin "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin" + "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events" ) func (m *Manager) StartPlugin(pluginID string) error { @@ -155,7 +156,7 @@ func (m *Manager) StartPlugin(pluginID string) error { // Register event subscriptions if thisPlugin.Spec.SubscriptionsEvents != nil { for eventName := range thisPlugin.Spec.SubscriptionsEvents { - eventType := zoraxyPlugin.EventName(eventName) + eventType := events.EventName(eventName) err := eventsystem.Publisher.RegisterSubscriberToEvent(thisPlugin, eventType) if err != nil { m.Log("Failed to subscribe plugin "+thisPlugin.Spec.Name+" to event "+string(eventName), err) diff --git a/src/mod/plugins/zoraxy_plugin/event.go b/src/mod/plugins/zoraxy_plugin/events/events.go similarity index 99% rename from src/mod/plugins/zoraxy_plugin/event.go rename to src/mod/plugins/zoraxy_plugin/events/events.go index 0e0924e..3f54b2e 100644 --- a/src/mod/plugins/zoraxy_plugin/event.go +++ b/src/mod/plugins/zoraxy_plugin/events/events.go @@ -1,4 +1,4 @@ -package zoraxy_plugin +package events import ( "encoding/json" diff --git a/src/mod/plugins/zoraxy_plugin/zoraxy_plugin.go b/src/mod/plugins/zoraxy_plugin/zoraxy_plugin.go index 08efe3c..17180bb 100644 --- a/src/mod/plugins/zoraxy_plugin/zoraxy_plugin.go +++ b/src/mod/plugins/zoraxy_plugin/zoraxy_plugin.go @@ -5,6 +5,8 @@ import ( "fmt" "os" "strings" + + "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events" ) /* @@ -102,8 +104,8 @@ type IntroSpect struct { UIPath string `json:"ui_path"` //UI path of your plugin (e.g. /ui), will proxy the whole subpath tree to Zoraxy Web UI as plugin UI /* Subscriptions Settings */ - SubscriptionPath string `json:"subscription_path"` //Subscription event path of your plugin (e.g. /notifyme), a POST request with SubscriptionEvent as body will be sent to this path when the event is triggered - SubscriptionsEvents map[EventName]string `json:"subscriptions_events"` //Subscriptions events of your plugin, paired with comments describing how the event is used, see Zoraxy documentation for more details + SubscriptionPath string `json:"subscription_path"` //Subscription event path of your plugin (e.g. /notifyme), a POST request with SubscriptionEvent as body will be sent to this path when the event is triggered + SubscriptionsEvents map[events.EventName]string `json:"subscriptions_events"` //Subscriptions events of your plugin, paired with comments describing how the event is used, see Zoraxy documentation for more details /* API Access Control */ PermittedAPIEndpoints []PermittedAPIEndpoint `json:"permitted_api_endpoints"` //List of API endpoints this plugin can access, and a description of why the plugin needs to access this endpoint