Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

No Format
SchemaTypeData:
SchemaTypeEvent:

These types may be represented by the strings "data" and "event", respectively.

Schema Identifier

Schema are identified by a combination of their package name and class name. A hash value over the body of the schema provides a revision identifier. The class SchemaClassKey SchemaClassId represents this Schema identifier.

No Format
class SchemaClassKeySchemaClassId:
      <constructor>( package=<package-name-str>, 
                     class=<class-name-str>,
                     hash=<hash-str, format="%08x-%08x-%08x-%08x">, 
type=<SchemaTypeData|SchemaTypeEvent>)
                     hash=<hash-str,  type=<SchemaTypeData|SchemaTypeEvent>)format="%08x-%08x-%08x-%08x">, 
      .getPackageName(): returns <package-name-str>
      .getClassName(): returns <class-name-str>
      .getHashString(): returns <hash-str, "%08x-%08x-%08x-%08x">
      .getType(): returns SchemaTypeObject or SchemaTypeEvent

Schema for describing data Properties

The SchemaProperty class represents the description of a property datum. Once instantiated, the SchemaProperty is immutable.

No Format
class SchemaProperty:
      .mapEncode(): returns a map encoding of the instance.

If the hash is not supplied, then the default value "00000000-00000000-00000000-00000000" will be supplied. This may be the case when a SchemaClass is being dynamically constructed, and a proper hash is not yet available.

The map encoding of a SchemaClassId:

Index

Optional

Type

Description

"package_name"

N

string

The name of the associated package.

"class_name"

N

string

The name of the class within the package.

"type"

N

string

The type of schema, either "data" or "event".

"hash_str"

Y

string

The MD5 hash of the schema, in the format "%08x-%08x-%08x-%08x"

Schema for describing data Properties

The SchemaProperty class represents the description of a property datum. Once instantiated, the SchemaProperty is immutable.

No Format

class SchemaProperty:
      <constructor>( name=<name-value>, 
                     type=<type-value>,
                     ...)
      .getName(): name of property (string)
      .getType(): typecode for property data
      .getAccess(): "RC"=read/create, "RW"=read/write, "RO"=read only (default)<constructor>( name=<name-value>, 
                     type=<type-value>,
                     ...)
      .getName(): name of property (string)
      .getType(): typecode for property data
      .getAccess(): 1=read/create, 2=read/write, 3=read only
      .getIndex(): True if this property is an index.
      .isOptional(): True if this property is optional
      .getUnit(): string describing units (optional)
      .getMin(): minimum value (optional)
      .getMax(): maximum value (optional)
      .getMaxLen(): maximum length for string values (optional)
      .getDesc(): optional string description of this Property
      .getReference(): if type==objId, name (str) of referenced class
                       (optional) 
      .getParentRefisIndex(): True if this property referencesis an object inindex.
              .isOptional(): True if this property is optional
      .getUnit(): string describing which this object is in a child-parent
    units (optional)
      .getMin(): minimum value (optional)
      .getMax(): maximum value (optional)
      .getMaxLen(): maximum length for  relationship.

Schema for describing a Statistic

The SchemaStatistic class represents the description of a statistic datum. Once instantiated, the SchemaStatistic is immutable.

No Format

class SchemaStatistic:string values (optional)
      <constructor>.getDesc( name=<name-value>, 
    ): optional string description of this Property
      .getReference(): if type==objId, name (str) of referenced class
    type=<type-value>,
                     ... )(optional) 
      .getNameisParentRef(): True nameif ofthis theproperty statistic (string)
  references an object in
    .getType(): typecode for statistic
      .getUnit(): string describing units (optional)
      .getDesc(): string description of this statistic (optional)

Schema for describing Method Calls

The Schema for describing a method call involves two classes. The SchemaMethod class describes the method's structure, and contains a SchemaArgument class for each argument declared by the method. An Agent may construct a SchemaMethod's argument list.

No Format

class SchemaMethod:
      <constructor>( name=<name-value>,which this object is in a child-parent
                     [args=<list of SchemaArguments>]relationship.
      .getNamemapEncode(): namereturns ofa method
map encoding of the instance.

The map encoding of a SchemaProperty:

Index

Optional

Type

Description

"name"

N

string

The name of the property.

"type"

N

integer

The QMF type code indicating property's data type.

"access"

Y

string

The access allowed to this property, default "RO"

"index"

Y

boolean

True if this property is an index value, default False

"optional"

Y

boolean

True if this property is optional, default False

"unit"

Y

string

Description of the units used to express this property.

"min"

Y

integer

The minimum allowed value for this property

"max"

Y

integer

The maximun allowed value for this property

"maxlen"

Y

integer

For string types, this is the maximum length in
bytes required to represent the longest permittable instance of this string.

"desc"

Y

string

Human-readable description of this property.

"reference"

Y

string

unknown?

"parent_ref"

Y

boolean

True if this property references an object
in which this object is in a child-parent relationship. Default False

Schema for describing a Statistic

The SchemaStatistic class represents the description of a statistic datum. Once instantiated, the SchemaStatistic is immutable.

No Format

class SchemaStatistic:
      <constructor>( name=<name-value>, 
                     type=<type-value>,
                     ... )
      .getName(): name of the statistic (string  .getArgCount(): count of arguments
      .getArguments(): returns a list of SchemaArgument instances, one
                       for each argument.
      .getArg(index): return the SchemaArgument at index 
      .addArgument(SchemaArgument): adds a SchemaArgument 


class SchemaArgument:
      <constructor>( name=<name-value>,
                     type=<type-value>,
                     ...)
      .getName(): name of argument
      .getType(): type of argument
      .getDirection(): "I"=input, "O"=output, or "IO"=input/output
      .getUnit(): string describing units (optional)
      .getMin(): minimum value (optional)
      .getMax(): maximum value (optional)
      .getMaxLengetType(): maximum length for string values typecode for statistic
      .getUnit(): string describing units (optional)
      .getDesc(): string description of this argumentstatistic (optional)
      .getDefaultmapEncode(): returns default value.

Schema for Data Objects and Events

A top-level data object in QMF is a collection of statistics, properties, and methods. Data objects are described by the class SchemaObjectClass. Data objects may be managed (owned) by an Agent.

Events describe a change within the underlying management system. Unlike data objects, events do not correspond to a managable entity. They are composed of a list of arguments that apply to the event. Event objects are described by the class SchemaEventClass.

Both of these classes derive from the virtual base SchemaClass.

a map encoding of the instance.

The map encoding of a SchemaStatistic:

Index

Optional

Type

Description

"name"

N

string

The name of the statistic.

"type"

N

integer

The QMF type code indicating statistic's data type.

"unit"

Y

string

Description of the units used to express this statistic.

"desc"

Y

string

Human-readable description of this statistic.

Schema for describing Method Calls

The Schema for describing a method call involves two classes. The SchemaMethod class describes the method's structure, and contains a SchemaArgument class for each argument declared by the method. An Agent may construct a SchemaMethod's argument listAgent applications may dynamically construct instances of these objects by adding properties/statistics/methods/etc. at run time. However, once the Schema is published, it must be considered immutable, as the hash value must be constant once the Schema is in use.

No Format
class SchemaClassSchemaMethod:
      .getType<constructor>(): return SchemaTypeObject or SchemaTypeEvent
 name=<name-value>,
         .getClassKey(): return the SchemaClassKey that identifies this
      [args=<list of SchemaArguments>]
      .getName(): name of method
     Schema instance..getArgCount(): count of arguments
      .generateHashgetArguments(): generatereturns a hash over the body of the schema,
list of SchemaArgument instances, one
                       for each argument.
  and return a string representation of .getArg(index): return the hash
SchemaArgument at index 
      .addArgument(SchemaArgument): adds a SchemaArgument 
      .mapEncode(): returns a map inencoding formatof  "%08x-%08x-%08x-%08x"the instance.



class SchemaObjectClass(SchemaClass)SchemaArgument:
      <constructor>(?tbd?) name=<name-value>,
      .getPropertyCount(): return the number of properties.
             .getStatisticCount(): return the number of statistics.
  type=<type-value>,
                .getMethodCount(): return the number of methods...)
      .getPropertygetName(index): returnname the index'th SchemaProperty.of argument
      .getStatisticgetType(index): returntype the index'th SchemaStatistic.of argument
      .getMethodgetDirection(index): return the index'th SchemaMethod

"I"=input, "O"=output, or "IO"=input/output
      .addPropertygetUnit(SchemaProperty): appendstring adescribing newunits property(optional)
      .addStatisticgetMin(SchemaStatistic): appendminimum a new statisticvalue (optional)
      .addMethodgetMax(SchemaMethod): append a new method.


class SchemaEventClass(SchemaClass):
      <constructor>(?tbd? maximum value (optional)
      .getMaxLen(): maximum length for string values (optional)
      .getArgCountgetDesc(): string returndescription theof countthis of arguments.argument (optional)
      .getArgumentgetDefault(index): return the index'th SchemaArgumentdefault value.

      .addArgumentgetRefPackage(SchemaArgument): append a new argument.

Data Model

The QMF defines three layers of data representation:

  1. arbitrarily structured data
  2. structured data
  3. managed structured data

Arbitrarily structured data is represented by a map of named data items. There is no schema associated with this data, as its structure is arbitrary. This class of data is represented by the QmfData class.

Data that has a formally defined structure is represented by the QmfDescribed class. This class extends the QmfData class by associating the data with a formal schema.

Managed structured data extends the concept of structured data by providing an owner for the data. In QMF, this owner is an Agent. This class of data extends the QmfDescribed class by adding an identifier of the owning Agent.

QmfData Class

No Format

class QmfData:
      <constructor>( map of "name=value" pairs )

QmfDescribed Class

No Format

class QmfDescribed(QmfData):
      <constructor>( class QmfData, class SchemaClassKey )
      .getSchemaClassKey(): returns the identifier of the Schema that
                            describes the structure of the data.
      .getIndex(): return a string composed from "index" property
                   values. 
      .getProperties(): return a list of (SchemaProperty, value) pairs
                        for each of the object's properties.
      .getStatistics(): return a list of (SchemaStatistics, value)
                        pairs for each of the object's statistics.

QmfManaged Class

The QmfManaged class represents a data object that is owned by a particular Agent. All QmfManaged objects contain a unique object identifier.

The QmfManaged class extends the QmfDescribed class:

No Format

class QmfManaged(QmfDescribed):
      .getObjectId(): return ObjectId for this object.
Object Identification

An instance of managed object must be uniquely identified within the management system. Each managed object is given a name that is unique within the domain of the object's managing Agent. Note that these names are not unique across Agents. Therefore, a globally unique name for an instance of a managed object is the concatenation of the object's name and the managing Agent's name. This unique object identifier is represented by the ObjectId class.

ObjectIds are considered hashable. That is, it is a requirement that ObjectIds are deterministically sortable.

 return name of the package referenced by this argument
      .getRefClass(): return name of the class referenced by this argument
      .mapEncode(): returns a map encoding of the instance.

The map encoding of a SchemaArgument:

Index

Optional

Type

Description

"name"

N

string

The name of the argument.

"type"

N

integer

The QMF type code indicating the argument's data type.

"dir"

N

string

Direction for an argument when passed to a Method call: "I", "O", "IO", default value: "I"

"default"

Y

based on "type"

Default value to use if none provided.

"unit"

Y

string

Description of the units used to express this argument.

"min"

Y

integer

The minimum allowed value for this argument

"max"

Y

integer

The maximun allowed value for this argument

"maxlen"

Y

integer

For string types, this is the maximum length in bytes required to represent the longest permittable instance of this string.

"desc"

Y

string

Human-readable description of this argument.

"ref_package"

Y

string

Name of package referenced by this argument.

"ref_class"

Y

string

Name of class referenced by this argument.

The map encoding of a SchemaMethod:

Index

Optional

Type

Description

"name"

N

string

The name of the method.

"arguments"

Y

list

Ordered list of maps, one for each argument to the method.

"desc"

Y

string

Human-readable description of this method.

Schema for Data Objects and Events

A top-level data object in QMF is a collection of statistics, properties, and methods. Data objects are described by the class SchemaObjectClass. Data objects may be managed (owned) by an Agent.

Events describe a change within the underlying management system. Unlike data objects, events do not correspond to a managable entity. They are composed of a list of arguments that apply to the event. Event objects are described by the class SchemaEventClass.

Both of these classes derive from the virtual base SchemaClass.

Agent applications may dynamically construct instances of these objects by adding properties/statistics/methods/etc. at run time.However, once the Schema is published, it must be considered immutable, as the hash value must be constant once the Schema is in use.

No Format

class SchemaClass:
      <constructor>( package=<package-name-str>
No Format

class ObjectId:
      <constructor>(agent="agent name", 
                    name="object name")
 class=<class-name-str>,
       .getAgentName(): returns <agent name> string.
      .getObjectName(): returns <object name> string.
 type=<SchemaTypeData|SchemaTypeEvent>)
       .operators(==, !=, <, >) supported.

QmfEvent Class

A QMF Event is a type of QmfDescribed data that is not managed. Events are notifications that are sent by Agents. Unlike QmfManaged objects, events do not correspond to managed data on the Agent. Instead, an event notifies a Console of a change in some aspect of the system under managment. For example, an event may indicate that a threshold was exceeded, or a resource was returned. The structure of an event is described by the SchemaEventClass. An instance of an event is represented by the QmfEvent class.

No Format

class QmfEvent(QmfDescribed):
      <constructor>( timestamp, argument_list )
      .getTimestamp(): return a timestamp indicating when the Event
              hash=<hash-str, format="%08x-%08x-%08x-%08x">)
      .getClassId(): return the SchemaClassId that identifies this
                      Schema instance.
      .generateHash(): generate a hash over the body of the schema,
                       and return a string representation of the hash
                        triggered.in format  "%08x-%08x-%08x-%08x"
      .getArgumentsmapEncode(): returnreturns a listmap encoding of (SchemaArgument, value) pairsthe instance.


class SchemaObjectClass(SchemaClass):
      .getArgument(<name>): return the value of argument <name>
<constructor>( package=<package-name-str>, 
             ?tbd? do we need to identify the originating Agent?

Data Management

The role of a QMF component determines how it will interact with managment data. Therefore the QmfManaged class is subclassed to provide an Agent specific implementation and a Console specific implementation.

The Console application represents a managed data object by the QmfConsoleData class. The Console has "read only" access to the statistics and properties in the data object via this class. The Console can also invoke the methods defined by the object via this class. The actual data stored in this object is cached from the Agent. In order to update the cached values, the Console invokes the refresh() method.

Note that the refresh() and invokeMethod() methods require communication with the remote Agent. As such, they may block. For these two methods, the Console has the option of blocking in the call until the call completes. Optionally, the Console can receive a notification asynchronously when the operation is complete. See below for more detail regarding synchronous and asynchronous API calls.

No Format

class QmfConsoleData(QmfManaged):
      <constructor>(?tbd?)
      .getTimestamps(): returns a list of timestamps describing theclass=<class-name-str>,
                     type=<SchemaTypeData|SchemaTypeEvent>)
                     hash=<hash-str, format="%08x-%08x-%08x-%08x">,
                     _properties=[list of SchemaProperty instances],
                        lifecycle _stats=[list of the object:SchemaStatistics instances],
                     _methods=[list of SchemaMethod [0] = time of last update from Agent,instances])
      .getPropertyCount(): return the number of properties.
      .getStatisticCount(): return the number    [1] = creation timestamp of statistics.
      .getMethodCount(): return the number of methods.
      .getProperty(index): return the   index'th SchemaProperty.
  [2] = deletion timestamp, or zero if not deleted .getStatistic(index): return the index'th SchemaStatistic.
      .isDeletedgetMethod(index): True if deletion timestamp not zero.return the index'th SchemaMethod

      .addProperty(SchemaProperty): append a new property
      .refresh([reply-handle | timeout]addStatistic(SchemaStatistic): requestappend thata thenew Agentstatistic
      .addMethod(SchemaMethod): append a new method.


class SchemaEventClass(SchemaClass):
      <constructor>( package=<package-name-str>, 
 update the value of this object's contents.
      .invokeMethod(name, inArgs[], [[reply-handle] | [timeout]]): 
      class=<class-name-str>,
                     type=<SchemaTypeData|SchemaTypeEvent>)
        invoke the named method.
             hash=<hash-str, format="%08x-%08x-%08x-%08x">,
        .getStatistic(name): return the value             _arguments=[list of the named statisticSchemaArgument instances])
      .getPropertygetArgCount(name): return the valuecount of thearguments.
 named property.

The Agent that manages the data represents it by the QmfAgentData class. The Agent is responsible for managing the values of the properties and statistics within the object, as well as servicing the object's method calls. Unlike the Console, the Agent has full control of the state of the object.

More ?tbd?

No Format

class QmfAgentObject(QmfObject):
      <constructor>( ObjectId, ?tbd?)     .getArgument(index): return the index'th SchemaArgument.

      .destroyaddArgument(SchemaArgument): markappend thea object as deleted by setting the deletion
                  timestamp to the current time.
      .setObjectId(ObjectId): set the value of the ObjectId.
      .setProperty(name, value): update the value of the property.
      .setStatistic(name, value): set the value of a statistic.
      .incStatistic(name, delta): add the delta to the statistic.
      .decStatistic(name, delta): subtract the delta from the statistic.
      ?tbd?

Note that some languages will allow properties, statistics, and methods to act as attributes of the QmfObject itself. As an example, assume an QmfConsoleObject exists with a property named "state". In python, it will be possible to access the value of "state" as if it where an attribute of the QmfConsoleObject. The following two statements are equivalent:

new argument.

The map encoding of a SchemaObjectClass:

Index

Optional

Type

Description

"class_id"

N

map

Map containing the SchemaClassId for this object.

"properties"

Y

list

Ordered list of SchemaProperty maps. One map for each property in this object.

"statistics"

Y

list

Ordered list of SchemaStatistics maps. One map for each statistic in this object.

"methods"

Y

list

Ordered list of SchemaMethod maps. One map for each method in this object.

The map encoding of a SchemaEventClass:

Index

Optional

Type

Description

"class_id"

N

map

Map containing the SchemaClassId for this object.

"arguments"

Y

list

Order list of SchemaArgument maps, one map for each argument in this event.

Data Model

The QMF defines three layers of data representation:

  1. arbitrarily structured data
  2. structured data
  3. managed structured data

Arbitrarily structured data is represented by a map of named data items. There is no schema associated with this data, as its structure is arbitrary. This class of data is represented by the QmfData class.

Data that has a formally defined structure is represented by the QmfDescribed class. This class extends the QmfData class by associating the data with a formal schema.

Managed structured data extends the concept of structured data by providing an owner for the data. In QMF, this owner is an Agent.This class of data extends the QmfDescribed class by adding an identifier of the owning Agent.

QmfData Class

No Format

class QmfData:
      <constructor>( map of "name=value" pairs )

QmfDescribed Class

No Format

class QmfDescribed(QmfData):
      <constructor>( class QmfData, class SchemaClassId )
      .getSchemaClassId(): returns the identifier of the Schema that
 
No Format

           print("My state is '%s'" %
                 myQmfConsoleObject.getProperty("state"))

           print("My state is '%s'" %
            describes the structure of the myQmfConsoleObject.state)

Be aware - a QmfConsoleObject provides read-only access, so the following statement would be illegal:

No Format
data.
      .getIndex(): return a string composed myQmfConsoleObject.state =from "upindex"
Invoking Methods

A managed object's methods provide a mechanisms for a Console application to perform a "remote procedure call" against the object. The method actually executes on the Agent, and the result is passed back to the Console on completion.

The value(s) returned to the Console when the method call completes are represented by the MethodResult class. The MethodResult class indicates whether the method call succeeded or not, and, on success, provides access to all data returned by the method call.

Should a method call result in a failure, this failure is indicated by the presence of a QmfData object in the MethodResult. This object is described as an "exception", and contains a description of the reason for the failure. There are no returned arguments when a method call fails.

A successful method invokation is indicated by the absence of an exception in the MethodResult. In addition, a map of returned argument values may be present. The structure of the returned arguments is described by the SchemaArgument list associated with the MethodSchema that defines the method. The map contains only those arguments that the SchemaArgument marks with an "output" direction.

 property
                   values. 
      .getProperties(): return a list of (SchemaProperty, value) pairs
                        for each of the object's properties.
      .getStatistics(): return a list of (SchemaStatistics, value)
                        pairs for each of the object's statistics.

QmfManaged Class

The QmfManaged class represents a data object that is owned by a particular Agent. All QmfManaged objects contain a unique object identifier.

The QmfManaged class extends the QmfDescribed class:

No Format

class QmfManaged(QmfDescribed):
No Format

class MethodResult:
      <constructor>( QmfData <exception> | <argument-map> )
      .getExceptiongetObjectId(): returnsreturn exceptionObjectId datafor ifthis method fails.
      .getArgumentCount(): returns number of arguments.
      .getArguments(): returns a list of (SchemaArgument, value) pairs
         object.
Object Identification

An instance of managed object must be uniquely identified within the management system. Each managed object is given a name that is unique within the domain of the object's managing Agent. Note that these names are not unique across Agents. Therefore, a globally unique name
for an instance of a managed object is the concatenation of the object's name and the managing Agent's name. This unique object identifier is represented by the ObjectId class.

ObjectIds are considered hashable. That is, it is a requirement that ObjectIds are deterministically sortable.

No Format

class ObjectId:
      <constructor>(agent="agent name", 
       for each returned argument.             name="object name")
      .getArgumentgetAgentName(<name>): returns value of argument named "name".

Queries

A Query is a mechanism for interrogating the management database. A Query represents a selector which is sent to an Agent. The Agent applies the Query against the management database, and returns those objects which meet the constraints contained in the query.

 <agent name> string.
      .getObjectName(): returns <object name> string.
      .operators(==, !=, <, >) supported.

QmfEvent Class

A QMF Event is a type of QmfDescribed data that is not managed.
Events are notifications that are sent by Agents. Unlike QmfManaged objects, events do not correspond to managed data on the Agent. Instead, an event notifies a Console of a change in some
aspect of the system under managment. For example, an event may indicate that a threshold was exceeded, or a resource was returned. The structure of an event is described by the SchemaEventClass. An instance of an event is represented by the QmfEvent class.

No Format

class QmfEvent(QmfDescribed)
No Format

class Query:
      <constructor>(<SchemaClassKey> |  timestamp, argument_list )
      .getTimestamp(): return a timestamp indicating when the Event
       <ObjectId> | 
              triggered.
      <package-name>[, <class-name>])
      .getSchemaClassKey().getArguments(): return a list of (SchemaArgument, value) pairs
      .getObjectIdgetArgument(<name>): return the value of argument <name>
      .getPackageName()
      .getClassName()

The target for a Query is determined by the constructor. When a Query is created using a SchemaClassKey, it will match against the SchemaClass identified by that key. When a Query is created using an ObjectId, it will match against the QmfObject or Event identified by that ObjectId. When a Query is created with only a package name, it will return all class names that belong to that package. If both the package and class names are provided, the Query will match against the SchemaClassKey identified by the combination of those names.

Subscriptions

A subscription is a mechanism for monitoring management data for changes in its state. A Console creates a subscription with an Agent based on a Query. The Query specifies the set of management data that is to be monitored. When the Agent detects changes to the selected set, a notification is sent to the subscribing Console(s). A Subscription is represented by the SubscriptionId class. A Console must cancel the subscription when the console no longer needs to monitor the data.

?tbd? do we need to identify the originating Agent?

Data Management

The role of a QMF component determines how it will interact with managment data. Therefore the QmfManaged class is subclassed to provide an Agent specific implementation and a Console specific
implementation.

The Console application represents a managed data object by the QmfConsoleData class. The Console has "read only" access to the statistics and properties in the data object via this class. The Console can also invoke the methods defined by the object via this class. The actual data stored in this object is cached from the Agent. In order to update the cached values, the Console invokes the refresh() method.

Note that the refresh() and invokeMethod() methods require communication with the remote Agent. As such, they may block. For these two methods, the Console has the option of blocking in the call until the call completes. Optionally, the Console can receive a notification asynchronously when the operation is complete. See below for more detail regarding synchronous and asynchronous API calls.

No Format

class QmfConsoleData(QmfManaged)
No Format

class SubscriptionId:
      <constructor>(?tbd?

Agent Identifiers

An Agent is uniquely identified by an AgentId. An AgentId is a three-tuple containing:

  • the name of the vendor that produced the agent
  • the name of the product using the agent
  • the name of the agent component within the product.

This naming convention allows for a single product to host multiple distinct Agents. The Agent identifier is represented by the AgentId class. An AgentId is considered hashable. That is, it is a requirement that AgentIds are deterministically sortable.

No Format

class AgentId)
      .getTimestamps(): returns a list of timestamps describing the
                        lifecycle of the object:
      <constructor>( vendor, product, name )
      .getVendor(): return the vendor name string
   [0] = time .getProduct(): return the product name stringof last update from Agent,
                        [1] = creation timestamp 
                        [2] = deletion timestamp, or zero if not deleted.
      .getNameisDeleted(): True returnif agentdeletion componenttimestamp namenot string

By convention, AgentIds are specified as a string containing the vendor, product, and name strings separated by colons ":", in that order. For example: "company.com:OurProduct:AnAgent"

Console application model

A QMF console component is represented by a Console class. This class is the topmost object of the console application's object model.

A Console is composed of the following objects:

  • a connection to the AMQP bus
  • a queue of inbound work items
  • a collection of all known schemas
  • a list of all known remote Agents
  • a cache of QmfConsoleObject proxies

The connection to the AMQP bus is used to communicate with remote Agents. The queue is used as a source for notifications coming from remote Agents.

Asychronous event model.

The original QMF API defined a set of callback methods that a Console application needed to provide in order to process asynchronous QMF events. Each asynchonous event defined its own callback method.

The new API replaces this callback model with a work-queue approach. All asynchronous events are represented by a WorkItem object. When a QMF event occurs it is translated into a WorkItem object and placed in a FIFO queue. It is left to the console application to drain this queue as needed.

This new API does require the console application to provide a single callback. The callback is used to notify the console application that WorkItem object(s) are pending on the work queue. This callback is invoked by QMF when the work queue transitions from the empty to the non-empty state. To avoid any potential threading issues, the console application is not allowed to call any QMF API from within the callback context. The purpose of the callback is to allow the console application to schedule itself to drain the work queue at the next available opportunity.

For example, a console application may be designed using a select() loop. The application waits in the select() for any of a number of different descriptors to become ready. In this case, the callback could be written to simply make one of the descriptors ready, and then return. This would cause the application to exit the wait state, and start processing pending events.

The callback is represented by the Notifier virtual base class. This base class contains a single method. A console application derives a custom handler from this class, and makes it available to the Console object.

No Format

class Notifier:
    .consoleIndication():  Called when the console's internal work
    queue becomes non-empty due to the arrival of one or more
    WorkItems. This method may be called by the internal console
    management thread - it is illegal to invoke any QMF APIs from
    within this callback.  Its purpose is to indicate that the console
    application should schedule itself to process the work items. 

The WorkItem class represents a single notification event that is read from the work queue:

No Format

class WorkItem:
    #
    # Enumeration of the types of WorkItems produced by the Console
    #
    AGENT_ADDED = 1
    AGENT_DELETED = 2
    NEW_PACKAGE = 3
    NEW_CLASS = 4
    OBJECT_UPDATE = 5
    EVENT_RECEIVED = 7
    AGENT_HEARTBEAT = 8

    .getType(): Identifies the type of work item by returning one of
    the above type codes. 

    .getHandle(): return the handle for an asynchronous operation, if present.

    .getParams(): Returns the data payload of the work item.  The type
    of this object is determined by the type of the workitem (?TBD?). 

Local representation of a remote Agent.

The console application maintains a list of all known remote Agents. Each Agent is represented by the Agent class:

No Format

class Agent:
      <constructor>( AgentId )
      .getName(): returns the AgentId
      ?tbd?

The Console Object.

The Console class is the top-level object used by a console application. All QMF console functionality is made available by this object. A console application must instatiate one of these objects.

As noted below, some Console methods require contacting a remote Agent. For these methods, the caller has the option to either block for a (non-infinite) timeout waiting for a reply, or to allow the method to complete asynchonously. When the asynchronous approach is used, the caller must provide a unique handle that identifies the request. When the method eventually completes, a WorkItem will be placed on the work queue. The WorkItem will contain the handle that was provided to the corresponding method call.

All blocking calls are considered thread safe - it is possible to have a multi-threaded implementation have multiple blocking calls in flight simultaneously.

If a name is supplied, it must be unique across all Consoles attached to the AMQP bus. If no name is supplied, a unique name will be synthesized in the format: "qmfc-<hostname>.<pid>"

zero.
      .refresh([reply-handle | timeout]): request that the Agent
                    update the value of this object's contents.
      .invokeMethod(name, inArgs[], [[reply-handle] | [timeout]]): 
                          invoke the named method.
      .getStatistic(name): return the value of the named statistic
      .getProperty(name): return the value of the named property.

The Agent that manages the data represents it by the QmfAgentData class. The Agent is responsible for managing the values of the properties and statistics within the object, as well as
servicing the object's method calls. Unlike the Console, the Agent has full control of the state of the object.

No Format

class QmfAgentObject(QmfObject):
      <constructor>( ObjectId, ?tbd?)
      .destroy(): mark the object as deleted by setting the deletion
                  timestamp to the current time.
      .setObjectId(ObjectId): set the value of the ObjectId.
      .setProperty(name, value): update the value of the property.
      .setStatistic(name, value): set the value of a statistic.
      .incStatistic(name, delta): add the delta to the statistic.
      .decStatistic(name, delta): subtract the delta from the statistic.
      ?tbd?

Note that some languages will allow properties, statistics, and methods to act as attributes of the QmfObject itself. As an example, assume an QmfConsoleObject exists with a property named "state". In python, it will be possible to access the value of "state" as if it where an attribute of the QmfConsoleObject. The following two statements are equivalent:

No Format

           print("My state is '%s'" %
                 myQmfConsoleObject.getProperty("state"))

           print("My state is '%s'" %
                 myQmfConsoleObject.state)

Be aware - a QmfConsoleObject provides read-only access, so the
following statement would be illegal:

No Format

           myQmfConsoleObject.state = "up"
Invoking Methods

A managed object's methods provide a mechanisms for a Console application to perform a "remote procedure call" against the object. The method actually executes on the Agent, and the result is passed back to the Console on completion.

The value(s) returned to the Console when the method call completes are represented by the MethodResult class. The MethodResult class indicates whether the method call succeeded or not, and, on success, provides access to all data returned by the method call.

Should a method call result in a failure, this failure is indicated by the presence of a QmfData object in the MethodResult. This object is described as an "exception", and contains a description of the reason for the failure. There are no returned arguments when a method call fails.

A successful method invokation is indicated by the absence of an exception in the MethodResult. In addition, a map of returned argument values may be present. The structure of the returned
arguments is described by the SchemaArgument list associated with the MethodSchema that defines the method. The map contains only those arguments that the SchemaArgument marks with an "output" direction.

No Format

class MethodResult:
      <constructor>( QmfData <exception> | <argument-map> )
      .getException(): returns exception data if method fails.
      .getArgumentCount(): returns number of arguments.
      .getArguments(): returns a list of (SchemaArgument, value) pairs
                       for each returned argument.
      .getArgument(<name>): returns value of argument named "name".

Queries

A Query is a mechanism for interrogating the management database. A Query represents a selector which is sent to an Agent. The Agent applies the Query against the management database, and returns those objects which meet the constraints contained in the query.

No Format

class Query:
      <constructor>(<SchemaClassId> | 
                    <ObjectId> | 
                    <package-name>[, <class-name>])
      .getSchemaClassId()
      .getObjectId()
      .getPackageName()
      .getClassName()

The target for a Query is determined by the constructor. When a Query is created using a SchemaClassId, it will match against the SchemaClass identified by that key. When a Query is created using an ObjectId, it will match against the QmfObject or Event identified by
that ObjectId. When a Query is created with only a package name, it will return all class names that belong to that package. If both the package and class names are provided, the Query will match against the SchemaClassId identified by the combination of those names.

Subscriptions

A subscription is a mechanism for monitoring management data for changes in its state. A Console creates a subscription with an Agent based on a Query. The Query specifies the set of management data that is to be monitored. When the Agent detects changes to the selected set, a notification is sent to the subscribing Console(s). A Subscription is represented by the SubscriptionId class. A Console must cancel the subscription when the console no longer needs to monitor the data.

No Format

class SubscriptionId:
      ?tbd?

Agent Identifiers

An Agent is uniquely identified by an AgentId. An AgentId is a three-tuple containing:

  • the name of the vendor that produced the agent
  • the name of the product using the agent
  • the name of the agent component within the product.

This naming convention allows for a single product to host multiple distinct Agents. The Agent identifier is represented by the AgentId class. An AgentId is considered hashable. That is, it is a requirement that AgentIds are deterministically sortable.

No Format

class AgentId:
      <constructor>( vendor, product, name )
      .getVendor(): return the vendor name string
      .getProduct(): return the product name string
      .getName(): return agent component name string

By convention, AgentIds are specified as a string containing the vendor, product, and name strings separated by colons ":", in that order. For example: "company.com:OurProduct:AnAgent"

Console application model

A QMF console component is represented by a Console class. This class is the topmost object of the console application's object model.

A Console is composed of the following objects:

  • a connection to the AMQP bus
  • a queue of inbound work items
  • a collection of all known schemas
  • a list of all known remote Agents
  • a cache of QmfConsoleObject proxies

The connection to the AMQP bus is used to communicate with remote Agents. The queue is used as a source for notifications coming from remote Agents.

Asychronous event model.

The original QMF API defined a set of callback methods that a Console application needed to provide in order to process asynchronous QMF events. Each asynchonous event defined its own callback method.

The new API replaces this callback model with a work-queue approach. All asynchronous events are represented by a WorkItem object. When a QMF event occurs it is translated into a WorkItem object and placed in a FIFO queue. It is left to the console application to drain this queue as needed.

This new API does require the console application to provide a single callback. The callback is used to notify the console application that WorkItem object(s) are pending on the work queue. This callback is invoked by QMF when the work queue transitions from the empty to the non-empty state. To avoid any potential threading issues, the console application is not allowed to call any QMF API from within the callback context. The purpose of the callback is to allow the console
application to schedule itself to drain the work queue at the next available opportunity.

For example, a console application may be designed using a select() loop. The application waits in the select() for any of a number of different descriptors to become ready. In this case, the callback could be written to simply make one of the descriptors ready, and then
return. This would cause the application to exit the wait state, and start processing pending events.

The callback is represented by the Notifier virtual base class. This base class contains a single method. A console application derives a custom handler from this class, and makes it available to the Console object.

No Format

class Notifier:
    .indication():  Called when the internal work queue becomes
    non-empty due to the arrival of one or more WorkItems. This method
    will be called by the internal QMF management thread - it is
    illegal to invoke any QMF APIs from within this callback.  The
    purpose of this callback is to indicate that the application
    should schedule itself to process the work items.  

The WorkItem class represents a single notification event that is read
from the work queue:

No Format

class WorkItem:
    #
    # Enumeration of the types of WorkItems produced by the Console
    #
    AGENT_ADDED = 1
    AGENT_DELETED = 2
    NEW_PACKAGE = 3
    NEW_CLASS = 4
    OBJECT_UPDATE = 5
    EVENT_RECEIVED = 7
    AGENT_HEARTBEAT = 8

    .getType(): Identifies the type of work item by returning one of
    the above type codes. 

    .getHandle(): return the handle for an asynchronous operation, if present.

    .getParams(): Returns the data payload of the work item.  The type
    of this object is determined by the type of the workitem (?TBD?). 

Local representation of a remote Agent.

The console application maintains a list of all known remote Agents. Each Agent is represented by the Agent class:

No Format

class Agent:
      <constructor>( AgentId )
      .getName(): returns the AgentId
      ?tbd?

The Console Object.

The Console class is the top-level object used by a console application. All QMF console functionality is made available by this object. A console application must instatiate one of these objects.

As noted below, some Console methods require contacting a remote Agent. For these methods, the caller has the option to either block for a (non-infinite) timeout waiting for a reply, or to allow the method to complete asynchonously. When the asynchronous approach is used, the caller must provide a unique handle that identifies the request. When the method eventually completes, a WorkItem will be placed on the work queue. The WorkItem will contain the handle that was provided to the corresponding method call.

All blocking calls are considered thread safe - it is possible to have a multi-threaded implementation have multiple blocking calls in flight simultaineously.

If a name is supplied, it must be unique across all Consoles attached to the AMQP bus. If no name is supplied, a unique name will be synthesized in the format: "qmfc-<hostname>.<pid>"

No Format

class Console:
      <constructor>(name=<name-str>, 
                    notifier=<class Notifier>,
                    timeout=<default for all blocking calls>,
                    subscription_duration=<default lifetime of a subscription>)

      .destroy(timeout=None): Must be called to release Console's resources.

      .addConnection(QPID Connection): Connect the console to the AMQP cloud.

      .removeConnection(conn): Remove the AMQP connection from the
          console.  Un-does the addConnection() operation, and
          releases any agents associated with the connection.  All
          blocking methods are unblocked and given a failure status.
          All outstanding asynchronous operations are cancelled
          without producing WorkItems.

      .getAddress():
          Get the AMQP address this Console is listening to (type str).

      .findAgent( class AgentId, [timeout | handle] ): Query for the
      presence of a specific agent. Returns a class Agent if the agent
      is present.  May be called blocking (with default timeout
      override), or may allow asynchronous completion (producing a
      WorkItem with the given handle).

      .enableAgentDiscovery(): Called to enable the asynchronous
          Agent Discovery process. Once enabled, AGENT_ADD work items
          can arrive on the WorkQueue.

      .disableAgentDiscovery(): Called to disable the async Agent
      Discovery process enabled by calling enableAgentDiscovery().  

      .getWorkItemCount(): Returns the count of pending WorkItems that
      can be retrieved. 

      .getNextWorkItem([timeout=0]): Obtains the next pending work
      item, or None if none available. 

      .releaseWorkItem(wi): Releases a WorkItem instance obtained by
      getNextWorkItem(). Called when the application has finished
      processing the WorkItem. 

      .getAgents(): Returns a list of available agents (class Agent)

      .getAgent( class AgentId ): Return the class Agent for the
          named agent, if known. 

      .getPackages( [class Agent] ): Returns a list of the names of
          all known packages.  If an optional Agent is provided, then
          only those packages available from that Agent are returned.

      .getClasses( [class Agent] ):  Returns a list of SchemaClassIds
          for all available Schema.  If an optional Agent is provided,
          then the returned SchemaClassIds are limited to those
          Schema known to the given Agent.

      .getSchema( class SchemaClassId [, class Agent]): Return a list
          of all available class SchemaClass across all known agents.
          If an optional Agent is provided, restrict the returned
          schema to those supported by that Agent.

      .makeObject( SchemaClassId, **kwargs ): returns an uninitialized
      instance of a QmfDescribed data object.

      .getObjects( _SchemaClassId= | _package=, _class= |
                    _objectId=,
                   [timeout=],
                   [list-of-class-Agent] ): perform a blocking query
           for QmfConsoleObjects.  Returns a list (possibly empty) of matching
           objects. The selector for the query may be either:
           * class SchemaClassId - all objects whose schema match the
                    schema identified by _SchemaClassId parameter.
           * package/class name - all objects whose schema are
                    contained by the named package and class.
           * the object identified by _objectId
           This method will block until all known agents reply, or the
                    timeout expires. Once the timeout expires, all
                    data retrieved to date is returned.  
           If a list of agents is supplied, then the query is sent to
                    only those agents.  


      .createSubscription( class Query [, duration=<secs> [, list of agents] ): creates a
            subscription using the given Query.  If a list of agents
            is provided, the Query will apply only to those agents.
            Otherwise it will apply to all active agents, including
            those discovered during the lifetime of the subscription.
            The duration argument can be used to override the
            console's default subscription lifetime for this
            subscription.  Returns a class SubscriptionId.

      .refreshSubscription( SubscriptionId [, duration=<secs>] ):
      (re)activates a subscription.  Uses the console default duration
      unless the duration is explicitly specified.

      .cancelSubscription( SubscriptionId ): terminates the
      subscription. 

Example Console Application

The following pseudo-code performs a blocking query for a particular agent.

No Format

logging.info( "Starting Connection" )
conn = Connection("localhost")
conn.connect()

logging.info( "Starting Console" )
myConsole = Console()
myConsole.addConnection( conn )

logging.info( "Finding Agent" )
myAgent = myConsole.findAgent( AgentId( "aCompany.com", "Examples", "anAgent" ), _timeout=5 )

if myAgent:
   logging.info( "Agent Found: %s" % myAgent )
else:
   logging.info( "No Agent Found!")

logging.info( "Removing connection" )
myConsole.removeConnection( conn )

logging.info( "Destroying console:" )
myConsole.destroy( _timeout=10 )

The following pseudo-code performs a non-blocking query for all agents. It completes when at least one agent is found.

No Format

class MyNotifier(Notifier):
    def __init__(self, context):
        self._myContext = context
        self.WorkAvailable = False

    def indication(self):
        print("Indication received! context=%d" % self._myContext)
        self.WorkAvailable = True

noteMe = MyNotifier( 668 )

logging.info( "Starting Connection" )
conn = Connection("localhost")
conn.connect()

myConsole = Console(notifier=noteMe)
myConsole.addConnection( conn )

myConsole.enableAgentDiscovery()
logging.info("Waiting...")


while not noteMe.WorkAvailable:
    print("No work yet...sleeping!")
    time.sleep(1)


print("Work available = %d items!" % myConsole.getWorkItemCount())
wi = myConsole.getNextWorkitem(timeout=0)
while wi:
    print("work item %d:%s" % (wi.getType(), str(wi.getParams())))
    wi = myConsole.getNextWorkitem(timeout=0)


logging.info( "Removing connection" )
myConsole.remove_connection( conn )

logging.info( "Destroying console:" )
myConsole.destroy( 10 )

Agent Application Model

A QMF agent component is represented by a instance of the Agent class. This class is the topmost object of the agent application's object model. Associated with a particular agent are

  • the set of objects managed by that agent
  • a collection of consoles that are interfacing with the agent

The Agent class communicates with the application using the same notification-based model as the console. The agent maintains a work-queue of pending requests. Each pending request is
associated with a handle. When the application is done servicing the work request, it passes the response to the agent along with the handle associated with the originating request.

An agent can support one of two different models for managing its object database: internal or external store.

Internal Object Store

An agent that implements internal object store takes full responsibility for managing its associated objects. In this model, the application passes a reference for each managed objects to the agent. The agent manages the set of objects internally, directly accessing the contents of the object in order to service console requests.

With this model, the application's complexity is reduced. The application needs to instantiate the object and register it with the agent. The application also maintains a reference to the object, as the application is responsible for updating the object's properties and the statistics as necessary.

The application must also service method calls invoked on the object. The agent notifies the application when a method call has been requested by a console. The application services the method call, passing the result of the method back to the agent. The agent then relays the response to the originating console.

The application may decide to delete an object instance. The application does this by invoking the destroy() method on the object. This notifies the agent, which will mark the object as deleted in its database. Once the application invokes the destroy() method on an object, it must no longer access the object. The agent will clean up the object at a later point in time.

Internal object store is the default model for agent object managment.

Data Consistency

The internal object store requires sharing of the managed data between the agent and the application. The application is responsible for keeping the data up to date, while the agent is responsible for providing the data to client consoles. It is likely that these components may be implemented in separate execution contexts. This raises the possibility that a data item could be in the process of being written to by the application at the same moment the agent attempts to read it. This would result in invalid data being read.

To prevent this from occuring, the QmfAgentObject class provides accessors for all property and statistic data in the object. These accessors provide atomic access to the underlying data. Therefore, both the agent and the application code must use these accessors to manipulate a shared object's data.

External Object Store

An alternate agent implementation allows the application to take full responsibility for managing the objects. With this model, all instances of managed objects exist external to the agent. When a console requests an action against an object, that action is transferred from the agent to the application. The application then must process the request, and send the result to the agent. The agent then sends a reply to the requesting console.

The model gives full control of the managed objects to the application, but usually requires more application development work.

Agent Class

The base class for the agent object is the Agent class. This base class represents a single agent implementing internal store.

No Format

class Agent:
      <constructor>( vendor=<vendor-string>,
                     product=<product-string>,
                     name=<name-string>,
                     class Notifier ): the vendor/product/name
            combination must uniquely identify this agent instance
            within the QMF domain.  The Notifier is used to alert the
            application to incoming method requests.
      .setConnection( QPID Connection ): connect the agent to the AMQP cloud.
      .registerObjectClass( class SchemaObjectClass ): Register a
            schema for an object class with the agent.  The agent must
            have a registered schema for an object class before it can
            handle objects of that class.
      .registerEventClass( class SchemaEventClass ) : Register a
            schema for an event class with the agent.  The agent must
            have a registered schema for an event class before it can
No Format

class Console:
      <constructor>(name=<name-str>, 
                    notifier=<class Notifier>,
                    timeout=<default for all blocking calls>,
                    subscription_duration=<default lifetime of a subscription>)

      .destroy(timeout=None): Must be called to release Console's resources.

      .addConnection(QPID Connection): Connect the console to the AMQP cloud.

      .removeConnection(conn): Remove the AMQP connection from the
          console.  Un-doeshandle theevents addConnection() operation, andof that class.
      .raiseEvent( class QmfEvent ): releasesCause anythe agentsagent associatedto withraise the connection.  All
          blocking methods are unblocked and given a failure statusevent.
      .addObject( class QmfManaged, object_name=<object Allname outstanding asynchronous operations are cancelledstr> ):
          without producing WorkItems.

passes a reference    .getAddress():
      to an instance of a managed QMF object
    Get the AMQP address this Console is listening to (typethe str)agent.

 The object name must  .findAgent( class AgentId, [timeout | handle] ): Query for the
      presence of a specificuniquely identify this
            object among all objects known to this agent.  Returns a
   class Agent if the agent
     class isObjectId present.containing the Mayobject beidentifier. called
 blocking (with default timeout
  .getWorkItemCount(): Returns the count override),of orpending mayWorkItems allowthat
 asynchronous completion (producing a
      WorkItem with thecan givenbe handle)retrieved.

      .enableAgentDiscoverygetNextWorkItem([timeout=0]): CalledObtains tothe enablenext thepending asynchronouswork
             Agent Discovery process. Once enabled, AGENT_ADD work items
          can arrive on the WorkQueue.

item, or None if none available. 
      .releaseWorkItem(wi): Releases a WorkItem instance obtained by
            .disableAgentDiscoverygetNextWorkItem():. Called towhen disablethe theapplication asynchas Agentfinished
      Discovery    process enabled byprocessing callingthe enableAgentDiscovery()WorkItem.  

      .getWorkItemCount(): Returns the count of pending WorkItems that
methodResponse( handle=<handle from WorkItem>,
           can be retrieved. 

      .getNextWorkItem([timeout=0]): Obtains the next[output pendingargument worklist],
      item, or None if none available. 

      .releaseWorkItem(wi): Releases a WorkItem instance obtained byresult=<status code>,
      getNextWorkItem(). Called when the application has finished
               processing the WorkItem. 

      .getAgents(): Returns a list of available agents (class Agent)

      .getAgent( class AgentId ): Return the class Agent for the
exception=<QmfData> ): Indicate to the agent
            that the application has completed processing a method
            request. A result code namedof agent,zero ifindicates knownsuccess.  If the

      .getPackages( [class Agent] ): Returns a listresult ofcode the names of
      is non-zero, exception may optionally be set to a
    all known packages.  If an optional Agent isQmfData provided,object then
that describes the failure.  On success, zero or
  only those packages available from that Agent are returned.

  more output arguments may .getClasses( [class Agent] ):  Returns a list of SchemaClassKeys
be supplied as defined by the method's
            schema. 

AgentExternal Class

The AgentExternal class must be used by those applications that implement the external store model. The AgentExternal class extends the Agent class by adding interfaces that notify the application when it needs to service a request for management operations from the agent.

No Format

class AgentExternal(Agent):
      <constructor>(vendor, product, name, class Notifier)
 all available Schema.  If an optional Agent is provided,
          then the returned SchemaClassKeys are limited to those.allocObjectId( name="object name"): create a class ObjectId
          Schema known tousing the object givenname Agentprovided.

  The object name must .getSchema(be
 class SchemaClassKey [, class Agent]): Return a list
    unique across all objects known to ofthis allagent. available classReturns SchemaClassa
 across all known agents.
        class  IfObjectId. an optionalOnce Agentthis ismethod providedreturns, restrictthe theagent returnedwill
            schemaservice torequests thosefrom supportedconsoles byreferencing thatthis AgentObjectId.

      .makeObjectfreeObjectId( SchemaClassKey, **kwargsclass ObjectId ): returnsreleases anthe uninitializedObjectId
      instance of a QmfDescribed data object.

 previously allocated by allocObjectId()  method.getObjects( _SchemaClassKey= | _package=, _class= |
Once
            this call is complete, the agent will reject    _objectId=,all further
            requests from consoles     [timeout=],referencing this ObjectId.
      .queryResponse( handle=<handle from WorkItem>,
          [list-of-class-Agent] ): perform a blocking query
       class QmfAgentObject,
   for QmfConsoleObjects.  Returns a list (possibly empty) of matching
          prop=<True objects. The selector for the query may be either:
| False>,
                  * class SchemaClassKey - allstat=<True objects| whoseFalse>): schemasend matcha the
managed object in
            reply to a received query.  schema identified by _SchemaClassKey parameter.If (prop), send object's
           * package/class name - all objects whose schema areproperties. If (stat), send object's statistics.  Note
            that ownership of the object instance is returned containedto by the
 named package and class.
        caller on return *from the object identified by _objectIdthis call.
      .queryComplete( handle=<handle from   This method will block until all known agents reply, or the
WorkItem>, 
                      result=<status code> ):  Indicate to timeout expires. Once the timeoutagent
 expires, all
          that the application has completed processing a query request.
  data retrieved to date is returned.  
   Zero or more calls to the queryResponse() method Ifshould abe
 list of agents is supplied, then the query is sent to
 invoked before calling queryComplete().  If the query should
           only thosefail agents.- for 


example, due to authentication error - .createSubscription( class Query [, duration=<secs> [, list of agents] ): creates a
            subscription using the given Query.  If a list of agents
the result
            should be set to a non-zero error code ?TBD?.
      .subscriptionResponse( handle=<handle from WorkItem>,
                is provided, the Query will apply only to those agents.
    result=<status code>,
       Otherwise it will apply to all active agents, including
            those discovered during the lifetime of the subscription.
subscription_handle=<application context>):
            Indicate the status of Thea durationsubscription argumentrequest. can beIf usedresult
 to override the
         is zero, the console'ssubscription defaultis subscriptionaccepted lifetimeby forthe thisapplication,
            subscription.and an Returnssubscription ahandle classis SubscriptionIdprovided.

  This handle must
  .refreshSubscription( SubscriptionId [, duration=<secs>] ):
      (re)activates a subscription.  Usesbe passed to the application when the console default duration
      unless the duration is explicitly specified.

      .cancelSubscription( SubscriptionId ): terminates theagent unsubscribes.

Asychronous event model.

The Agent uses the same notification driven work queue model as the Console. In the Agent case, the WorkItem supports the following set of work types:

  • METHOD_CALL
  • QUERY
  • SUBSCRIBE
  • UNSUBSCRIBE

In the case of an internal store agent implementation, only the METHOD_CALL work item is generated. An external store agent must support all work item types.

No Format

  METHOD_CALL parameters: ( name=<method name>, 
      subscription. 

Example Console Application

The following pseudo-code performs a blocking query for a particular agent.

No Format

logging.info( "Starting Connection" )
conn  = Connection("localhost")
conn.connect()

logging.info( "Starting Console" )
myConsole = Console()
myConsole.addConnection( conn )

logging.info( "Finding Agent" )
myAgent = myConsole.findAgent( AgentId( "aCompany.com", "Examples", "anAgent" ), _timeout=5 )

if myAgent:
   logging.info( "Agent Found: %s" % myAgent )
else:
   logging.info( "No Agent Found!")

logging.info( "Removing connection" )
myConsole.removeConnection( conn )

logging.info( "Destroying console:" )
myConsole.destroy( _timeout=10 )

The following pseudo-code performs a non-blocking query for all agents. It completes when at least one agent is found.

No Format

class MyNotifier(Notifier):
    def __init__(self, context):
 [argument list],
                            class ObjectId,
                self._myContext = context
        self.WorkAvailable = False

    def console_indication(self):
        print("Indication received! context=%d" % self._myContext)
  user_id=<authenticated id of the user> )

The METHOD_CALL WorkItem describes a method call that must be serviced by the application on behalf of this agent. On completion of the method call, the application must invoke the agent's
methodResponse() method.

No Format

  QUERY parameters: ( class Query, 
          self.WorkAvailable = True

noteMe = MyNotifier( 668 )

logging.info( "Starting Connection" )
conn = Connection("localhost")
conn.connect()

myConsole = Console(notifier=noteMe)
myConsole.addConnection( conn )

myConsole.enableAgentDiscovery()
logging.info("Waiting...")


while not noteMe.WorkAvailable:
    print("No work yet...sleeping!")
    time.sleep(1)


print("Work available = %d items!" % myConsole.getWorkItemCount())
wi = myConsole.getNextWorkitem(timeout=0)
while wi:
    print("work item %d:%s" % (wi.getType(), str(wi.getParams())))
    wi = myConsole.getNextWorkitem(timeout=0)


logging.info( "Removing connection" )
myConsole.remove_connection( conn )

logging.info( "Destroying console:" )
myConsole.destroy( 10 )

Revision History

       user_id=<authenticated id of the user> )

The QUERY WorkItem describes a query that the application must service. The application should call the queryResponse() method for each object that satisfies the query. When complete, the application must call the queryComplete() method. If a failure occurs, the application should indicate the error to the agent by calling the queryComplete() method with a description of the error.

No Format

  SUBSCRIBE parameters: ( class Query, 
                          user_id=<authenticated id of the user> )

The SUBSCRIBE WorkItem provides a query that the application should monitor until the subscription is cancelled. On receipt of this WorkItem, the application should call the subscriptionResponse() agent method to acknowledge the response. Whenever the matching objects are updated, the application should call queryResponse() for each updated object, followed by a call to queryComplete() when done. The subscription remains in effect until an UNSUBSCRIBE WorkItem for the subscription is received.

No Format

  UNSUBSCRIBE parameters: ( <handle associated with subscription> )

Alerts the application that the corresponding subscription has been cancelled. The application should no longer supply query updates against the subscribed query.

Revision History

11/20/2009 - First Revision
11/24/2009 - Added agent classes
12/01/2009 - Cleaned up Schema api and added map definitions.10/20/2009 - First Revision (by kgiusti)