-
Home
- Developers 3rd-Party KM Extensions 2
Advanced Extensions
You can add pages to the Monitoring Studio X Web interface with advanced user interactions. This implies using PSL scripts and developing in JavaScript and AngularJS.
Internal Architecture
Before extending Monitoring Studio X, you need to understand its internal architecture and how the Web interface works.
Monitoring Studio X starts an HTTP server through its Java Collection Hub. This HTTP server is configured to serve 2 types of resources:
- Static files (typically HTML, CSS and JS, but also debug files for example)
- REST API endpoints, in the form of PSL functions executed on the PATROL Agent to respond to HTTP requests
To summarize, the Monitoring Studio X Web application is made of static HTML, CSS and JS files where the JS code makes HTTP requests to the REST API, which is made of PSL functions executed on the PATROL Agent.
Interactive UI with AngularJS
The front-end of Monitoring Studio X is developed with AngularJS 1.x (not to be confused with the most recent Angular). To extend the Web interface of Monitoring Studio X, you must first understand how AngularJS works. It is strongly recommended to have a good expertise in AngularJS before working on Monitoring Studio X extensions.
When extending Monitoring Studio X, the main steps are:
- Declare and implement additional REST API endpoints in PSL that will be invoked by the Web interface to interact with your KM
- Declare an AngularJS module
- Create an AngularJS service that implements methods that query your REST API endpoints
- Create components that implement parts of your UI
- Declare routes in $routeProvider that map URLs to your main components
Declaring REST API Endpoints in PSL
In Monitoring Studio X, the REST API backend is implemented in PSL. For example, a specific PSL function is invoked when the user browser requests the /rest/agent
URL. The functions called on specific URL requests are called endpoints.
You may declare endpoints from your KM's PSL libraries. Endpoints are PSL functions that are called when specific HTTP requests are made to the HTTP server of Monitoring Studio X.
To declare your own endpoints, you need to set the /<class>/X_httpMapPsl
namespace variable. The X_httpMapPsl variable must be set to a PSL list formatted as below:
set("/<class>/X_httpMapPsl", [
"<url>;<PSL library>;<PSL function>",
...
]);
where:
<class>
is one of your KM's class. This is where this information is stored. The KM's main class is typically used.<url>
is the URL for which the specified PSL function will be invoked. All requests on this URL and its sub-resources (“subdirectories”) will trigger the execution of the specified PSL function.<PSL library>
is the name of the compiled PSL library which contains the code of the specified PSL function.<PSL function>
is the name of the PSL function to execute when the specified URL is requested. This function must be exported in the specified compiled PSL library.
Example (from Storage Analyzer KM):
set("/SKM_MAIN/X_httpMapPsl", [
"/rest/skm;SKM_restapi;swRestApi"
]);
Notes:
- The X_httpMapPsl namespace variable can be set with a list of multiple REST API endpoints.
- You do not need to set this namespace variable for every class of your KM. You must set
/<class>/X_httpMapPsl
on only one class that will be loaded and activated. - The PSL script that sets this namespace variable must be the pre-discovery script of a class of your KM, to ensure it is executed before the discovery of Monitoring Studio X.
REST API Functions
The specified REST API endpoint functions are called with the below arguments:
method
: GET, PUT, POST or DELETEpath
: the requested URL pathquery
: the part behind the ‘?’ in the URLheaderList
: the list of headers in the HTTP requestrequestBody
: the body of the HTTP requestusername
: the username if the user is authenticatedremoteAddress
: the address of the browser or client performing the HTTP requestreadOnly
: whether the request is made by a user that has read-only access (and therefore no full access)
The specified PSL function must return a PSL list that contains the elements of the HTTP response:
- First line: the HTTP response code (200, 400, 500, etc.)
- HTTP response headers: one header per line (e.g.:
["Content-type: application/json"]
) - Empty line as a separator between the headers and the response body
- HTTP response body
Example of a REST API endpoint PSL function:
export function restEndpointExample;
function restEndpointExample(method, path, query, headerList, requestBody, username, remoteAddress, readOnly) {
# Only supported method is GET
if (method == "GET") {
return [
200,
"Content-type: application/json; charset=utf-8",
"\n",
"{ \"result\": \"An example\", \"success\": true, \"time\": ".time()." }"
];
}
# For any other method, return 400 Bad Request
return [
400,
"Content-type: application/json; charset=utf-8",
"\n",
"{ \"result\": \"Bad request\", \"success\": false, \"time\": ".time()." }"
];
}
The above PSL code must be compiled into a PSL library. If the PSL source file is restLibraryExample.psl, it will be compiled into a library with the below command:
psl -l restLibraryExample.psl
The resulting restLibraryExample.lib PSL library needs to be copied to the PATROL Agent's $PATROL_HOME/lib/psl directory. If the PSL library already existed and was already loaded, the PATROL Agent needs to be restarted.
Then, this REST API endpoint PSL function should be declared with the X_httpMapPsl namespace variable in the prediscovery PSL script of your KM, as below:
# Map /rest/example to restEndpointExample
set("/EXAMPLE_CLASS/X_httpMapPsl", [
"/rest/example;restLibraryExample;restEndpointExample"
]);
After a restart of the PATROL Agent, the prediscovery of your KM sets X_httpMapPsl and the discovery of Monitoring Studio X takes this into account when starting its HTTP server. Sending an HTTP request to get /rest/example
will then trigger the execution of our restEndpointExample() PSL function. Such request would typically be made from the user browser, in the frontend Web application.
Example with curl:
$ curl -k https://localhost:3443/rest/example
{ "result": "An example", "success": true, "time": 1583351013 }
$ curl -k https://localhost:3443/rest/example/sub-example/1
{ "result": "An example", "success": true, "time": 1583351045 }
$ curl -k -X POST https://localhost:3443/rest/example
{ "result": "Bad request", "success": false, "time": 1583351070 }
When writing your REST API endpoint functions, you may leverage utility functions declared in the X_restapi_utils PSL library, which ships with Monitoring Studio X. Simply adds the below line at the very beginning of your PSL source files:
requires X_restapi_utils;
Here are some useful functions in X_restapi_utils:
Function | Description |
---|---|
list2JsonArray(list) |
Converts the specified PSL list into a JSON array. Example: list2JsonArray(["first", "second"]) will return ["first", "second"] |
string2Json(string) |
Returns a JSON-encoded string representation of the specified string, including the surrounding quotes. Example: "my \"quoted string\" with\nmultiple lines" |
string2FullJson(string) |
Full (but slower) version of string2Json() , properly encoding all non-printable characters. Example: "Special \u000d \u001f" Use this function only when there is a risk that the string to encode contains non-printable chars other than newline ( \n ) and tab (\t ) |
uriDecode(uri) |
Decodes the specified URI. Example: uriDecode("Studio+rulez%21") will return Studio rulez! |
returnSimpleJsonResponse(httpResponseCode, json) |
Returns a properly formatted HTTP response (as described above) with the specified JSON document. Example: return returnSimpleJsonResponse(200, "{\"result\": \"success\"}"); |
returnSimpleInformation(message) |
Returns an HTTP/200 response with the specified message. Example: return returnSimpleInformation("It worked!"); |
returnSimpleError(message) |
Returns an HTTP/500 response (“Internal Error”) with the specified message. Example: return returnSimpleError("It failed miserably..."); |
returnBadRequest(message) |
Returns an HTTP/400 response (“Bad request”) with the specified (optional) message. Example: return returnBadRequest(); |
Exposing Additional Web Resources (HTML, CSS, JS)
When extending the Web interface for your KM, you will need to expose your front-end code (JS, HTML, CSS and images) to the user browser.
From the PSL code of a KM, you can configure the HTTP server of Monitoring Studio X to serve the content of a directory, a ZIP or a JAR file, under a specified “virtual” folder.
This is achieved by setting the /<class>/X_httpMapResources
namespace variable during the pre-discovery. The value of X_httpMapResources
is a PSL list with each line containing an entry to map:
<virtual folder>;<path to resource>
Example of PSL script:
set("/SW_MAIN/X_httpMapResources", [
"/swsy;./lib/SW_web.jar"
"/swsy/help;./lib/SW_help"
]);
Notes:
- Path to the resource can be a directory, a ZIP or a JAR file
- Path to the resource is relative to $PATROL_HOME (except if the specified path is absolute)
- In the above example, an HTTP request to
https://localhost:3443/swsy/index.html
returns the content of index.html in $PATROL_HOME/lib/SW_web.jar. - In the above example, an HTTP request to
https://localhost:3443/swsy/help/css/bootstrap4.min.css
returns the content of $PATROL_HOME/lib/swsy/help/css/bootstrap4.min.css - You do not need to set this namespace variable for every class of your KM. You must set
/<class>/X_httpMapResources
for only one class that will be loaded and activated. - The PSL script that sets this namespace variable must be the pre-discovery script of a class of the KM, to ensure it is executed before the discovery of Monitoring Studio X.
Authentication
By default, resources that are exposed through X_httpMapResources
do not require the user to be authenticated to retrieve them. Since the authentication is handled by the Web interface, it is necessary for its HTML, CSS, JS and other resources to be accessible before being authenticated.
If you need to expose other file resources, non-static Web resources like subdirectories of the PATROL Agent, or other parts of the local filesystem, it is strongly recommended to enforce authentication before allowing anyone to read these files.
Instead of declaring resources to be mapped with X_httpMapResources
, you will use /<class>/X_httpMapResourcesSecure
. This namespace variable behaves the very same way as X_httpMapResources
, but accessing these resources will require the proper authentication token (which can be obtained through the Web interface or OAuth 2.0).
Notes:
- All resources (with or without authentication) are read-only.
- Authorization (which user can authenticate) is managed in the Monitoring Studio X settings.
Loading JS and CSS
For the Web interface to leverage additional JS and CSS code of your own, it is necessary to ensure the JS and CSS files are loaded by the browser.
To do so, you will declare such resources in the /<class>/X_browserLoad
namespace variable. The X_browserLoad
variable contains a PSL list of resource paths that will be loaded dynamically by the browser when the user connects to the Web interface, as in the example below:
set("/SW_MAIN/X_browserLoad", [
"/swsy/js/swsy-service.js",
"/swsy/components/swsy-config/swsy-config.js",
"/swsy/components/swsy-config/swsy-config.css"
]);
Notes:
- Paths are virtual paths, i.e. accessible by the browser through Monitoring Studio X's Web server.
- While not recommended, absolute URLs are supported and can reference CDNs for common resources (like Bootstrap, jQuery, Angular, etc.).