Plugin Datasets
The plugin
configuration entry allows you to define a dataset which is fetched by executing a Perl module on the server side. The Perl module will have access to the Jarvis database connection, and will have the user authentication tasks already performed. This makes is simple to add new server-side functionality which cannot be easily represented in a SQL statement.
Jarvis plugin datasets should be accessed by the GET
or POST
methods. None or more plugin
elements may be configured.
Configuration
The configuration attributes for a plugin
element are as follows.
Attribute | Default | Notes |
---|---|---|
dataset |
(none) | Dataset name which is to be interpreted as a plugin rather than a regular dataset. Mandatory parameter. |
access |
(none) | This lists the group names that the logged-in user must belong to one of before they can access this plugin . Specify a group name, comma-separated list, * or ** . See the documentation for read and write groups on regular datasets. |
lib |
(none) | This is an additional directory to be optionally added to the @INC path when loading this module.If the necessary path for the module is defined using the global <default_lib> element in the configuration, then this attribute is not necessary. |
module |
(none) | This is the Perl module name with subdirectories separated by :: and ending in .pm . |
add_headers |
no |
If yes, Jarvis will add Cookie , Content-Type and Content-Disposition headers to the response. Otherwise the plugin module is entirely responsible for printing ALL headers.If add_headers is no , be sure to add the header Cache-Control and set the value to no-cache yourself in the outgoing response if you want to avoid responses being cached by IE. |
mime_type |
(none) | Only used if add_headers is yes . Allow plugin to override the default MIME type. This takes precedence over any mime type which may be derived from a filename. |
filename_parameter |
(none) | Only used if add_headers is yes . We expect a CGI parameter of this name to be present and to contain the returned filename. |
default_filename |
(none) | Only used if add_headers is yes . Default filename to use if no filename_parameter is defined or if the CGI parameter named by filename_parameter is not present. |
parameter |
(none) | One or more sub-elements defining static parameters to be passed to the plugin. Each parameter element has a name and value attribute.This allows site-specific plugin configuration to be stored in a common, accessible location. This also allows one Perl module to be used by different plugin instances within the same application, each with their own dataset name and each with slightly different behavior. |
debug |
(none) | Enable debug output to standard error for this plugin only. This parameter can not be used to disable global debugging. |
dump |
(none) | Enable dump output to standard error for this plugin only. This parameter can not be used to disable global dump output. |
Plugin ::do Method
The Plugin is implemented by a ::do
method in a Perl Module. The ::do
method will receive the following arguments:
$jconfig
- The internal Jarvis context.$user_args
- A HASH of the CGI arguments, plus numbered and named RESTful arguments.$plugin_parameters
- A HASH of the static plugin parameters from the Jarvis XML file.
The $jconfig
context is internal to Jarvis. The following fields are available for read-only access:
Attribute | Notes |
---|---|
$jconfig->{app_name} |
Name of Jarvis application. |
$jconfig->{cgi} |
The CGI object for this CGI request. |
$jconfig->{username} |
Current Logged-In Username or '' . |
$jconfig->{group_list} |
Current Logged-In Group List or '' . |
$jconfig->{logged_in} |
0 /1 are we logged in? |
$jconfig->{error_string} |
Login error message if not logged-in. |
$jconfig->{debug} |
0 /1 is debug tracing enabled? |
$jconfig->{dump} |
0 /1 is dump tracing enabled? |
$jconfig->{format} |
json /json.rest /xml /csv /xlsx /etc… |
$jconfig->{action} |
select /insert /update /delete . |
$jconfig->{dataset_name} |
Name of top-level Dataset implemented by this request. |
$jconfig->{dataset_type} |
Type of top-level Dataset implemented by this request (i /s /e /p ). |
The $jconfig
object is also required as a parameter for invoking Jarvis services such as the Jarvis::Error::debug
and Jarvis::Error::dump
methods.
Note: The $user_args
parameter has NOT been checked for safety.It is user-supplied values and must be treated with suspicion.
Note: The dataset_type
is either i
= Internal, s
= SQL, e
= Exec, p
= Plugin.
Output & Headers
Jarvis offers support for add_headers
, filename_parameter
and default_parameter
handling for plugin
datasets identical to exec
datasets.
Exception Handling
To handle an exception in your plugin, simply call die
. You may optionally set an explicit HTTP status to return. Otherwise Jarvis will return a 500 Internal Server Error
.
$jconfig->{status} = '404 Not Found';
die "Plugin cannot continue, moon not found in expected phase.\n";
Note: The use of the newline escape \n
at the end of the error. The newline at the end of the error will suppress the default Perl behavior of including the location of the error (file and row number). Normally it would not be appropriate to include the file and line number of the error when explicitly calling die, and in this manner it can be removed.
Getting Dataset Content with fetch_rows
A plugin may often wish to perform complex calculations and combine multiple datasets in non-standard ways. To support this, Jarvis provides an official
mechanism for plugins to execute a dataset and get the results for their own purposes.
use Jarvis::Dataset;
my $rows = &Jarvis::Dataset::fetch_rows ($jconfig, $dataset_name, $user_args, $extra_href);
...
The $jconfig
object is the one given to the plugin.
The $dataset_name
is the name of the dataset you wish to execute.
The $user_args
are the numbered and named arguments to use when performing the dataset fetch. Named parameters to the dataset must be provided here. The fetch_rows ()
method does not access any parameters from the $jconfig->{cgi}
object. You may pass undef
if you have no user args.
The $extra_href
parameter should be a hash reference. Dataset hooks may add additional entries to this hash and will expect the plugin to return them as top-level parameters. You may pass undef
if you do not plan to take notice of hook-requested extra top level-parameters.
The result is an ARRAY reference containing the returned rows. Noting:
- Sorting and paging may have been applied if the relevant paging parameters were provided.
- Dataset security checks will be performed.
- The Dataset/Global
dataset_pre_fetch
anddataset_fetched
hooks will be applied. - Nested datasets will be executed and merged into the results.
Using Datasets to Store Content with store_rows
Datasets may contain store logic that plugins wish to reuse. To support this, Jarvis provides an “official” mechanism for plugins to use a dataset to store (or delete) data.
use Jarvis::Dataset;
my ($success, $message, $modified, $results) = &Jarvis::Dataset::store_rows ($jconfig, $dataset_name, $ttype, $user_args,$rows_aref, $extra_href);
...
The $jconfig
object is the one given to the plugin.
The $dataset_name
is the name of the dataset you wish to execute.
The $ttype
is the transaction type you wish to perform - either insert
, update
, delete
or mixed
.
The $user_args
are the numbered and named arguments to use when performing the dataset store. Named parameters to the dataset must be provided here. The store_rows ()
method does not access any parameters from the $jconfig->{cgi}
object. You may pass undef
if you have no user args.
The $rows_aref
parameter should be an array reference for the rows that you wish to store or delete.
The $extra_href
parameter should be a hash reference. Dataset hooks may add additional entries to this hash and will expect the plugin to return them as top-level parameters. You may pass undef
if you do not plan to take notice of hook-requested extra top level-parameters.
$success
will be 1
if all rows are processed successfully; in case of failure it will be 0
.
If $success
is 0
, $message
will contain a description of the failure.
$modified
will be a count of the number of top-level rows that were modified.
$results_aref
will be an ARRAY reference containing the returned results, if any.
Note:
- Dataset security checks will be performed.
- The Dataset/Global
dataset_pre_store
,before_all
,before_one
,after_one
,after_all
anddataset_stored
hooks will be applied. - Nested datasets will be executed.
Example Plugin
The Demo application includes a sample FileDownload
plugin, configured as follows:
<jarvis>
<app>
<plugin dataset="FileDownload" access="**" lib="/usr/share/jarvis/demo" module="plugin::FileDownload" add_headers="yes" mime_type="text/plain">
<parameter name="interview" value="Cross-Sectional"/>
</plugin>
...
The source code is as follows:
use strict;
use warnings;
use Jarvis::Error;
use Jarvis::DB;
sub plugin::FileDownload::do {
my ($jconfig, $user_args, %plugin_args) = @_;
# User args includes numbered and named REST args.
my $rest0 = (defined $user_args->{0}) ? $user_args->{0} : '<undef>';
my $rest1 = (defined $user_args->{1}) ? $user_args->{1} : '<undef>';
my $boat_class = (defined $user_args->{boat_class}) ? $user_args->{boat_class} : '<undef>';
# User args also includes the CGI-supplied parameters.
my $app_name = $jconfig->{app_name};
my $cgi_myval = (defined $user_args->{cgi_myval}) ? $user_args->{cgi_myval} : '<undef>';
&Jarvis::Error::debug ($jconfig, "App Name: '%s'.", $app_name);
&Jarvis::Error::dump ($jconfig, "CGI MyVal: '%s'.", $cgi_myval);
my $interview = $plugin_args{interview} || 'Unknown';
my $dbh = &Jarvis::DB::handle ($jconfig);
my $rows = $dbh->selectall_arrayref ("SELECT COUNT(*) as count FROM boat", { Slice => {} });
my $num_boats = $$rows[0]{count};
my $content =
"Param|Value
App Name|$app_name
Interview|$interview
Rest 0|$rest0
Rest 1|$rest1
Boat Class|$boat_class
All Boats|$num_boats";
return $content;
}
1;
This demonstrates:
- Using the Jarvis debug mechanism.
- Accessing the Jarvis Config
$jconfig
object. - Accessing the static configured plugin parameters.
- Accessing the Jarvis-supplied database connection.
Accessing this plugin via the following URL:
http://localhost/jarvis-agent/demo/boat/X%20Class/download/?filename=x
The output is a text file x.txt
with content similar to the following:
Param|Value
App Name|demo
Interview|Cross-Sectional
Rest 0|boat
Rest 1|X Class
Boat Class|X Class
All Boats|45