JavaScript (Feed)

The JavaScript feed type is only available from the JavaScript Connection, and its purpose is to provide users with an open-ended means of fetching and processing data.

Property Name
Description
Script At a minimum, the user must implement two functions, getAttributes(nodeVars, secVars) and getRecords(nodeVars, secVars). Unlike the Custom (JavaScript) Feed and JavaScript Transform, the source data is not already provided. The user must implement some way of retrieving or generating the data. See the Script Implementation section below for details.
Poll Interval (seconds)
This poll rate determines how often the server will check the data for updates.
Enable Server Subscription If set, the server will subscribe to the feed, just as a client feed would. This means that the data and any resources that would otherwise be allocated “on-demand” for the first user to view a Visualization that leverages the data produced by this feed are allocated when the server is started and maintained as long as this feed is configured.

Script References

This 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 Feed. For more information, see Configuring Secured Variables.
Java Libraries If the Feed’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 Feed’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 Implementation

Users are required to implement two functions: getAttributes(nodeVars, secVars) and getRecords(nodeVars, secVars). Since the JavaScript Feed does not already provide any source data, it is up to the user to determine how the data will be retrieved or generated.

Arguments #

  • nodeVars: An object whose properties correspond to any variables defined for this feed. To access a variable, use nodeVars.varName.
  • secVars: An object whose properties correspond to any secured variables defined for the current user. To access a variable, use secVars.varName.

getAttributes(nodeVars, secVars) #

This function must return one of the following:

  • jsAttributesSuccess(attributes, “Optional success message for debugging”)
  • jsAttributesFailure(“Optional failure message”)

In the success case, attributes is an array of objects, where each object represents an attribute definition. Attribute definition objects have the following properties:

  • name: required, should consist of alphanumerics and underscores only with no leading, trailing, or adjacent underscores.
  • type: valid types are ‘string’, ‘int’, ‘long’, ‘number’, ‘boolean’, and ‘date’. If not set, ‘string’ is used as the default type.
  • isId: true or false. If not set, false is the default value.
  • units: valid units are ‘millis’ or ‘seconds’. This property must be set if the type is ‘date’ and the data values consist of Unix timestamps in milliseconds or seconds, respectively.
  • format: valid formats consist of pattern strings such as those documented in the SimpleDateFormat Javadoc. This property should be set if the type is ‘date’ and the data values consist of parseable date strings. If not set, the server will attempt to identify the format, but the output may not be as predictable as if the user were to define the format ahead of time.

getRecords(nodeVars, secVars) #

This function must return one of the following:

  • jsRecordsSuccess(records, “Optional success message for debugging”)
  • jsRecordsFailure(“Optional failure message”)

In the success case, records is an array of objects, where each object represents a record. Record property names should match attribute names defined in getAttributes(nodeVars, secVars) (e.g. if a string attribute “foo” is one of the defined attributes, one can assign record.foo = “bar”).

Nashorn allows the use of both java.util.Date objects as well as ES5 JavaScript Date objects. While similar, each type has its own API. When the edgeSuite server stores date values from the JavaScript Feed, it will do so using java.util.Date, with the conversion from JavaScript Date occurring behind the scenes. In other words, you can assign record.dateValue = new java.util.Date() or record.dateValue = new Date() and it should work just the same.

Data Retrieval and/or Generation #

Fetching and generating data will require some knowledge of network and/or file system I/O. Users can leverage any Java classes designed for such purposes, which would allow for direct interaction with objects and their respective methods and attributes. Alternatively, JavaScript Feeds can be used to launch external processes, the output of which can be read as a string (similar to how the Shell Exec connector operates).

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.

Log information #

Basic logger capability is provided to all runtime scripts via:

yellowstone/server/src/main/java/edge/server/script/ScriptEngineService.java

To get information into a log file, use the following syntax:

if ( logger.isFatalEnabled() ) {
    logger.fatal("Failed to calculate status level ...");
}
if ( logger.isErrorEnabled() ) {
    logger.error("Failed to calculate status level ...");
}
if ( logger.isWarnEnabled() ) {
    logger.warn("Warning: calculation of status level ...");
}
if ( logger.isInfoEnabled() ) {
    logger.info("calculation of status level: {}, completed in: {} seconds", level, instant);
}
if ( logger.isDebugEnabled() ) {
    logger.debug("calculation of status level: {}, completed in: {} seconds", level, instant);
}
if ( logger.isTraceEnabled() ) {
    logger.trace("calculation of status level: {}, completed in: {} seconds", level, instant);
}

More information on the Log4j API can be found at the link below:

https://logging.apache.org/log4j/2.0/log4j-api/apidocs/org/apache/logging/log4j/Logger.html

 

Examples #

Using Java NIO to List All CSV Files in {prod.home}/data

Using an External Process to Create Data