AggreGate SDK

Top  Previous  Next

The AggreGate Software Development Kit (SDK) provides the ability to extend AggreGate Platform and integrate it with the other enterprise systems. AggreGate SDK is a set of open-source modules that provide compatibility with different operating systems. The modules are implemented in Java programming language.

AggreGate SDK includes the following components:

AggreGate Server Application Programming Interface (API) for managing AggreGate Server and connected hardware from the other applications via secure network connection
AggreGate Server Driver Development Kit (DDK) for connecting new hardware devices to the system using custom Device Drivers
AggreGate Server Plugin SDK for extending AggreGate Server with new data processing and presentation modules
Agent SDK for implementing Agents running on PC-based controllers

AggreGate SDK Distribution Package

The AggreGate SDK is available as a ZIP archive that contains:

Source code (/src folder)
Examples (/src/examples folder)
Unit tests (/test folder)
Functional tests (/test folder)
Javadocs (/docs folder)
Pre-built Java Archive (JAR) with SDK classes (aggregate-api.jar)
Necessary third-party libraries (aggregate-api-libs.jar)

Using AggreGate SDK

To use the AggreGate SDK, you have to add the following java archives (JARs) to the classpath of your Java application:

aggregate-api.jar
aggregate-api-libs.jar

The first archive contains AggreGate-specific code, while the second one contains the third-party libraries used by the SDK.

Javadocs and Sources

This section of the manual provides only top-level functional documentation and step-by-step guides for using different aspects of AggreGate SDK. For detailed information on specific classes and interfaces included in the SDK refer to:

Javadocs located in the /docs folder of SDK distribution package
Source code located in the /src folder of SDK distribution package

Basic Concepts

AggreGate SDK indoctrinates a generic approach to managing any type of data flowing inside the system, both raw data coming from devices and pre-processed data provided by different system facilities, such as alerts or trackers. This approach also applies to any of the pre-built vertical market solution, such as AggreGate Network Manager, AggreGate SCADA/HMI, AggreGate Access Control, and other.

Overall Operation

The elementary unit of all data flowing inside the system is Data Table. Even simple scalar values (integers, strings, booleans) are represented by single-cell Data Tables for the sake of uniformity. The java representation of Data Table is DataTable class. If includes zero of more DataRecord instances representing individual records.
Format of DataTable is represented by TableFormat class. It refers zero or more FieldFormat instances defining format of individual table fields.
Generally, all data should be accessed through different server contexts. Contexts are organized as a hierarchical context tree. The SDK includes Context interface for handling different context operations. Context instances may be retrieved from the ContextManager by their paths (full names). The Context interface also has a series of methods to access its parent and children.

Accessing Context Variables, Functions and Events

Every context provides access to its variables, functions and events. There are several methods to get their definitions: getVariableDefinition(), getVariableDefinitions(), getFuncitonDefinition(), getFuncitonDefinitions(), getEventDefinition(), getEventDefinitions(). Classes representing the definitions are VariableDefinition, FunctionDefinition and EventDefinition respectively.
Context interface provide a way to read/write values of variables: getVariable() and setVariable(). Value of every variable is an instance of DataTable.
Context also provides a method for calling its functions: callFunction(). Both input and output of function are instances of DataTable.
Events are handled by adding and removing event listeners using addEventListner() and removeEventListener() methods. Event listener must implement ContextEventListerner interface, but the real implementations will extend DefaultContextEventListener in most cases. Listeners working inside server plugins and drivers should pass an instance of UncheckedCallerController to the constructor of DefaultContextEventListener to ensure proper permissions.

note_warning-wt

getVariable() method returns a clone of variable value's DataTable even in the case of server-side code (plugins, drivers). To apply new value of the variable to the context, call setVariable() after making modifications to the data table.

Modifications of DataTable returned by getVariable() won't affect the context until setVariable() call is made.

Defining and Implementing Context Variables, Functions and Events

Server plugins and drivers, along with Java-based Agents, usually create their own definitions of variables, functions and events. These definitions are added to the contexts using addVariableDefinition(), addFunctionDefinition() and addEventDefinition() methods. There are also corresponding removal methods: removeVariableDefinition(), removeFunctionDefinition() and removeEventDefinition().
Manually added variables should have a non-null getter implementing VariableGetter interface. The purpose of getter is providing custom variable reading code. Writable variables should also have a non-null setter implementing VariableSetter interface. The setter should somehow store new variable value modified by system operators or different server facilities.

note_tip-wt

If variable added to a server context has no custom getter/setter, the default ones will be used:

Default getter will retrieve variable value from the database;
Default setter will persistently store variable value in the database.
Manually added functions must have a non-null implementation that is a derived from FunctionImplementation interface. The implementation should analyze function input, process it, and generate the output.
Plugins, drivers and Agents may generate context events using fireEvent() method of Context interface.

note_warning-wt

Format of data table returned by variable getter and function implementation must match format contained in their definitions. Format of data table passed to fireEvent() method must match format contained in event definition. Failure to follow this rule may result in data loss since the system will try convert the data tables to definition-provided formats preserving as much data as it can.

Finding and Accessing Arbitrary Data

This section explains how to find, read or modify any data flowing inside the AggreGate installation.

1. Finding the proper context

First step is locating the context that exposes the necessary setting, operation or event. There are several ways to achieve that:

Check server core context reference and/or vertical-solution-specific context references (that are also part of this documentation)
Find necessary context in the System Tree of AggreGate Client or Web Desktop

2. Finding name or necessary variable/function or event

If the context containing necessary data was found in the context reference, check Public Variables, Public Functions or Public Events section of the corresponding article for name of variable/funciton/event providing necessary data
If using AggreGate Server UI to locate the data, consider the following:
oTooltips of rows and cells of the Properties Editor component show names of variables;
oTooltips of events in Event Log component show event source context and name;
oFunction names may be tracked down using Entity Selector component;
oProperties Editor provides View Variable Information operation in its context menu, while Event Log has View Event Definition context operation. These operations show all properties of the definitions, their formats, etc.

3. Determining Field Names and Types

Since every value is a Data Table, it's necessary to find out what fields does its format have. That includes field names and types.

If the necessary definition is found in context reference, its description contain a format table describing field names, types, and purposes.
If using the UI, consider the following:
oValues of variables, events data, or functions input/output are always opened in the Data Table Editor component. Column, row and cell tooltips in the Data Table Editor show field names and types;
oView Variable Information and View Event Definition operations (see above) provide comprehensive information about all field propeties, including their defaults, selection values, etc.

4. Accessing The Data Programmatically

After locating the necessary context, variable/function/event, and their fields, you can access them programmatically, both from server plugins or using remote API:

Get the necessary Context object using ContextManager.get(), Context.getChild() or Context.getParent() methods.
Get/set variable, call function, of add event listeners using getVariable(), setVariable(), callFunction(), addEventListner() methods.
To construct new value of variable of function input value from scratch, use the following code: new DataTable(VariableDefinition.getFormat()) or new DataTable(FunctionDefinition.getInputFormat()).
When processing a DataTable, you can get a certain DataRecord using getRecord() method. The shortcut for getting first record is rec() method.
DataRecord provides generic getValue() and setValue() methods for reading/writing field values. However, there is a set of methods for getting field value casted to a certain type: getInt(), getString(), getBoolean(), etc.

Dealing with Access Permissions

This section covers programmating handling of AggreGate Server security and permissions issues.

Accessing Context Data

Many methods of the Context and ContextManager interfaces accept a parameter of type CallerController. Caller controller is an object that incorporates effective permissions of the calling side. There are two generic rules for using caller controllers:

Any server-side code (device drivers and plugins) must pass an instance of CallerController to every method that accepts it. Failure to do so will result to the None effective permission level of the calling side, thus making most calls fail with an error or return null values.
Any remote code (applications using AggreGate Server API or Java-based Agents) should use methods that do not accept caller controller or pass null as its value. This will perfectly work since client-side code does not perform permission checking, while the requested remote server-side operation will anyway incorporate permission level obtained during authorization (call to login() function of the root context).

Server-side code may obtain caller controllers in several ways:

Create an instance of UncheckedCallerController to suppress any permission checking and get full access. This should be done only by some system code that is not assumed to execute operations with permissions of a certain system user.
Get a caller controller by calling DeviceContext.getCallerController(). This controller will incorporate permission of system user owning the device account. This way of getting caller controllers mostly applies to Device Driver code.

Extending Contexts

When device driver of server plugin adds definitions of variables, functions or events to a server context, it may assign custom permission levels to them using VariableDefinition.setReadPermissions(), VariableDefinition.setWritePermissions(), FunctionDefinition.setPermissions(), and EventDefinition.setPermissions() methods. If permission level of the definition is null, it will match permission level of the parent context. Note, setting definition's permission levels lower or equal to context's permission level is meaningless.

To get predefined values of different permission levels, use the following code:

Permission Level

Code

None

LinkServerPermissionChecker.getNullPermissions()

Observer

LinkServerPermissionChecker.getObserverPermissions()

Operator

LinkServerPermissionChecker.getOperatorPermissions()

Manager

LinkServerPermissionChecker.getManagerPermissions()

Engineer

LinkServerPermissionChecker.getEngineerPermissions()

Administrator

LinkServerPermissionChecker.getAdminPermissions()

Logging

AggreGate libraries report their activities via logging. To enable and configure logging in the Java application that uses AggreGate Server API or Agent SDK, call Log.start() method and pass the URL of logging configuration file to it. You can copy this file from AggreGate Server or AggreGate Client installation directory. Edit this file by changing logging level in certain categories for debugging purposes.

Essential Java Classes and Interfaces of the AggreGate SDK

Class Name

Description

RemoteLinkServer

A container for server connection parameters (address, port, username and password). An instance of this class is passed to the constructor of RemoteLinkServerController.

RemoteLinkServerController

This class is used to establish and control a connection with the AggreGate Server. It provides access to a ContextManager interface which, in turns, lets you access the server's context tree.

ContextManager

An interface that provides access to the context tree. An instance of the class implementing this interface may be retrieved from the RemoteLinkServerController through the getContextManager() method.

Context

An interface letting you work with a single context. Instances of classes implementing this interface are returned by different methods of ContextManager.

VariableDefinition

Definition of the context variable. Provides access to its properties, format, getter and setter.

FunctionDefinition

Definition of the context function. Provides access to its properties, input/output formats and implementation.

EventDefinition

Definition of the context event. Provides access to its properties and format.

VariableGetter

Implementations of this interface should provide custom variable value reading logic.

VariableSetter

Implementations of this interface should provide custom variable value writing logic.

FunctionImplementation

Implementations of this interface should provide custom function execution logic, i.e. processing of input and generation of output.

ContextEventListener

A base interface for context event listeners. The listener's handle() method is called when event is fired in the context to that the listener was added.

DefaultContextEventListener

Default implementation of ContextEventListener. Generally, most listeners should extend this class.

DataTable

Implementation of a Data Table. It provides access to the format and records of the table. Instances of this class are returned by getVariable() and callFunction() methods of Context.

DataRecord

Implementation of a single Data Table record.

TableFormat

Class implementing the format of a Data Table. It includes table properties and a list of fields.

FieldFormat

Class implementing the format of a single Data Table field. Defines name, type and other parameters of the field, including validators, selection values etc.

CallerController

The instance of this class is passed to many context operations. It incorporates permissions of the calling side.

UncheckedCallerController

A special type of caller controller that suppress any permission checking, giving full access to the calling side. Should be used for system calls.

Permissions

A list of permissions (Permission objects) what must be satisfied when accessing a certain server resource.

LinkServerPermissionChecker

This class provides a set of static methods for getting Permissions to assign for newly added variable/function/event definitions.