The CosNaming Service is a service developed to help users and programmers identify objects by human readable names rather than by a reference. By binding a name to a naming context (another object), a contextual reference is formed. This is helpful when navigating in the object space. In addition, identifying objects by name allows you to evolve and/or relocate objects without client code modification.
The CosNaming service has some concepts that are important:
A name is allways resolved in a context, there no absolute names exist. Because a context is like any other object, it can also be bound to a name in a naming context. This will result in a naming graph (a directive graph with notes and labeled edges). The graph allows more complex names to refer to an object. Given a context, you can use a sequence to reference an object. This sequence is henceforth refered to as name and the individual elements in the sequence as name components. All but the last name component are bound to naming contexts.
The diagram in figure 1 illustrates how the Naming Service provides a contextual relationship between objects, NamingContexts and NameBindings to create an object locality,as the object itself, has no name.
The naming contexts provide a directory of contextual reference and naming for objects (an object can appear to have more than one name).
In figure 1 the object to the right can either be
called alpha
from one context or gamma
from another.
The Naming Service has an initial naming context, which is shown
in the diagram as the top-most object in the naming graph.
It has two names beta
and epsilon
, which are bound to other
naming contexts. The initial naming context is a well known location
used to share a common name space between multiple programs.
You can traverse the naming graph until you reach a name, which is
bound to an object, which is not a naming context.
We recommend reading chapter 12, CORBA Fundamentals and Programming, for detailed information regarding the Naming Service.
The basic use-cases of the Naming Service are:
In order to use the naming service you have to fetch an initial reference to it. This is done with:
NS = corba:resolve_initial_references("NameService").
NS in the other use-cases refers to this initial reference. |
There are two functions for creating a naming context. The first function, which only creates a naming context object is:
NC = 'CosNaming_NamingContext':new_context(NS).
The other function creates a naming context and binds it to a name in an already existing naming context (the initial context in this example):
NC = 'CosNaming_NamingContext':bind_new_context(NS, lname:new(["new"])).
The following steps illustrate how to bind/unbind an object reference
to/from a name. For the example below, assume that the NamingContexts
in the path are already bound to the name /workgroup/services
,
and that reference to the services context are in the variable
Sc
.
Name = lname:new(["object"]).
'CosNaming_NamingContext':bind(Sc, Name, Object).
'CosNaming_NamingContext':unbind(Sc, Name).
Objects can have more than one name, to indicate different paths to the same object. |
The following steps show how to retrieve the object reference to the service context above (/workgroup/services).
Name = lname:new(["workgroup", "services"]).
Sc = 'CosNaming_NamingContext':resolve(NS, Name).
An alternative is to use:
Sc = corba:string_to_object("corbaname:rir:/NameService#workgroup/services/").
The corbaname
schema is described further in the Interoperable
Naming Service section.
{BList, BIterator} = 'CosNaming_NamingContext':list(Sc, 10). lists:foreach(fun({{Id, Kind},BindingType}) -> case BindingType of nobject -> io:format("id: %s, kind: %s, type: object~n", [Id, Kind]); _ -> io:format("id: %s, kind: %s, type: ncontext~n", [Id, Kind]) end end, Blist).
Normally a BindingIterator is helpful in situations where you have a large number of objects in a list, as the programmer then can traverse it more easily. In Erlang it is not needed, because lists are easily handled in the language itself. |
Remember that the BindingIterator (BIterator in the example) is an object and therefore
must be removed otherwise dangling processes will occur.
Use |
'CosNaming_NamingContext':destroy(BIterator).
The naming contexts are persistent and must be explicitly removed. (they are also removed if all Orber nodes in the domain are stopped).
'CosNaming_NamingContext':destroy(Sc).
The OMG specifies URL schemes, which represent a CORBA object and a CORBA object bound in a NamingContext, for resolving references from other ORB:s. As of today, three schemes are defined:
A stringified IOR is a valid URL format but difficult for humans to handle through non-electronic means. This URL format does not depeend on a specific Name Service and, thus, is robust and insulates the client from the encapsulated transport information and object key used to reference the object.
The notation of this scheme is similar to the more well known URL http
, and
the full corbaloc
BNF is:
<corbaloc> = "corbaloc:"<obj_addr_list>["/"<key_string>] <obj_addr_list> = [<obj_addr>","]*<obj_addr> <obj_addr> = <prot_addr> | <future_prot_addr> <prot_addr> = <rir_prot_addr> | <iiop_prot_addr> <rir_prot_addr> = <rir_prot_token>":" <rir_prot_token> = rir <future_prot_addr> = <future_prot_id><future_prot_addr> <future_prot_id> = <future_prot_token>":" <iiop_prot_addr> = <iiop_id><iiop_addr> <iiop_id> = <iiop_default> | <iiop_prot_token>":" <iiop_default> = ":" <iiop_prot_token> = "iiop" <iiop_addr> = <version><host>[":"<port>] <host> = DNS-style Host Name | ip_address <version> = <major>"."<minor>"@" | empty_string <port> = number <major> = number <minor> = number <key_string> = for example NameService
The corbaloc
scheme consists of 3 parts:
iiop
or rir
is supported.
Using rir
means that we will resolve the given Key locally, i.e.,
the same as using corba:resolve_initial_references("NameService").
Version
, Host
and Port
. If the version or port are left out they will be set to the default
values 1.0
and 2809
respectively.
A corbaloc
can be passed used together with
corba:string_to_object("corbaloc::1.0@erlang.org:4001/NameService")
or set as the
configuration variables orbInitilRef
or orbDefaultInitilRef
and calling
corba:resolve_initial_references("NameService")
. For more information see the Orber
installation chapter. corbaloc
can also be used together with corbaname
to gain an easy access to a Name Service.
Currently, the OMG defines a set of reserved keys and the type of object,
listed below, they should be associated with. The NameService
key may not be changed in Orber. If you want to add one of the
reserved keys as an initial service, simply use:
1> Factory = cosNotificationApp:start_global_factory(). 2> corba:add_initial_service("NotificationService", Factory).
This object can then be easily resolved by any other ORB, supporting the Interoperable Naming Service, by using:
3> NF = corba:string_to_object("corbaloc::1.0@erlang.org:4001/NotificationService").
String Name | Object Type |
RootPOA | PortableServer::POA |
POACurrent | PortableServer::Current |
InterfaceRepository | CORBA::Repository |
NameService | CosNaming::NamingContext |
TradingService | CosTrading::Lookup |
SecurityCurrent | SecurityLevel1::Current/SecurityLevel2::Current |
TransactionCurrent | CosTransaction::Current |
DynAnyFactory | DynamicAny::DynAnyFactory |
ORBPolicyManager | CORBA::PolicyManager |
PolicyCurrent | CORBA::PolicyCurrent |
NotificationService | CosNotifyChannelAdmin::EventChannelFactory |
TypedNotificationService | CosTypedNotifyChannelAdmin::TypedEventChannelFactory |
CodecFactory | IOP::CodecFactory |
PICurrent | PortableInterceptors::Current |
The corbaname
URL scheme is an extension of the corbaloc
scheme, and
the full corbaname
BNF is:
<corbaname> = "corbaname:"<obj_addr_list>["/"<key_string>]["#"<string_name>] <obj_addr_list> = as described above. <key_string> = as described above.
The string_name
, concatenated to the corbaloc
string, identifies
a binding in a naming context. A name component consists of two parts, i.e.,
id
and kind
, which is represented as follows:
String Name | Name Sequence | Comment |
"id1/./id3.kind3" | [{"id1",""},{"",""},{"id3","kind3"}] | The first component has no kind defined while the second component's both fields are empty. |
"id1//id3.kind3" | ERROR | Not allowed, must insert a '.' between the '//'. |
"id1.kind1/." | [{"id1","kind1"},{"",""}] | The first component's fields are both set while the second component's both fields are empty. |
"id1.kind1/id2." | ERROR | An Id with a trailing '.' is not allowed. |
"i\\/d1/i\\.d2" | [{"i/d1",""},{"i.d2",""}] | Since '.' and '/' are used to separate the components, these tokens must be escaped to be correctly converted. |
After creating a stringified Name we can either use:
NameStr = "org.erlang", NS = corba:resolve_initial_references("NameService"), Obj = 'CosNaming_NamingContextExt':resolve_str(NS, NameStr),
or concatenate the Name String using:
NameStr = "Swedish/Soccer/Champions", Address = "corbaname:iiop:1.0@www.aik.se:2000/NameService", NS = corba:resolve_initial_references("NameService"), URLStr = 'CosNaming_NamingContextExt':to_url(NS, Address, NameStr), Obj = corba:string_to_object(URLStr),
Using the first alternative, the configuration variables orbInitilRef
and
orbDefaultInitilRef
, will determine which other ORB's or the local
Name Service Orber will try to resolve the given string from. The second
alternative allows us to override any settings of the configuration variables.
The function to_url/3
will perform any necessary escapes compliant with
IETF/RFC 2396. US-ASCII alphanumeric characters and
"," | "/" | ":" | "?" | "@" | "&" | "=" | "+" | "$" | ";" | "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
are not escaped.