Contents Hide
Out-of-the-box, the BrightXpress Mobility Suite provides integration into relational databases and flat files (either a fixed length format file or as a Comma Separated Values CSV file). This means BrightServer can read and write data to and from databases and files without any additional work. It just needs to be configured to access these types of data sources. In the real world, however, there are more complex data sources that a mobile solution needs to integrate into. These data sources may include web services, XML file exchange, legacy backend systems, email servers etc. For instance one may need to read data from a web service and send data to remote field clients, and in the same fashion, send the data collected in field to a backend system via a web service. There are many more real world scenarios that need to be handled in a generic framework. BrightServer supports this via server side scripting, providing flexible architecture and framework for mobility developers to create data consumer and producers using JavaScript.
BrightServer supports adhoc data queries issued from field. They are called Online Queries. Standard queries and stored procedure/RPC calls can be handled by the server out-of-the-box. However if the adhoc query source needs to be other than a relational database, a script can be written to service these online queries.
Scripting is also available to implement script based scheduled jobs at the server. BrightServer can execute a script based job running at a desired schedule and carry out certain house keeping, data collection and distribution requirements at the server side. For instance field devices may collect data and send it to a known database table. A server side JavaScript based job can then process the collected data and post the data to the required backend systems.
Scripting allows developers to develop solutions with greater flexibility, to and from unconventional sources, and with additional/more complex operations supported. This makes scripting a powerful data source as they do not need to adhere to the conventions set by database and file structures, leading to systems with higher levels of automation, flexibility, communication and control.
Scripts are written in JavaScript and interface seamlessly into the BrightXpress mobility suite through the use of defined interface functions depending on what functionality developers wish the script to incorporate. Helper and imported methods may also be used during this process, utilising Java libraries. The details of writing scripts will be detailed in this topic.
Once written, scripts are defined as a data source via the Sync panel of a BrightXpress project. In BrightXpress Applications, sync reader and sync writer queries may specifically be interfaced, via the Query panel in the application designer. For more information, please refer to the respective sections via the links.
BrightServer allows scripting in the following scenarios :
Implementing user defined sync sources : Using scripting additional sync sources can be provided in the system. In order to implement a new sync source, one needs to implement the sync reader interface in a script. The read interface allows a robust and well defined contract between the script and the system. If you have data sources other than database and files, you can expose them through reader scripts to send the data to field clients. The legacy systems can be read and mobilised to the field through scripts.
Implementing user defined sync destinations: In a similar fashion, scripts can be used to provide sync end points to consume the data received from the field devices by utilising the sync writer interface. The data collected in the field can be sent to other systems. For instance, you may need to send the data to a backend system through a web service call, or you may need to create a specialised file other than the standard flat or CSV formatted files such as XML or HTML files. In other words, if the destination of the collected data is other than a relational database or a flat file, then a script will be perfectly suitable for the task at hand.
Servicing online user queries from field : Scripts can also be an excellent tool to service any adhoc field, or online queries in realtime. For instance, a BrightForms™ client can send a query to BrightServer to get a snapshot of backend data. In this instance, the script can get the query and its payload and submit the request the way that the backend understands and send the result back to the remote device. Upon receiving a query from the field, it can invoke a web service and get the result and send it client in real time.
Serving online RPC queries from field :This is similar to the online query scenario mentioned above. The system will pass the remote procedure name, its input parameter names and values to a RPC script. The script will then source the data by querying relevant data sources and send it back to the device in real time.
Push functionality : Script methods may be utilised to send messages, records directly to devices, or trigger sync rules to run in the background on devices. Devices may process these push events via Forms' On Push expressions, which will run after a successful push is received. For more information, please refer to the Script Push chapter of this document.
Generating server-side reports : Server-side reports may be generated using script methods, which print reports defined in the BEP on server data sources. This will write a PDF report on the server's file system, which may then be used for backend purposes, or synchronised to devices with the externalBlob format. For more information, please refer to the BrightServer > Reports section of this document.
Creating script based jobs in the system : BrightServer allows you to create JavaScript based job scripts that can be run at certain intervals or at the times defined by a Cron schedule. BrightServer will execute your scripts for you to carry out various tasks. These tasks may include house keeping, or processing and sending data to various destinations, generating reports, emails etc. Scripting in this context provides excellent mechanism for batch processing in the system.
Scripts which perform jobs on a schedule or on server events do not need to be present in the Sync Points of a BEP project. They may also be deployed, similar to licenses on a running BrightServer instance independently from BEP projects via the Configuration > Jobs node of the server in the 'Servers' panel.
Performing tasks on BrightServer events : Scripts may also be defined and allocated to perform on BrightServer events, such as server startup, and user log in/log off. This is managed by specifying Script Type for a given script in BrightBuilder.
Perform operations triggered by an external system : BrightServer may receive and respond to Web Service Calls by external sources. This is performed via the web services interface, which may be called using a URL and basic/form authentication. For more information, please refer to the BrightServer > Web Services chapter of this document.
Scripts are managed in a BrightXpress BEP project using the scripts node to create and organise both new and existing ones. When a new script is created, the following New Script Wizard window will appear:
Script templates provides the script author with a skeleton code where the required script functions are defined. The script writer must simply implement the required functionality through the required script functions. Once the script is loaded and executed these functions will be called by the system to interact with the script written. If the expected function is not present, then the server will issue an error to report the missing functionality. The script can written in any style with additional functions and variable as needed as long as all the must-have function are present in the script.
Depending on the type of script to be programmed, BrightBuilder provides developers with a number of templates which highlight the necessary methods and typical parsing incorporated by server scripts. This ensures all necessary methods are accounted for such that the system can execute the necessary functionality through standard interface exposed by the script being authored.
As with all BrightServer elements, opening, adding, removing and renaming of scripts is handled by the scripts node which contain all scripts. Adding (via the wizard) and pasting elements are done via right click access to the node itself, while cutting, copying and renaming of the scripts is done via right clicking on the corresponding script.
The properties of the script may also be accessed through this right click menu. This screen may be used to define the script as a scheduled script, and also the intervals to which this script will run. The script type may also be set, if the script needs to run based on BrightServer events, such as server start or user login.
Simply selecting the script will also display these options in the properties pane, if open.
BrightXpress Mobility Suite scripts are written in JavaScript and as such, standard JavaScript conventions apply for syntax and naming. See following for further information on https://developer.mozilla.org/en/Rhino.
BrightBuilder™ provides the necessary editing tools for creating your scripts in the system.
The first section of every script would be the statements to import the external functionality provided by the external libraries. There are three main sources that you import using importClass or importPackage.
Bright Software provided helper classes
Java class libraries that come as a part of Java runtime environment
Java libraries authored by you or third parties
The next section in a script would be the declaration of the script variables used throughout your script. These variables are global to the script scope. This means any function in the script can access and modify their values.
The rest of the script would contain the function that are predefined by the templates and your helper functions. Make sure that the required functions depending upon where the script is used are always present. BrightServer will generate an error if a required function with the expected function signature is not found in the script.
Using Bright Software Helper Classes
BrightXpress Mobility Suite ships with the following helper objects for you to import and use depending upon where your script is used.
Record : This object represents a collection of values. This is analogous to a database table record. Values in a record can be of different data types including numeric, string, datetime and binary data etc. Record objects would be used when writing sync source or sync destination scripts to process the data received from the field or send back the data read from other data sources.
RecordSet : A collection of records is a RecordSet, which is what this helper object represents. Every RecordSet object has a name and it contains meta data as to what sort of fields or values exist in every record. This is analogous to the database's table definition. In short field info data describes the data. RecordSet objects are used in conjunction of Record object when producing or consuming data.
FieldInfo : Each RecordSet object contains a collection of FieldInfo to describe its data. FieldInfo contains the field's name, its data type etc.
Blob : This is a utility object that can be used to load and save binary data. JavaScript does not have a binary or byte data type as such. So this object would be handy when processing binary data.
Util :This is another utility object that provides functionality to encode or decode Base64 data if required in your script.
When you wish to use any of these objects in your scripts, then you need to include one or combination of the following import statements in your script.
importClass (Packages.au.com.brightsoft.integrator.Record);
importClass (Packages.au.com.brightsoft.integrator.RecordSet);
importClass (Packages.au.com.brightsoft.integrator.FieldInfo);
importClass (Packages.au.com.brightsoft.integrator.Blob);
importClass (Packages.au.com.brightsoft.integrator.Util);
See the Script Methods Reference Manual for the complete documentation on these objects.
Furthermore, external classes through Java may be imported, using importClass and importPackage where necessary, for example:
importClass (java.util.Calendar);
importClass (java.util.Vector);
importClass (java.lang.Integer);
importPackage (java.io);
When these are defined, their Java methods may be accessed. For example:
now = Calendar.getInstance().getTime();
vec = new Vector();
vec.add(new Integer(42));
may be used in your script with the above segment imported.
This is similar to importing Bright Software helper classes and Java classes, using importClass or importPackage statements. Make sure the full package and class path is included in the statement.
Note - Any third party Java library must be stored in the "lib" subdirectory where BrightServer is installed.
Values are generally able to be passed using corresponding JavaScript native objects as is. The exception to this is with Integers, as JavaScript uses doubles by default, and binary data, which is not supported. Refer to the table below for more detail.
Depending on the type, the fields of records must specify an int value of the type to be read, as JavaScript does not support type definitions. These are also listed in the table below, and will be explained further in the Fields section below.
Int Value | Constant | Notes |
0 | FieldInfo.UNKNOWN | |
1 | FieldInfo.STRING | Maps to JavaScript strings. |
2 | FieldInfo.BOOLEAN | Maps to JavaScript booleans. |
3 | FieldInfo.INTEGER | Should be converted using the new Integer(value) method call. This method must be imported by adding importClass (java.lang.Integer) in the script’s header. This is due to all JavaScript numerical values being in the double format. |
4 | FieldInfo.DOUBLE | Maps to JavaScript numerical values. |
5 |
FieldInfo.DATETIME | Maps to the Java Calendar class. Similar to integer, the class must be imported in the script's header. |
6 |
FieldInfo.BASE64BINARY | Maps to the Java byte[] object. Helper methods are provided to compress and decompress this data, or convert to a Base64 string. See the Script Methods Reference Manual for more detail. |
Fields hold values of data, and other values used for database functionality and synchronisation. On the server, they must map to fields in tables if mapping is set to default, or to the mapping that is specified in the BrightServer project.
Fields are defined using a vector of FieldInfo in scripts, and are applied on RecordSet construction, or via the setFieldInfo() method.
Table Name - result set's name must match the table the records are mapped to.
Column - name mapped, string
Type - specifies how the Field should be read to BrightServer. The codes for these types, and the constant values that may be used are as follows.
Int Value | Constant |
0 | FieldInfo.UNKNOWN |
1 | FieldInfo.STRING |
2 | FieldInfo.BOOLEAN |
3 | FieldInfo.INTEGER |
4 | FieldInfo.DOUBLE |
5 |
FieldInfo.DATETIME |
6 |
FieldInfo.BASE64BINARY |
Note, the type of the field must correspond to the value place
in it. Depending on the type, using values as is may cause
errors. For more information, see the above section - Values.
Primary Key - boolean value stating whether the passed value is a primary key or not.
Length - necessary for strings. 0 otherwise.
Allow Nulls - boolean value stating whether NULL can exist as the value for the field.
RecordSets whose fields do not match the mapping or table definitions for the synchronisation path defined may not be consumed by BrightServer, causing a server-side exception when processed.
Record – a vector of fields which can also be referenced to see if the values need creating/modifying or deleting in the database. This is done via the method getStatus().
Int Value | Constant | Description |
0 | Record.UNKNOWN | |
1 | Record.ADDED | Marks that a record needs to be added |
2 | Record.MODIFIED | Marks that a record needs to be modified or updated |
3 | Record.DELETED | Marks that a record needs to be deleted |
When a record is to be deleted, please note that only the primary key values will be passed to the script.
A RecordSet is a vector of records, passed to write and expected to be returned by the Read() method for use in Bright Applications. It's is how table data is passed to and from the script data source, and is thus analogous to the concepts of Tables in BrightBuilder and BrightServer.
Thus when synchronising RecordSets, they pass the string name of the table to synchronise to, as defined by the server's mapping. This is achieved by setting the name on creation with new RecordSet(<name>).
A vector of records also acts as the input parameter for Write(), and has the variable name 'data'. These record sets may be iterated through, using the RecordSet.size() and RecordSet.get() methods. Refer to Scripts > Implementing Scripts > Sync Writer for more detail.
Payload - Data used for online and read queries. This is passed to the script query in a form defined by the Bright Software Application. The format is usually a string, but can be of any type set by the application. For more information, refer to the Sync Reader and Online Query sections below.
RPC calls may return complex data values. It may not return just a single data value. To simplify returning data from script queries, ResultRPC objects are used.
ResultRPC object represents a RPC result. A RPC call may return a number of output parameter values, or a recordset, or both depending upon the requirements for the RPC query sent from the remote field device. This object is simply a container object for holding the returned values. It allows setting the returned output parameter name and value pairs. It also allows returning a RecordSet object for returning records in the RPC result object. A ResultRPC object also holds a query result integer value. An error code can be returned by setting the result code as well.
Parameters are passed to scripted Remote Procedure Calls (also known as stored procedures) via two variables:
paramNames - Vector of strings holding the names of parameters passed for a remote procedure call.
paramValues - Vector of Objects, types equal to those passed by the Bright Software Application
Below is a diagram to show how data is mapped from query panel to script.
Depending on the usage, scripts must have a number of methods present; else the server will produce an error on the script’s execution. A script isn’t limited to a set number of methods either. One script may house methods supporting different types of queries, as well as helper functions too. It is important to consider this when planning the items in the sync panel.
The goal of the sync reader is to take a defined payload, process it, and then return a set of results via the read method. This read method will be called numerous times, thus producing a number of record sets, which are then processed by BrightServer's synchronisation engine to ensure that records are read efficiently. The reading will occur until an empty RecordSet is retrieved from the read() operation.
This transaction must be defined in a BrightForms application via a Server to Client sync rule on a script query. For more information on this process, please refer to BrightBuilder > Sync Rules and BrightBuilder > Queries > Scripted Queries.
Below is a diagram how the sync reader is utilised, both between server and script (represented by grey arrows) and the order of method calls (purple arrows).
In order to implement a sync reader script, the following methods must be implemented:
function openReader(query, limit)
{
in = new BufferedReader(new FileReader("filename"));
mark1 = query.charAt(0); // get 1st char
mark2 = query.charAt(1); // get 2nd char
}
The function may also be used to open/retain any resources needed by the reader.
read() commands return a specific record set based on the query given with openReader(). It may be called numerous times, with BrightServer amalgamating the results when sending them to the device. Record.add() and RecordSet.addRecord() are thus typically used to populate the returned set of records.
function read()
{
rs = new RecordSet("TABLE4");
// operations to populate the result set ...
while ((str = in.readLine()) != null)
{
strs = str.split(mark1,2);
strs2;
if (strs.size() < 2)
strs2 = strs[1].split(mark2,2);
// create record
record = new Record();
record.add(strs[0]);
record.add(strs2.size() < 2 ? "" : strs[1]);
record.add(strs2.size() < 2 ? "" : strs[2]);
rs.addRecord(record);
}
return rs ;
}
dataConsumed() signals to the reader that data from the read() command has been successfully retrieved.
closeReader() closes the reader, used to close or release any resources used at the opening stage.
function closeReader()
{
// ...
in.close();
}
Like the sync reader, the sync writer uses BrightServer's synchronisation engine to process records being sent to the script. While the reader deals with server to client transactions, the sync writer's methods are called for client to server ones.
The sync writer's goal is to write data, maintaining its integrity, given a set of records. As such, commit and rollback methods must also be provided to support this process of ensuring data is not compromised.
Whether or not a writer is to commit or rollback is dependant upon the isInTransaction() method, which returns a boolean value given the state of the writer. Using this value, the server will determine if it is to commit or roll back. If not in transaction, the server assume the data is automatically committed (i.e. the writer is in the auto-commit mode).
Below is a diagram how this process takes place, both between server and script (represented by grey arrows) and the flow of method calls (purple arrows).
In order to implement a sync writer script, the following methods must be implemented:
openWriter()/closeWriter() used to open/close the reader, and any resources that may be needed for its operations.
openWriter()
{
out = new BufferedWriter(new FileWriter("filename", true));
// ...
}
closeWriter()
{
// ...
out.close();
}
beginTransaction() is used to set up any write operations that may take place. It marks the beginning of a transaction.
write()
is used writing created, modified or deleted data based on
records sent to the method. Recordsets are sent via a vector
called "data", i.e. the set of tables. Thus, this
data type needs to be parsed correctly in order for values
to be accessed. If a data for multiple tables are sent from
client (i.e. a sync rule using a multi table query to send
multiple tables records, for example, order headers and order
items in a sync rule), then the data input parameter will
be a vector of recordsets. For a single table write this data
vector will contain just a single recordset containing the
records from the table in question.
A template for this is provided in the writing template, using
get() methods, and for loops to access a particular record
set, a particular record.
write(data)
{
for (i = 0; i < data.size(); i++)
{
rs = data.get(i) ;
for (j = 0; j < rs.size(); j++)
{
record = rs.get(j) ;
// Consume ...
//...
}
}
}
With this record ( rs.get(j) ), field values may be processed individually.
// Consume ...
if ( record.getStatus() == 1)
{
v.add( record.get(0) );
v.add( record.get(1) + "/" + record.get(2) );
v.add( "\n" );
} else if ( ...
The state of data, ie, whether to modify, create or delete can be retrieved by the getStatus() method. It will return an int value depending on the record’s state. For more information on the status of records, please refer to the Records section in the previous section.
commit() is called by the transaction manager to make the write commands’ changes permanent. It also marks the end of a transaction, and this should be reflected in the code.
write(data)
{
for (i = 0; i < v.size; i++)
{
out.write(v.get(i) + ",");
if (v.get(i) == "\n")
out.newLine();
}
}
rollback() is called by the transaction manager to revert any write changes that took place and restore the state to what it was after BeginTransaction() was called.
rollback()
{
v = new Vector();
}
isInTransaction() is called by the transaction manager to query whether write operations are in progress.
isInTransaction()
{
return (v.size() > 0);
}
A Script Job is a type of script that will run its set of operations repeated over a set period, defined by the server. This period is defined either by a set interval or via a Cron expression, and when elapsed, will call the run() function defined in the script. This run function may encompass any range of procedures or call a range of methods, and does not have a return type. Once performed, the server will call the function again once the particular interval has elapsed.
Job scripts is an excellent mechanism to implement various housekeeping jobs, distributing the data collected from field to multiple destinations, generating emails, creating reports, exporting data in specific formats for instance in XML or HTML formats at the scheduled intervals.
A script may be defined as a Script Job by its properties, accessed with by the context menu (shown below) or the properties panel.
Once in the properties pane or dialog, perform the following steps:
Set 'Execute On Schedule' as true. The icon should change in the projects panel under the Script node as shown.
Define how you want to the script to operate, via the 'Schedule Type' drop down menu. This will define whether the script's run() method will execute at a set interval in seconds or via Cron scheduling.
Input the schedule intervals (in seconds) or the Cron string. For more information on Cron scheduling, refer to Appendix > Cron Expressions.
When deployed to a BrightServer instance, job scripts may be monitored, enabled and disabled via the server's Job Status node.
By default, scripts uploaded from BEP files will be added to the server in the 'enabled' state.
Furthermore, Job scripts may also be implemented on the server via defining them as 'User Scripts' and deployed via BrightServer runtime configuration. For more information, please refer to the Job Configuration chapter of this document.
Similar to Read queries, online queries take in a payload with their execute() method and returns a set of values matching the types specified by the queries’ output field. The payload will be defined in the application, and the execute() method will be expected to interpret it, much like the read() method of the sync reader interface.
The difference between these two types of queries is that Online Queries bypass the synchronisation process in BrightServer, and thus is useful when data does not need to be saved to the local database at the client side.
Despite taking in the same payload variable, the two payloads could be of completely different formats in a read and online query.
Remote procedure calls, also referred as stored procedure queries, are handled by scripts by implementing executeRPC() methods. Inputs into this method are the name of the function to be executed, a vector of parameter names and a vector of parameter values, which are all set in the Queries panel of a Bright Software BSP Project. These parameters are indexed in order of definition in this project. Likewise, output should match the output fields specified in the query panel and be of the expected types.
Every executeRPC() method should return a ResultRPC object. This object represents a RPC query result. It is a data container and it holds output parameter names and values, a result code, and a RecordSet object for returning resultsets if needed. This mean a RPC call can return a set of out parameter values, or a RecordSet, or both depending on the requirements. The output parameters defined the query's "out" or "in/out" parameters are returned by the ResultRPC object using setOuputParameter method. Scripts can also return records in a RecordSet object by creating and setting a recordset object in the RPC result object. If the recordset of a ResultRPC is not set, then the query result will not return any records. See the reference manual for details on the executeRPC method and the ResultRPC object.
Transformation scripts are used as intermediary points between device/server tables and data accessors or mappings. Using this script, data retrieved from a device may be modified, having complex operations occur for particular fields, or completely re-arranging the record itself. It is specified as an intermediate sync point in the Sync Panel as follows:
The transformation within the script is performed via a single transform() method, which takes in and returns a vector of Record Sets - 'data'. This output set is then used to write the record to the server.
An example, which multiplies the incoming data set's field by 1000 before sending it to its destination, is as follows:
function transform(data)
{
// Write a message on the server.
ScriptSession.logInfo("Multiplying FIELD5 in TABLE4 by 1000 !") ;
// Iterate through the first RecordSet and process each Record.
rs = data.get(0) ;
for (i=0; i<rs.size(); i++)
{
record = rs.get(i) ;
// Transform record
record.set(4, new Double(record.get(4)*1000)) ;
}
// Return modified dataset.
return data ;
}
The number of RecordSets in this vector is determined by the number of parent and child tables are included in the synchronisation transaction; if there are no child tables, only data.get(0) would need to be used to retrieve the record set, however, if there are parent/children tables and relationships in the sync, all tables will be contained in the data vector.
Transformations will also occur at the end of the transaction when after the final table is sent - which in parent/child scenarios, may differ depending which child records are sent to the server. As a result, the same transformation script must be connected to all client to server pathways in the entire set, and contain the transformation logic for each table in the transaction, even if the particular table itself does not need a transformation on its records.
For an example how to implement this, please refer to Transformation Examples > Multiple Table Transformations.
Using a script's 'Type' property, scripts may be set to run on events which occur on BrightServer, such as the server starting up, shutting down, and during the user login/log off process. This property may be set in the script properties panel for any script in the BEP.
These scripts executing on server events require a run() function, with the exception of the Authentication type of script. Any script with a script type without the expected function defined will produce an error on the server upon execution. BrightServer will invoke these functions when the event occurs, set by the 'Type' field.
The types which scripts may be defined as are as follows:
Server Start : Runs immediately after the server has been started. This may be used to perform or prepare the server as it starts. The example below will display information in the log regarding last server start time:
function run()
{
// Display a message in the log/server window.
ScriptSession.logInfo("Server Started!");
// Display persisted value when server was last stopped.
var dtLast = ScriptSession.getVariable("LastStopped");
ScriptSession.logInfo("Last Stopped: " + dtLast.toString());
}
Server Stopped : Runs when the server has been stopped. This may be used in cases to capture the server state, or send notifications the state, such as via the Email object. The following is an example capturing the time the user logs off and persisting it for future use:
importClass (java.util.Calendar);
function run()
{
// Display a message in the log/server window.
ScriptSession.logInfo("Server stopped!");
// Save the current time as last server start.
var now = Calendar.getInstance().getTime();
ScriptSession.persistVariable("LastStopped", now);
}
User Login : Runs when a user successfully logs in to the system. This happens after an Authentication type script returns true, if it exists in a project. This type of script may be useful for preparing and performing specific procedures by the server after login. The following script displays how to retrieve the user who currently logged in.
function run()
{
// Produce warning if user meets certain criteria.
var usr = ScriptSession.getUserName();
if (usr == "someuser")
ScriptSession.logWarn("Warning: User " + usr + " logged into system" );
}
User Logout : Runs when a user logs out of the system. This may be used for clearing a server state after the user logs out.
function run()
{
// Retrieve username.
var usr = ScriptSession.getUserName();
// Perform some kind of clean-up after a user logs off.
doCleanUp(usr);
}
Authentication : Runs when a user attempts to log in to the system via BrightForms or BrightWeb. Unlike other scripts specified to run on server events, the Authentication script uses an authenticate() function with username and password parameters. These parameters passed by BrightServer may be processed by the script, which will return a boolean return value - true if the user login is to continue, and false to invalidate the login attempt.
Due to its nature, only a single authentication script may exist in a project. If there are more than one script in the system marked as Authentication script, BrightServer will execute only the first one found, ignore the other authentication scripts defined in the system.
The following demonstrates how the username and password are passed to the authenticate() method.
function authenticate(name, password)
{
// Display user name and password in log/server window.
ScriptSession.logInfo("Checking credentials for " + name + " [" + password + "]") ;
ScriptSession.logInfo(name + " IP Address is: " + ScriptSession.getUserRemoteHostAddress()) ;
// Check if username and password are equal, if not, invalidate.
if (name == password)
return true;
return false ;
}
A script with a run() function can be defined as both a scheduled job script and contain a script type. In this scenario, the script will perform its run() function on BrightServer event, while also executing on schedule. If the job is disabled by the Job Status panel, it will still be triggered by server events regardless of this state.
BrightServer has the ability to process Web Service calls, with the Web Services script type.
These requests are directed to the URL: /brightserver/ws?<name of script>.
Upon receiving the request, the script will process the message via its handle() function. This function will also construct the response message to send back to the server as its return value.
SOAP requests and responses are deserialised internally via the WebMessage object. This enables developers to analyse and construct SOAP communications, while not needing any specific parsing. The methods to analyse and construct these WebMessage objects are as follows:
request.getMessageName() Returns the name of the WebMessage.
request.getParam() Returns the value of the specified parameter of the WebMessage. Requires a parameter name.
response.createMessage() Create a new message to send to the web service caller as a response. Message name is specified as an input.
response.addParam() Used to add a new parameter to the response message, which serialised as a SOAP message when sent back to the caller. Takes in inputs for parameter name and the parameter value itself.
For more information, please refer to the BrightServer > Web Services chapter of this documentation.
The blob object is provided to assist the handling of binary data, as JavaScript supports only native data types. Binary data is synchronised to and from BrightServer as byte arrays (byte[]). This binary data may be processed from the client via the Blob object when implementing scripts. The blob object's methods used to access this byte array, providing methods to access and store binary data. An example of blob use is as follows:
blob = new Blob(record.get(i));
blob.decompress();
blob.writeToFile(fileName);
Furthermore, this data may be mapped to incorporate compression specified by a BrightXpress project. As such, in order to access these values to conventional BrightXpress project types, decompression must take place. Similarly, to store these values correctly, compression of blobs must be done.
If base64 operations are needed within a script, the Util.encodeBase64() and Util.decodeBase64() methods may be used. They can be used on strings to covert them into byte arrays, and vice versa. An example of this code is as follows:
blob = new Blob(record.get(i));
str = util.encodeBase64(binarydata);
blob2 = util.decodeBase64(str);
The script session object holds information about a script when instantiated, and also allows information to be outputted to the server’s log through a number of methods. It is primarily used to query system information, log data or output of the script, and handle exceptions. For more information, please refer to the sections below, and the Script Methods Reference Manual.
Entries may be logged to the BrightServer log by using the ScriptSession object. They can be logged to either the debug, info, warn or error levels, depending on the methods used. It is also important that accompanying helper methods for checking the log trace level to avoid unnecessary string creations and manipulations which would slow the server drastically. For instance if a debug is logged, then isDebugLogEnabled() method should be used to check the trace level. An example of the code required is as follows :
//Creates a debug log entry level
if (ScriptSession.isDebugLogEnabled())
{
ScriptSession.logDebug(message) ;
}
//Creates a log entry at info level
if (ScriptSession.isInfoLogEnabled())
{
ScriptSession.logInfo(message);
}
//Creates a log entry at error level
ScriptSession.logError(message);
Error exceptions may be handled by the ScriptSession object in order to capture all the data in Java when thrown.
Set the error message before the throw exception. If the code is thrown, the message may be retrieved through the ScriptSession.getLastError() method. Below is an example of how exception handling may be handled in a script, using the Script session object to capture data.
try
{
if (q < 0) throw ("Err1");
if (q > 30) throw ("Err2");
}
catch (e)
{
if (e == "Err1") ScriptSession.setError(100,"Number too small");
if (e == "Err2") ScriptSession.setError(100,"Number too large");
throw e ;
}
Any exception which is not caught will terminate the script and have the device's synchronisation fail, returning the error code '10041'.
In order to maximise the reuse, the importing scripts (or creating references to other scripts within a script, in other words including other scripts within a script) are allowed. Natively there is no standard import or include statements in JavaScript language for allowing the reuse of scripts.
BrightServer allows this through a special place holder string reference in the following format.
//#includescript<ScriptName>
It is very important to use the includescript statements in the strict format defined. Otherwise the server will generate an error or the statement will be ignored altogether. Note that it starts with double forward slashes followed by the "#includescript<" with no spaces. Then it includes the script name to be imported followed by the closing ">".
The following sample script includes a script named "TestScript" to invoke the logMessage() function.
//#includescript<TestScript>
function myfunction()
{
logMessage() ;
}
TestScript is defined as follows.
importClass (java.util.Calendar) ;
function logMessage()
{
ScriptSession.logInfo("Run @ " + Calendar.getInstance().getTime()) ;
}
In some cases one may need to implement scripts where some state data needs to be persisted between the executions of scripts. One possible option is that the script developer can implement the necessary mechanism to persist the required state data between executions using a file or a database based storage media.
To address this requirement, BrightServer provides an out-of-the-box simple persistence mechanism through ScriptSession object methods to store and retrieve simple state information either to the system memory or the system's internal runtime database.
ScriptSession.setVariable() allows the user to store a name and value pair to the system memory. This means the values stored by using this method will only be available as long as BrightServer is running and will be lost when BrightServer is restarted.
ScriptSession.peristVariable() allows the user to store a name and value pair to the system's internal runtime database for access within the same server configuration and deployment. This means the values stored by using this method will be available to this configuration even if BrightServer is restarted. That is, they are permanently stored for later retrieval. The variable name, combined with the configuration name must not be more than 128 characters long.
ScriptSession.getVariable() retrieves the named value stored as either a standard or persisted variable within a configuration. If the named value does not exist in the system, then a NULL will be returned.
ScriptSession.persistUniversalVariable() allows the user to store a name and value paid to the system's internal runtime database, such that the value may be accessible to all scripts running on the server. The variable name for this must not be more than 128 characters long.
ScriptSession.getUniversalVariable() retrieves the named value stored as a universal variable on the BrightServer instance. If the named value does not exist in the system, then a NULL will be returned.
Values stored via the above methods can be of any Java object type.
The name value pairs for standard and persisted variables are stored in the context of the configuration deployment, accessible to all its defined scripts. Universal variables are stored under the global context, that is, they are available from any script executed by the server defined in any deployment. Therefore, creating meaningful namespaces is very important when naming and storing values in the system. The names must be ensured to be unique to prevent accidental overwrites.