Directory Service

The Directory Service (DS) is a service that allows agents and services to store information about themselves in records. Each record has a number of entries (key/value pairs) which can be used to store properties. In addition to this, the DS offers a simple query language to find agents and/or services based on their properties.

Primary uses:

  • Locating Services (clients can search for an interface name)
  • Find Agents (based on certain properties)

Each agent can have a number of records in the DS (one for each handle). A service has only a single service ID, and as such also a single record. By default, there is no record associated with an agent handle, but AgentScape creates a simple record for each service, that allows them to be found automatically.

NOTE Since AgentScape 2.0-M4 the directory service is a builtin service. It is automatically activated when starting a host. If you are running an old version of AgentScape, please use the old DS wiki page.

Examples

This section contains some small examples of usage scenarios that frequently occur.

Agent registering itself

An agent can register itself so that other agents are able to find it based on some other properties. The registration process would go as follows:

DSRecordIdentifier id = new DSRecordIdentifier(getPrimaryHandle());
DirectoryService ds = getServiceBroker().bind(DirectoryService.class);
ds.createRecord(id);
ds.addEntry(id, "Name","TestAgent");
ds.addEntry(id, "Age","35");
ds.addEntry(id, "Group","TestGroup");

In this case, the agent creates a record for its primary handle. This handle will be automatically put in the record.

When creating a new DSRecord, several entries are automatically created and added:

  • RecordID contains a string with the AgentHandle of the creating agent (useful for communicating with this agent).
  • CreationTime contains the time the entry was originally created.
  • UpdateTime contains the time the entry was last updated.

Searching for agents

In order to find all agents that match certain criteria, you can perform a query on the DS.

ds.search("Name=TestAgent");
ds.search("Age>=35");
ds.search("Group","TestGroup");

You can perform a search to target a specific agent (by searching for its name), or to find a group of agents. For example, multiple agents can be part of the group TestGroup, so a query on that would yield multiple results. Another option is to search for all agents that have at least a certain age: old agents can be found by using the Age>=35 query.

A reference of all queries that can be performed is here.

Searching for Services

Services will be automatically published in the DS by AgentScape. Services can be found by looking for records with similar properties.

ServiceID=xxx
ServiceInterface=org.iids.aos.services.ServletService
Name=ServletService
Access=World

The most usual case for an agent wanting to bind to a service of a certain interface is

Class target = ServletService.class;
String query = "ServiceInterface=" + target.getName();
Collection<DSRecord> result = ds.search(query);

This query may result in a number of records. The client can look through the list to find the best alternative.

Query Syntax

The directory service query language supports the following operators.

Operator Function Priority
= Equality check 2 (low)
!= Not equal 2 (low)
| OR 1
& AND 1
! NOT 0 (highest)
< Smaller than 2 (low)
<= Smaller or equal 2 (low)
>= Greater than 2 (low)
>= Greater or equal 2 (low)

Query strings can be composed of any combination of operators. To avoid any confusion, it is recommended to use a number of braces.

String query = "((Age>30)|(Name=Test))&(Group=TestGroup)

To test whether a field is specified (regardless of its value) use the ? as value.

String query = "Name=?";

This query will ignore any record that does not have the Name field specified. If a record specified a name (with any value) it will be found by the query.

The result from the query operation is a collection of DSRecord objects. These can be inspected one at a time for further properties.

String query = "Name=?";
Collection<DSRecord> result = ds.search(query);
for (DSRecord rec : result)
{
  for (DSRecordEntry entry : rec.getEntries())
  {
    String key = entry.getKey();
    String value = entry.getValue();
  }
}

Query Utilities

There are a number of utilities to make working with the DS a little bit easier. There are utilities to build queries and to

DSQuery

Class: org.iids.aos.directoryservice.DSQuery

Allows you to compose queries from Java objects. For example, the previous querys could be written like:

// ((Age>30)|(Name=Test))&(Group=TestGroup)
ds.search(DSQuery.AND(
  DSQuery.OR(
    DSQuery.GREATER("Age","30"),
    DSQuery.EQUAL("Name","Test")
  ),
  DSQuery.EQUAL("Group","TestGroup")
));

and

// Name=?
ds.search(DSQuery.CONTAINS("Name"));

DSUtil

Class: org.iids.aos.directoryservice.DSUtil

Allows to make it a little bit easier to extract data from records. For example, if you are only interested in the names of all the agents, you might use the following construct. This will perform a query on all records that have a name, and returns the value of the name fields for all agents.

DirectoryService ds = getServiceBroker().bind(DirectoryService.class);
List<String> names = DSUtil.getValuesFor(ds, DSQuery.CONTAINS("Name"), "Name");

A small variation that returns all names of agents that are older than 70 could use the following strategy.

DirectoryService ds = getServiceBroker().bind(DirectoryService.class);
List<String> names = DSUtil.getValuesFor(ds, DSQuery.GREATER("Age",70), "Name");

API

// Create a new record in the DS, identified by the supplied DSRecordIdentifier.
// This identifier is based on either an AgentHandle or a ServiceID.
createRecord(DSRecordIdentifier id);
 
// Delete a record from the DS, identified by the given identifier.
deleteRecord(DSRecordIdentifier id);
 
// Add a new (or update an existing) entry to the record identified by id.
addEntry(DSRecordIdentifier id, String key, Object value);
 
// Delete the entry identified by /key/ from the record identifier by id.
deleteEntry(DSRecordIdentifier id, String key);
 
// Issue a query to the DS. Returns any records that match the expression specified in the query.
// Matching is supported for text and simple numerical values. Combining and nesting of expressions is supported.
search(String query)
development/service/directoryservice.txt · Last modified: 2013/10/29 11:07 by michel