11.2 Use Case: Gathering Information from the User for Script Invocation on a Server

In many cases, before an operation executed by a server script can perform an action, it is necessary to gather information by interacting with the user. NOC Script fully supports this type of interaction by:

  • Allowing a server-side script to send a script to the client session that invoked it

  • Gathering information from the user

  • Issuing a “call back” to the server script, supplying the user input to the originating server-side script

Consider the example where a trouble ticket is created for an element that has an outage. The user must supply information to “cut” the ticket, such as a summary of the problem, before the server-side script logic can create a trouble ticket.

A simple prompt() invocation suffices for gathering the summary information from the user. However, invoking the script on the client side raises the issue of applying to the information some logic on the server, which might be the only connectivity resource that can interact with the trouble ticket system. Thus, it might be better to originate the script on the server side. (There is another way to solve this problem, as shown in Section 11.3, Use Case: Invoking a Server-Side Script from a Client Script.)

The following example, illustrated in detail, describes how to create a server-side script to resolve the problem:

11.2.1 Configuring the Script

To configure this script, copy the following operations.ini section to the operations.ini file that resides in the /OperationsCenter_install_path/database/shadowed directory:

[Enter Trouble Ticket]
description=Trouble Ticket...
context=element
target=dname:root=Elements
permission=manage
type=serverscript
operation=@examples/ticket

This operation denotes a right-click menu command that can be invoked on any element that resides in the Elements top-level tree in Operations Center. It is a server-side script, which simply delegates invocation to a script named ticket that resides in the /OperationsCenter_install_path/database/scripts/examples directory.

11.2.2 Script File Content

The following is the contents of the ticket script file:

///////////////////////////////////////////////////////////
// Operation definitions to add to an element: (paste into Operations.ini)
//
// [Enter Trouble Ticket]
// description=Trouble Ticket...
// context=element
// target=dname:root=Elements
// permission=manage
// type=serverscript
// operation=// @debug off \nload( "examples/ticket" );
//

formula.log.info( "Here!" )

// Set our log category
formula.setLogCategory( "Ticket" )

// Log startup
formula.log.info( "Starting trouble ticket script" )

// Create our object which will be the "callback" from the client
// Note: this is standard javascript syntax for creating an object with named properties/values
var callback =
{
    setTicketInfo: function( reason )
    {
       // We'll log what the user did, to simulate connecting to the ticketing system.
       formula.log.info( "User created trouble ticket:" )
       formula.log.info( "   Element: " + element )
       formula.log.info( "   Reason: " + reason )

       // Let's notify the user that we did what was asked.
       session.sendMessage( 'Trouble ticket created for ' + element + '. Content:\n\n' + reason )
    },

    cancel: function()
    {
       formula.log.info( "User cancelled trouble ticket creation" )
       session.sendMessage( 'Trouble ticket cancelled for ' + element + '.' )
    }
}

// We're going to send this callback and a prompt script to the client, which will
// then cause execution to this script through remote proxy.

var clientTicketScript = "\
    // @opt -1 \
    // @debug off \
    var result = prompt( 'Enter trouble ticket information for ' + elementName + ':', \
                         'Trouble Ticket' ) \
    if( ! result ) \
        callback.cancel() \
    else \
        callback.setTicketInfo( result )\
"

//
// Now, send the dialog script to the user who invoked this script
//
// Note: this script is sent to variables, called "callback" and "elementName"
//       The callback is wrapped via a remote proxy using the formula.util.makeRemote()
//       function. The element name is simply the element name of the element
//       the user initiated this ticket for.
//
formula.log.info( "Sending dialog script to client" )
session.invokeScript( 'Enter Trouble Ticket',
                      clientTicketScript,
                      [ formula.util.makeRemote( callback ), element.name ],
                      [ 'callback', 'elementName' ] )
formula.log.info( "Done!" )

11.2.3 Notes About the Script

Several notes about this script:

  • The script declares a “callback” object in JavaScript with two properties that are functions which either: 1) accept the data entered by the user or 2) cancel the operation.

  • The actual client script is embedded as a textual string in this script. See this declaration in the section that declares the value of clientTicketScript. If the client-side script is large, remove it from this script and place it in the repository. Refer to the script using only a load() statement or the @ symbol notation.

  • The script to execute against the session is invoked using the invokeScript method, which takes the parameters of the script name, the script itself, and optional parameters to send to the script. These are exposed as variables when the session executes the script.

  • Prepare the value of the callback variable for remote invocation using the formula.util.makeRemote() function, which turns a JavaScript object into an entity that can be remote, suitable for distributed function invocations.

  • The client-side script calls the callback variable remotely, which results in sending data back to the originating server-side script, or calling the cancel method.

  • Both callback functions send a message to the originating session, displaying a message to the user about what happened.