8.6 The Naming Service

The naming service standard provides a mechanism for mapping names to object references. The requester of an IOR provides a name to the naming service and the naming service returns the object reference associated with that name .

The naming service acts as a kind of telephone directory, in which the name is used to look up the number. It allows client and consumer programs to look up object references by name. The naming service can be used to map other application resources in addition to providing simple IOR maps. A mapping from a name to an object reference is called name binding. A collection of name bindings is associated with a naming context object. To illustrate the notion of a naming context, lets say we have an application that does travel planning that consists of a large and diverse collection of objects. We can organize these groups of objects according to function. Some objects are associated with file I/O, some object with security. Other objects are specifically related to transportation: train, bus, car, and bicycle objects. Each grouping forms a context. For instance, to logically group the transportation related objects together we can create a transportation context, and associate each of our forms of transportation with that context. This grouping forms a naming context. We bind the name of each form of transportation with its IOR. This is name binding. We then associate that binding with the transportation context. We use contexts to logically organize groups of related objects. Furthermore, a collection of connected naming contexts forms a naming graph. Naming contexts are represented by objects. Since a naming context is implemented as an object, it can participate in name binding just like any other object. This means that a naming context can potentially contain other naming contexts. For instance, Figure 8-7 contains several contexts including a logical representation for our transportation context.

Figure 8-7. Several different naming contexts.

graphics/08fig07.gif

Notice that the last entry in the transportation context is the name airborne . The airborne name maps to another context named flying_machines . The flying_machines context contains bindings of several objects related by function. The transportation context, together with the flying_machines context, form a naming graph. Notice in Figure 8-7 that the last object in the flying_machines context is named sonic . The sonic name maps to the fast_flying_machines context. That is, the sonic name has an object reference of 8888 . This adds another context to the naming graph. This is an example of one naming context containing another naming context. The naming graph can be used to represent the "big picture" of the structure of the relationships within a distributed object-oriented application. The naming graph captures the landscape of a distributed application. For multiagent systems the naming graph can be used as a kind of semantic network (see sidebar 8.1). Although the objects involved may be scattered among diverse hardware platforms, operating systems, programming languages, and geographical locations, the naming graph can present a single logical structure of the relationships and connections between the objects. Figure 8-8 shows an alternative representation of the naming graph from Figure 8-7. Figure 8-8 has the same naming contexts as Figure 8-7 and it clearly shows the relationships between the naming contexts. Figure 8-8 also demonstrates that there is a path from the transportation context to the fast_flying_machines context and then back to the transportation context.

Figure 8-8. An alternative representation of the naming graph.

graphics/08fig08.gif

Graph traversal algorithms can even be employed to traverse through the naming graph in the process of distributed problem solving. Using traversal in this way, various paths through a naming graph can represent solutions to problems. The naming service provides the requester access to naming contexts and naming graphs. Naming contexts can be accessed through naming graphs. Bindings can be accessed through naming contexts. The binding provides a direct association between a name and an object reference. Program 8.3 shows a simple producer that creates a name binding and associates that name binding with a naming context.

Program 8.3
 1  #include <iostream>  2  #include <fstream>  3  #include "permutation_impl.h"  4  #define MICO_CONF_IMR  5  #include <CORBA-SMALL.h>  6  #include <iostream.h>  7  #include <fstream.h>  8  #include <unistd.h>  9  #include <mico/CosNaming.h> 10 11 12  int main(int argc, char *argv[]) 13  { 14     CORBA::ORB_var Orb = CORBA::ORB_init                              (argc,argv, "mico-local-orb"); 15     CORBA::Object_var PoaObj =              Orb->resolve_initial_references("RootPOA"); 16     PortableServer::POA_var Poa =                         PortableServer::POA::_narrow(PoaObj); 17     PortableServer::POAManager_var Mgr = Poa->the_POAManager(); 18     inversion Server; 19     PortableServer::ObjectId_var Oid =                         Poa->activate_object(&Server); 20     Mgr->activate(); 21     permutation_ptr ObjectReference = Server._this(); 22     CORBA::Object_var NameService =               Orb->resolve_initial_references ("NameService"); 23     CosNaming::NamingContext_var NamingContext =         CosNaming::NamingContext::_narrow (NameService); 24     CosNaming::Name name; 25     name.length (1); 26     name[0].id = CORBA::string_dup ("Inflection"); 27     name[0].kind = CORBA::string_dup (" "); 28     NamingContext->bind (name, ObjectReference); 29     Orb->run(); 30     Poa->destroy(TRUE,TRUE); 31     return(0); 32  } 33 34 

S 8.1. Semantic Networks

A semantic network or semantic net is one of the oldest and easiest to understand knowledge representation schemes. A semantic network is basically a graphic depiction of knowledge that shows the hierarchical relationships between objects. Sidebar Figure 8-1 shows a simple semantic network that conveys knowledge about vehicles in general and knowledge about certain vehicles in particular.

. Sidebar Figure 8-1 A simple vehicle semantic network.

graphics/08sbfig01.gif

The circles in the semantic net are called nodes. The lines are called links. The links represent some kind of relationship between the nodes. The nodes are used to represent objects and facts or descriptors. Links are used to represent relationships and connections. Some links are definitional while other links can be computational. The links can be used to show inheritance or subordination. Together the nodes and the links convey chunks of knowledge. For example, from the semantic network in Sidebar Figure 8-1, we know that a F-15 is a vehicle and a flying machine that has at least two wings. Semantic networks are used to understand and design the knowledge needed by problem-solving software.


8.6.1 Using the Naming Service and Creating Naming Contexts

On line 22, the server program gets a reference to the naming service:

 CORBA::Object_var NameService = Orb->resolve_initial_ references ("NameService"); 

In addition to returning object references for the Implementation Repository and the Interface Repository, the resolve_initial_references() method of the ORB is used to return a reference to the naming service. After obtaining a reference to the naming service, the server program creates a naming context from the object reference of the naming service on line 23:

 CosNaming::NamingContext_var NamingContext = CosNaming::NamingContext::_narrow(NameService); 

This technique provides a naming context referred to as the initial naming context. The initial naming context plays the part of a default context. Once the naming service is located and the initial naming context is created, then the server program can add name/object reference pairs (name bindings) to the context. The names may be domain objects or other contexts. To add a name/object pair to a context, a name must first be created. Names are implemented in the CORBA standard by the NameComponent structure:

 struct NameComponent {    //...    Istring_var id;    Istring_var kind; } 

The MICO implementation of CORBA declaring the NameComponent structure is the CosNaming.h file. The NameComponent structure has two attributes: id and kind . The first attribute is used to hold the text of the name and the second attribute is an identifier that can be used to classify the object. For example:

 //... CosNaming::Name ObjectName; ObjectName.length(1); ObjectName.id = Corba::string_dup("train"); ObjectName.kind = Corba::string_dup("land_transportation"); NamingContext->bind(ObjectName,ObjectReference); //... 

Declares a NameComponent object. The id attribute is set to " train " and the kind attribute is set to land_transportation . Obviously the id attribute should be descriptive of the object. The kind attribute can be used to describe the context or the logical group that the object belongs to. In this case, it classifies train as a land_transportation object. The bind() method maps the ObjectName to the ObjectReference and associates it with the initial naming context. A name can consist of multiple NameComponent objects. If the name only consists of a single NameComponent , it is called a simple name. If it consists of multiple NameComponent objects, it is called a component name. If the name is a compound name, then the kind attribute can be used to describe a relationship. This technique is discussed further in Chapter 12. Program 8.3 binds its object with an object reference and associates it with a naming context. Once it is associated with the naming context, then the client object may access it through the name service. In Programs 8.1 and 8.2, we used a file to communicate a stringified IOR between the consumer program and the producer program. The naming service is used for communication with the client for Program 8.3.

The details for installing and executing the naming service is implementation specific. The MICO environment contains a program named nsd that implements a COS-compliant naming service. The nsd program requires the micod daemon to be running and appropriate entries to be made to the Implementation Repository before the naming service will be available to the consumer program. See the man pages for nsd , micod , and imr for a description of these programs and the MICO manual for a description of how they are used. Furthermore, the MICO distribution is accompanied by a wealth of examples of how to use the imr , nsd , micod , and ird programs. Example 8.5 is an excerpt from the shell script used to set up the server in Program 8.3 so that the name service would be available to the consumer program.

Example 8.5 Shell script that adds an entry to the Implementation Repository and starts the naming service.
  micod  -ORBIIOPAddr inet:hostname:portnumber  -forward &  imr  create NameService poa 'which nsd' IDL:omg.org/CosNaming/ NamingContext:1.0#NameService \     -ORBImplRepoAddr inet:hostname:portnumber \     -ORBNamingAddr inet:hostname:hostname:portnumberportnumber  imr  create permutation persistent "'pwd'/permutation_server \     -ORBImplRepoAddr inet:hostname:portnumber \  -ORBNamingAddr inet:hostname:portnumber" IDL:permutation:1.0 \    -ORBImplRepoAddr inet:hostname:portnumber \  -ORBNamingAddr inet:hostname:portnumber  imr  activate permutation -ORBImplRepoAddr inet:hostname:portnumber \    -ORBNamingAddr inet:hostname:portnumber 

This shell script can be used in conjunction with the server in Program 8.3. In fact, this script actually helps to automatically start the server program named permutation_server . Note that hostname and portnumber in Example 8.5 need to be replaced by the hostname of the computer where the server is running and an appropriate port number.

8.6.2 A Name Service Consumer/Client

Program 8.3 associates the name of an object with a naming context. Program 8.4 contains a consumer program that uses the naming service to access the object/reference bindings that were created in Program 8.3 Program 8.3 produces a permutation of any string of characters that it receives. Permutations are creating by inflections of the characters within a string. For instance:

Objcte

JbOetc

tbOjec

Ojbect

JObetc

 

Ojbcet

JtObec

 

are permutations of the string Object. The client gives the server a string to permute and the server generates N permutations. The server associates the name "Inflection" with the naming context. This name is the name that the client program will have to specify in order to get the object reference from the naming context.

Program 8.4
 1  int main(int argc, char *argv[])  2  {  3  4   try{  5          CORBA::ORB_var Orb = CORBA::ORB_init              (argc,argv,"mico-local-orb");  6          object_reference Remote("NameService",Orb);  7          Remote.objectName("Inflection");  8          permutation_var Client =             permutation::_narrow(Remote.objectReference());  9          char Value[1000]; 10          strcpy(Value,"Common Object Request Broker"); 11          Client->original(Value); 12          int N; 13          for(N = 0;N < 15;N++) 14          { 15          cout << "Value of nextPermutation() "                  << Client->nextPermutation() << endl; 16          } 17      } 18      catch (CosNaming::NamingContext::NotFound_catch &exc) { 19             cerr << " Object NotFound exception" << endl; 20      } 21      catch (CosNaming::NamingContext::InvalidName_catch &exc) { 22              cerr << "InvalidName exception" << endl; 23      } 24 25      return(0); 26  } 

Three steps the consumer program must take to access the appropriate object in the naming context are:

  1. Get a reference to the name service.

  2. Obtain a reference to the appropriate naming context through the name service.

  3. Obtain a reference to the appropriate object through the naming context.

Step 1 is accomplished by calling the resolve_initial_references() method:

 //... CORBA::Object_var NameService; NameService = Orb->resolve_initial_references ("NameService"); //... 

This will return an object reference to the name service. In Step 2 this reference is used to get an object reference for the naming context:

 CosNaming::NamingContext_var NameContext; NameContext = CosNaming::NamingContext::_narrow (NameService); 

The value of NameService is narrowed in Step 3, resulting in an object reference for NameContext . The consumer program needs the NameContext object so that it may call the NameContext 's resolve() method. The technique from Program 8.3 lines 24-27 is used to construct the name that will passed to the NameContext 's resolve() method:

 Name.length (1); Name[0].id = CORBA::string_dup ("Inflection"); Name[0].kind = CORBA::string_dup (" "); try {        ObjectReference = NameContext->resolve (Name); } 

The resolve() method will return the object reference associated with the name. In this case, the object's name is " Inflection ." Note that this is the same name associated with the naming context on line 28 from Program 8.3. Once the consumer program has this object reference, it can be narrowed and then the remote object can be accessed by the consumer program. The process of obtaining an object reference for a remote object is such a common event that it makes sense to simplify the process by encapsulating the components within a class.

 class object_reference{ //... protected:    CORBA::Object_var NameService;    CosNaming::NamingContext_var NameContext;    CosNaming::Name Name;    CORBA::Object_var ObjectReference; public:    object_reference(char *Service,CORBA::ORB_var Orb);    CORBA::Object_var objectReference(void);    void objectName(char *FileName,CORBA::ORB_var Orb);    void objectName(char *OName); //... } 

Program 8.4 takes advantage of the simple skeleton object_reference class that we have created for this purpose.

Notice on line 6 from Program 8.4 that an object named Remote of type object_reference is created. On line 8, this object is used to obtain a reference to the remote object using the method call:

 Remote.objectReference(); 

After making this call the consumer program has access to the remote object. The object_reference class hides some of the work that needs to be done and therefore makes writing the consumer program easier. The constructor for the object_reference class is called on line 6 of Program 8.4. The constructor is implemented as:

 object_reference::object_reference(char *Service,CORBA::ORB_var Orb) {     NameService = Orb->resolve_initial_references (Service);     NameContext = CosNaming::NamingContext::_narrow (NameService); } 

The constructor gets a reference to the name service and instantiates the NameContext object. On line 7, the object's name is passed to the method objectName() . This process will using the naming context to retrieve the object reference associated with the object's name. The objectName() method is implemented as:

 void object_reference::objectName(char *OName) {    Name.length (1);    Name[0].id = CORBA::string_dup (OName);    Name[0].kind = CORBA::string_dup (" ");    try {           ObjectReference = NameContext->resolve (Name);    }    catch(...){         cerr << "   Problem resolving Name  " << endl;    throw;    } } 

After the objectName() method is called the consumer program has access to the remote object's reference. All that is left to do is to call the objectReference() method. This occurs on line 8 of Program 8.4. The resolve() function does most of the work in the objectName() method. Programs 8.3 and 8.4 form a simple distributed client/server application that uses the naming service instead of stringified IORs to communicate object references. Both the naming service approach and the stringified IOR can be used in an intranet or on the Internet. Both can be used as support structure components within the context of the new Web services model.



Parallel and Distributed Programming Using C++
Parallel and Distributed Programming Using C++
ISBN: 0131013769
EAN: 2147483647
Year: 2002
Pages: 133

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net