cla/reg - Registry Manipulation
The Clarive registry holds extension points to many parts of the system, both client and server.
These functions are mostly useful in init/
plugin entrypoints to register
items like palette operations (services), menu entries, events and others.
Create a file in CLARIVE_BASE/plugins/myplugin/init/myplugin-init.js
for registration and hooks to be implemented at Clarive system start.
When the Clarive server (web or dispatcher) starts in debug mode (ie. cla
web-start -d
), it will report all plugin init registrations.
For example:
(D)2018-11-06 17:23:12.183[22795] Running plugin init: .../plugins/myplugin/init/my-controller.js (D)2018-11-06 17:23:12.197[22795] Registered controller path /plugin/myplugin/envs (D)2018-11-06 17:23:12.197[22795] Registered controller path /plugin/myplugin/servers
reg.register(key, config)¶
Creates a registry entry in Clarive.
Registry entries can typically be of the following types:
event.
- an event that will be later fired by the plugin.dashlet.
- a dashlet that can be introduced into a dashboard.service.
- an operation that can be used in rules.action.
- a security action, available when creating roles.-
config.
- an "Advanced Config" key that can be changed by admins. -
key
: a string that uniquely identifies the registered item. It should follow this pattern:[event|service|dashlet|config|action].[yourpluginid].[eventname]
-
config
: a data structure (Javascript object) that describes the
Registering a new plugin event:
var reg = require('cla/reg'); reg.register('event.myplugin.test',{ name: 'Test Event' });
Registering a config key:
var reg = require('cla/reg'); reg.register('config.myplugin', { name: 'Config my plugin', metadata: [ { id: 'timeout', label: 'Plugin Timeout', default: 90 }, { id: 'frequency', label: 'Plugin Frequency', default: 120 } ] } ); // then later, use it in your code: var config = require('cla/config'); var pluginConfig = config.get('config.myplugin'); console.log('The timeout is = ' + pluginConfig.timeout );
Registering a security action:
var reg = require('cla/reg'); reg.register('action.myplugin.allowed', { name: 'Action that allows users to do something with this plugin' } ); // then later... var user = ci.findOneCi({ collection: 'user', username: 'janet' }); var allowed = user.hasAction('action.myplugin.allowed'); if( allowed ) { console.log('user is good for this feature'); }
reg.launch(key, parameters)¶
Launches a registered service. Services are also known as operations, which are available in the rule designer palette to build rules.
var reg = require('cla/reg'); reg.register('service.test',{ name: 'Foo Service', handler: function(){ return 99 } }); reg.launch('service.test', { name: 'just trying this out', config: { foo: 'bar' } });
Options:
config
- a config object to be sent to the handler.name
- reports the op name so that its logging information is more descriptive.dataKey
- reports the op name so that its logging information is more descriptive.stash
- an alternative stash; defaults to the current stash.
reg.fireEvent(eventKey, eventData, eventFunction)¶
Fires an event.
If you register a new event in your plugin, you probably also want to be able to fire it. This function fires events.
eventKey
- the key string of the event we are firing, ie.event.myplugin.someevent
.eventData
- any random data (Javascript object) from our plugin and related to the event that we want to share with rules or other extensions that may customize the event.eventFunction
- this is the core code that runs the event logic. This is optional, but it allows rules and other hooks to prevent it from executing. Data returned by theeventFunction
will be merged into theeventData
and will be accessible toafter
event hooks and rules (online and offline).
In the following example we register and fire an event:
var reg = require('cla/reg'); reg.register('event.myplugin.something', { name: 'Event fired when something happens' }); // then later in your plugin... reg.fireEvent( 'event.myplugin.something', { foo: 123, bar: [1,2,3] }, function(stash){ console.log('This is the core of what happens in my event'); console.log('Got foo here=' + stash.foo); // return values get pushed into the stash for event hooks to use return { result: 'this result goes back into the stash' }; } );
Registering and firing events in your plugin is a great way to enable user customization (with rules) and interop with other plugins. We recommend using it for any pluging features that you may deem extensible or customizable by others.
Warning
Do not fire Clarive's internal events from within your plugin!
(example: event.topic.create
)
Unexpected things may happen. Use fireEvent
for firing events
your created in your plugin.
reg.beforeEvent(eventKey, hookFunction)¶
Runs the hookFunction
code every time an event is fired, before the event logic run.
reg.afterEvent(eventKey, hookFunction)¶
Runs the hookFunction
code every time an event is fired, after the event logic run.
The before event hook enables your plugin to be called immediately before the event's core logic runs.
The after event This means your plugin can alter Clarive's core behavior functionality. Use it wisely.
eventKey
: the event key string that identifies the event to hook to.hookFunction
: your registered hook function that will be called every time the event fires. The function will receive the event data as the first argument.
Before Events¶
If an error is thrown from a before event hook, the event logic will not execute. This is useful for adding ad-hoc verifications to system logic.
Also, before events can change the data being sent to the event core logic, which is useful for modifying content like topic fields, adding descriptions, etc.
Warning
Very few event hooks need to run before events, so think
again before choosing your hook to be beforeEvent
.
After Events¶
After-hook code executes immediately after the event has fired and it's core logic has finished, but before control is returned to the user (in case of online events).
After-hook events are useful when additional modifications need to be performed once data has been created.
Some examples:
var reg = require('cla/reg'); reg.afterEvent("event.clarive.started", function() { console.log("CLARIVE has started successfully"); }); reg.beforeEvent("event.auth.ok", function(stash) { console.log("New user login: " + stash.username); if( stash.username === "bob" ) { throw new Error('Bob is not authorized to login'); } }); reg.afterEvent("event.topic.create", function(stash) { console.log("Topic created with title = " + stash.title); });
For a complete list of events, check the event ids available
in the rule designer web interface under Admin:Rule Designer
.
Note
Do not execute long running code in the beforeEvent()
or afterEvent()
methods. It will negativelly affect the user
experience directly as online event hooks are sequential and hold up
the UI while executing.
reg.controller(url, { authenticate: boolean, handler: function })¶
Registers a controller endpoint.
Controllers are web endpoints that can be called directly into the Clarive server.
-
url
- entry endpoint. This url will be accessible throughhttps://clariveserver:port/plugin/[pluginid]/[url]
. -
handler
- thehandler
function is mandatory. This is the code that will be called at the endpoint with every request. The handler will receive a request (as first argument) and generate a response (the second argument). The 3rd argument is theuser
object that has information of the logged in user session. -
authenticate
- a boolean indicating if the endpoint requires the user to be authenticate, or is available to any user.
For more information, please refer to the controller reference document.
var reg = require('cla/reg'); reg.controller('foobar',{ authenticate: false, handler: function(req,res){ res.body( "hello world" ); } });
Running Services - Examples¶
Using reg.launch()
any rule palette operation may be called from a plugin,
making it easy to leverage the power of complex functionality already available
in the core of Clarive or as external plugins in your own plugin.
In order to execute services within plugins, you need to know which variables
have to be passed to them in order for them to function correctly. Please check
the rule designer interface for hints on what service needs which variables by
selecting the Metadata
tab for each operation.
Among the items that may be called are: launching remote scripts, shipping files via SSH, creation of Topics, etc.
Below are a number of examples of palette items that may be called, along with the variables needed for these. Not all variables are needed in every case, but we have listed here all those that may be used.
Executing remote commands (service.scripting.remote):¶
This is the service responsible for executing commands remotely.
reg.launch('service.scripting.remote', { name: 'Remote launch', // Name of the task to be executed config: { errors: 'fail', // Type of errors to be monitored server: '1234', // Server ID on which it will be executed user: 'clarive', // User for connecting to the server path: 'ls -l', // Command we wish to launch output_error: '', // Regular expressions for monitoring errors output_warn: '', // Regular expressions for monitoring errors output_capture: '', // Regular expressions for monitoring errors output_ok: '', // Regular expressions for monitoring errors meta: {foor: bar}, // Metadata of the service where it is executed rc_ok: '200', // rc Ok code for monitoring errors rc_error: '404', // rc Error code for monitoring errors rc_warn: '302' // rc Warn code for monitoring errors } });
Shipping files remotely (service.fileman.ship)¶
Service responsible for shipping files remotely to another server.
reg.launch('service.fileman.ship', { name: 'Remote ship', // Name of the task to be executed config: { server: '1234', // Server ID to which the file is to be shipped user: 'clarive', // User for connecting to the server recursive: "0", // Perform the operation recursively or not local_mode: "local_files", // Mode for shipping local files local_path: "/Home/", // Path to the file to be shipped remote_path: "/tmp/", // Directory of the remote server to which we would like to ship the file exist_mode_local: "skip", // Action mode when file not found rel_path: "file_only", // Shipping mode only for files or retaining the job path exist_mode: "reship", // Action mode when files have already been shipped by the job backup_mode: "none", // File backup mode rollback_mode: "none", // Rollback mode track_mode: "none", // File tracking mode audit_tracked: "none", // File audit mode chown: "", // chown permissions chmod: "", // chmod permissions max_transfer_chunk_size: "", // Maximum transfer size copy_attrs: "0" // Copy file attributes } });
Change in Topic Status (service.topic.change_status)¶
Service used for changing the Topic Status in Clarive.
reg.launch('service.topic.change_status', { name: 'Change topic status', // Name of the task to be executed config: { topics: '123', // ID of the Topic we would like to change old_status: '3', // ID of the status from which the Topic is to be changed new_status: '4', // ID of the new Status we would like to assign to the Topic username: 'clarive'// User to which the change in Status is to be assigned } });
Creation of Topics ('service.topic.create')¶
Service used for creating Topics in Clarive.
reg.launch('service.topic.create', { name: 'Create topic', // Name of the task to be executed config: { title: 'Topic title', // Title of the Topic that will be created category: '34', // ID of the category to which the Topic belongs status: '3', // ID of the Initial Status with which it is created username: 'clarive', // User to which creation of the Topic is assigned variables: {desc: 'hello'} // The different variables or fields inherent to the Topic to be created } });
Topic Update ('service.topic.update')¶
Service used for updating Topic content in Clarive.
reg.launch('service.topic.update', { name: 'Update topic', // Name of the task to be executed config: { mid: '123', // ID of the Topic we would like to change username: 'clarive', // User to which Topic creation is assigned variables: {desc: 'hello'} // The different variables or fields inherent to the Topic to be updated } });
Deleting Topics ('service.topic.delete')¶
Service used for deleting Topics in Clarive.
reg.launch('service.topic.delete', { name: 'Delete topic', // Name of the task to be executed config: { topics: '123', // ID of the Topic we wish to change username: 'clarive' // User to which Topic creation is assigned } });