Plugin Development - Preview -

The proxy core runtime provides a set of extension points to provide custom functionality that extends various aspects of the core runtime and the configurable routing and loadbalancing engine. With that, plugins give greater control over custom logic than plain Zuul Groovy filters and they integrate seamlessly into the core configuration mechanism.

Important

The whole plugin feature should not be enabled or used in production as it is not fully tested and therefore marked as preview. Nevertheless it can already be used for development purposes to learn more about plugin handling and the potentials.

Extension Points

Currently the following extension points are defined:

Zuul Filters

Add compiled Zuul filters as Java classes

Configuration Reload

Add custom ReloadListener implementations that get called on configuration reload

Routing

Add custom types for ProxyAction, Restriction, Condition

Load Balancing

Add custom BackendPool types

Admin Endpoints

Custom REST resources available at the admin HTTP listener

Health Checks

Add health checks to determine the health status of Proxy itself

Development

Refer to the example plugin implementation as a reference. Start with its README file and look at its build.gradle file and ExamplePlugin class to get an overview of how to develop an own plugin.

Whenever possible, use the io.ox.proxy.plugins.spi.PluginContext to register extensions, as it provides convenient and type-safe methods to do so.

Please note that plugin initialization happens during Guice binding time (dependency injection / wiring), very early in the server startup phase. Any kind of asynchronous task or heavy I/O operation is supposed to happen at runtime and must therefore be delayed by executing them from within according callbacks or by utilizing the runtime call behavior of the respective extensions.

Important: Any exception during initialization will lead to termination of the proxy process!

Plugin Enabling

Plugin handling must be globally enabled by setting Java system property proxy.pluginsEnabled when starting proxy server.

Important: Do not enable plugins in production environments

Plugin Loading

Plugins must be packaged as JAR files (one per plugin) and placed – along with any additional dependencies – within a configurable directory before server startup. The plugins directory is defined by Java system property proxy.pluginsdir.

To isolate plugin code from core code at runtime, plugins are loaded using a dedicated classloader. All plugin classes are loaded using an URLClassLoader instance that knows all JAR files from the plugins directory and that delegates to the core runtime classloader to resolve any dependencies therein. This provides some sort of security as plugin classes cannot be loaded by the core runtime by their name alone, i.e. invocations of Class.forName("my.plugin.Clazz") will fail with NoClassDefFoundError.

Each implemented io.ox.proxy.plugins.spi.Plugin is supposed to be made available using the Java ServiceLoader mechanism. Any extensions are then supposed to be provided as java.lang.Class instances or actual instances of their implemented interfaces.

Wiring of runtime instances happens via the Guice dependency injection framework. Plugins may alter the low-level binding configuration, but for many use-cases more high-level mechanisms are available to register extensions. However, plugin resolution and initialization happens during the Guice binding phase.