****************************** 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 :ref:`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.