Package io.kroxylicious.proxy.plugin


@ReturnValuesAreNonnullByDefault @DefaultAnnotationForParameters(edu.umd.cs.findbugs.annotations.NonNull.class) @DefaultAnnotation(edu.umd.cs.findbugs.annotations.NonNull.class) package io.kroxylicious.proxy.plugin
API for defining plugins within configuration.

Terminology

A plugin interface is a Java interface (or possibly a class) that can be used in the implementation of a component of the proxy. FilterFactory is one example of a plugin interface.

A plugin implementation provides a concrete behaviour by implementing the plugin interface (or extending the class). There will usually be more than one plugin implementation for a given plugin interface. Plugin implementations can be referenced in a configuration file by their fully qualified class name, or by their unqualified class name if that is unambiguous. Such references are known as plugin implementation names. Any class that implements FilterFactory is an example of a plugin implementation.

Plugin implementations often require some configuration to be provided in the configuration. The configuration is represented in Java using a "config record", or "config class". Different plugin implementations will generally use different config records.

Using a plugin implementation

The author of a FooFilter that wants to use a HttpGetter to make an HTTP GET request, but doesn't want to depend directly on any particular HTTP client. HttpGetter is the plugin interface.


 interface HttpGetter<C> {
     void configure(C config);
     String get(String url);
 }
 

Note that this plugin interface doesn't know the concrete type of the configuration that an implementation requires. In this case it is using a type parameter C to represent that.

The config record for FooFilter would express its dependence on a HttpGetter, and also provide a property to hold the HttpGetter implementation's own configuration, like this


 record FooFilterConfig(
   @PluginImplName(HttpGetter.class)
   String httpGetterPluginImplName,
   @PluginImplConfig(implNameProperty="httpGetterPluginImplName")
   Object httpGetterConfig
 ) { }
 

The PluginImplConfig.implNameProperty() names the property of the config object that holds the plugin implementation name. In practice the author of FooFilter might want to chose config property names which are intuitive to someone writing a configuration file, such as httpImpl and httpConfig.

The FooFilter author can then get an instance of the plugin implementation configured by the user using the FilterFactoryContext, like this:


 class FooFilterFactory implements FilterFactory<FooFilterConfig, Void> {
     Void initialize(FilterFactoryContext context, FooFilterConfig config) {
       // get the configured HttpGetter
       this.httpGetter = context.pluginInstance(HttpGetter.class, config.httpGetterPluginImplName());
       // initialize it
       this.httpGetter.configure(config.httpGetterConfig());
       return null;
     }
     Filter createFilter(FilterFactoryContext context, Void v) {
         return new Filter() {
           // use the httpGetter
         };
     }
 }
 

Implementing a plugin

Someone can write an implementation of HttpGetter using Netty. They need to annotate their implementation with @Plugin to indicate the type of configuration it uses.


 @Plugin(configType=NettyConfig.class)
 class NettyHttpGetter implements HttpGetter<NettyConfig> {
     // ...
 }
 

and provide a record for that config:


 record NettyConfig(String trustStore) { }
 
  • Class
    Description
    Annotates a @Plugin implementation class whose fully-qualified type name has been changed and whose old name should no longer be used to refer to it.
    An annotation, on a plugin implementation class, that identifies the class of "config record" consumed by that implementation.
    Thrown when a plugin configuration is invalid
    An annotation that identifies a plugin instance name at a plugin point within the configuration.
    Annotates a property (within a "config record") that names a plugin implementation with the plugin interface.
     
    A reference to a plugin instance could not be resolved by the proxy runtime.