Extensions
Last updated
Last updated
Live Platform is extensible through different ways, one of most used forms we call Extensions and Live helps you to manage life cycle and configuration of extensions.
The installed extensions are managed through one of Integrations, Platform Customizations or Interface Customizations in Live administration menu.
The code below adds a very simple extension to Live Engine as part of a plugin starter code.
An extension is defined by a type and an configuration classes that should implements ExtensionType
and ExtensionConfig
interfaces respectively, as shown below.
TIP: Live provides a helper class LiveJson
to ease translate a JSON string to class attributes and automatically fulfill the SomeConfig.ships
attribute in our example above.
The string returned by typename
method will represent the Live element in Live Engine, e.g. if the extension provides a REST service the typename will prefix the url location of it. Give some love to it.
Extensions can be hosted in Live under the main areas INTEGRATION
, PLATFORM
or CUSTOMIZATION
, as previously seen in screenshot at top of this section.
Extensions can be organized using a set of roles to ease find them on the Live marketplace. The following roles are supported:
INPUT
: indicates that extension could receive data or event and makes them available in Live.
Built-in: ActiveMQ, Phone Sensors, Replay, REST and TCP.
NOTIFICATION
: indicates that extension could notify live activities to external applications.
Built-in: ActiveMQ and SMTP.
QUERY
: typically used by query providers to operate alongside pipes.
Built-in: Pipes, Esper, Groovy Snippets, Lognit, MongoDB and SQL.
STORAGE
: when the extension saves live events in some data stores.
Built-in: MongoDB, PostgreSQL and SQL.
UI
: customizes how Live UI looks.
Built-in: Dashboard Templates, CSS Files, CSS Snippets, JS Files and JS Snippets.
AUTH
: adds some other authentication method to Live.
Built-in: LDAP, OAuth 2.0 and SAML 2.0.
OUTPUT
: configures an output for a event query.
TIP: Extension roles are optional, just organizational purposes, e.g. there's another built-in extension that doesn't use any of these roles: Lookup Tables.
Extensions are qualified by a string provided at configuration time, typically when Live administrator fulfill the parameters required for an ExtensionConfig concrete class. The extension developer can handle the qualifier received in register
and test
methods to identify different instances of an extension.
Qualifiers in Live must be unique but Live also allows the existence of an empty qualifier. Remember that multiple qualifiers are organized under the same extension type.
Live supports multiple instances of a same extension. It's useful to read from many storage providers or to receive data from any arbitrary number of REST input endpoints and process all data together from event processing capabilities in Live, e.g. using Pipes queries.
After compile and package your very first tutorial plugin, you may upload it using Plugins menu in Live administration menu.
The tutorial plugin just adds an extension type, so you can check the message saying "added extension type 'plugin-tutorial' as PLATFORM" in the plugin list screen.
Now, let's go find it under the Platform Customization area in Live administration.
Extension instance configuration provides a basic form to fulfill the qualifier and a JSON that will be serialized as string and given as argument to concrete version ofExtensionType.parseConfig
method.
The Live default form provides two form buttons Test and Save.
Test action will trigger a POST to Live internal endpoint /rest/extension/test
using data provided on the form provided and also the plugin metadata (e.g. typename).
Live will automatically dispatch the method call to the concrete version of ExtensionConfig.validate
in order to validate the configuration provided for that instance described by that qualifier. So, developer may check if the config attributes meet its requirements returning a ValidationBuilder
object.
Once validated, the Live will represent the validation results as VALID
or INVALID
.
For example, our SomeConfig.validate
method required the ships to be a not null attribute. In case of missing the fulfill of ships
JSON field it remains null and validation will fail.
Save action will trigger a POST to another Live internal endpoint /rest/extension
in order to save the new instance itself. The mechanics of validation and configuration parsing is the same but now Live creates a new element in Live Engine and calls ExtensionType.register
to proceed the developer code on the fresh new instance created.
At this time, the extension instance has an unique ID in Live subsystems and further operations as instance stop or plugin stop will be handled by Live itself.
Extension instances can be stopped and removed from Live through its own listing on Live area. The same where you trigger the creation of the instance.
In detail, ExtensionType.register
method must return a ElementHandle
object.
ElementHandle
is a abstract class that enables the extension to inform its status
and Live calls refresh
periodically (extension should update its status at that calls) and delegates the termination of an instance through close
method. The code below shows a short version and a complete version (with helper inner classes) of this class.
The status of an extension (actually of any Live element) is represented by ElementState
and can assume a sort of states: OK
, UNKNOWN
, UNSUPPORTED
, INACTIVE
, STARTING
, TIMEOUT
, etc.
These states provide some additional information at top of a basic ElementStatus
enumeration. In turn, ElementStatus
could assume one of VALID
, VALID_BUT
, INVALID
or INACTIVE
statuses. Just VALID
means true
and the others mean false
.
The most used states are OK
(VALID
status) and INACTIVE
and STARTING
(INVALID
statuses).
For instance, if something goes wrong at registration phase (or even in status method) you could return something like new ElementState(ElementStatus.INVALID, "with some message")
.
Let's make a simple modification to our tutorial Extension that enables the persistence of ships
data using Settings for didactic purposes of topics covered in Web Services section.
In case you need to list all extensions created, you may use the live.data().getContext()
API and the AllExtensions
Live facility as the criteria to query the underlay SQL database. The Live package net.intelie.live.queries
delivers other similar facilities for all Live basic entities (e.g dashboards, datasources, plugins, perspectives, etc).
The EntityContext
API and Live Data API will be discussed in details in another section.
Frontend plugins have no such API to list extensions (or generic entities). Each resource in Live REST API is protected according. For example, the `/rest/extension` endpoint list all extensions but it is restricted to Live administrative users only.