|
|
This chapter contains the following topics:
The FactoryFinder interface provides clients with one object reference that serves as the single point of entry into the WLE domain. The WLE NameManager provides the mapping of factory names to object references for the FactoryFinder. Multiple FactoryFinders and NameManagers together provide increased availability and reliability. In this release, the level of functionality has been extended to support multiple domains.
Note:
The NameManager is not a naming service, such as CORBAservices Naming Service, but is merely a vehicle for storing registered factories.
In the WLE environment, application factory objects are used to create objects that clients interact with to perform their business operations (for example, TellerFactory and Teller). Application factories are generally created during server initialization and are accessed by both remote clients and clients located within the server application.
The FactoryFinder interface and the NameManager services are contained in separate (nonapplication) servers. A set of application programming interfaces (APIs) is provided so that both client and server applications can access and update the factory information.
The support for multiple domains in this release benefits customers that need to scale to a large number of machines or who want to partition their application environment. To support multiple domains, the mechanism used to find factories in a WLE environment has been enhanced to allow factories in one domain to be visible in another. The visibility of factories in other domains is under the control of the system administrator.
During server application initialization, application factories need to be registered with the NameManager. Clients can then be provided with the object reference of a FactoryFinder to allow them to retrieve a factory object reference based on associated names that were created when the factory was registered.
The following functional capabilities, limitations, and requirements apply to this release:
Capabilities, Limitations, and Requirements
The WLE environment promotes the use of the factory design pattern as the primary means for a client to obtain a reference to an object. Through the use of this design pattern, client applications require a mechanism to obtain a reference to an object that acts as a factory for another object. Because the WLE environment has chosen CORBA as its visible programming model, the mechanism used to locate factories is modeled after the FactoryFinder as described in the CORBAservices Specification, Chapter 6 "Life Cycle Service," December 1997, published by the Object Management Group.
In the CORBA FactoryFinder model, application servers register active factories with a FactoryFinder. When an application server's factory becomes inactive, the application server removes the corresponding registration from the FactoryFinder. Client applications locate factories by querying a FactoryFinder. The client application can control the references to the factory object returned by specifying criteria that is used to select one or more references.
A client application must obtain a reference to a FactoryFinder before it can begin locating an appropriate factory. To obtain a reference to a FactoryFinder in the domain to which a client application is associated, the client application must invoke the Tobj_Bootstrap.resolve_initial_references
operation with a value of "FactoryFinder"
. This operation returns a reference to a FactoryFinder that is in the domain to which the client application is currently attached. For more information, see the description of the com.beasys.Tobj_Bootstrap
object in the
Note:
The references to the FactoryFinder that are returned to the client application can be references to factory objects that are registered on the same machine as the FactoryFinder, on a different machine than the FactoryFinder, or possibly in a different domain than the FactoryFinder.
For a client application to be able to obtain a reference to a factory, an application server must register a reference to any factory object for which it provides an implementation with the FactoryFinder (see Figure 5-1). Using the WLE TP Framework, the registration of the reference for the factory object can be accomplished using the TP.register_factory
operation, once a reference to a factory object has been created. The reference to the factory object, along with a value that identifies the factory, is passed to this operation. The registration of references to factory objects is typically done as part of initialization of the application; normally, as part of the implementation of the Server.initialize
operation.
When the server application is shutting down, it must unregister any references to the factory object that it has previously registered in the application server. This is done by passing the same reference to the factory object, along with the corresponding value used to identify the factory, to the TP.unregister_factory
operation. Once unregistered, the reference to the factory object can then be destroyed. The process of unregistering a factory with the FactoryFinder is typically done as part of the implementation of the Server.release
operation. For more information about these operations, see the section "Java TP Framework Interfaces" on page 3-18.
For a client application to request a factory to create a reference to an object, it must first obtain a reference to the factory object. The reference to the factory object is obtained by querying a FactoryFinder with specific selection criteria, as shown in Figure 5-2. The criteria are determined by the format of the particular FactoryFinder interface and method used.
The WLE software extends the CosLifeCycle.FactoryFinder
interface by introducing three methods in addition to the find_factories
method declared for the FactoryFinder. Therefore, using the Tobj extensions, a client can use either the find_factories
or find_factories_by_id
methods to obtain a list of application factories. A client can also use the find_one_factory
or find_one_factory_by_id
method to obtain a single application factory, and the list_factories
method to obtain a list of all registered factories.
The CosLifeCycle.FactoryFinder
interface defines a factory_key
, which is a sequence of id
and kind
strings conforming to the CosNaming Name shown in Listing 5-1. The kind
field of the NameComponent for all WebLogic Enterprise application factories is set to the string FactoryInterface
by the TP Framework when an application factory is registered. Applications supply their own value for the id
field.
Assuming that the CORBAservices Life Cycle Service modules are contained in their own file (ns.idl
and lcs.idl,
respectively), only the OMG IDL code for that subset of both files that is relevant for using the WebLogic Enterprise FactoryFinder is shown in the following listings.
Listing 5-1 shows the portions of the ns.idl
file that are relevant to the FactoryFinder.
Listing 5-1
CORBAservices Naming OMG IDL
// ------ ns.idl ------ module CosNaming { }; // This information is taken from CORBAservices: Common Object Functional Description
Locating a FactoryFinder
Registering a Factory
Figure 5-1 Registering a Factory Object
Locating a Factory
Figure 5-2 Locating a Factory Object
CORBAservices Naming Service Module OMG IDL
typedef string Istring;
struct NameComponent {
Istring id;
Istring kind;
};
typedef sequence <NameComponent> Name;
// Services Specification, page 3-6. Revised Edition:
// March 31, 1995. Updated: November 1997. Used with permission by OMG.
Listing 5-2 shows the portions of the lcs.idl file that are relevant to the FactoryFinder.
Listing 5-2 Life Cycle Service OMG IDL
// ----- lcs.idl -----
#include "ns.idl"
module CosLifeCycle{
typedef CosNaming::Name Key;
typedef Object Factory;
typedef sequence<Factory> Factories;
exception NoFactory{ Key search_key; }
interface FactoryFinder {
Factories find_factories(in Key factory_key)
raises(NoFactory);
};
};
// This information is taken from CORBAservices: Common Object
// Services Specification, pages 6-10, 11. Revised Edition:
// March 31, 1995. Updated: November 1997. Used with permission by OMG.
Listing 5-3 shows the Tobj Module OMG IDL.
Listing 5-3 Tobj Module OMG IDL
// ----- Tobj.idl -----
module Tobj {
// Constants
const string FACTORY_KIND = "FactoryInterface";
// Exceptions
exception CannotProceed { };
exception InvalidDomain {};
exception InvalidName { };
exception RegistrarNotAvailable { };
// Extension to LifeCycle Service
struct FactoryComponent {
CosLifeCycle::Key factory_key;
CosLifeCycle::Factory factory_ior;
};
typedef sequence<FactoryComponent> FactoryListing;
interface FactoryFinder : CosLifeCycle::FactoryFinder {
CosLifeCycle::Factory find_one_factory(in CosLifeCycle::Key
factory_key)
raises (CosLifeCycle::NoFactory,
CannotProceed,
RegistrarNotAvailable);
CosLifeCycle::Factory find_one_factory_by_id(in string
factory_id)
raises (CosLifeCycle::NoFactory,
CannotProceed,
RegistrarNotAvailable);
CosLifeCycle::Factories find_factories_by_id(in string
factory_id)
raises (CosLifeCycle::NoFactory,
CannotProceed,
RegistrarNotAvailable);
FactoryListing list_factories()
raises (CannotProceed,
RegistrarNotAvailable);
};
};
Typically, a FactoryFinder returns references to factory objects that are in the same domain as the FactoryFinder itself. However, it is possible to return references to factory objects in domains other than the domain in which a FactoryFinder exists. This can occur if a FactoryFinder contains information about factories that are resident in another domain (see Figure 5-3). A FactoryFinder finds out about these interdomain factory objects through configuration information that describes the location of these other factory objects.
When a FactoryFinder receives a request to locate a factory object, it must first determine if a reference to a factory object that meets the specified criteria exists. If there is registration information for a factory object that matches the criteria, the FactoryFinder must then determine if the factory object is local to the current domain or needs to be imported from another domain. If the factory object is from the local domain, the FactoryFinder returns the reference to the factory object to the client.
If, on the other hand, the information indicates that the factory object is from another domain, the FactoryFinder delegates the request to an interdomain FactoryFinder in the appropriate domain. As a result, only a FactoryFinder in the same domain as the factory object will contain a reference to the factory object. The interdomain FactoryFinder is responsible for returning the reference of the factory object to the local FactoryFinder, which subsequently returns it to the client.
The WLE software extends the interfaces defined in the CORBAservices specification, Chapter 6 "Life Cycle Service," December 1997, published by the Object Management Group, for the following reasons:
Therefore, WLE extends the interfaces defined in the CORBAservices specification to make using a FactoryFinder easier. The extensions are manifested as refined interfaces to the FactoryFinder that are derived from the interfaces specified in the CORBAservices specification.
Two of the four methods provided in the Tobj.FactoryFinder
interface accept CosLifeCycle.Keys
, which corresponds to CosNaming.Name
. A client must be able to construct these keys.
The CosNaming Specification describes two interfaces that constitute a Names Library interface that can be used to create and manipulate CosLifeCycle.Keys
. The pseudo OMG IDL statements for these interfaces is described in the following section.
Note:
This information is taken from the CORBAservices: Common Object Services Specification, pp. 3-14 to18. Revised Edition: March 31, 1995. Updated: November 1997. Used with permission by OMG.
To allow the representation of names to evolve without affecting existing client applications, it is desirable to hide the representation of names from the client application. Ideally, names themselves would be objects; however, names must be lightweight entities that are efficient to create, manipulate, and transmit. As such, names are presented to programs through the names library.
The names library implements names as pseudo-objects. A client application makes calls on a pseudo-object in the same way it makes calls on an ordinary object. Library names are described in pseudo-IDL (to suggest the appropriate language binding). C++ client applications use the same client language bindings for pseudo-IDL (PIDL) as they use for IDL.
Pseudo-object references cannot be passed across OMG IDL interfaces. As described in Chapter 3 of the CORBAservices: Common Object Services Specification, in the section "The CosNaming Module," the CORBAservices Naming Service supports the NamingContext OMG IDL interface. The names library supports an operation to convert a library name into a value that can be passed to the name service through the NamingContext interface.
Note:
It is not a requirement to use the names library in order to use the CORBAservices Naming Service.
The names library consists of two pseudo-IDL interfaces, the LNameComponent interface and the LName interface, as shown in Listing 5-4.
Listing 5-4
Names Library Interfaces in Pseudo-IDL
interface LNameComponent { // PIDL exception NotSet{ }; string get_id interface LName { // PIDL LName create_lname(); Creating Application Factory Keys
Names Library Interface Pseudo OMG IDL
const short MAX_LNAME_STRLEN = 128;
exception OverFlow{ };
raises (NotSet);
void set_id(in string i)
raises (OverFlow);
string get_kind()
raises(NotSet);
void set_kind(in string k)
raises (OverFlow);
void destroy();
};
exception NoComponent{ };
exception OverFlow{ };
exception InvalidName{ };
LName insert_component(in unsigned long i,
in LNameComponent n)
raises (NoComponent, OverFlow);
LNameComponent get_component(in unsigned long i)
raises (NoComponent);
LNameComponent delete_component(in unsigned long i)
raises (NoComponent);
unsigned long num_components();
boolean equal(in LName ln);
boolean less_than(in LName ln);
Name to_idl_form()
raises (InvalidName);
void from_idl_form(in Name n);
void destroy();
};
LNameComponent create_lname_component();
To create a library name component pseudo-object, use the following method:
LNameComponent create_lname_component();
The returned pseudo-object can then be operated on using the operations shown in Listing 5-4.
To create a library name pseudo-object, use the following method:
LName create_lname();
The returned pseudo-object reference can then be operated on using the operations shown in Listing 5-4.
A name component consists of two attributes: identifier and kind . The LNameComponent interface defines the operations associated with these attributes, as follows:
string get_id()
raises(NotSet);
void set_id(in string k);
string get_kind()
raises(NotSet);
void set_kind(in string k);
The following operations are described in this section:
The destroy operation destroys library name component pseudo-objects.
void destroy();
A name has one or more components. Each component except the last is used to identify names of subcontexts. (The last component denotes the bound object.) The insert_component
operation inserts a component after position i
.
LName insert_component(in unsigned long i, in LNameComponent lnc) If component i
-1 is undefined and component i
is greater than 1 (one), the insert_component
operation raises the NoComponent
exception.
If the library cannot allocate resources for the inserted component, the OverFlow
exception is raised.
The get_component
operation returns the i
th component. The first component is numbered 1 (one).
LNameComponent get_component(in unsigned long i) If the component does not exist, the NoComponent
exception is raised.
The delete_component
operation removes and returns the i
th component.
LNameComponent delete_component(in unsigned long i) If the component does not exist, the NoComponent
exception is raised.
After a delete_component
operation has been performed, the compound name has one fewer component and components previously identified as i+1...n
are now identified as i...n-1
.
The num_components
operation returns the number of components in a library name.
unsigned long num_components();
The equal operation tests for equality with library name ln
.
boolean equal(in LName ln);
The less_than
operation tests for the order of a library name in relation to library name ln
.
boolean less_than(in LName ln);
This operation returns true if the library name is less than the library name ln
passed as an argument. The library implementation defines the ordering on names.
Pseudo-objects cannot be passed across OMG IDL interfaces. The library name is a pseudo-object; therefore, it cannot be passed across the OMG IDL interface for the CORBAservices Naming Service. Several operations in the NamingContext interface have arguments of an OMG IDL-defined structure, Name
. The following PIDL operation on library names produces a structure that can be passed across the OMG IDL request.
Name to_idl_form() If the name is of length 0 (zero), the InvalidName
exception is returned.
Pseudo-objects cannot be passed across OMG IDL interfaces. The library name is a pseudo-object; therefore, it cannot be passed across the OMG IDL interface for the CORBAservices Naming Service. The NamingContext interface defines operations that return an IDL struct of type Name
. The following PIDL operation on library names sets the components and kind
attribute for a library name from a returned OMG IDL defined structure, Name
.
void from_idl_form(in Name n);
The destroy
operation destroys library name pseudo-objects.
void destroy();
The names library pseudo OMG IDL interface maps to the Java classes contained in the com.beasys.Tobj
package, shown in Listing 5-5. All exceptions are contained in the same package.
For a detailed description of the Library Name class, refer to Chapter 3 in the CORBAservices: Common Object Services Specification.
Listing 5-5
Java Mapping for LNameComponent
package com.beasys.Tobj;
public class LNameComponent { package com.beasys.Tobj;
public class LName {
public static LName create_lname(); Destroying a Library Name Component Pseudo-Object
Inserting a Name Component
raises(NoComponent, OverFlow);
Getting the ith Name Component
raises(NoComponent);
Deleting a Name Component
raises(NoComponent);
Number of Name Components
Testing for Equality
Testing for Order
Producing an OMG IDL form
raises(InvalidName);
Translating an IDL Form
Destroying a Library Name Pseudo-Object
Java Mapping
public static LNameComponent create_lname_component();
public static final short MAX_LNAME_STRING = 128;
public void destroy();
public String get_id() throws NotSet;
public void set_id(String i) throws OverFlow;
public String get_kind() throws NotSet;
public void set_kind(String k) throws OverFlow;
};
public void destroy();
public LName insert_component(long i, LNameComponent n)
throws NoComponent, OverFlow;
public LNameComponent get_component(long i)
throws NoComponent;
public LNameComponent delete_component(long i)
throws NoComponent;
public long num_components();
public boolean equal(LName ln);
public boolean less_than(LName ln); // not implemented
public org.omg.CosNaming.NameComponent[] to_idl_form()
throws InvalidName;
public void from_idl_form(org.omg.CosNaming.NameComponent[] nr);
};
The documentation for the Java methods on the FactoryFinder interface is in the Java API Reference.
The following listings show Java programming examples of how to program using the FactoryFinder interface.
Note: Remember to check for exceptions in your code.
Listing 5-6 shows how to program a server to register a factory.
Listing 5-6 Server Application: Registering a Factory
// Register the factory reference with the factory finder.
//
// The second parameter to TP.register_factory() is a string
// identifier that is used to identify the object.
// This same string is used in the call to TP.unregister_factory().
// It is also used in the call to find_one_factory_by_id() that
// is called by clients of this interface.
//
TP.register_factory(
fact_oref, // factory object reference
tellerFName // factory name
);
Listing 5-7 shows how to program a client to get a FactoryFinder object reference.
Listing 5-7 Client Application: Getting a FactoryFinder Object Reference
// Create the Bootstrap object,
// the TOBJADDR properly contains host and port to connect to.
Tobj_Bootstrap bootstrap = new Tobj_Bootstrap (orb,"");
// Use the Bootstrap object to find the factory finder.
org.omg.CORBA.Object fact_finder_oref =
bootstrap.resolve_initial_references("FactoryFinder");
// Narrow the factory finder.
FactoryFinder fact_finder_ref =
FactoryFinderHelper.narrow(fact_finder_oref);
Listing 5-8 shows how to program a client to find one factory using the Tobj approach.
Listing 5-8 Client Application: Finding One Factory Using the Tobj Approach
// Use the factory finder to find the teller factory.
org.omg.CORBA.Object teller_fact_oref =
fact_finder_ref.find_one_factory_by_id("TellerFactory_1");
|
Copyright © 1999 BEA Systems, Inc. All rights reserved.
|