Server Action

Overview #

Conceptually, a Server Action is a feed that works in reverse. Instead of pulling data in from a source (left to right), a Server Action updates values on the source (right to left). Server Actions are typically used to update values for a specific record, such as changing ticket status from “open” to “acknowledged”. They require special configuration off of a connection before they become available on a page.

Pipeline Modes #

Server Actions have a special pipeline mode. In the pipeline, there is a button group located at the far right of the footer. By default, it is set to “Data”. This mode shows the normal data flow, from source to visualization, and hides Server Actions.

In order to see Server Actions, the pipeline must be set to “Actions”. This hides the normal flow of data, and shows only the Server Action Feeds that write back to the server.

Configuring a Server Action #

Server Actions are different from normal actions in that they require specialized configuration off of a connection. Currently, only database, JavaScript, shell, and web data connection types support the concept of Server Actions.

Action Name #

Give this Action a name that will be used on a context menu if more than one Action is configured for the event.

Wait for server response #

Determines whether this Action will block a user from interacting with the user interface while waiting for the Action to be completed by the server.

Yes The user is blocked from interacting with the user interface until the action is complete.
No The user can continue interacting with the user interface. They will be notified via a client message when the server action is complete.

User Notification #

Always This will notify an end user whenever a server action completes successfully or when there is an error.
Never This will suppress all messages for server actions.
On Error This will only notify an end user when there is an error.

The Message Center should also contain information about the results of the server action.

SQL Action: #

Query Timeout #

Number of seconds to wait for the query to return results from the database. If time is exceeded, the feed and downstream pipeline steps will display an error.

Ignore SQL Comment

Yes Text inside of the comment block /* … */ or inline comment — in the query statement will be ignored
No The server will attempt to parse comments for edgeSuite tokens nodeVar, safeNodeVar, and src which can result in server error. This option should be on in most of the cases unless you need to have /*, */ or — as part of a literal string.

Statement #

A SQL statement that will fire when a Server Action is initialized on the client.

JavaScript Action: #

Script References

This step is an opportunity to explicitly declare any references the script makes to resources on the filesystem or otherwise, which would be required to be included in any partial backups made where this JavaScript feed is involved.

Properties
Description
Secured Variables Secured Variables resolve to values based on the User that is logged into the system. If you have configured Secured Variables in the system, you can include them here to filter the data that will be returned based on what User is accessing this Action. For more information, see Configuring Secured Variables.To access a variable in the script, use secVars.varName.
Java Libraries If the Action’s script contains any references to Java library code which depends on any libraries installed in the [INSTALL_HOME]/lib directory, then they should be selected here.
JavaScript Libraries If the Action’s script contains any references to user-supplied JavaScript libraries/modules/files, they should be selected here. The supported locations within [INSTALL_HOME] are /data/scripts/static-web, and /login. Any files with the .js extension within these directory trees will be made available for selection here.

Script #

JavaScript code that will fire when a Server Action is initialized on the client. The user must implement one function: main(actionId, actionName, nodeVars, secVars). The function should return either makeActionSuccessResult(“optional message”) or makeActionFailureResult(“optional message”).


Node Variable Mappings #

When Node Variables are used in Server Actions, the administrator will be presented with some additional configuration to define how the Node Variables should be evaluated.

Default Use the default value for the Node Variable.
Page Variable  Set the Node Variable based on the current value of a Page Variable on the page.
Prompt User

Present a dialog for the user to manually enter a value at the time of the action.

Optionally initialize the value with any of the other four options listed in this table.

Record Value Use the value of an attribute on the record associated with the action.
Static Assign a hard-coded value for the action that is always used whenever the action is fired.

Node Variables in JavaScript Actions can be accessed via nodeVars.varName.

Test Server Action (JavaScript) #

This feature is available in the JavaScript Action configuration UI. Clicking the Test Server Action button will cause the action to execute, the results of which will appear in the space below.

Status SUCCEEDED, FAILED, or ERROR
Action Result Details Any message passed to makeActionSuccessResult(detailString) or makeActionFailureResult(detailString)
Console Output Any text written to stdout using the print(string) function
Log Statements Any text written to the edgeSuite log files using logger.debug()logger.info()logger.warn(), or logger.error().
Message Appears in the event of an error when executing the JavaScript
Reference Error details and, if available, a stacktrace to help identify where the error occurred

Additional Services

Some situations require fetching the results of other data producers within the pipeline. This can be achieved via the dataProducerService object.

dataProducerService API for edgeSuite 3.7.x and newer #

fetchRecords(producerName, nodeVars, secVars) #

This function takes the name of the producer, as well as the nodeVars and secVars objects. Generally speaking, the nodeVars and secVars objects can be passed from the parent function (see above documentation for details). However, nodeVars can also be defined as an object with key:value pairs, which are then internally converted as required by the server.

The returned value is an array of objects (records) whose properties correspond to the attribute names of the resulting data set. The value of a record for a given attribute can then be accessed via record.attrName, e.g. record.foo = “bar”.

dataProducerService API for edgeSuite 3.6.x and older #

fetch(producerName, nodeVars, secVars) #

This function behaves similarly to the one above, the main difference being that the returned value is a Java object of type DataResultsDO. Use of this function is no longer recommended, however versions as old as 3.4.x can leverage a simple workaround to achieve functionality similar to that of 3.7.x. Assuming the returned DataResultsDO object is defined, and its data is both defined and of type List<TabularRecordDO>, users may convert the data to an array of JavaScript objects by calling convertSourceRecordsForJs([returnedObject.getData()])[0]. This conversion call will generate an array of objects similar to the result of fetchRecords(producerName, nodeVars, secVars) in 3.7.x.

In addition to getData(), the returned DataResultsDO object has a method getResultStatusCode(), which returns an enum, the value of which is one of CURRENT, ERROR_STALE, ERROR_MISSING, REQUIRE_CREDENTIALS, or BAD_CREDENTIALS.

Example Statements #

The example below shows a sample statement that updates the status of a ticket.

Example Statement
UPDATE incident
SET status = '{nodeVar.Status}'
WHERE ticketid = '{nodeVar.TicketId}'

This is the first of two steps required to configure a server action. This initial step will make a new action available off of any Visualization that uses this dataset. In the example above, an administrator will need to pass in two values to satisfy the variables used in the statement. These values will be passed in based on the record that is clicked in the associated Visualization. The variables can be wired to any attribute available in the underlying dataset, which means even values that are not displayed in the Visualization can be used.

Another action written in JavaScript is as follows:

Logging Server Actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var Files = Java.type("java.nio.file.Files");
var Paths = Java.type("java.nio.file.Paths");
var StandardOpenOption = Java.type("java.nio.file.StandardOpenOption");
function main(actionId, actionName, nodeVars, secVars) {
    var logPath = Paths.get(secVars.installHome, "logs""serverActions.log");
    var logEntry = [(new Date()).getTime(), actionId, actionName, secVars.userAndDomain].join(" - ") + "\n";
    var option = (Files.exists(logPath)) ? StandardOpenOption.APPEND : StandardOpenOption.CREATE;
    try {
        Files.write(logPath, logEntry.getBytes(), option);
    catch (err) {
        return makeActionFailureResult(err.toString());
    }
    return makeActionSuccessResult();
}

The above example, although simplistic in nature, illustrates how to conduct file I/O operations from within the user-defined JavaScript. For this example, two secured variables, installHome and userAndDomain, were created and added to the server action. Had any node variables been included, they would have been similarly accessed via nodeVars.varName.

Additionally you can write actions off of a Javascript Connection that can invoke one or more other actions.

Advanced Server Actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var ResponseStatus = Java.type("edge.server.pipeline.connect.ServerActionResponseDO.ResponseStatus");
var LogManager = Java.type("org.apache.logging.log4j.LogManager");
var logger = LogManager.getLogger("edge");
function main(actionId, actionName, nodeVars, secVars) {   
    var actionDO = serverActionService.getActionByName("NamedActionOne");
    // Re-construct the ParameterValueListDO Java object from the nodeVars JSON.
    var params = makeParameterValueList(nodeVars);
    // Optionally build your own params via:
    /*var params = makeParameterValueList({
        "AlertGroup": "abc"
    });*/
    var actionResponseDO = serverActionService.invokeServerActionByAction(actionDO, params, null);
    // edgeSuite 3.6.1+ supports hasSucceededWithRowsAffected(); which will test success plus how many rows were updated (rowsAffected)
    //if ( actionResponseDO.hasSucceededWithRowsAffected() ) {
    if ( ResponseStatus.SUCCEEDED == actionResponseDO.getStatus() ) {
        logMessage("**** Action: WriteActionOne call SUCCEEDED: rowsAffected: " + actionResponseDO.getRowsAffected(), nodeVars);
        actionDO = serverActionService.getActionByName("NamedActionTwo");
        actionResponseDO = serverActionService.invokeServerActionByAction(actionDO, params, null);
        if ( actionResponseDO.getStatus() == ResponseStatus.SUCCEEDED ) {  
            logMessage("**** Action: NamedActionTwo call SUCCEEDED", nodeVars);
        else {
            logMessage("**** Action: NamedActionTwo call FAILED", nodeVars); 
            return makeActionFailureResult("NamedActionTwo failed.");
        }
    else {
        logMessage("**** Action: NamedActionOne call FAILED", nodeVars);
        return makeActionFailureResult("NamedActionOne failed.");
    }
    return actionResponseDO;
}
function logMessage(message, inUseParams) {
  logger.info(message + ": " + inUseParams);
}

Configuring Refresh #

Refresh determines whether any Feeds should be updated after the Server Action is performed. When a Feed is added to this list, any dataset downstream of that Feed will automatically refresh.

As of edgeSuite v3.7.2, there is an option to delay the refreshing of Feeds listed as part of the Server Action configuration. In case some time needs to be given for some datasources to update as a result of, or in relation to, the invoked Server Action, a delay in seconds can be specified. The default is to refresh all related pipeline jobs for the listed feeds immediately.

As of edgeSuite v3.8.4, there is an option to filter the refreshing of Feeds such that the pipeline jobs affected are only those whose Secured Variable values match the ones of the edgeSuite user who invoked the Server Action. Enabling this can reduce server resource use when there are potentially many pipeline jobs where refreshing them would be redundant, due to them being unrelated to the data affected by the Server Action.

When finished, the “incident_setstatus” Server Action appears as a visible node off of a connection.

Refresh Indication #

Switching the Pipeline to Data mode will hide the Server Action nodes. However, any Feed that has been targeted to be refreshed by a Server Action will have a  decorator.

Creating a Server Action #

Once you have completed the above configuration of a Server Action, you are ready to add the Server Action to any Visualization that is configured off of that same connection. For instructions on creating an Action in a Visualization, see Actions.

When a user invokes a Server Action that is configured to have User Notification, a Message will be generated to make sure the user is aware that an external data update has occurred. A brief message is shown in the banner, and a more detailed message is also logged. The user can view messages by selecting System Menu / Messages.

Invoking Server Actions via Edge CLI

Once a server action has been configured, it can be invoked using the Edge CLI action command. The data returned indicates whether the action succeeded or failed, as well as any pertinent details such as the number of rows affected by a SQL server action, or the result message of a JavaScript action. The format for the command is action -n NAME [-v VARS...] where NAME is the name of the action, and VARS (which is optional) is a list of “key=value” pairs to set any node variables that have been defined for the action. An example of the command is as follows:

./bin/es-cli.sh action -n incident_setstatus

To run the command, user credentials need to accompany the arguments, or the edgeSuite server needs to be configured for pre-authenticated CLI access. For more information about action and other commands, see Edge CLI.