3.6. Accessing Derived Information through Active Collections
- Configure Active Collections
- Present Results from an Event Processor Network
- Publish Active Collection Contents as JMX Notifications
- Query Active Collections via REST
- Use Pre-Defined Active Collections
- Implement an Active Collection Source, which can be used to subscribe to a source of information which can result in data being inserted, updated and removed from an associated active collection.
- Implement an Active Change Listener that can associated with an Active Collection Source, and automatically notified of changes to an associated Active Collection.
- Write a custom application for accessing Active Collections.
3.6.1. Configuring Active Collections
3.6.1.1. Defining the Active Collection Source
[
{
"@class" : "org.overlord.rtgov.active.collection.epn.EPNActiveCollectionSource",
"name" : "ServiceResponseTimes",
"type" : "List",
"itemExpiration" : 0,
"maxItems" : 100,
"subject" : "ServiceResponseTimes",
"aggregationDuration" : 1000,
"groupBy" : "serviceType + \":\" + operation + \":\" + fault",
"aggregationScript" : "AggregateServiceResponseTime.mvel"
},{
"@class" : "org.overlord.rtgov.active.collection.epn.EPNActiveCollectionSource",
"name" : "ServiceDefinitions",
"type" : "Map",
"itemExpiration" : 0,
"maxItems" : 100,
"subject" : "ServiceDefinitions",
"scheduledScript" : "TidyServiceDefinitions.mvel",
"scheduledInterval" : 60000,
"properties" : {
"maxSnapshots" : 5
},
"maintenanceScript" : "MaintainServiceDefinitions.mvel"
},{
"@class" : "org.overlord.rtgov.active.collection.epn.EPNActiveCollectionSource",
"name" : "Situations",
"type" : "List",
"itemExpiration" : 40000,
"maxItems" : 0,
"subject" : "Situations",
"activeChangeListeners" : [ {
"@class" : "org.overlord.rtgov.active.collection.jmx.JMXNotifier",
"objectName" : "overlord.rtgov.services:name=Situations",
"descriptionScript" : "SituationDescription.mvel",
"insertTypeScript" : "SituationType.mvel"
} ],
"derived": [ {
"name": "FilteredSituations",
"predicate": {
"type": "MVEL",
"expression": "map = context.getMap(\"IgnoredSituationSubjects\"); if (map == null) { return false; } return !map.containsKey(subject);"
},
"properties" : {
"active" : false
}
} ]
},{
"@class" : "org.overlord.rtgov.active.collection.ActiveCollectionSource",
"name" : "IgnoredSituationSubjects",
"type" : "Map",
"lazy" : true,
"factory" : {
"@class" : "org.overlord.rtgov.active.collection.infinispan.InfinispanActiveCollectionFactory",
"cache" : "IgnoredSituationSubjects"
}
},{
"@class" : "org.overlord.rtgov.active.collection.ActiveCollectionSource",
"name" : "Principals",
"type" : "Map",
"lazy" : true,
"visibility" : "Private",
"factory" : {
"@class" : "org.overlord.rtgov.active.collection.infinispan.InfinispanActiveCollectionFactory",
"cache" : "Principals"
}
}
]
This configuration shows the definition of multiple Active Collection Sources. The top level elements for a source, that are common to all active collection sources, are:
Table 3.32. Elements of Active Collection Sources
| Field | Description |
|---|---|
| @class | This attribute defines the Java class implementing the Active Collection Source. This class must be directly or indirectly derived from org.overlord.rtgov.active.collection.ActiveCollectionSource. |
| name | The name of the Active Collection that will be created and associated with this source. |
| type | The type of active collection. The currently supported values (as defined in the org.overlord.rtgov.active.collection.ActiveCollectionType enum are List (default) and Map. |
| visibility | This value specifies the visibility of active collection, that is, whether an active collection is accessible via the remote access mechanisms such as REST or not. The currently supported values (as defined in the org.overlord.rtgov.active.collection.ActiveCollectionVisibility enum are Public (default) and Private. |
| lazy | This value specifies whether active collection must be created on startup, or instantiated upon first use. The default value is false. |
| itemExpiration | If not zero, then defines the number of milliseconds until an item in the collection expires and is removed. |
| maxItems | If not zero, defines the maximum number of items that the collection must hold. If an insertion causes the size of the collection to increase above this value, then the oldest item must be removed. |
| aggregationDuration | The duration (in milliseconds) over which the information is aggregated. |
| groupBy | An expression defining the key to be used to categorize the information being aggregated. The expression can use properties associated with the information being aggregated. |
| aggregationScript | The MVEL script used for aggregating the information. |
| scheduledInterval | The interval (in milliseconds) between the invocation of the scheduled script. |
| scheduledScript | The MVEL script invoked at a fixed interval to perform routine tasks on the collection. |
| maintenanceScript | By default, events received by the active collection source are inserted into the associated active collection. If a MVEL maintenance script is specified, then it is invoked to manage the way in which the received information is applied to the active collection. |
| properties | A set of properties that can be accessed by the various scripts. |
| derived | An optional list of definitions for derived collections that will be created with the top level active collection, and retained regardless of whether any users are currently accessing them. Normally when a derived collection is created dynamically on demand, once it has served its purpose, it is cleaned up. |
| activeChangeListeners | The list of active change listeners that must be instantiated and automatically registered with the Active Collection. The listeners must be derived from the Java class org.overlord.rtgov.active.collection.AbstractActiveChangeListener. |
| factory | The optional factory for creating the active collection, derived from the class org.overlord.rtgov.active.collection.ActiveCollectionFactory. |
- Scripts
- The aggregation script is used to aggregate information being provided by the source, before being applied to the collection. The values available to the MVEL script are:
Table 3.33. Aggregate Script Values
Variable Description events The list of events to be aggregated. The scheduled script is used to perform regular tasks on the active collection, independent of any information being applied to the collection. The values available to the MVEL script are:Table 3.34. Scheduled Script Values
Variable Description acs The active collection source. acs.properties The properties configured for the active collection source. variables A map associated with the active collection source that can be used by the scripts to cache information. The maintenance script is used to manage how new information presented to the source is applied to the active collection. If no script is defined, then the information is inserted by default. The values available to the MVEL script are:Table 3.35. Scheduled Script Values
Variable Description acs The active collection source. acs.properties The properties configured for the active collection source. key The key for the information being inserted. You can have null value for key. value The value for the information being inserted. variables A map associated with the active collection source that can be used by the scripts to cache information. Here is an example script, showing how you can use these variables :int maxSnapshots=acs.properties.get("maxSnapshots"); snapshots = variables.get("snapshots"); if (snapshots == null) { snapshots = new java.util.ArrayList(); variables.put("snapshots", snapshots); } // Update the current snapshot currentSnapshot = variables.get("currentSnapshot"); if (currentSnapshot == null) { currentSnapshot = new java.util.HashMap(); } snapshots.add(new java.util.HashMap(currentSnapshot)); currentSnapshot.clear(); // Remove any snapshots above the number configured while (snapshots.size() > maxSnapshots) { snapshot = snapshots.remove(0); } // Merge snapshots merged = org.overlord.rtgov.analytics.util.ServiceDefinitionUtil.mergeSnapshots(snapshots); // Update existing, and remove definitions no longer relevant foreach (entry : acs.activeCollection) { org.overlord.rtgov.analytics.service.ServiceDefinition sd=null; if (merged.containsKey(entry.key)) { acs.update(entry.key, merged.get(entry.key)); } else { acs.remove(entry.key, entry.value); } merged.remove(entry.key); } // Add new definitions for (key : merged.keySet()) { acs.insert(key, merged.get(key)); }This example shows the script accessing the Active Collection Source and its properties, as well as accessing (and updating) the variables cache associated with the source. - Active Change Listeners
- The activeChangeListeners element defines a list of Active Change Listener implementations that is instantiated and registered with the active collection. The fields associated with this component are:
Table 3.36. Active Change Listener Fields
Field Description @class The Java class that provides the listener implementation and is directly or indirectly derived from org.overlord.rtgov.active.collection.AbstractActiveChange. - Factory
- The factory element defines an Active Collection Factory implementation that will be used to create the active collection. The fields associated with this component are:
Table 3.37. Active Collection Factory Fields
Field Description @class The Java class that provides the factory implementation and is directly or indirectly derived from org.overlord.rtgov.active.collection.ActiveCollectionFactory.Factory implementation include Infinispan. The fields associated with theorg.overlord.rtgov.active.collection.infinispan.InfinispanActiveCollectionFactorycomponent are:Table 3.38. Infinispan Fields
Field Description cache The name of the cache to be presented as an Active Map. container The optional JNDI name used to obtain the cache container. If not defined, then the default container is obtained from the infinispan.container property from overlord- rtgov.propertiesfile in the$JBOSS_HOME/standalone/configurationfolder. If the default container is not defined, then a default cache manager is instantiated.
3.6.1.2. Registering the Active Collection Source
- JEE Container
- The Active Collection Source is deployed within the JEE container as a WAR file with the following structure:
warfile | |-META-INF | |- beans.xml | |-WEB-INF | |-classes | | |-acs.json | | |-<custom classes/resources> | | | |-lib | |-acs-loader-jee.jar | |-<additional libraries>
Theacs.jsonfile contains the JSON representation of the Active Collection Source configuration. Theacs-loader-jee.jaracts as a bootstrapper to load and register the Active Collection Source.If custom active collection source or active change listeners are defined, then the associated classes and resources can be defined in theWEB-INF/classesfolder or within additional libraries located in theWEB-INF/libfolder. Amaven pom.xmlthat creates this structure is:<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>....</groupId> <artifactId>....</artifactId> <version>....</version> <packaging>war</packaging> <name>....</name> <properties> <rtgov.version>....</rtgov.version> </properties> <dependencies> <dependency> <groupId>org.overlord.rtgov.active-queries</groupId> <artifactId>active-collection</artifactId> <version>${rtgov.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.overlord.rtgov.active-queries</groupId> <artifactId>acs-loader-jee</artifactId> <version>${rtgov.version}</version> </dependency> .... </dependencies> </project>If deploying in JBoss Application Server, then include the following fragment to define the dependency on the core Runtime Governance modules:..... <build> <finalName>....</finalName> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> <archive> <manifestEntries> <Dependencies>deployment.overlord-rtgov.war</Dependencies> </manifestEntries> </archive> </configuration> </plugin> </plugins> </build> .....
3.6.2. Presenting Results from an Event Processor Network
org.overlord.rtgov.active.collection.epn.EPNActiveCollectionSource implementation:
[[
{
"@class" : "org.overlord.rtgov.active.collection.epn.EPNActiveCollectionSource",
"name" : "Situations",
"type" : "List",
"itemExpiration" : 40000,
"maxItems" : 0,
"subject" : "Situations",
"activeChangeListeners" : [ {
"@class" : "org.overlord.rtgov.active.collection.jmx.JMXNotifier",
"objectName" : "overlord.rtgov.services:name=Situations",
"descriptionScript" : "SituationDescription.mvel",
"insertTypeScript" : "SituationType.mvel"
} ],
"derived": [ {
"name": "FilteredSituations",
"predicate": {
"type": "MVEL",
"expression": "map = context.getMap(\"IgnoredSituationSubjects\"); if (map == null) { return false; } return !map.containsKey(subject);"
},
"properties" : {
"active" : false
}
} ]
}
]
Table 3.39. Active Collection Source Fields for EPN
| Field | Description |
|---|---|
| subject | The EPN subject upon which the information has been published. |
{
"name" : "SLAMonitorEPN",
"subscriptions" : [ {
"nodeName" : "SLAViolations",
"subject" : "ServiceResponseTimes"
} ],
"nodes" : [
{
"name" : "SLAViolations",
"sourceNodes" : [ ],
"destinationSubjects" : [ ],
"maxRetries" : 3,
"retryInterval" : 0,
"eventProcessor" : {
"@class" : "org.overlord.rtgov.ep.drools.DroolsEventProcessor",
"ruleName" : "SLAViolation"
},
"predicate" : null,
"notifications" : [ {
"type" : "Processed",
"subject" : "SituationsProcessed"
},{
"type" : "Results",
"subject" : "Situations"
} ]
}
],
"version" : "1"
}
3.6.3. Publishing Active Collection Contents as JMX Notifications
[
.....
{
.....
"activeChangeListeners" : [ {
"@class" : "org.overlord.rtgov.active.collection.jmx.JMXNotifier",
"objectName" : "overlord.sample.slamonitor:name=SLAViolations",
"insertType" : "SLAViolation"
} ],
.....
}
]
Table 3.40. JMXNotifier Listener Implementation Fields
| Field | Description |
|---|---|
| objectName | The MBean (JMX) object name to be used to report the notification. |
| descriptionScript | The MVEL script that can be used to derive the description field on the notification. If not defined, then the information's toString() value is used. |
| insertType | The type field for the notification when performing an insert. |
| insertTypeScript | An optional MVEL script that can be used to derive the type field for an insert. |
| updateType | The optional type field for the notification when performing an update. |
| updateTypeScript | An optional MVEL script that can be used to derive the type field for an update. |
| removeType | The optional type field for the notification when performing a removal. |
| removeTypeScript | An optional MVEL script that can be used to derive the type field for a removal. |
3.6.4. Querying Active Collections via REST
<host>/overlord-rtgov/acm/query
Table 3.41. Attributes for Active Collections Query
| Attribute | Description |
|---|---|
| collection | The active collection name. |
| predicate | Optional. If defined with the parent name, then can be used to derive a child collection that filters its parent's content (and notifications) based on the predicate. |
| parent | Optional. If deriving a child collection, this field defines the parent active collection from which it will be derived. |
| maxItems | Defines the maximum number of items that should be returned in the result, or 0 if unrestricted. |
| truncate | If a maximum number of items is specified, then this field can be used to indicate whether the Start or End of the collection should be truncated. |
| style | Allows control over how the results are returned. The value Normal means as it appears in the collection. The value Reversed means the order of the contents should be reversed. |
{
"parent" : "ServiceResponseTime",
"maxItems" : 5000,
"collection" : "OrderService",
"predicate" : {
"type" : "MVEL",
"expression" : "serviceType == \"{urn:switchyard-quickstart-demo:orders:0.1.0}OrderService\" && operation == \"submitOrder\""
},
"truncate" : "End",
"style" : "Reversed"
}
If the Active Collection Manager (ACM) does not have a collection named OrderService , then it uses the supplied defaults to create the derived collection. If the collection already exists, then the contents will be returned, allowing multiple users to share the same collection.
3.6.5. Pre-Defined Active Collections
3.6.5.1. ServiceResponseTimes Active Collection
3.6.5.2. Situations Active Collection
org.overlord.rtgov.analytics.situation.Situation objects.
[
{
........
},{
"@class" : "org.overlord.rtgov.active.collection.epn.EPNActiveCollectionSource",
"name" : "Situations",
"type" : "List",
"itemExpiration" : 40000,
"maxItems" : 0,
"subject" : "Situations",
"activeChangeListeners" : [ {
"@class" : "org.overlord.rtgov.active.collection.jmx.JMXNotifier",
"objectName" : "overlord.rtgov:name=Situations",
"descriptionScript" : "SituationDescription.mvel",
"insertTypeScript" : "SituationType.mvel"
} ],
.......
}
]
3.6.5.3. ServiceDefinitions Active Collection
org.overlord.rtgov.analytics.service.ServiceDefinition objects. For more details on this class, see the API documentation.
{
"serviceType":"{http://www.jboss.org/examples}OrderService",
"operations":[{
"name":"buy",
"metrics":{
"count":30,
"average":1666,
"min":500,
"max":2500
},
"requestResponse":{
"metrics":{
"count":10,
"average":1000,
"min":500,
"max":1500
},
"invocations":[{
"serviceType":"{http://www.jboss.org/examples}CreditAgencyService",
"metrics":{
"count":10,
"average":500,
"min":250,
"max":750
},
"operation":"checkCredit"
}]
},
"requestFaults":[{
"fault":"UnknownCustomer",
"metrics":{
"count":20,
"average":2000,
"min":1500,
"max":2500
}
}]
}],
"metrics":{
"count":30,
"average":1666,
"min":500,
"max":2500
}
}
- scheduledInterval (in milliseconds): It dictates how often a snapshot of the current service definition information is stored.
- maxSnapshots: It defines the maximum number of snapshots that must be used.
3.6.5.4. Principals Active Collection
3.6.6. Implementing an Active Collection Source
org.overlord.rtgov.active.collection.ActiveCollectionSource class and implement the following methods:
Table 3.42. ActiveCollectionSource Methods for New Active Collection Source
| Method | Description |
|---|---|
void init() | This method is invoked when the Active Collection Source is registered, and should be used to create the subscription to the relevant source of information. The implementation of this method MUST call the init() method on the super class first. |
void close() | This method is invoked when the Active Collection Source is unregistered, and should be used to unsubscribe from the source of information. The implementation of this method MUST call the close() method on the super class first. |
Table 3.43. ActiveCollectionSource Methods
| Method | Description |
|---|---|
public void insert(Object key, Object value) | This method is called to insert a new element into the collection. The value is the information to be inserted. The key is potentially optional, depending on the nature of the active collection (List or Map). For a List the key is optional. If specified, then it MUST be an integer representing the index where the value must be inserted. The Map key represents the map key to be associated with the value, and is therefore not optional. |
public void update(Object key, Object value) | This method is called to update an existing element within the collection. The value is the information to be updated. The key is potentially optional, depending on the nature of the active collection (List or Map). For a List the key is optional. If specified, then it MUST be an integer representing the index of the value to be updated. If not specified, then the value will be used to locate the index within the list. The Map key represents the map key associated with the value, and is therefore not optional. |
public void remove(Object key, Object value) | This method is called to remove an element from the collection. The value is the information to be updated. The key is potentially optional, depending on the nature of the active collection (List or Map). For a List the key is optional. If specified, then it MUST be an integer representing the index of the value to be removed. If not specified, then the value will be used to locate the index within the list. The Map key represents the map key associated with the value, and is therefore not optional. However in this situation, the value is optional. |
3.6.7. Implement an Active Change Listener
org.overlord.rtgov.active.collection.ActiveChangeListener interface. The Active Collection API supports add and remove methods to register and unregister these active change listeners. The methods that need to be implemented for an active change listener are:
Table 3.44. Active Change Listener Methods
| Method | Description |
|---|---|
void inserted(Object key, Object value) | This method is called when a new value is inserted into the collection, with the key being dependent upon the type of collection (List or Map). The optional List key is the index and the mandatory Map key. The List key is the index and the Map key is the key information used in the map's key/value pair. |
void updated(Object key, Object value) | This method is called when an existing value is updated within the collection, with the key being dependent upon the type of collection (List or Map). The optional List key is the index and the mandatory Map key. The List key is the index and the Map key is the key information used in the map's key/value pair. |
void removed(Object key, Object value) | This method is called when an existing value is removed from the collection, with the key being dependent upon the type of collection (List or Map). The optional List key is the index and the mandatory Map key. The List key is the index, and the Map key is the key information used in the map's key/value pair. |
org.overlord.rtgov.active.collection.AbstractActiveChangeListener abstract class, then it can be registered with the Active Collection Source configuration, and automatically initialized when the source is registered. The benefit of this approach is that it does not require the user to write custom code to register the Active Collection Listener against the Active Collection. An example of this type of implementation is the org.overlord.rtgov.active.collection.jmx.JMXNotifier, which automatically generates JMX notifications when an object is added to the associated active collection. The implementations derived from this abstract active change listener implementation are no different from other active change listener implementations, with the exception that they can be serialized as part of the Active Collection Source configuration. Also, they support the following lifecycle methods for initialization and closing:
Table 3.45. Abstract Implementation Methods
| Method | Description |
|---|---|
void init() | This method can be overridden to initialize the active change listener implementation. The super class init() method MUST be called first. |
void close() | This method can be overridden to close the active change listener implementation. The super class close() method MUST be called first. |
3.6.8. Accessing Active Collections
3.6.8.1. Retrieving an Active Collection
- Directly accessing the ActiveCollectionManagerActive Collections are created as a bi-product of registering an Active Collection Source. The Active Collection Source is registered with an Active Collection Manager, which creates the collection to be updated from the source. This Active Collection then becomes available for applications to retrieve from the manager. here is an example:
import org.overlord.rtgov.active.collection.ActiveCollectionManager; import org.overlord.rtgov.active.collection.ActiveCollectionManagerAccessor; import org.overlord.rtgov.active.collection.ActiveList; ..... ActiveCollectionManager acmManager=ActiveCollectionManagerAccessor.getActiveCollectionManager(); ActiveList list = (ActiveList) acmManager.getActiveCollection(listName);This approach is used to retrieve the top level active collections. These are the collections directly maintained by the Active Collection Manager, each with an associated Active Collection Source defining the origin of the collection changes. The maven dependency required to access the ActiveCollectionManager and active collections is:<dependency> <groupId>org.overlord.rtgov.active-queries</groupId> <artifactId>active-collection</artifactId> <version>${rtgov.version}</version> <scope>provided</scope> </dependency> - Using Injectable Collection ManagerUsing Injectable Collection Manager approach is aimed at simplifying the use of active collections from within a client application. It offers a simple API, and associated default implementation, that can be injected using CDI. Here is an example:
@Inject private org.overlord.rtgov.client.CollectionManager _collectionManager=null; private org.overlord.rtgov.active.collection.ActiveMap _principals=null; protected void init() { if (_collectionManager != null) { _principals = _collectionManager.getMap(PRINCIPALS); } ....... }If injection is not possible (for example, when using SwitchYard Interceptors), then a default implementation can be directly instantiated with the classorg.overlord.rtgov.client.DefaultCollectionManager. The maven dependencies required to access the CollectionManager, and the subsequent active collections are:<dependency> <groupId>org.overlord.rtgov.integration</groupId> <artifactId>rtgov-client</artifactId> <version>${rtgov.version}</version> </dependency> <dependency> <groupId>org.overlord.rtgov.active-queries</groupId> <artifactId>active-collection</artifactId> <version>${rtgov.version}</version> <scope>provided</scope> </dependency>
3.6.8.2. Creating a Derived Active Collection
- parent: The parent collection from which the child may be derived. Although this is generally the name of a top level collection, it is possible to derive a collection from another child collection, forming a tree.
- predicate: A predicate is specified to determine whether information in a parent collection (and subsequently its changes), are relevant to the child collection or not.
- properties: Properties are used to initialize the derived collection.
import org.overlord.rtgov.active.collection.predicate.Predicate;
import org.overlord.rtgov.active.collection.ActiveCollectionManager;
import org.overlord.rtgov.active.collection.ActiveList;
.....
Predicate predicate=.....;
ActiveList parent = (ActiveList)acmManager.getActiveCollection(parentName);
if (parent != null) {
java.util.Map<String,Object> properties=.....;
alist = (ActiveList)acmManager.create(childName,
parent, predicate, properties);
}}
3.6.8.3. Registering for Active Change Notifications
addActiveChangeListener method on the collection, and similarly use the removeActiveChangeListener method to unregister for change notifications. Here is an example:
import org.overlord.rtgov.active.collection.ActiveList;
import org.overlord.rtgov.active.collection.ActiveChangeListener;
.....
ActiveList list=.....;
list.addActiveChangeListener(new ActiveChangeListener() {
public void inserted(Object key, Object value) {
....
}
public void updated(Object key, Object value) {
....
}
public void removed(Object key, Object value) {
....
}
});

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.