package extension import ( "context" "net/http" "github.com/konduktor/konduktor/internal/logging" ) // Extension is the interface that all extensions must implement type Extension interface { // Name returns the unique name of the extension Name() string // Initialize is called when the extension is loaded Initialize() error // ProcessRequest processes an incoming request before routing. // Returns: // - response: if non-nil, the request is handled and no further processing occurs // - handled: if true, the request was handled by this extension // - err: any error that occurred ProcessRequest(ctx context.Context, w http.ResponseWriter, r *http.Request) (handled bool, err error) // ProcessResponse is called after the response is generated but before it's sent. // Extensions can modify the response here. ProcessResponse(ctx context.Context, w http.ResponseWriter, r *http.Request) // Cleanup is called when the extension is being unloaded Cleanup() error // Enabled returns whether the extension is currently enabled Enabled() bool // SetEnabled enables or disables the extension SetEnabled(enabled bool) // Priority returns the extension's priority (lower = earlier execution) Priority() int } // BaseExtension provides a default implementation for common Extension methods type BaseExtension struct { name string enabled bool priority int logger *logging.Logger } // NewBaseExtension creates a new BaseExtension func NewBaseExtension(name string, priority int, logger *logging.Logger) BaseExtension { return BaseExtension{ name: name, enabled: true, priority: priority, logger: logger, } } // Name returns the extension name func (b *BaseExtension) Name() string { return b.name } // Enabled returns whether the extension is enabled func (b *BaseExtension) Enabled() bool { return b.enabled } // SetEnabled sets the enabled state func (b *BaseExtension) SetEnabled(enabled bool) { b.enabled = enabled } // Priority returns the extension priority func (b *BaseExtension) Priority() int { return b.priority } // Initialize default implementation (no-op) func (b *BaseExtension) Initialize() error { return nil } // Cleanup default implementation (no-op) func (b *BaseExtension) Cleanup() error { return nil } // ProcessRequest default implementation (pass-through) func (b *BaseExtension) ProcessRequest(ctx context.Context, w http.ResponseWriter, r *http.Request) (bool, error) { return false, nil } // ProcessResponse default implementation (no-op) func (b *BaseExtension) ProcessResponse(ctx context.Context, w http.ResponseWriter, r *http.Request) { } // Logger returns the extension's logger func (b *BaseExtension) Logger() *logging.Logger { return b.logger } // ExtensionConfig holds configuration for creating extensions type ExtensionConfig struct { Type string Config map[string]interface{} } // ExtensionFactory is a function that creates an extension from config type ExtensionFactory func(config map[string]interface{}, logger *logging.Logger) (Extension, error) // ResponseWriterWrapper is an optional interface that extensions can implement // to wrap the response writer for capturing/modifying responses type ResponseWriterWrapper interface { WrapResponseWriter(w http.ResponseWriter, r *http.Request) http.ResponseWriter } // ResponseFinalizer is an optional interface for response writers that need // to perform finalization after the response is written (e.g., caching) type ResponseFinalizer interface { Finalize() }