Skip to content
Platform > Plugins

Enabling and Disabling Plugins

Whether an installed plugin is used is controlled by plugin lists: properties such as ami.datasource.plugins that name which plugins of one type each component creates. This page covers the plugin list syntax, which property governs which plugin type, and how to pass settings to an individual plugin.

Overview

Every plugin type has its own plugin list. At startup, each component that supports the type reads the list and creates the plugins it names. A plugin in the list is enabled; a registered plugin not in the list is installed but unused.

The shipped values of the plugin lists are in the installation's config/defaults.properties. Do not edit that file. To change a list, add the property with its new value to config/local.properties, the installation's override file, where it takes precedence over the shipped value. A newly created installation has no plugin lists in config/local.properties, so to see a list's current value, check config/local.properties first and config/defaults.properties second.

Most shipped lists are *, which enables every registered plugin of that type. A newly installed bundle therefore needs no configuration change in most cases, only a restart. Check which property governs a plugin, and whether it is enabled, with ami.showPlugins() on the admin console; its ManagerProperty column names the list. See Checking installed plugins.

The plugin list syntax

A plugin list is a comma-separated list of entries:

Entry Meaning
* Every registered plugin of this type.
ID This plugin. The server fails to start if no plugin with this ID is registered.
!ID Not this plugin. Exclusions apply after everything else, wherever they appear in the list.
empty, or property not set No plugins of this type. An empty list is not the same as *.

Spaces around entries are ignored, and plugin IDs are case-sensitive: KAFKA is not kafka.

The shipped Center datasource list shows each form:

# Every datasource plugin except 4 that are excluded by default
ami.datasource.plugins=*, !SHELL, !RESTAPI, !SSH, !SFTP

Turning a plugin off

To stop a plugin being used without uninstalling it, add an exclusion to its list and restart. For example, to disable the Kafka feed handler:

ami.relay.feedhandler.plugins=*,!KAFKA

The plugin stays registered, so it still appears in ami.showPluginRegistry(), but it no longer appears in ami.showPlugins().

To turn it back on, remove the exclusion and restart. If the line in config/local.properties existed only to hold the exclusion, delete the whole line so the shipped value applies again.

The class name also works in an exclusion, e.g: !com.f1.ami.relay.fh.kafka.AmiKafkaFeedHandlerPlugin.

Warning

A misspelled exclusion is ignored without any warning. !KAFKAA leaves KAFKA enabled and the server starts normally. After adding an exclusion, confirm with ami.showPlugins() that the plugin is gone.

Naming a plugin explicitly

Where a list does not contain *, add the plugin's ID to it. To keep the shipped entries and add one, refer to the existing value with $${...}:

ami.relay.feedhandler.plugins=$${ami.relay.feedhandler.plugins},KAFKA

The server expands this to the shipped list followed by the new ID, here *,KAFKA. While the list contains *, this is unnecessary, because * already includes the new plugin.

Warning

Naming an ID that is not registered stops the server from starting. This happens after a typo, after a change of case, or after the bundle that provided the ID is removed. The error lists every registered ID of that type, including those from installed bundles:

Error processing property ami.relay.feedhandler.plugins=*,KAFKA
Plugin not found: KAFKA  (available RELAY_FEEDHANDLER plugins: AMI_RTCLIENT,AMI_RTSERVER)

Here the Kafka bundle had been removed while KAFKA was still named in the list.

Plugin ID or class name

A plugin can be named by its plugin ID or by its fully qualified class name, e.g: KAFKA or com.f1.ami.relay.fh.kafka.AmiKafkaFeedHandlerPlugin. Both work for a plugin that is registered from a bundle or built in. We recommend the plugin ID: it is what every listing shows, and it does not change if the plugin's class is renamed.

A class name only works for a registered plugin. A class that is on the classpath but not in any bundle is not a valid entry; install it as a bundle instead.

Which property enables which plugins

Each plugin type has one plugin list. Where a type is used by more than one component, the same property applies to all of them: ami.datasource.plugins governs datasource plugins in both the Center and the Relay.

Plugin type Plugin list Components Shipped value
Datasource adapters ami.datasource.plugins Center, Relay *, !SHELL, !RESTAPI, !SSH, !SFTP
Relay feed handlers ami.relay.feedhandler.plugins Relay *
Relay invokables ami.relay.invokable.plugins Relay *
Services ami.service.plugins Relay *
Center triggers ami.db.trigger.plugins Center *
Center timers ami.db.timer.plugins Center *
Center procedures ami.db.procedure.plugins Center *
Table persisters ami.db.persister.plugins Center *
SQL dialects ami.db.dialect.plugins Center *
Center database objects ami.db.dbo.plugins Center not set, so none
Web panels ami.web.panel.plugins Web *
Web realtime processors ami.realtime.processor.plugins Web *
Web menus ami.web.extension.plugins Web *
AmiScript extern languages ami.extern.plugins Center, Relay, Web, Gateway *,!PYTHON
AmiScript libraries ami.library.plugins Center, Relay, Web, Gateway not set, so none
REST endpoints ami.rest.plugin.classes REST server *,!QUERY,!ADMIN
WebSocket protocol endpoints ami.rpc.ws.plugin.classes WebSocket server DAP,LSP,LSP_OPEN

Authentication plugins, and plugins that control which hosts may connect, are selected by single-value properties, not plugin lists, and are covered in the Security section.

Warning

AmiScript library plugins are read from ami.library.plugins, which the shipped configuration does not set, so none load by default. The shipped configuration sets ami.web.library.plugins=* instead, but nothing reads that property. To use a library plugin, set:

ami.library.plugins=*

For example, the spreadsheet bundle, amispreadsheet.tar.gz, registers 2 plugins. With the shipped configuration only its menu plugin is enabled, and the startup log shows REGISTERED PLUGIN: SCRIPT_LIBRARY>SPREADSHEET with no matching CREATED PLUGIN line. After ami.library.plugins=* is set and the server restarted, the library plugin is created in the Center, the Relay, and the Web, and ami.showPlugins() lists it with ami.library.plugins in the ManagerProperty column.

AmiScript extern and library plugins are not available on the WebBalancer or the WebManager.

Configuring an individual plugin

A plugin reads its own settings from properties that begin with its fully qualified class name followed by a dot. The class name is shown in the Class column of ami.showPlugins(). For a plugin whose class is com.example.MyPlugin, a setting named timeout is written:

com.example.MyPlugin.timeout=30

The plugin ID is not used as the prefix. Which settings a plugin accepts is specific to that plugin, and some plugins read their settings differently; neither is covered in this section.

Security warnings from plugins

Some plugins log a SECURITY-WARNING at startup describing what they can access. The shipped exclusions exist for this reason:

  • SHELL datasource: "Allows access to run arbitrary script on host machine".
  • QUERY REST endpoint: "The REST query endpoint is enabled. This allows executing arbitrary queries via HTTP".

These warnings appear at every startup because the plugins are registered, even though the shipped lists exclude them. A warning is informational only: nothing is blocked because of it. Removing a shipped exclusion enables a plugin that warns about itself.

What this does not support

  • A warning for a misspelled exclusion: an exclusion that matches no plugin is ignored.
  • Plugin classes on the classpath but not in any bundle: only plugins registered from a bundle, or built in, can be named.