Lookup-Service

Introduction

The lookup-service allows the user to search for containers by using various lookup-technologies. Searching for containers can be perfomed based on the name of the desired container or any other container property (Meta-Information) like container size, geographical location, data domain etc. Containers can only be found if they have been published explicitly in the first place.

The lookup-service consists of a Lookup-Manager and a set of Lookup-Units performing the lookup itself. The user uses the services of the Lookup-Manager which provides the following three functionalities:

  • publish: to explicitly publish a container. In the course of the process the container name and the Meta-Information of the container are published.
  • unpublish: to unpublish containers.
  • lookup: to perform the lookup of a container and to retrieve its container references. It is possible to search for the name of a container and/or Meta-Information about the container.

Lookup-Manager

The Lookup-Manager manages the various Lookup-Unit implementations. It provides the functionality of the lookup-service for the user. Various Lookup-Unit implementations can be used at once. When publishing a container the Lookup-Manager publishes the container on all known Lookup-Units. When searching for a container, the Lookup-Manager asks the installed Lookup-Units to perform the search. The search will either be stopped immediatly after a container has been found by a Lookup-Unit, or when all of them have finished searching. The order in which the Lookup-Units are called can be configured as well. The Lookup-Manager can be configured in two different ways:

  • using an xml-file
  • using method variables

Lookup-Units

A Lookup-Unit is an implementation of a lookup-technologie. It provides functionalities to the Lookup-Manager, namly lookup, publish and unpublish. The Lookup-Units, which should be used by the Lookup-Manager, have to be specified at the start-up, using an XML-file or a method variable for configuration.

MozartSpaces provides the user with two implementations of a Lookup-Unit:

XVSM Lookup-Unit

The XVSM Lookup-Unit uses basic xvsm containers to perform the search for containers. The lookup-Unit uses a predefined MozartSpaces Core to store the information necessary for the lookup of containers. The remote core uses two containers, namely the "LookupContainer" storing the names, URI, and ContainerRef of published containers and the "LookupContainerDetails" containing the ContainerRef and a set of Meta-Information in a Key-Value pair-structure of the published containers. Those containers are created automatically by the Lookup-Manager, thus the user should not try to delete them by himself.

The following lookup-unit specific parameters have to be specified:

  • RemoteUri: specifies the core that contains the lookup-containers.

The example code below illustrates a valid XML-file, which configures the xvsm lookup-unit:

<?xml version="1.0" encoding="ISO-8859-1"?>
<LookupManager>
   <Lookup Priority="1"> 
      <LookupName>org.xvsm.lookup.xvsm.XVSMLookup</LookupName>
      <!-- The jar file needs to be specified only, if the class is not in the same jar file as the rest -->
      <JarFile>lookup.jar</JarFile>
      <!-- The URI of the server, which will contain the lookup-containers. -->
      <LookupUnitSpecific>
          <RemoteURI>tcpjava://localhost:4321</RemoteURI> 
      </LookupUnitSpecific>
   </Lookup>
</LookupManager>
LDAP Lookup-Unit

The LDAP lookup-service uses an ldap server to store the information necessary for the lookup. Any ldap server can be used for that, which has to be installed and running.

Possible LDAP servers can be found here: [[1]] OpenLDAP (for Linux) http://www.openldap.org/ [[2]] OpenDS (for Windows) https://opends.dev.java.net/

There are various Lookup-Unit specific parameters, for the LDAP dependent configuration:

  • INITIAL_CONTEXT_FACTORY: This is the LDAP implementation. Normally should this parameter be "com.sun.jndi.ldap.LdapCtxFactory".
  • PROVIDER_URL: This is the Url of the LDAP server.
  • SECURITY_PRINCIPAL: a valid username for the LDAP server
  • SECURITY_CREDENTIALS: a valid password for the user specified above
  • SECURITY_AUTHENTICATION: The type auf authentication, that can be used. This can be left away, or it can be "none", "simple", etc. For further information consult the manual of your LDAP server.
  • For further LDAP-server specific parameters consult the manual of your LDAP server.

The example code below illustrates a valid XML-file, which is configures the LDAP Lookup-Unit:

<?xml version="1.0" encoding="ISO-8859-1"?>
<LookupManager>
   <Lookup Priority="1">
      <LookupName>org.xvsm.lookup.ldap.LDAPLookup</LookupName>
      <!-- The jar file needs to be specified only, if the class is not in the same jar file as the rest -->
      <JarFile>lookup.jar</JarFile>
      <!-- This depends on the configuration of your LDAP server. -->
      <LookupUnitSpecific>
          <INITIAL_CONTEXT_FACTORY>com.sun.jndi.ldap.LdapCtxFactory</INITIAL_CONTEXT_FACTORY>
          <PROVIDER_URL>ldap://localhost:389/dc=example,dc=com</PROVIDER_URL>
          <REFERRAL>follow</REFERRAL>
          <SECURITY_PRINCIPAL>cn=UserName</SECURITY_PRINCIPAL>
          <SECURITY_CREDENTIALS>12345678</SECURITY_CREDENTIALS>
      </LookupUnitSpecific>
   </Lookup>
</LookupManager>

Using The Lookup-Service

Configuration

There are two possible ways to configure the Lookup-Manager.

1) Configuration can be done by using an XML-File
The XML-file has to contain all the necessary parameters of all the Lookup-Units, which should be used.

There are two categories of parameters, which have to be specified:

  1. Lookup-Manager specific parameters
    • Properties: specifies the behaviour of the manager.
    • AskAllUnits: specifies, if lookup should be aborted after the first successful lookup-operation(false), or if all received results from every Lookup-Unit should be merged(true).
    • Priority: This parameter specifies the order, in which a lookup will be done. The priority has to be unique.
    • LookupName: The name of the class (including packages), that implements the Lookup-Unit.
    • JarFile: The name of the jar file, which contains the class. This parameter does not have to be specified, if the class is in the same jar file, as the Lookup-Manager.
  2. Lookup-Unit specific parameters

    Each Lookup-Unit may require different parameters. Currently, the XVSM Lookup-Unit and the LDAP Lookup-Unit have been implemented.

The example code below illustrates a valid XML-file:

<?xml version="1.0" encoding="ISO-8859-1"?>
<LookupManager ="">
   <Properties>
      <!-- the default-value for AskAllUnits is false, if it is not specified -->
      <Property Key="AskAllUnits">false</Property>
   </Properties>
   <Lookup Priority="1"> 
      <LookupName>org.xvsm.lookup.xvsm.XVSMLookup</LookupName>
      <!-- The jar file needs only to be specified, if the class is not in the same jar file as the rest -->
      <JarFile>lookup.jar</JarFile>
      <!-- The URI of the server, which will contain the lookup-containers. -->
      <LookupUnitSpecific>
          <RemoteURI>tcpjava://localhost:4321</RemoteURI> 
      </LookupUnitSpecific>
   </Lookup>
   <Lookup Priority="2">
      <LookupName>org.xvsm.lookup.ldap.LDAPLookup</LookupName>
      <!-- The jar file needs only to be specified, if the class is not in the same jar file as the rest -->
      <JarFile>lookup.jar</JarFile>
      <!-- This depends on the configuration of your LDAP server. -->
      <LookupUnitSpecific>
          <INITIAL_CONTEXT_FACTORY>com.sun.jndi.ldap.LdapCtxFactory</INITIAL_CONTEXT_FACTORY>
          <PROVIDER_URL>ldap://localhost:389/dc=example,dc=com</PROVIDER_URL>
          <REFERRAL>follow</REFERRAL>
          <SECURITY_PRINCIPAL>cn=UserName</SECURITY_PRINCIPAL>
          <SECURITY_CREDENTIALS>12345678</SECURITY_CREDENTIALS>
      </LookupUnitSpecific>
   </Lookup>
</LookupManager>

2) Configuration using an environment variable: The Lookup-Manager can also be configured using a method variable. The possibilities are the same, as when using an xml-file.

Example:

Capi capi = new Capi();
Hashtable<String, String> table = new Hashtable<String, String>();
// the default-value for AskAllUnits is false, if it is not specified
table.put("AskAllUnits", "false");
// 1 of Lookup1 specifies the priority.
table.put("Lookup1", "org.xvsm.lookup.xvsm.XVSMLookup");
table.put("org.xvsm.lookup.xvsm.XVSMLookup.JarFile", "lookup.jar");
table.put("org.xvsm.lookup.xvsm.XVSMLookup.RemoteURI", "tcpjava://localhost:4321");
// 2 of Lookup2 specifies the priority. 1 must exist, if 2 is used. It is not possible to specify the priority 2 if 1 has not been specified.
table.put("Lookup2", "org.xvsm.lookup.ldap.LDAPLookup");
table.put("org.xvsm.lookup.xvsm.LDAPLookup.JarFile", "lookup.jar");
// The names are the same as in the xml-file. Just with the prefix "org.xvsm.lookup.xvsm.LDAPLookup.".
table.put("org.xvsm.lookup.xvsm.LDAPLookup.INITIAL_CONTEXT_FACTORY", "com.sun.jndi.ldap.LdapCtxFactory"); 
table.put("org.xvsm.lookup.xvsm.LDAPLookup.PROVIDER_URL", "ldap://localhost:389/dc=example,dc=com");
table.put("org.xvsm.lookup.xvsm.LDAPLookup.REFERRAL", "follow");
table.put("org.xvsm.lookup.xvsm.LDAPLookup.SECURITY_PRINCIPAL", "cn=UserName");
table.put("org.xvsm.lookup.xvsm.LDAPLookup.SECURITY_CREDENTIALS", "12345678");

// the first parameter of the constructor always specifies the "local-peer". null means, that there is an embedded MozartSpaces server.
LookupManager lm = new LookupManager(null, table);
                
lm.lookup("Test-Container");
...

Application Usage

A simple example demonstrating how to use the lookup-service:

Capi capi = new Capi();
// the first parameter of the constructor always specifies the "local-peer". null means, that there is an embedded MozartSpaces server.
LookupManager lm = new LookupManager(null); 
ContainerRef cref1 = capi.createContainer(null, null, "test1", IContainer.INFINITE_SIZE, new LindaCoordinator());
lm.publish(cref1);

...

ContainerRef[] crefe1 = lm.lookup("test1");
Publish

The container reference is the only parameter needed to publish a container. Publish will try to publish the container on all Lookup-Unit implementations.

Example:

Capi capi = new Capi();

// the first parameter of the constructor always specifies the "local-peer". null means, that there is an embedded MozartSpaces server.
LookupManager lm = new LookupManager(null, table); 
                
ContainerRef cref1 = capi.createContainer(null, null, "test1", IContainer.INFINITE_SIZE, new LindaCoordinator());
lm.publish(cref1);
Unpublish

The container reference is the only parameter needed to unpublish a container. Unpublish will try to unpublish the container on all Lookup-Unit implementations.

Example:

Capi capi = new Capi();

// the first parameter of the constructor always specifies the "local-peer". null means, that there is an embedded MozartSpaces server.
LookupManager lm = new LookupManager(null, table); 
                
ContainerRef cref1 = capi.createContainer(null, null, "test1", IContainer.INFINITE_SIZE, new LindaCoordinator());
lm.publish(cref1);

...

lm.unpublish(cref1);
Lookup

Lookup will look up a container. It is possible to look up a container reference based on its name and/or Meta-Information. How to add Meta-Information to a container in the correct format will be explained later in the chapter Meta-Information. If the user tries to look up a containername the search is performed on the local MozartSpaces core first. If it cannot be found there the Lookup-Manager will conduct the installed Lookup-Units to perform the search for the required container.

Example, look up a containername:

Capi capi = new Capi();

// the first parameter of the constructor always specifies the "local-peer". null means, that there is an embedded MozartSpaces server.
LookupManager lm = new LookupManager(null, table); 
                
lm.lookup("Test-Container");

Example, look up Meta-Information:

Capi capi = new Capi();

// the first parameter of the constructor always specifies the "local-peer". null means, that there is an embedded MozartSpaces server.
LookupManager lm = new LookupManager(null, table); 
                
Hashtable<String, String> list = new Hashtable<String, String>(); 
list.put("sitze", "2");
list.put("Farbe", "schwarz");

lm.lookup(list);

Example, lookup a containername and Meta-Information:

Capi capi = new Capi();

// the first parameter of the constructor always specifies the "local-peer". null means, that there is an embedded MozartSpaces server.
LookupManager lm = new LookupManager(null, table); 
                
Hashtable<String, String> list = new Hashtable<String, String>(); 
list.put("sitze", "2");
list.put("Farbe", "schwarz");

lm.lookup("Test-Container", list);
Update Description

If the Meta-Information of a container is changed, after the container has been published, the Lookup-Units have to be informed. The Lookup-Manager provides the function UpdateDescription(ContainerRef) for this.

Example:

Capi capi = new Capi();

// the first parameter of the constructor always specifies the "local-peer". null means, that there is an embedded MozartSpaces server.
LookupManager lm = new LookupManager(null, table); 
                
ContainerRef cref1 = capi.createContainer(null, null, "test1", IContainer.INFINITE_SIZE, new LindaCoordinator());
lm.publish(cref1);

...

lm.updateDescription(cref1);

Publishing Meta-Information

Meta-Information has to be stored in the right format to be recognized by the Lookup-Units. The following example illustrates how to store the key-value pairs "sitze", "2" and "Farbe", "schwarz" in the right format.

// cref specifies the container-reference of the container, for that the Meta-Information will be stored
ContainerRef metaCref = capi.lookupMetaContainer(null, cref); 
ContainerRef info = null;

try {
        info = (ContainerRef)((AtomicEntry) capi.read(metaCref, 0, null,
        new KeySelector<String>("system", "meta_information"))[0]).getValue();
}
catch(CountNotMetException cnme) {
        info = capi.createContainer(null, null, null, IContainer.INFINITE_SIZE, new LindaCoordinator());
        capi.write(metaCref, 0, null,
                        new AtomicEntry<ContainerRef>(info, ContainerRef.class,
                        new KeySelector<String>("system", "meta_information")));
}
        
Entry a1 = new AtomicEntry<String>("sitze");
Entry a2 = new AtomicEntry<String>("2");
Tuple t1 = new Tuple(a1, a2);
                
capi.shift(info, null, t1);

Entry a3 = new AtomicEntry<String>("Farbe");
Entry a4 = new AtomicEntry<String>("schwarz");
Tuple t2 = new Tuple(a3, a4);
                
capi.shift(info, null, t2);